Merge pull request #1468 from pi-hole/tweak/help-output

New Help Output
This commit is contained in:
Adam Warner 2017-05-14 16:46:58 +01:00 committed by GitHub
commit ed04be5faa
6 changed files with 429 additions and 443 deletions

View file

@ -8,7 +8,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.
#Functions############################################################################################################## # Functions
piLog="/var/log/pihole.log" piLog="/var/log/pihole.log"
gravity="/etc/pihole/gravity.list" gravity="/etc/pihole/gravity.list"
@ -67,7 +67,7 @@ normalChrono() {
echo " ${IPV4_ADDRESS}" echo " ${IPV4_ADDRESS}"
echo "" echo ""
uptime | cut -d' ' -f11- uptime | cut -d' ' -f11-
#uptime -p #Doesn't work on all versions of uptime #uptime -p # Doesn't work on all versions of uptime
uptime | awk -F'( |,|:)+' '{if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}' uptime | awk -F'( |,|:)+' '{if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'
echo "-------------------------------" echo "-------------------------------"
echo "Recently blocked:" echo "Recently blocked:"
@ -82,16 +82,13 @@ normalChrono() {
} }
displayHelp() { displayHelp() {
cat << EOM echo "Usage: pihole -c [options]
::: Displays stats about your piHole! Example: 'pihole -c -j'
::: Calculates stats and displays to an LCD
::: Usage: sudo pihole -c [optional:-j]
::: Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds Options:
::: -j, --json Output stats as JSON formatted string
::: Options: -h, --help Display this help text"
::: -j, --json output stats as JSON formatted string
::: -h, --help display this help text
EOM
exit 0 exit 0
} }

View file

