Compare commits
48 Commits
v6.1.3
...
5ed52554d7
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ed52554d7 | |||
| 75286a1626 | |||
| 9bc17a1f2b | |||
| 86850e9020 | |||
| d4562a1deb | |||
| 62ccfc77de | |||
| 0df3b41ca0 | |||
| 5cb601200c | |||
| 342c8b693b | |||
| 24d8754033 | |||
| 966e466c9e | |||
| 37ec67e9a3 | |||
| 364ba99b1f | |||
| 9252e90bd6 | |||
| ae0fef4626 | |||
| 5b4a7b8b74 | |||
| a9680db218 | |||
| 7aa57e154e | |||
| 05f4ae7719 | |||
| 29b6252935 | |||
| f324d4cc7d | |||
| 310f0711fa | |||
| 9580dc6560 | |||
| 70e317f373 | |||
| 285b3c37f9 | |||
| 41f6738e97 | |||
| 22e6ff2cdf | |||
| be36432f24 | |||
| 4bea9a1d12 | |||
| 35ce3580e5 | |||
| 90eb5778ca | |||
| c0539a4fb0 | |||
| da85a7a2a7 | |||
| 3c52ce98d4 | |||
| ae048201a2 | |||
| dad27f8d06 | |||
| c0b512be60 | |||
| cef7fd4b02 | |||
| c09da77e2b | |||
| 18e8396a44 | |||
| 1bef0415db | |||
| d6a83baf4f | |||
| 605ff8183a | |||
| e231107e81 | |||
| 71501e15e5 | |||
| 0187087da0 | |||
| 05ad3d7155 | |||
| ea8272d7d4 |
+24
-13
@@ -150,7 +150,6 @@ LoginAPI() {
|
|||||||
|
|
||||||
# Try to login again until the session is valid
|
# Try to login again until the session is valid
|
||||||
while [ ! "${validSession}" = true ] ; do
|
while [ ! "${validSession}" = true ] ; do
|
||||||
echo "Authentication failed. Please enter your Pi-hole password"
|
|
||||||
|
|
||||||
# Print the error message if there is one
|
# Print the error message if there is one
|
||||||
if [ ! "${sessionError}" = "null" ] && [ "${1}" = "verbose" ]; then
|
if [ ! "${sessionError}" = "null" ] && [ "${1}" = "verbose" ]; then
|
||||||
@@ -161,6 +160,14 @@ LoginAPI() {
|
|||||||
echo "Error: ${sessionMessage}"
|
echo "Error: ${sessionMessage}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${1}" = "verbose" ]; then
|
||||||
|
# If we are not in verbose mode, no need to print the error message again
|
||||||
|
echo "Please enter your Pi-hole password"
|
||||||
|
else
|
||||||
|
|
||||||
|
echo "Authentication failed. Please enter your Pi-hole password"
|
||||||
|
fi
|
||||||
|
|
||||||
# secretly read the password
|
# secretly read the password
|
||||||
secretRead; printf '\n'
|
secretRead; printf '\n'
|
||||||
|
|
||||||
@@ -183,13 +190,20 @@ Authentication() {
|
|||||||
echo "No response from FTL server. Please check connectivity"
|
echo "No response from FTL server. Please check connectivity"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# obtain validity, session ID and sessionMessage from session response
|
|
||||||
validSession=$(echo "${sessionResponse}"| jq .session.valid 2>/dev/null)
|
|
||||||
SID=$(echo "${sessionResponse}"| jq --raw-output .session.sid 2>/dev/null)
|
|
||||||
sessionMessage=$(echo "${sessionResponse}"| jq --raw-output .session.message 2>/dev/null)
|
|
||||||
|
|
||||||
# obtain the error message from the session response
|
# obtain validity, session ID, sessionMessage and error message from
|
||||||
sessionError=$(echo "${sessionResponse}"| jq --raw-output .error.message 2>/dev/null)
|
# session response, apply default values if none returned
|
||||||
|
result=$(echo "${sessionResponse}" | jq -r '
|
||||||
|
(.session.valid // false),
|
||||||
|
(.session.sid // null),
|
||||||
|
(.session.message // null),
|
||||||
|
(.error.message // null)
|
||||||
|
' 2>/dev/null)
|
||||||
|
|
||||||
|
validSession=$(echo "${result}" | sed -n '1p')
|
||||||
|
SID=$(echo "${result}" | sed -n '2p')
|
||||||
|
sessionMessage=$(echo "${result}" | sed -n '3p')
|
||||||
|
sessionError=$(echo "${result}" | sed -n '4p')
|
||||||
|
|
||||||
if [ "${1}" = "verbose" ]; then
|
if [ "${1}" = "verbose" ]; then
|
||||||
if [ "${validSession}" = true ]; then
|
if [ "${validSession}" = true ]; then
|
||||||
@@ -353,12 +367,9 @@ apiFunc() {
|
|||||||
if [ "${verbosity}" = "verbose" ]; then
|
if [ "${verbosity}" = "verbose" ]; then
|
||||||
echo "Data:"
|
echo "Data:"
|
||||||
fi
|
fi
|
||||||
|
# Attempt to print the data with jq, if it is not valid JSON, or not installed
|
||||||
if command -v jq >/dev/null && echo "${data}" | jq . >/dev/null 2>&1; then
|
# then print the plain text.
|
||||||
echo "${data}" | jq .
|
echo "${data}" | jq . 2>/dev/null || echo "${data}"
|
||||||
else
|
|
||||||
echo "${data}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Delete the session
|
# Delete the session
|
||||||
LogoutAPI "${verbosity}"
|
LogoutAPI "${verbosity}"
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
# This file is copyright under the latest version of the EUPL.
|
# This file is copyright under the latest version of the EUPL.
|
||||||
# Please see LICENSE file for your rights under this license.
|
# Please see LICENSE file for your rights under this license.
|
||||||
|
|
||||||
readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
||||||
readonly utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||||
# shellcheck source="./advanced/Scripts/utils.sh"
|
# shellcheck source="./advanced/Scripts/utils.sh"
|
||||||
source "${utilsfile}"
|
source "${utilsfile}"
|
||||||
|
|
||||||
readonly apifile="${PI_HOLE_SCRIPT_DIR}/api.sh"
|
apifile="${PI_HOLE_SCRIPT_DIR}/api.sh"
|
||||||
# shellcheck source="./advanced/Scripts/api.sh"
|
# shellcheck source="./advanced/Scripts/api.sh"
|
||||||
source "${apifile}"
|
source "${apifile}"
|
||||||
|
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Pi-hole: A black hole for Internet advertisements
|
|
||||||
# (c) 2019 Pi-hole, LLC (https://pi-hole.net)
|
|
||||||
# Network-wide ad blocking via your own hardware.
|
|
||||||
#
|
|
||||||
# ARP table interaction
|
|
||||||
#
|
|
||||||
# This file is copyright under the latest version of the EUPL.
|
|
||||||
# Please see LICENSE file for your rights under this license.
|
|
||||||
|
|
||||||
coltable="/opt/pihole/COL_TABLE"
|
|
||||||
if [[ -f ${coltable} ]]; then
|
|
||||||
# shellcheck source="./advanced/Scripts/COL_TABLE"
|
|
||||||
source ${coltable}
|
|
||||||
fi
|
|
||||||
|
|
||||||
readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
|
||||||
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
|
||||||
# shellcheck source=./advanced/Scripts/utils.sh
|
|
||||||
source "${utilsfile}"
|
|
||||||
|
|
||||||
# Determine database location
|
|
||||||
DBFILE=$(getFTLConfigValue "files.database")
|
|
||||||
if [ -z "$DBFILE" ]; then
|
|
||||||
DBFILE="/etc/pihole/pihole-FTL.db"
|
|
||||||
fi
|
|
||||||
|
|
||||||
flushARP(){
|
|
||||||
local output
|
|
||||||
if [[ "${args[1]}" != "quiet" ]]; then
|
|
||||||
echo -ne " ${INFO} Flushing network table ..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Stop FTL to prevent database access
|
|
||||||
if ! output=$(service pihole-FTL stop 2>&1); then
|
|
||||||
echo -e "${OVER} ${CROSS} Failed to stop FTL"
|
|
||||||
echo " Output: ${output}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Truncate network_addresses table in pihole-FTL.db
|
|
||||||
# This needs to be done before we can truncate the network table due to
|
|
||||||
# foreign key constraints
|
|
||||||
if ! output=$(pihole-FTL sqlite3 -ni "${DBFILE}" "DELETE FROM network_addresses" 2>&1); then
|
|
||||||
echo -e "${OVER} ${CROSS} Failed to truncate network_addresses table"
|
|
||||||
echo " Database location: ${DBFILE}"
|
|
||||||
echo " Output: ${output}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Truncate network table in pihole-FTL.db
|
|
||||||
if ! output=$(pihole-FTL sqlite3 -ni "${DBFILE}" "DELETE FROM network" 2>&1); then
|
|
||||||
echo -e "${OVER} ${CROSS} Failed to truncate network table"
|
|
||||||
echo " Database location: ${DBFILE}"
|
|
||||||
echo " Output: ${output}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Flush ARP cache of the host
|
|
||||||
if ! output=$(ip -s -s neigh flush all 2>&1); then
|
|
||||||
echo -e "${OVER} ${CROSS} Failed to flush ARP cache"
|
|
||||||
echo " Output: ${output}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Start FTL again
|
|
||||||
if ! output=$(service pihole-FTL restart 2>&1); then
|
|
||||||
echo -e "${OVER} ${CROSS} Failed to restart FTL"
|
|
||||||
echo " Output: ${output}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${args[1]}" != "quiet" ]]; then
|
|
||||||
echo -e "${OVER} ${TICK} Flushed network table"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
args=("$@")
|
|
||||||
|
|
||||||
case "${args[0]}" in
|
|
||||||
"arpflush" ) flushARP;;
|
|
||||||
esac
|
|
||||||
Executable
+84
@@ -0,0 +1,84 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
|
# (c) 2019 Pi-hole, LLC (https://pi-hole.net)
|
||||||
|
# Network-wide ad blocking via your own hardware.
|
||||||
|
#
|
||||||
|
# Network table flush
|
||||||
|
#
|
||||||
|
# This file is copyright under the latest version of the EUPL.
|
||||||
|
# Please see LICENSE file for your rights under this license.
|
||||||
|
|
||||||
|
coltable="/opt/pihole/COL_TABLE"
|
||||||
|
if [[ -f ${coltable} ]]; then
|
||||||
|
# shellcheck source="./advanced/Scripts/COL_TABLE"
|
||||||
|
source ${coltable}
|
||||||
|
fi
|
||||||
|
|
||||||
|
readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
||||||
|
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||||
|
# shellcheck source=./advanced/Scripts/utils.sh
|
||||||
|
source "${utilsfile}"
|
||||||
|
|
||||||
|
# Source api functions
|
||||||
|
# shellcheck source="./advanced/Scripts/api.sh"
|
||||||
|
. "${PI_HOLE_SCRIPT_DIR}/api.sh"
|
||||||
|
|
||||||
|
flushNetwork(){
|
||||||
|
local output
|
||||||
|
|
||||||
|
echo -ne " ${INFO} Flushing network table ..."
|
||||||
|
|
||||||
|
local data status error
|
||||||
|
# Authenticate with FTL
|
||||||
|
LoginAPI
|
||||||
|
|
||||||
|
# send query again
|
||||||
|
data=$(PostFTLData "action/flush/network" "" "status")
|
||||||
|
|
||||||
|
# Separate the status from the data
|
||||||
|
status=$(printf %s "${data#"${data%???}"}")
|
||||||
|
data=$(printf %s "${data%???}")
|
||||||
|
|
||||||
|
# If there is an .error object in the returned data, display it
|
||||||
|
local error
|
||||||
|
error=$(jq --compact-output <<< "${data}" '.error')
|
||||||
|
if [[ $error != "null" && $error != "" ]]; then
|
||||||
|
echo -e "${OVER} ${CROSS} Failed to flush the network table:"
|
||||||
|
echo -e " $(jq <<< "${data}" '.error')"
|
||||||
|
LogoutAPI
|
||||||
|
exit 1
|
||||||
|
elif [[ "${status}" == "200" ]]; then
|
||||||
|
echo -e "${OVER} ${TICK} Flushed network table"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Delete session
|
||||||
|
LogoutAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
flushArp(){
|
||||||
|
# Flush ARP cache of the host
|
||||||
|
if ! output=$(ip -s -s neigh flush all 2>&1); then
|
||||||
|
echo -e "${OVER} ${CROSS} Failed to flush ARP cache"
|
||||||
|
echo " Output: ${output}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Process all options (if present)
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
"--arp" ) doARP=true ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
flushNetwork
|
||||||
|
|
||||||
|
if [[ "${doARP}" == true ]]; then
|
||||||
|
echo -ne " ${INFO} Flushing ARP cache"
|
||||||
|
if flushArp; then
|
||||||
|
echo -e "${OVER} ${TICK} Flushed ARP cache"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
+14
-24
@@ -37,19 +37,16 @@ Options:
|
|||||||
}
|
}
|
||||||
|
|
||||||
GenerateOutput() {
|
GenerateOutput() {
|
||||||
local data gravity_data lists_data num_gravity num_lists search_type_str
|
local counts data num_gravity num_lists search_type_str
|
||||||
local gravity_data_csv lists_data_csv line current_domain url type color
|
local gravity_data_csv lists_data_csv line url type color
|
||||||
data="${1}"
|
data="${1}"
|
||||||
|
|
||||||
# construct a new json for the list results where each object contains the domain and the related type
|
# Get count of list and gravity matches
|
||||||
lists_data=$(printf %s "${data}" | jq '.search.domains | [.[] | {domain: .domain, type: .type}]')
|
# Use JQ to count number of entries in lists and gravity
|
||||||
|
# (output is number of list matches then number of gravity matches)
|
||||||
# construct a new json for the gravity results where each object contains the adlist URL and the related domains
|
counts=$(printf %s "${data}" | jq --raw-output '(.search.domains | length), (.search.gravity | group_by(.address,.type) | length)')
|
||||||
gravity_data=$(printf %s "${data}" | jq '.search.gravity | group_by(.address,.type) | map({ address: (.[0].address), type: (.[0].type), domains: [.[] | .domain] })')
|
num_lists=$(echo "$counts" | sed -n '1p')
|
||||||
|
num_gravity=$(echo "$counts" | sed -n '2p')
|
||||||
# number of objects in each json
|
|
||||||
num_gravity=$(printf %s "${gravity_data}" | jq length)
|
|
||||||
num_lists=$(printf %s "${lists_data}" | jq length)
|
|
||||||
|
|
||||||
if [ "${partial}" = true ]; then
|
if [ "${partial}" = true ]; then
|
||||||
search_type_str="partially"
|
search_type_str="partially"
|
||||||
@@ -62,7 +59,7 @@ GenerateOutput() {
|
|||||||
if [ "${num_lists}" -gt 0 ]; then
|
if [ "${num_lists}" -gt 0 ]; then
|
||||||
# Convert the data to a csv, each line is a "domain,type" string
|
# Convert the data to a csv, each line is a "domain,type" string
|
||||||
# not using jq's @csv here as it quotes each value individually
|
# not using jq's @csv here as it quotes each value individually
|
||||||
lists_data_csv=$(printf %s "${lists_data}" | jq --raw-output '.[] | [.domain, .type] | join(",")')
|
lists_data_csv=$(printf %s "${data}" | jq --raw-output '.search.domains | map([.domain, .type] | join(",")) | join("\n")')
|
||||||
|
|
||||||
# Generate output for each csv line, separating line in a domain and type substring at the ','
|
# Generate output for each csv line, separating line in a domain and type substring at the ','
|
||||||
echo "${lists_data_csv}" | while read -r line; do
|
echo "${lists_data_csv}" | while read -r line; do
|
||||||
@@ -71,11 +68,11 @@ GenerateOutput() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Results from gravity
|
# Results from gravity
|
||||||
printf "%s\n\n" "Found ${num_gravity} adlists ${search_type_str} matching '${COL_BLUE}${domain}${COL_NC}'."
|
printf "%s\n\n" "Found ${num_gravity} lists ${search_type_str} matching '${COL_BLUE}${domain}${COL_NC}'."
|
||||||
if [ "${num_gravity}" -gt 0 ]; then
|
if [ "${num_gravity}" -gt 0 ]; then
|
||||||
# Convert the data to a csv, each line is a "URL,domain,domain,...." string
|
# Convert the data to a csv, each line is a "URL,type,domain,domain,...." string
|
||||||
# not using jq's @csv here as it quotes each value individually
|
# not using jq's @csv here as it quotes each value individually
|
||||||
gravity_data_csv=$(printf %s "${gravity_data}" | jq --raw-output '.[] | [.address, .type, .domains[]] | join(",")')
|
gravity_data_csv=$(printf %s "${data}" | jq --raw-output '.search.gravity | group_by(.address,.type) | map([.[0].address, .[0].type, (.[] | .domain)] | join(",")) | join("\n")')
|
||||||
|
|
||||||
# Generate line-by-line output for each csv line
|
# Generate line-by-line output for each csv line
|
||||||
echo "${gravity_data_csv}" | while read -r line; do
|
echo "${gravity_data_csv}" | while read -r line; do
|
||||||
@@ -97,15 +94,8 @@ GenerateOutput() {
|
|||||||
|
|
||||||
# cut off type, leaving "domain,domain,...."
|
# cut off type, leaving "domain,domain,...."
|
||||||
line=${line#*,}
|
line=${line#*,}
|
||||||
# print each domain and remove it from the string until nothing is left
|
# Replace commas with newlines and format output
|
||||||
while [ ${#line} -gt 0 ]; do
|
echo "${line}" | sed 's/,/\n/g' | sed "s/^/ - ${COL_GREEN}/" | sed "s/$/${COL_NC}/"
|
||||||
current_domain=${line%%,*}
|
|
||||||
printf ' - %s\n' "${COL_GREEN}${current_domain}${COL_NC}"
|
|
||||||
# we need to remove the current_domain and the comma in two steps because
|
|
||||||
# the last domain won't have a trailing comma and the while loop wouldn't exit
|
|
||||||
line=${line#"${current_domain}"}
|
|
||||||
line=${line#,}
|
|
||||||
done
|
|
||||||
printf "\n\n"
|
printf "\n\n"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -73,7 +73,9 @@ getFTLPID() {
|
|||||||
# Example getFTLConfigValue dns.piholePTR
|
# Example getFTLConfigValue dns.piholePTR
|
||||||
#######################
|
#######################
|
||||||
getFTLConfigValue(){
|
getFTLConfigValue(){
|
||||||
pihole-FTL --config -q "${1}"
|
# Pipe to cat to avoid pihole-FTL assuming this is an interactive command
|
||||||
|
# returning colored output.
|
||||||
|
pihole-FTL --config -q "${1}" | cat
|
||||||
}
|
}
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
@@ -86,9 +88,17 @@ getFTLConfigValue(){
|
|||||||
# setFTLConfigValue dns.upstreams '[ "8.8.8.8" , "8.8.4.4" ]'
|
# setFTLConfigValue dns.upstreams '[ "8.8.8.8" , "8.8.4.4" ]'
|
||||||
#######################
|
#######################
|
||||||
setFTLConfigValue(){
|
setFTLConfigValue(){
|
||||||
pihole-FTL --config "${1}" "${2}" >/dev/null
|
local err
|
||||||
if [ $? -eq 5 ]; then
|
{ pihole-FTL --config "${1}" "${2}" >/dev/null; err="$?"; } || true
|
||||||
printf " %s %s set by environment variable. Please unset it to use this function\n" "${CROSS}" "${1}"
|
|
||||||
exit 5
|
case $err in
|
||||||
fi
|
0) ;;
|
||||||
|
5)
|
||||||
|
# FTL returns 5 if the value was set by an environment variable and is therefore read-only
|
||||||
|
printf " %s %s set by environment variable. Please unset it to use this function\n" "${CROSS}" "${1}";
|
||||||
|
exit 5;;
|
||||||
|
*)
|
||||||
|
printf " %s Failed to set %s. Try with sudo power\n" "${CROSS}" "${1}"
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
_pihole() {
|
_pihole() {
|
||||||
local cur prev opts opts_checkout opts_debug opts_logging opts_query opts_update opts_version
|
local cur prev opts opts_lists opts_checkout opts_debug opts_logging opts_query opts_update opts_networkflush
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
@@ -7,7 +7,7 @@ _pihole() {
|
|||||||
|
|
||||||
case "${prev}" in
|
case "${prev}" in
|
||||||
"pihole")
|
"pihole")
|
||||||
opts="allow allow-regex allow-wild deny checkout debug disable enable flush help logging query repair regex reloaddns reloadlists status tail uninstall updateGravity updatePihole version wildcard arpflush api"
|
opts="allow allow-regex allow-wild deny checkout debug disable enable flush help logging query repair regex reloaddns reloadlists setpassword status tail uninstall updateGravity updatePihole version wildcard networkflush api"
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||||
;;
|
;;
|
||||||
"allow"|"deny"|"wildcard"|"regex"|"allow-regex"|"allow-wild")
|
"allow"|"deny"|"wildcard"|"regex"|"allow-regex"|"allow-wild")
|
||||||
@@ -34,9 +34,13 @@ _pihole() {
|
|||||||
opts_update="--check-only"
|
opts_update="--check-only"
|
||||||
COMPREPLY=( $(compgen -W "${opts_update}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts_update}" -- ${cur}) )
|
||||||
;;
|
;;
|
||||||
"core"|"admin"|"ftl")
|
"networkflush")
|
||||||
|
opts_networkflush="--arp"
|
||||||
|
COMPREPLY=( $(compgen -W "${opts_networkflush}" -- ${cur}) )
|
||||||
|
;;
|
||||||
|
"core"|"web"|"ftl")
|
||||||
if [[ "$prev2" == "checkout" ]]; then
|
if [[ "$prev2" == "checkout" ]]; then
|
||||||
opts_checkout="master dev"
|
opts_checkout="master development"
|
||||||
COMPREPLY=( $(compgen -W "${opts_checkout}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts_checkout}" -- ${cur}) )
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -116,11 +116,11 @@ c=70
|
|||||||
PIHOLE_META_PACKAGE_CONTROL_APT=$(
|
PIHOLE_META_PACKAGE_CONTROL_APT=$(
|
||||||
cat <<EOM
|
cat <<EOM
|
||||||
Package: pihole-meta
|
Package: pihole-meta
|
||||||
Version: 0.4
|
Version: 0.5
|
||||||
Maintainer: Pi-hole team <adblock@pi-hole.net>
|
Maintainer: Pi-hole team <adblock@pi-hole.net>
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Description: Pi-hole dependency meta package
|
Description: Pi-hole dependency meta package
|
||||||
Depends: awk,bash-completion,binutils,ca-certificates,cron|cron-daemon,curl,dialog,dnsutils,dns-root-data,git,grep,iproute2,iputils-ping,jq,libcap2,libcap2-bin,lshw,netcat-openbsd,procps,psmisc,sudo,unzip
|
Depends: awk,bash-completion,binutils,ca-certificates,cron|cron-daemon,curl,dialog,dnsutils,dns-root-data,git,grep,iproute2,iputils-ping,jq,libcap2,libcap2-bin,lshw,procps,psmisc,sudo,unzip
|
||||||
Section: contrib/metapackages
|
Section: contrib/metapackages
|
||||||
Priority: optional
|
Priority: optional
|
||||||
EOM
|
EOM
|
||||||
@@ -130,12 +130,12 @@ EOM
|
|||||||
PIHOLE_META_PACKAGE_CONTROL_RPM=$(
|
PIHOLE_META_PACKAGE_CONTROL_RPM=$(
|
||||||
cat <<EOM
|
cat <<EOM
|
||||||
Name: pihole-meta
|
Name: pihole-meta
|
||||||
Version: 0.2
|
Version: 0.3
|
||||||
Release: 1
|
Release: 1
|
||||||
License: EUPL
|
License: EUPL
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
Summary: Pi-hole dependency meta package
|
Summary: Pi-hole dependency meta package
|
||||||
Requires: bash-completion,bind-utils,binutils,ca-certificates,chkconfig,cronie,curl,dialog,findutils,gawk,git,grep,iproute,jq,libcap,lshw,nmap-ncat,procps-ng,psmisc,sudo,unzip
|
Requires: bash-completion,bind-utils,binutils,ca-certificates,chkconfig,cronie,curl,dialog,findutils,gawk,git,grep,iproute,jq,libcap,lshw,procps-ng,psmisc,sudo,unzip
|
||||||
%description
|
%description
|
||||||
Pi-hole dependency meta package
|
Pi-hole dependency meta package
|
||||||
%prep
|
%prep
|
||||||
@@ -143,6 +143,9 @@ Pi-hole dependency meta package
|
|||||||
%files
|
%files
|
||||||
%install
|
%install
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Jul 14 2025 Pi-hole Team - 0.3
|
||||||
|
- Remove nmap-ncat from the list of dependencies
|
||||||
|
|
||||||
* Wed May 28 2025 Pi-hole Team - 0.2
|
* Wed May 28 2025 Pi-hole Team - 0.2
|
||||||
- Add gawk to the list of dependencies
|
- Add gawk to the list of dependencies
|
||||||
|
|
||||||
@@ -164,6 +167,17 @@ for var in "$@"; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [[ "${runUnattended}" == true ]]; then
|
||||||
|
# In order to run an unattended setup, a pre-seeded /etc/pihole/pihole.toml must exist
|
||||||
|
if [[ ! -f "${PI_HOLE_CONFIG_DIR}/pihole.toml" ]]; then
|
||||||
|
printf " %b Error: \"%s\" not found. Cannot run unattended setup\\n" "${CROSS}" "${PI_HOLE_CONFIG_DIR}/pihole.toml"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
printf " %b Performing unattended setup, no dialogs will be displayed\\n" "${INFO}"
|
||||||
|
# also disable debconf-apt-progress dialogs
|
||||||
|
export DEBIAN_FRONTEND="noninteractive"
|
||||||
|
fi
|
||||||
|
|
||||||
# If the color table file exists,
|
# If the color table file exists,
|
||||||
if [[ -f "${coltable}" ]]; then
|
if [[ -f "${coltable}" ]]; then
|
||||||
# source it
|
# source it
|
||||||
@@ -1791,8 +1805,12 @@ FTLinstall() {
|
|||||||
# Before stopping FTL, we download the macvendor database
|
# Before stopping FTL, we download the macvendor database
|
||||||
curl -sSL "https://ftl.pi-hole.net/macvendor.db" -o "${PI_HOLE_CONFIG_DIR}/macvendor.db" || true
|
curl -sSL "https://ftl.pi-hole.net/macvendor.db" -o "${PI_HOLE_CONFIG_DIR}/macvendor.db" || true
|
||||||
|
|
||||||
# Stop pihole-FTL service if available
|
|
||||||
stop_service pihole-FTL >/dev/null
|
# If the binary already exists in /usr/bin, then we need to stop the service
|
||||||
|
# If the binary does not exist (fresh installs), then we can skip this step.
|
||||||
|
if [[ -f /usr/bin/pihole-FTL ]]; then
|
||||||
|
stop_service pihole-FTL >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
# Install the new version with the correct permissions
|
# Install the new version with the correct permissions
|
||||||
install -T -m 0755 "${binary}" /usr/bin/pihole-FTL
|
install -T -m 0755 "${binary}" /usr/bin/pihole-FTL
|
||||||
@@ -2235,15 +2253,6 @@ main() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${fresh_install}" == false ]]; then
|
|
||||||
# if it's running unattended,
|
|
||||||
if [[ "${runUnattended}" == true ]]; then
|
|
||||||
printf " %b Performing unattended setup, no dialogs will be displayed\\n" "${INFO}"
|
|
||||||
# also disable debconf-apt-progress dialogs
|
|
||||||
export DEBIAN_FRONTEND="noninteractive"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${fresh_install}" == true ]]; then
|
if [[ "${fresh_install}" == true ]]; then
|
||||||
# Display welcome dialogs
|
# Display welcome dialogs
|
||||||
welcomeDialogs
|
welcomeDialogs
|
||||||
|
|||||||
+5
-4
@@ -105,9 +105,9 @@ Available commands and options:
|
|||||||
Flush the Pi-hole log
|
Flush the Pi-hole log
|
||||||
.br
|
.br
|
||||||
|
|
||||||
\fB-r, reconfigure\fR
|
\fB-r, repair\fR
|
||||||
.br
|
.br
|
||||||
Reconfigure or Repair Pi-hole subsystems
|
Repair Pi-hole subsystems
|
||||||
.br
|
.br
|
||||||
|
|
||||||
\fB-t, tail\fR [arg]
|
\fB-t, tail\fR [arg]
|
||||||
@@ -317,9 +317,10 @@ Switching Pi-hole subsystem branches
|
|||||||
Switch to core development branch
|
Switch to core development branch
|
||||||
.br
|
.br
|
||||||
|
|
||||||
\fBpihole arpflush\fR
|
\fBpihole networkflush\fR
|
||||||
.br
|
.br
|
||||||
Flush information stored in Pi-hole's network tables
|
Flush information stored in Pi-hole's network table
|
||||||
|
Add '--arp' to additionally flush the ARP table
|
||||||
.br
|
.br
|
||||||
|
|
||||||
\fBpihole api stats/summary\fR
|
\fBpihole api stats/summary\fR
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
# This file is copyright under the latest version of the EUPL.
|
# This file is copyright under the latest version of the EUPL.
|
||||||
# Please see LICENSE file for your rights under this license.
|
# Please see LICENSE file for your rights under this license.
|
||||||
|
|
||||||
readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
||||||
|
|
||||||
# PI_HOLE_BIN_DIR is not readonly here because in some functions (checkout),
|
# PI_HOLE_BIN_DIR is not readonly here because in some functions (checkout),
|
||||||
# they might get set again when the installer is sourced. This causes an
|
# they might get set again when the installer is sourced. This causes an
|
||||||
@@ -20,7 +20,7 @@ readonly colfile="${PI_HOLE_SCRIPT_DIR}/COL_TABLE"
|
|||||||
# shellcheck source=./advanced/Scripts/COL_TABLE
|
# shellcheck source=./advanced/Scripts/COL_TABLE
|
||||||
source "${colfile}"
|
source "${colfile}"
|
||||||
|
|
||||||
readonly utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||||
# shellcheck source=./advanced/Scripts/utils.sh
|
# shellcheck source=./advanced/Scripts/utils.sh
|
||||||
source "${utilsfile}"
|
source "${utilsfile}"
|
||||||
|
|
||||||
@@ -96,8 +96,18 @@ flushFunc() {
|
|||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Deprecated function, should be removed in the future
|
||||||
|
# use networkFlush instead
|
||||||
arpFunc() {
|
arpFunc() {
|
||||||
"${PI_HOLE_SCRIPT_DIR}"/piholeARPTable.sh "$@"
|
shift
|
||||||
|
echo -e " ${INFO} The 'arpflush' command is deprecated, use 'networkflush' instead"
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/piholeNetworkFlush.sh "$@"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
networkFlush() {
|
||||||
|
shift
|
||||||
|
"${PI_HOLE_SCRIPT_DIR}"/piholeNetworkFlush.sh "$@"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,10 +157,11 @@ uninstallFunc() {
|
|||||||
|
|
||||||
versionFunc() {
|
versionFunc() {
|
||||||
exec "${PI_HOLE_SCRIPT_DIR}"/version.sh
|
exec "${PI_HOLE_SCRIPT_DIR}"/version.sh
|
||||||
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadDNS() {
|
reloadDNS() {
|
||||||
local svcOption svc str output status pid icon FTL_PID_FILE
|
local svcOption svc str output status pid icon FTL_PID_FILE sigrtmin
|
||||||
svcOption="${1:-reload}"
|
svcOption="${1:-reload}"
|
||||||
|
|
||||||
# get the current path to the pihole-FTL.pid
|
# get the current path to the pihole-FTL.pid
|
||||||
@@ -169,7 +180,10 @@ reloadDNS() {
|
|||||||
str="FTL is not running"
|
str="FTL is not running"
|
||||||
icon="${INFO}"
|
icon="${INFO}"
|
||||||
else
|
else
|
||||||
svc="kill -RTMIN ${pid}"
|
sigrtmin="$(pihole-FTL sigrtmin 2>/dev/null)"
|
||||||
|
# Make sure sigrtmin is a number, otherwise fallback to RTMIN
|
||||||
|
[[ "${sigrtmin}" =~ ^[0-9]+$ ]] || unset sigrtmin
|
||||||
|
svc="kill -${sigrtmin:-RTMIN} ${pid}"
|
||||||
str="Reloading DNS lists"
|
str="Reloading DNS lists"
|
||||||
icon="${TICK}"
|
icon="${TICK}"
|
||||||
fi
|
fi
|
||||||
@@ -264,6 +278,7 @@ Time:
|
|||||||
LogoutAPI
|
LogoutAPI
|
||||||
|
|
||||||
echo -e "${OVER} ${TICK} ${str}"
|
echo -e "${OVER} ${TICK} ${str}"
|
||||||
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
piholeLogging() {
|
piholeLogging() {
|
||||||
@@ -519,7 +534,8 @@ Options:
|
|||||||
reloadlists Update the lists WITHOUT flushing the cache or restarting the DNS server
|
reloadlists Update the lists WITHOUT flushing the cache or restarting the DNS server
|
||||||
checkout Switch Pi-hole subsystems to a different GitHub branch
|
checkout Switch Pi-hole subsystems to a different GitHub branch
|
||||||
Add '-h' for more info on checkout usage
|
Add '-h' for more info on checkout usage
|
||||||
arpflush Flush information stored in Pi-hole's network tables";
|
networkflush Flush information stored in Pi-hole's network tables
|
||||||
|
Add '--arp' to additionally flush the ARP table ";
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,7 +544,7 @@ if [[ $# = 0 ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# functions that do not require sudo power
|
# functions that do not require sudo power
|
||||||
need_root=1
|
need_root=
|
||||||
case "${1}" in
|
case "${1}" in
|
||||||
"-h" | "help" | "--help" ) helpFunc;;
|
"-h" | "help" | "--help" ) helpFunc;;
|
||||||
"-v" | "version" ) versionFunc;;
|
"-v" | "version" ) versionFunc;;
|
||||||
@@ -536,31 +552,32 @@ case "${1}" in
|
|||||||
"-q" | "query" ) queryFunc "$@";;
|
"-q" | "query" ) queryFunc "$@";;
|
||||||
"status" ) statusFunc "$2";;
|
"status" ) statusFunc "$2";;
|
||||||
"tricorder" ) tricorderFunc;;
|
"tricorder" ) tricorderFunc;;
|
||||||
|
"allow" | "allowlist" ) listFunc "$@";;
|
||||||
|
"deny" | "denylist" ) listFunc "$@";;
|
||||||
|
"--wild" | "wildcard" ) listFunc "$@";;
|
||||||
|
"--regex" | "regex" ) listFunc "$@";;
|
||||||
|
"--allow-regex" | "allow-regex" ) listFunc "$@";;
|
||||||
|
"--allow-wild" | "allow-wild" ) listFunc "$@";;
|
||||||
|
"enable" ) piholeEnable true "$2";;
|
||||||
|
"disable" ) piholeEnable false "$2";;
|
||||||
|
"api" ) shift; apiFunc "$@"; exit 0;;
|
||||||
|
|
||||||
# we need to add all arguments that require sudo power to not trigger the * argument
|
# we need to add all arguments that require sudo power to not trigger the * argument
|
||||||
"allow" | "allowlist" ) need_root=0;;
|
"-f" | "flush" ) need_root=true;;
|
||||||
"deny" | "denylist" ) need_root=0;;
|
"-up" | "updatePihole" ) need_root=true;;
|
||||||
"--wild" | "wildcard" ) need_root=0;;
|
"-r" | "repair" ) need_root=true;;
|
||||||
"--regex" | "regex" ) need_root=0;;
|
"-l" | "logging" ) need_root=true;;
|
||||||
"--allow-regex" | "allow-regex" ) need_root=0;;
|
"uninstall" ) need_root=true;;
|
||||||
"--allow-wild" | "allow-wild" ) need_root=0;;
|
"-d" | "debug" ) need_root=true;;
|
||||||
"-f" | "flush" ) ;;
|
"-g" | "updateGravity" ) need_root=true;;
|
||||||
"-up" | "updatePihole" ) ;;
|
"reloaddns" ) need_root=true;;
|
||||||
"-r" | "repair" ) ;;
|
"reloadlists" ) need_root=true;;
|
||||||
"-l" | "logging" ) ;;
|
"setpassword" ) need_root=true;;
|
||||||
"uninstall" ) ;;
|
"checkout" ) need_root=true;;
|
||||||
"enable" ) need_root=0;;
|
"updatechecker" ) need_root=true;;
|
||||||
"disable" ) need_root=0;;
|
"arpflush" ) need_root=true;; # Deprecated, use networkflush instead
|
||||||
"-d" | "debug" ) ;;
|
"networkflush" ) need_root=true;;
|
||||||
"-g" | "updateGravity" ) ;;
|
"-t" | "tail" ) need_root=true;;
|
||||||
"reloaddns" ) ;;
|
|
||||||
"reloadlists" ) ;;
|
|
||||||
"setpassword" ) ;;
|
|
||||||
"checkout" ) ;;
|
|
||||||
"updatechecker" ) ;;
|
|
||||||
"arpflush" ) ;;
|
|
||||||
"-t" | "tail" ) ;;
|
|
||||||
"api" ) need_root=0;;
|
|
||||||
* ) helpFunc;;
|
* ) helpFunc;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -572,20 +589,15 @@ fi
|
|||||||
|
|
||||||
# Check if the current user is not root and if the command
|
# Check if the current user is not root and if the command
|
||||||
# requires root. If so, exit with an error message.
|
# requires root. If so, exit with an error message.
|
||||||
if [[ $EUID -ne 0 && need_root -eq 1 ]];then
|
# Add an exception for the user "pihole" to allow the webserver running gravity
|
||||||
echo -e " ${CROSS} The Pi-hole command requires root privileges, try:"
|
if [[ ( $EUID -ne 0 && ${USER} != "pihole" ) && -n "${need_root}" ]]; then
|
||||||
|
echo -e " ${CROSS} This Pi-hole command requires root privileges, try:"
|
||||||
echo -e " ${COL_GREEN}sudo pihole $*${COL_NC}"
|
echo -e " ${COL_GREEN}sudo pihole $*${COL_NC}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Handle redirecting to specific functions based on arguments
|
# Handle redirecting to specific functions based on arguments
|
||||||
case "${1}" in
|
case "${1}" in
|
||||||
"allow" | "allowlist" ) listFunc "$@";;
|
|
||||||
"deny" | "denylist" ) listFunc "$@";;
|
|
||||||
"--wild" | "wildcard" ) listFunc "$@";;
|
|
||||||
"--regex" | "regex" ) listFunc "$@";;
|
|
||||||
"--allow-regex" | "allow-regex" ) listFunc "$@";;
|
|
||||||
"--allow-wild" | "allow-wild" ) listFunc "$@";;
|
|
||||||
"-d" | "debug" ) debugFunc "$@";;
|
"-d" | "debug" ) debugFunc "$@";;
|
||||||
"-f" | "flush" ) flushFunc "$@";;
|
"-f" | "flush" ) flushFunc "$@";;
|
||||||
"-up" | "updatePihole" ) updatePiholeFunc "$@";;
|
"-up" | "updatePihole" ) updatePiholeFunc "$@";;
|
||||||
@@ -593,15 +605,13 @@ case "${1}" in
|
|||||||
"-g" | "updateGravity" ) updateGravityFunc "$@";;
|
"-g" | "updateGravity" ) updateGravityFunc "$@";;
|
||||||
"-l" | "logging" ) piholeLogging "$@";;
|
"-l" | "logging" ) piholeLogging "$@";;
|
||||||
"uninstall" ) uninstallFunc;;
|
"uninstall" ) uninstallFunc;;
|
||||||
"enable" ) piholeEnable true "$2";;
|
|
||||||
"disable" ) piholeEnable false "$2";;
|
|
||||||
"reloaddns" ) reloadDNS "reload";;
|
"reloaddns" ) reloadDNS "reload";;
|
||||||
"reloadlists" ) reloadDNS "reload-lists";;
|
"reloadlists" ) reloadDNS "reload-lists";;
|
||||||
"setpassword" ) SetWebPassword "$@";;
|
"setpassword" ) SetWebPassword "$@";;
|
||||||
"checkout" ) piholeCheckoutFunc "$@";;
|
"checkout" ) piholeCheckoutFunc "$@";;
|
||||||
"updatechecker" ) shift; updateCheckFunc "$@";;
|
"updatechecker" ) shift; updateCheckFunc "$@";;
|
||||||
"arpflush" ) arpFunc "$@";;
|
"arpflush" ) arpFunc "$@";; # Deprecated, use networkflush instead
|
||||||
|
"networkflush" ) networkFlush "$@";;
|
||||||
"-t" | "tail" ) tailFunc "$2";;
|
"-t" | "tail" ) tailFunc "$2";;
|
||||||
"api" ) shift; apiFunc "$@";;
|
|
||||||
* ) helpFunc;;
|
* ) helpFunc;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ pyyaml == 6.0.2
|
|||||||
pytest == 8.4.1
|
pytest == 8.4.1
|
||||||
pytest-xdist == 3.8.0
|
pytest-xdist == 3.8.0
|
||||||
pytest-testinfra == 10.2.2
|
pytest-testinfra == 10.2.2
|
||||||
tox == 4.27.0
|
tox == 4.28.4
|
||||||
pytest-clarity == 1.0.1
|
pytest-clarity == 1.0.1
|
||||||
|
|||||||
Reference in New Issue
Block a user