@ -3,14 +3,12 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net) # (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware. # Network-wide ad blocking via your own hardware.
# #
# Whitelists and blacklists domains # Whitelist and blacklist domains
# #
# 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.
# Globals
#globals
basename=pihole basename=pihole
piholeDir=/etc/${basename} piholeDir=/etc/${basename}
whitelist=${piholeDir}/whitelist.txt whitelist=${piholeDir}/whitelist.txt
@ -27,8 +25,7 @@ listMain=""
listAlt="" listAlt=""
helpFunc() { helpFunc() {
if [[ "${listMain}" == "${whitelist}" ]]; then
if [[ ${listMain} == ${whitelist} ]]; then
letter="w" letter="w"
word="white" word="white"
else else
@ -36,22 +33,23 @@ helpFunc() {
word="black" word="black"
fi fi
cat << EOM echo "Usage: pihole -${letter} [options] <domain> <domain2 ...>
::: Immediately ${word}lists one or more domains in the hosts file Example: 'pihole -${letter} site.com', or 'pihole -${letter} site1.com site2.com'
::: ${word^}list one or more domains
::: Usage: pihole -${letter} domain1 [domain2 ...]
::: Options:"
::: Options:
::: -d, --delmode Remove domains from the ${word}list if [[ "${letter}" == "b" ]]; then
::: -nr, --noreload Update ${word}list without refreshing dnsmasq echo " -wild, --wildcard Add wildcard entry to blacklist"
::: -q, --quiet Output is less verbose fi
::: -h, --help Show this help dialog
::: -l, --list Display your ${word}listed domains echo " -d, --delmode Remove domain(s) from the ${word}list
EOM -nr, --noreload Update ${word}list without refreshing dnsmasq
if [[ "${letter}" == "b" ]]; then -q, --quiet Make output less verbose
echo "::: -wild, --wildcard Add wildcard entry (only blacklist)" -h, --help Show this help dialog
fi -l, --list Display all your ${word}listed domains"
exit 0
exit 0
} }
EscapeRegexp() { EscapeRegexp() {
@ -61,13 +59,13 @@ EscapeRegexp() {
echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g" echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
} }
HandleOther(){ HandleOther() {
# First, convert everything to lowercase # First, convert everything to lowercase
domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1") domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
#check validity of domain # Check validity of domain
validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/') validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/')
if [ -z "${validDomain}" ]; then if [[ -z "${validDomain}" ]]; then
echo "::: $1 is not a valid argument or domain name" echo "::: $1 is not a valid argument or domain name"
else else
domList=("${domList[@]}" ${validDomain}) domList=("${domList[@]}" ${validDomain})
@ -75,12 +73,13 @@ HandleOther(){
} }
PoplistFile() { PoplistFile() {
#check whitelist file exists, and if not, create it # Check whitelist file exists, and if not, create it
if [[ ! -f ${whitelist} ]]; then if [[ ! -f ${whitelist} ]]; then
touch ${whitelist} touch ${whitelist}
fi fi
for dom in "${domList[@]}"; do for dom in "${domList[@]}"; do
# Logic : If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other # Logic: If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other
if ${addmode}; then if ${addmode}; then
AddDomain "${dom}" "${listMain}" AddDomain "${dom}" "${listMain}"
RemoveDomain "${dom}" "${listAlt}" RemoveDomain "${dom}" "${listAlt}"
@ -98,13 +97,12 @@ AddDomain() {
domain=$(EscapeRegexp "$1") domain=$(EscapeRegexp "$1")
if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
bool=true bool=true
#Is the domain in the list we want to add it to? # Is the domain in the list we want to add it to?
grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
if [[ "${bool}" == false ]]; then if [[ "${bool}" == false ]]; then
#domain not found in the whitelist file, add it! # Domain not found in the whitelist file, add it!
if [[ "${verbose}" == true ]]; then if [[ "${verbose}" == true ]]; then
echo "::: Adding $1 to $list..." echo "::: Adding $1 to $list..."
fi fi
@ -116,16 +114,14 @@ AddDomain() {
echo "::: ${1} already exists in ${list}, no need to add!" echo "::: ${1} already exists in ${list}, no need to add!"
fi fi
fi fi
elif [[ "${list}" == "${wildcardlist}" ]]; then elif [[ "${list}" == "${wildcardlist}" ]]; then
source "${piholeDir}/setupVars.conf" source "${piholeDir}/setupVars.conf"
#Remove the /* from the end of the IPv4addr. # Remove the /* from the end of the IPv4addr.
IPV4_ADDRESS=${IPV4_ADDRESS%/*} IPV4_ADDRESS=${IPV4_ADDRESS%/*}
IPV6_ADDRESS=${IPV6_ADDRESS} IPV6_ADDRESS=${IPV6_ADDRESS}
bool=true bool=true
#Is the domain in the list? # Is the domain in the list?
grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
if [[ "${bool}" == false ]]; then if [[ "${bool}" == false ]]; then
@ -134,7 +130,7 @@ AddDomain() {
fi fi
reload=true reload=true
echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}" echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}"
if [[ ${#IPV6_ADDRESS} > 0 ]] ; then if [[ "${#IPV6_ADDRESS}" > 0 ]]; then
echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}" echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}"
fi fi
else else
@ -150,36 +146,29 @@ RemoveDomain() {
domain=$(EscapeRegexp "$1") domain=$(EscapeRegexp "$1")
if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
bool=true bool=true
#Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa # Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
if [[ "${bool}" == true ]]; then if [[ "${bool}" == true ]]; then
# Remove it from the other one # Remove it from the other one
echo "::: Removing $1 from $list..." echo "::: Removing $1 from $list..."
# Busybox sed compatible case-insensitive domain removal # /I flag: search case-insensitive
# grep case insensitive domain from list, print line numbers sed -i "/${domain}/Id" "${list}"
# split on ':' with awk and print the line number
# For conditions with more than one match, substitute newline with ','
# sed substitute final trailing ',' with newline
sed -i "$(grep -in "^${domain}$" ${list} | awk -F':' '{print $1}' | tr '\n' ',' | sed 's/,$/\n/')d" ${list}
reload=true reload=true
else else
if [[ "${verbose}" == true ]]; then if [[ "${verbose}" == true ]]; then
echo "::: ${1} does not exist in ${list}, no need to remove!" echo "::: ${1} does not exist in ${list}, no need to remove!"
fi fi
fi fi
elif [[ "${list}" == "${wildcardlist}" ]]; then elif [[ "${list}" == "${wildcardlist}" ]]; then
bool=true bool=true
#Is it in the list? # Is it in the list?
grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
if [[ "${bool}" == true ]]; then if [[ "${bool}" == true ]]; then
# Remove it from the other one # Remove it from the other one
echo "::: Removing $1 from $list..." echo "::: Removing $1 from $list..."
# Busybox sed compatible case-insensitive domain removal # /I flag: search case-insensitive
sed -i "$(grep -in "/${domain}/" ${list} | awk -F':' '{print $1}' | tr '\n' ',' | sed 's/,$/\n/')d" ${list} sed -i "/address=\/${domain}/Id" "${list}"
reload=true reload=true
else else
if [[ "${verbose}" == true ]]; then if [[ "${verbose}" == true ]]; then
@ -195,13 +184,13 @@ Reload() {
} }
Displaylist() { Displaylist() {
if [[ ${listMain} == ${whitelist} ]]; then if [[ "${listMain}" == "${whitelist}" ]]; then
string="gravity resistant domains" string="gravity resistant domains"
else else
string="domains caught in the sinkhole" string="domains caught in the sinkhole"
fi fi
verbose=false verbose=false
echo -e " Displaying $string \n" echo -e "Displaying $string:\n"
count=1 count=1
while IFS= read -r RD; do while IFS= read -r RD; do
echo "${count}: ${RD}" echo "${count}: ${RD}"

View file

@ -3,7 +3,7 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net) # (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware. # Network-wide ad blocking via your own hardware.
# #
# Checkout other branches than master # Switch Pi-hole subsystems to a different Github branch
# #
# 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.
@ -18,9 +18,12 @@ PH_TEST="true" source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
# setupVars set in basic-install.sh # setupVars set in basic-install.sh
source "${setupVars}" source "${setupVars}"
update="false" update="false"
# Colour codes
red="\e[1;31m"
def="\e[0m"
fully_fetch_repo() { fully_fetch_repo() {
# Add upstream branches to shallow clone # Add upstream branches to shallow clone
local directory="${1}" local directory="${1}"
@ -35,7 +38,7 @@ fully_fetch_repo() {
return 0 return 0
} }
get_available_branches(){ get_available_branches() {
# Return available branches # Return available branches
local directory="${1}" local directory="${1}"
@ -81,23 +84,23 @@ checkout_pull_branch() {
} }
warning1() { warning1() {
echo "::: Note that changing the branch is a severe change of your Pi-hole system." echo " Please note that changing branches severely alters your Pi-hole subsystems"
echo "::: This is not supported unless one of the developers explicitly asks you to do this!" echo " Features that work on the master branch, may not on a development branch"
read -r -p "::: Have you read and understood this? [y/N] " response echo -e " ${red}This feature is NOT supported unless a Pi-hole developer explicitly asks!${def}"
read -r -p " Have you read and understood this? [Y/N] " response
case ${response} in case ${response} in
[yY][eE][sS]|[yY]) [yY][eE][sS]|[yY])
echo "::: Continuing." echo "::: Continuing with branch change."
return 0 return 0
;; ;;
*) *)
echo "::: Aborting." echo "::: Branch change has been cancelled."
return 1 return 1
;; ;;
esac esac
} }
checkout() checkout() {
{
local corebranches local corebranches
local webbranches local webbranches
@ -201,4 +204,3 @@ checkout()
fi fi
fi fi
} }

View file

@ -3,7 +3,7 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net) # (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware. # Network-wide ad blocking via your own hardware.
# #
# shows version numbers # Show version numbers
# #
# 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.
@ -142,8 +142,9 @@ defaultOutput() {
} }
helpFunc() { helpFunc() {
echo "Usage: pihole -v [REPO | OPTION] [OPTION] echo "Usage: pihole -v [repo | option] [option]
Show Pi-hole, Web Admin & FTL versions Example: 'pihole -v -p -l'
Show Pi-hole, Admin Console & FTL versions
Repositories: Repositories:
-p, --pihole Only retrieve info regarding Pi-hole repository -p, --pihole Only retrieve info regarding Pi-hole repository
@ -153,9 +154,8 @@ Repositories:
Options: Options:
-c, --current Return the current version -c, --current Return the current version
-l, --latest Return the latest version -l, --latest Return the latest version
-h, --hash Return the Github hash from your local repositories --hash Return the Github hash from your local repositories
--help Show this help dialog -h, --help Show this help dialog"
"
exit 0 exit 0
} }
@ -163,6 +163,6 @@ case "${1}" in
"-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";; "-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";;
"-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";; "-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";;
"-f" | "--ftl" ) shift; versionOutput "FTL" "$@";; "-f" | "--ftl" ) shift; versionOutput "FTL" "$@";;
"--help" ) helpFunc;; "-h" | "--help" ) helpFunc;;
* ) defaultOutput "$@";; * ) defaultOutput "$@";;
esac esac

View file

@ -8,7 +8,6 @@
# 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 setupVars="/etc/pihole/setupVars.conf" readonly setupVars="/etc/pihole/setupVars.conf"
readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf" readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf"
readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf" readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf"
@ -16,23 +15,19 @@ readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf"
readonly dhcpstaticconfig="/etc/dnsmasq.d/04-pihole-static-dhcp.conf" readonly dhcpstaticconfig="/etc/dnsmasq.d/04-pihole-static-dhcp.conf"
helpFunc() { helpFunc() {
cat << EOM echo "Usage: pihole -a [options]
::: Set admin options for the web interface of pihole Example: pihole -a -p password
::: Set options for the Admin Console
::: Usage: pihole -a [options]
::: Options:
::: Options: -f, flush Flush the Pi-hole log
::: -p, password Set web interface password, an empty input will remove any previously set password -p, password Set Admin Console password
::: -c, celsius Set Celsius temperature unit -c, celsius Set Celsius as preferred temperature unit
::: -f, fahrenheit Set Fahrenheit temperature unit -f, fahrenheit Set Fahrenheit as preferred temperature unit
::: -k, kelvin Set Kelvin temperature unit -k, kelvin Set Kelvin as preferred temperature unit
::: -h, --help Show this help dialog -h, --help Show this help dialog
::: -i, interface Setup interface listening behavior of dnsmasq -i, interface Specify dnsmasq's interface listening behavior
::: pihole -a -i local : Listen on all interfaces, but allow only queries from Add '-h' for more info on interface usage"
::: devices that are at most one hop away (local devices)
::: pihole -a -i single : Listen only on one interface (see PIHOLE_INTERFACE)
::: pihole -a -i all : Listen on all interfaces, permit all origins
EOM
exit 0 exit 0
} }
@ -61,21 +56,18 @@ delete_dnsmasq_setting() {
sed -i "/${1}/d" "${dnsmasqconfig}" sed -i "/${1}/d" "${dnsmasqconfig}"
} }
SetTemperatureUnit(){ SetTemperatureUnit() {
change_setting "TEMPERATUREUNIT" "${unit}" change_setting "TEMPERATUREUNIT" "${unit}"
} }
HashPassword(){ HashPassword() {
# Compute password hash twice to avoid rainbow table vulnerability # Compute password hash twice to avoid rainbow table vulnerability
return=$(echo -n ${1} | sha256sum | sed 's/\s.*$//') return=$(echo -n ${1} | sha256sum | sed 's/\s.*$//')
return=$(echo -n ${return} | sha256sum | sed 's/\s.*$//') return=$(echo -n ${return} | sha256sum | sed 's/\s.*$//')
echo ${return} echo ${return}
} }
SetWebPassword(){ SetWebPassword() {
if [ "${SUDO_USER}" == "www-data" ]; then if [ "${SUDO_USER}" == "www-data" ]; then
echo "Security measure: user www-data is not allowed to change webUI password!" echo "Security measure: user www-data is not allowed to change webUI password!"
echo "Exiting" echo "Exiting"
@ -175,8 +167,7 @@ trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE3
} }
SetDNSServers(){ SetDNSServers() {
# Save setting to file # Save setting to file
delete_setting "PIHOLE_DNS" delete_setting "PIHOLE_DNS"
IFS=',' read -r -a array <<< "${args[2]}" IFS=',' read -r -a array <<< "${args[2]}"
@ -207,49 +198,36 @@ SetDNSServers(){
# Restart dnsmasq to load new configuration # Restart dnsmasq to load new configuration
RestartDNS RestartDNS
} }
SetExcludeDomains(){ SetExcludeDomains() {
change_setting "API_EXCLUDE_DOMAINS" "${args[2]}" change_setting "API_EXCLUDE_DOMAINS" "${args[2]}"
} }
SetExcludeClients(){ SetExcludeClients() {
change_setting "API_EXCLUDE_CLIENTS" "${args[2]}" change_setting "API_EXCLUDE_CLIENTS" "${args[2]}"
} }
Reboot(){ Reboot() {
nohup bash -c "sleep 5; reboot" &> /dev/null </dev/null & nohup bash -c "sleep 5; reboot" &> /dev/null </dev/null &
} }
RestartDNS(){ RestartDNS() {
if [ -x "$(command -v systemctl)" ]; then if [ -x "$(command -v systemctl)" ]; then
systemctl restart dnsmasq &> /dev/null systemctl restart dnsmasq &> /dev/null
else else
service dnsmasq restart &> /dev/null service dnsmasq restart &> /dev/null
fi fi
} }
SetQueryLogOptions(){ SetQueryLogOptions() {
change_setting "API_QUERY_LOG_SHOW" "${args[2]}" change_setting "API_QUERY_LOG_SHOW" "${args[2]}"
} }
ProcessDHCPSettings() { ProcessDHCPSettings() {
source "${setupVars}" source "${setupVars}"
if [[ "${DHCP_ACTIVE}" == "true" ]]; then if [[ "${DHCP_ACTIVE}" == "true" ]]; then
interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//") interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//")
# Use eth0 as fallback interface # Use eth0 as fallback interface
@ -283,12 +261,12 @@ dhcp-leasefile=/etc/pihole/dhcp.leases
#quiet-dhcp #quiet-dhcp
" > "${dhcpconfig}" " > "${dhcpconfig}"
if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then
echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}" echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}"
fi fi
if [[ "${DHCP_IPv6}" == "true" ]]; then if [[ "${DHCP_IPv6}" == "true" ]]; then
echo "#quiet-dhcp6 echo "#quiet-dhcp6
#enable-ra #enable-ra
dhcp-option=option6:dns-server,[::] dhcp-option=option6:dns-server,[::]
dhcp-range=::100,::1ff,constructor:${interface},ra-names,slaac,${leasetime} dhcp-range=::100,::1ff,constructor:${interface},ra-names,slaac,${leasetime}
@ -301,8 +279,7 @@ ra-param=*,0,0
fi fi
} }
EnableDHCP(){ EnableDHCP() {
change_setting "DHCP_ACTIVE" "true" change_setting "DHCP_ACTIVE" "true"
change_setting "DHCP_START" "${args[2]}" change_setting "DHCP_START" "${args[2]}"
change_setting "DHCP_END" "${args[3]}" change_setting "DHCP_END" "${args[3]}"
@ -320,8 +297,7 @@ EnableDHCP(){
RestartDNS RestartDNS
} }
DisableDHCP(){ DisableDHCP() {
change_setting "DHCP_ACTIVE" "false" change_setting "DHCP_ACTIVE" "false"
# Remove possible old setting from file # Remove possible old setting from file
@ -333,23 +309,20 @@ DisableDHCP(){
RestartDNS RestartDNS
} }
SetWebUILayout(){ SetWebUILayout() {
change_setting "WEBUIBOXEDLAYOUT" "${args[2]}" change_setting "WEBUIBOXEDLAYOUT" "${args[2]}"
} }
CustomizeAdLists() { CustomizeAdLists() {
list="/etc/pihole/adlists.list" list="/etc/pihole/adlists.list"
if [[ "${args[2]}" == "enable" ]] ; then if [[ "${args[2]}" == "enable" ]]; then
sed -i "\\@${args[3]}@s/^#http/http/g" "${list}" sed -i "\\@${args[3]}@s/^#http/http/g" "${list}"
elif [[ "${args[2]}" == "disable" ]] ; then elif [[ "${args[2]}" == "disable" ]]; then
sed -i "\\@${args[3]}@s/^http/#http/g" "${list}" sed -i "\\@${args[3]}@s/^http/#http/g" "${list}"
elif [[ "${args[2]}" == "add" ]] ; then elif [[ "${args[2]}" == "add" ]]; then
echo "${args[3]}" >> ${list} echo "${args[3]}" >> ${list}
elif [[ "${args[2]}" == "del" ]] ; then elif [[ "${args[2]}" == "del" ]]; then
var=$(echo "${args[3]}" | sed 's/\//\\\//g') var=$(echo "${args[3]}" | sed 's/\//\\\//g')
sed -i "/${var}/Id" "${list}" sed -i "/${var}/Id" "${list}"
else else
@ -358,18 +331,15 @@ CustomizeAdLists() {
fi fi
} }
SetPrivacyMode(){ SetPrivacyMode() {
if [[ "${args[2]}" == "true" ]]; then
if [[ "${args[2]}" == "true" ]] ; then
change_setting "API_PRIVACY_MODE" "true" change_setting "API_PRIVACY_MODE" "true"
else else
change_setting "API_PRIVACY_MODE" "false" change_setting "API_PRIVACY_MODE" "false"
fi fi
} }
ResolutionSettings() { ResolutionSettings() {
typ="${args[2]}" typ="${args[2]}"
state="${args[3]}" state="${args[3]}"
@ -378,11 +348,9 @@ ResolutionSettings() {
elif [[ "${typ}" == "clients" ]]; then elif [[ "${typ}" == "clients" ]]; then
change_setting "API_GET_CLIENT_HOSTNAME" "${state}" change_setting "API_GET_CLIENT_HOSTNAME" "${state}"
fi fi
} }
AddDHCPStaticAddress() { AddDHCPStaticAddress() {
mac="${args[2]}" mac="${args[2]}"
ip="${args[3]}" ip="${args[3]}"
host="${args[4]}" host="${args[4]}"
@ -397,18 +365,14 @@ AddDHCPStaticAddress() {
# Full info given # Full info given
echo "dhcp-host=${mac},${ip},${host}" >> "${dhcpstaticconfig}" echo "dhcp-host=${mac},${ip},${host}" >> "${dhcpstaticconfig}"
fi fi
} }
RemoveDHCPStaticAddress() { RemoveDHCPStaticAddress() {
mac="${args[2]}" mac="${args[2]}"
sed -i "/dhcp-host=${mac}.*/d" "${dhcpstaticconfig}" sed -i "/dhcp-host=${mac}.*/d" "${dhcpstaticconfig}"
} }
SetHostRecord(){ SetHostRecord() {
if [ -n "${args[3]}" ]; then if [ -n "${args[3]}" ]; then
change_setting "HOSTRECORD" "${args[2]},${args[3]}" change_setting "HOSTRECORD" "${args[2]},${args[3]}"
echo "Setting host record for ${args[2]} -> ${args[3]}" echo "Setting host record for ${args[2]} -> ${args[3]}"
@ -421,17 +385,28 @@ SetHostRecord(){
# Restart dnsmasq to load new configuration # Restart dnsmasq to load new configuration
RestartDNS RestartDNS
} }
SetListeningMode(){ SetListeningMode() {
source "${setupVars}" source "${setupVars}"
if [[ "${args[2]}" == "all" ]] ; then if [[ "$3" == "-h" ]] || [[ "$3" == "--help" ]]; then
echo "Usage: pihole -a -i [interface]
Example: 'pihole -a -i local'
Specify dnsmasq's network interface listening behavior
Interfaces:
local Listen on all interfaces, but only allow queries from
devices that are at most one hop away (local devices)
single Listen only on ${PIHOLE_INTERFACE} interface
all Listen on all interfaces, permit all origins"
exit 0
fi
if [[ "${args[2]}" == "all" ]]; then
echo "Listening on all interfaces, permiting all origins, hope you have a firewall!" echo "Listening on all interfaces, permiting all origins, hope you have a firewall!"
change_setting "DNSMASQ_LISTENING" "all" change_setting "DNSMASQ_LISTENING" "all"
elif [[ "${args[2]}" == "local" ]] ; then elif [[ "${args[2]}" == "local" ]]; then
echo "Listening on all interfaces, permitting only origins that are at most one hop away (local devices)" echo "Listening on all interfaces, permitting only origins that are at most one hop away (local devices)"
change_setting "DNSMASQ_LISTENING" "local" change_setting "DNSMASQ_LISTENING" "local"
else else
@ -446,17 +421,14 @@ SetListeningMode(){
# Restart dnsmasq to load new configuration # Restart dnsmasq to load new configuration
RestartDNS RestartDNS
fi fi
} }
Teleporter() Teleporter() {
{
local datetimestamp=$(date "+%Y-%m-%d_%H-%M-%S") local datetimestamp=$(date "+%Y-%m-%d_%H-%M-%S")
php /var/www/html/admin/scripts/pi-hole/php/teleporter.php > "pi-hole-teleporter_${datetimestamp}.zip" php /var/www/html/admin/scripts/pi-hole/php/teleporter.php > "pi-hole-teleporter_${datetimestamp}.zip"
} }
main() { main() {
args=("$@") args=("$@")
case "${args[1]}" in case "${args[1]}" in
@ -479,7 +451,7 @@ main() {
"addstaticdhcp" ) AddDHCPStaticAddress;; "addstaticdhcp" ) AddDHCPStaticAddress;;
"removestaticdhcp" ) RemoveDHCPStaticAddress;; "removestaticdhcp" ) RemoveDHCPStaticAddress;;
"hostrecord" ) SetHostRecord;; "hostrecord" ) SetHostRecord;;
"-i" | "interface" ) SetListeningMode;; "-i" | "interface" ) SetListeningMode "$@";;
"-t" | "teleporter" ) Teleporter;; "-t" | "teleporter" ) Teleporter;;
"adlist" ) CustomizeAdLists;; "adlist" ) CustomizeAdLists;;
* ) helpFunc;; * ) helpFunc;;
@ -490,5 +462,4 @@ main() {
if [[ $# = 0 ]]; then if [[ $# = 0 ]]; then
helpFunc helpFunc
fi fi
} }

189
pihole
View file

@ -9,11 +9,11 @@
# 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" readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf" readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf"
# Must be root to use this tool # Must be root to use this tool
if [[ ! $EUID -eq 0 ]];then if [[ ! $EUID -eq 0 ]];then
if [ -x "$(command -v sudo)" ];then if [[ -x "$(command -v sudo)" ]]; then
exec sudo bash "$0" "$@" exec sudo bash "$0" "$@"
exit $? exit $?
else else
@ -80,12 +80,12 @@ updateGravityFunc() {
exit 0 exit 0
} }
scanList(){ scanList() {
domain="${1}" domain="${1}"
list="${2}" list="${2}"
method="${3}" method="${3}"
if [[ ${method} == "-exact" ]]; then if [[ "${method}" == "-exact" ]]; then
grep -i -E -l "(^|\s|\/)${domain}($|\s|\/)" ${list} grep -i -E -l "(^|\s|\/)${domain}($|\s|\/)" ${list}
else else
grep -i "${domain}" ${list} grep -i "${domain}" ${list}
@ -97,11 +97,11 @@ queryFunc() {
# If domain contains non ASCII characters, convert domain to punycode if python exists # If domain contains non ASCII characters, convert domain to punycode if python exists
# Cr: https://serverfault.com/a/335079 # Cr: https://serverfault.com/a/335079
if [ -z "${2}" ]; then if [[ -z "${2}" ]]; then
echo "::: No domain specified" echo "::: No domain specified"
exit 1 exit 1
elif [[ ${2} = *[![:ascii:]]* ]]; then elif [[ "${2}" = *[![:ascii:]]* ]]; then
[ `which python` ] && domain=$(python -c 'import sys;print sys.argv[1].decode("utf-8").encode("idna")' "${2}") [[ "$(which python)" ]] && domain=$(python -c 'import sys;print sys.argv[1].decode("utf-8").encode("idna")' "${2}")
else else
domain="${2}" domain="${2}"
fi fi
@ -109,14 +109,14 @@ queryFunc() {
# Scan Whitelist, Blacklist and Wildcards # Scan Whitelist, Blacklist and Wildcards
lists="/etc/pihole/whitelist.txt /etc/pihole/blacklist.txt $wildcardlist" lists="/etc/pihole/whitelist.txt /etc/pihole/blacklist.txt $wildcardlist"
result=$(scanList ${domain} "${lists}" ${method}) result=$(scanList ${domain} "${lists}" ${method})
if [ -n "$result" ]; then if [[ -n "$result" ]]; then
echo "$result" echo "$result"
[[ ! -t 1 ]] && exit 0 [[ ! -t 1 ]] && exit 0
fi fi
# Scan Domains lists # Scan Domains lists
result=$(scanList ${domain} "/etc/pihole/*.domains" ${method}) result=$(scanList ${domain} "/etc/pihole/*.domains" ${method})
if [ -n "$result" ]; then if [[ -n "$result" ]]; then
sort -t . -k 2 -g <<< "$result" sort -t . -k 2 -g <<< "$result"
else else
[ -n "$method" ] && exact="exact " [ -n "$method" ] && exact="exact "
@ -146,16 +146,16 @@ versionFunc() {
restartDNS() { restartDNS() {
dnsmasqPid=$(pidof dnsmasq) dnsmasqPid=$(pidof dnsmasq)
if [[ ${dnsmasqPid} ]]; then if [[ "${dnsmasqPid}" ]]; then
# service already running - reload config # Service already running - reload config
if [ -x "$(command -v systemctl)" ]; then if [[ -x "$(command -v systemctl)" ]]; then
systemctl restart dnsmasq systemctl restart dnsmasq
else else
service dnsmasq restart service dnsmasq restart
fi fi
else else
# service not running, start it up # Service not running, start it up
if [ -x "$(command -v systemctl)" ]; then if [[ -x "$(command -v systemctl)" ]]; then
systemctl start dnsmasq systemctl start dnsmasq
else else
service dnsmasq start service dnsmasq start
@ -164,16 +164,25 @@ restartDNS() {
} }
piholeEnable() { piholeEnable() {
if [[ "${1}" == "0" ]] ; then if [[ "${2}" == "-h" ]] || [[ "${2}" == "--help" ]]; then
#Disable Pihole echo "Usage: pihole disable [time]
Example: 'pihole disable', or 'pihole disable 5m'
Disable Pi-hole subsystems
Time:
#s Disable Pi-hole functionality for # second(s)
#m Disable Pi-hole functionality for # minute(s)"
exit 0
elif [[ "${1}" == "0" ]]; then
# Disable Pi-hole
sed -i 's/^addn-hosts=\/etc\/pihole\/gravity.list/#addn-hosts=\/etc\/pihole\/gravity.list/' /etc/dnsmasq.d/01-pihole.conf sed -i 's/^addn-hosts=\/etc\/pihole\/gravity.list/#addn-hosts=\/etc\/pihole\/gravity.list/' /etc/dnsmasq.d/01-pihole.conf
echo "::: Blocking has been disabled!" echo "::: Blocking has been disabled!"
if [[ $# > 1 ]] ; then if [[ $# > 1 ]]; then
if [[ ${2} == *"s"* ]] ; then if [[ "${2}" == *"s"* ]]; then
tt=${2%"s"} tt=${2%"s"}
echo "::: Blocking will be re-enabled in ${tt} seconds" echo "::: Blocking will be re-enabled in ${tt} seconds"
nohup bash -c "sleep ${tt}; pihole enable" </dev/null &>/dev/null & nohup bash -c "sleep ${tt}; pihole enable" </dev/null &>/dev/null &
elif [[ ${2} == *"m"* ]] ; then elif [[ "${2}" == *"m"* ]]; then
tt=${2%"m"} tt=${2%"m"}
echo "::: Blocking will be re-enabled in ${tt} minutes" echo "::: Blocking will be re-enabled in ${tt} minutes"
tt=$((${tt}*60)) tt=$((${tt}*60))
@ -187,7 +196,7 @@ piholeEnable() {
fi fi
fi fi
else else
#Enable pihole # Enable Pi-hole
echo "::: Blocking has been enabled!" echo "::: Blocking has been enabled!"
sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
fi fi
@ -196,15 +205,23 @@ piholeEnable() {
piholeLogging() { piholeLogging() {
shift shift
if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
echo "Usage: pihole logging [options]
Example: 'pihole logging on'
Specify whether the Pi-hole log should be used
if [[ "${1}" == "off" ]] ; then Options:
#Disable Logging on Enable the Pi-hole log at /var/log/pihole.log
off Disable the Pi-hole log at /var/log/pihole.log"
exit 0
elif [[ "${1}" == "off" ]]; then
# Disable logging
sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
pihole -f pihole -f
echo "::: Logging has been disabled!" echo "::: Logging has been disabled!"
elif [[ "${1}" == "on" ]] ; then elif [[ "${1}" == "on" ]]; then
#Enable logging # Enable logging
sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf
sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf
echo "::: Logging has been enabled!" echo "::: Logging has been enabled!"
@ -216,12 +233,12 @@ piholeLogging() {
} }
piholeStatus() { piholeStatus() {
if [[ $(netstat -plnt | grep -c ':53 ') > 0 ]]; then if [[ "$(netstat -plnt | grep -c ':53 ')" -gt "0" ]]; then
if [[ "${1}" != "web" ]] ; then if [[ "${1}" != "web" ]]; then
echo "::: DNS service is running" echo "::: DNS service is running"
fi fi
else else
if [[ "${1}" == "web" ]] ; then if [[ "${1}" == "web" ]]; then
echo "-1"; echo "-1";
else else
echo "::: DNS service is NOT running" echo "::: DNS service is NOT running"
@ -229,28 +246,28 @@ piholeStatus() {
return return
fi fi
if [[ $(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then if [[ "$(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then
#list is commented out # List is commented out
if [[ "${1}" == "web" ]] ; then if [[ "${1}" == "web" ]]; then
echo 0; echo 0;
else else
echo "::: Pi-hole blocking is Disabled"; echo "::: Pi-hole blocking is Disabled";
fi fi
elif [[ $(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then elif [[ "$(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then
#list set # List set
if [[ "${1}" == "web" ]] ; then if [[ "${1}" == "web" ]]; then
echo 1; echo 1;
else else
echo "::: Pi-hole blocking is Enabled"; echo "::: Pi-hole blocking is Enabled";
fi fi
else else
#addn-host not found # Addn-host not found
if [[ "${1}" == "web" ]] ; then if [[ "${1}" == "web" ]]; then
echo 99 echo 99
else else
echo "::: No hosts file linked to dnsmasq, adding it in enabled state" echo "::: No hosts file linked to dnsmasq, adding it in enabled state"
fi fi
#add addn-host= to dnsmasq # Add addn-host= to dnsmasq
echo "addn-hosts=/etc/pihole/gravity.list" >> /etc/dnsmasq.d/01-pihole.conf echo "addn-hosts=/etc/pihole/gravity.list" >> /etc/dnsmasq.d/01-pihole.conf
restartDNS restartDNS
fi fi
@ -263,55 +280,66 @@ tailFunc() {
} }
piholeCheckoutFunc() { piholeCheckoutFunc() {
if [[ "$2" == "-h" ]] || [[ "$2" == "--help" ]]; then
echo "Usage: pihole checkout [repo] [branch]
Example: 'pihole checkout master' or 'pihole checkout core dev'
Switch Pi-hole subsystems to a different Github branch
Repositories:
core [branch] Change the branch of Pi-hole's core subsystem
web [branch] Change the branch of Admin Console subsystem
Branches:
master Update subsystems to the latest stable release
dev Update subsystems to the latest development release"
exit 0
fi
source "${PI_HOLE_SCRIPT_DIR}"/piholeCheckout.sh source "${PI_HOLE_SCRIPT_DIR}"/piholeCheckout.sh
shift shift
checkout "$@" checkout "$@"
} }
tricorderFunc() {
if command -v openssl &> /dev/null; then
openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
else
nc tricorder.pi-hole.net 9999 < /dev/stdin
fi
}
helpFunc() { helpFunc() {
cat << EOM echo "Usage: pihole [options]
::: Control all Pi-hole specific functions Example: 'pihole -w -h'
::: Add '-h' after specific commands for more information on usage
::: Usage: pihole [options]
::: Add -h after -w (whitelist), -b (blacklist), -c (chronometer), or -a (admin) for more information on usage Whitelist/Blacklist Options:
::: -w, whitelist Whitelist domain(s)
::: Options: -b, blacklist Blacklist domain(s)
::: -w, whitelist Whitelist domain(s) -wild, wildcard Blacklist domain(s), and all its subdomains
::: -b, blacklist Blacklist domain(s) (exact match) Add '-h' for more info on whitelist/blacklist usage
::: -wild, wildcard Blacklist whole domain(s) (wildcard)
::: -d, debug Start a debugging session Debugging Options:
::: Automated debugging can be enabled with '-a'. -d, debug Start a debugging session
::: 'pihole -d -a' Add '-a' to enable automated debugging
::: -f, flush Flush the 'pihole.log' file -f, flush Flush the Pi-hole log
::: -t, tail Output the last lines of the 'pihole.log' file. Lines are appended as the file grows -r, reconfigure Reconfigure or Repair Pi-hole subsystems
::: -up, updatePihole Update Pi-hole components -t, tail View the live output of the Pi-hole log
::: -r, reconfigure Reconfigure or Repair Pi-hole
::: -g, updateGravity Update the list of ad-serving domains Options:
::: -c, chronometer Calculates stats and displays to an LCD -a, admin Admin Console options
::: -h, help Show this help dialog Add '-h' for more info on admin console usage
::: -v, version Show installed versions of Pi-hole and Web-Admin -c, chronometer Calculates stats and displays to an LCD
::: -q, query Query the adlists for a specific domain Add '-h' for more info on chronometer usage
::: 'pihole -q domain -exact' shows exact matches only -g, updateGravity Update the list of ad-serving domains
::: -l, logging Enable or Disable logging (pass 'on' or 'off') -h, --help, help Show this help dialog
::: -a, admin Admin webpage options -l, logging Specify whether the Pi-hole log should be used
::: uninstall Uninstall Pi-hole from your system! :( Add '-h' for more info on logging usage
::: status Display if Pi-hole is Enabled or Disabled -q, query Query the adlists for a specified domain
::: enable Enable Pi-hole DNS Blocking Add '-exact' AFTER a specified domain for exact match
::: disable Disable Pi-hole DNS Blocking -up, updatePihole Update Pi-hole subsystems
::: Blocking can also be disabled only temporarily, e.g., -v, version Show installed versions of Pi-hole, Admin Console & FTL
::: 'pihole disable 5m' - will disable blocking for 5 minutes Add '-h' for more info on version usage
::: restartdns Restart dnsmasq uninstall Uninstall Pi-hole from your system
::: checkout Check out different branches status Display the running status of Pi-hole subsystems
::: tricorder Upload log to Pi-hole's medical tricorder (uses SSL when possible) enable Enable Pi-hole subsystems
EOM disable Disable Pi-hole subsystems
Add '-h' for more info on disable usage
restartdns Restart Pi-hole subsystems
checkout Switch Pi-hole subsystems to a different Github branch
Add '-h' for more info on checkout usage";
exit 0 exit 0
} }
@ -336,12 +364,11 @@ case "${1}" in
"-l" | "logging" ) piholeLogging "$@";; "-l" | "logging" ) piholeLogging "$@";;
"uninstall" ) uninstallFunc;; "uninstall" ) uninstallFunc;;
"enable" ) piholeEnable 1;; "enable" ) piholeEnable 1;;
"disable" ) piholeEnable 0 $2;; "disable" ) piholeEnable 0 "$2";;
"status" ) piholeStatus "$2";; "status" ) piholeStatus "$2";;
"restartdns" ) restartDNS;; "restartdns" ) restartDNS;;
"-a" | "admin" ) webpageFunc "$@";; "-a" | "admin" ) webpageFunc "$@";;
"-t" | "tail" ) tailFunc;; "-t" | "tail" ) tailFunc;;
"checkout" ) piholeCheckoutFunc "$@";; "checkout" ) piholeCheckoutFunc "$@";;
"tricorder" ) tricorderFunc;;
* ) helpFunc;; * ) helpFunc;;
esac esac