diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 071fdf89..b289a1c0 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,4 +8,4 @@ Changes proposed in this pull request: - -@pihole/gravity +@pi-hole/gravity diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..e43b0f98 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.md b/README.md index d9848502..851e1639 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # Automated Install -##### Designed For Raspberry Pi A+, B, B+, 2, and Zero (with an Ethernet/Wi-Fi adapter) +##### Designed For Raspberry Pi A+, B, B+, 2, Zero, and 3B (with an Ethernet/Wi-Fi adapter) (Works on most Debian distributions!) + [![Join the chat at https://gitter.im/pi-hole/pi-hole](https://badges.gitter.im/pi-hole/pi-hole.svg)](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 1. Install Raspbian + 2. Run the command below ### ```curl -L https://install.pi-hole.net | bash``` diff --git a/adlists.default b/adlists.default index 0d99244f..8a396729 100644 --- a/adlists.default +++ b/adlists.default @@ -5,11 +5,11 @@ # 2. run `nano /etc/pihole/adlists.list` # # 3. Uncomment or comment any of the below lists # # # -# Know of any other lists? Feel free to let us know about them, or add them # +# Know of any other lists? Feel free to let us know about them, or add them # # to this file! # ################################################################################ -# The below list amalgamates several lists we used previously. +# The below list amalgamates several lists we used previously. # See `https://github.com/StevenBlack/hosts` for details https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts @@ -31,8 +31,8 @@ http://hosts-file.net/ad_servers.txt # ADZHOSTS list. Has been known to block legitimate domains #http://optimate.dl.sourceforge.net/project/adzhosts/HOSTS.txt -# Windows 10 telemetry list - warning this one may block windows update -#https://raw.githubusercontent.com/crazy-max/HostsWindowsBlocker/master/hosts.txt +# Windows 10 telemetry list +#https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/hostsBlockWindowsSpy.txt # Securemecca.com list - Also blocks "adult" sites (pornography/gambling etc) #http://securemecca.com/Downloads/hosts.txt @@ -40,6 +40,9 @@ http://hosts-file.net/ad_servers.txt # Quidsup's tracker list https://raw.githubusercontent.com/quidsup/notrack/master/trackers.txt +# Block the BBC News website Breaking News banner +#https://raw.githubusercontent.com/BreakingTheNews/BreakingTheNews.github.io/master/hosts + # Untested Lists: #https://raw.githubusercontent.com/reek/anti-adblock-killer/master/anti-adblock-killer-filters.txt diff --git a/advanced/Scripts/blacklist.sh b/advanced/Scripts/blacklist.sh old mode 100644 new mode 100755 index 70b8131a..9e5d557b --- a/advanced/Scripts/blacklist.sh +++ b/advanced/Scripts/blacklist.sh @@ -11,39 +11,46 @@ # (at your option) any later version. if [[ $# = 0 ]]; then - echo "Immediately blacklists one or more domains in the hosts file" - echo " " - echo "Usage: blacklist.sh domain1 [domain2 ...]" - echo " " - echo "Options:" - echo " -d, --delmode Remove domains from the blacklist" - echo " -nr, --noreload Update blacklist without refreshing dnsmasq" - echo " -f, --force Force updating of the hosts files, even if there are no changes" - echo " -q, --quiet output is less verbose" + echo "::: Immediately blacklists one or more domains in the hosts file" + echo ":::" + echo "::: Usage: sudo pihole.sh -b domain1 [domain2 ...]" + echo ":::" + echo "::: Options:" + echo "::: -d, --delmode Remove domains from the blacklist" + echo "::: -nr, --noreload Update blacklist without refreshing dnsmasq" + echo "::: -f, --force Force updating of the hosts files, even if there are no changes" + echo "::: -q, --quiet output is less verbose" exit 1 fi #globals -blacklist=/etc/pihole/blacklist.txt -adList=/etc/pihole/gravity.list +basename=pihole +piholeDir=/etc/$basename +adList=$piholeDir/gravity.list +blacklist=$piholeDir/blacklist.txt reload=true addmode=true force=false versbose=true + domList=() domToRemoveList=() - -piholeIPfile=/tmp/piholeIP piholeIPv6file=/etc/pihole/.useIPv6 # Otherwise, the IP address can be taken directly from the machine, which will happen when the script is run by the user and not the installation script IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}') -piholeIPCIDR=$(ip -o -f inet addr show dev $IPv4dev | awk '{print $4}' | awk 'END {print}') +piholeIPCIDR=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}') piholeIP=${piholeIPCIDR%/*} modifyHost=false +# After setting defaults, check if there's local overrides +if [[ -r $piholeDir/pihole.conf ]];then + echo "::: Local calibration requested..." + . $piholeDir/pihole.conf +fi + if [[ -f $piholeIPv6file ]];then # If the file exists, then the user previously chose to use IPv6 in the automated installer @@ -51,12 +58,11 @@ if [[ -f $piholeIPv6file ]];then fi -function HandleOther(){ +function HandleOther(){ #check validity of domain - validDomain=$(echo $1 | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/') - + validDomain=$(echo "$1" | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/') 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 domList=("${domList[@]}" $validDomain) fi @@ -66,13 +72,12 @@ function PopBlacklistFile(){ #check blacklist file exists, and if not, create it if [[ ! -f $blacklist ]];then touch $blacklist - fi - for dom in "${domList[@]}" - do - if $addmode; then - AddDomain $dom + fi + for dom in "${domList[@]}"; do + if "$addmode"; then + AddDomain "$dom" else - RemoveDomain $dom + RemoveDomain "$dom" fi done } @@ -86,18 +91,18 @@ function AddDomain(){ if $versbose; then echo -n "::: Adding $1 to blacklist file..." fi - echo $1 >> $blacklist + echo "$1" >> $blacklist modifyHost=true echo " done!" else if $versbose; then - echo "::: $1 already exists in blacklist.txt! No need to add" + echo "::: $1 already exists in $blacklist! No need to add" fi fi } function RemoveDomain(){ - + bool=false grep -Ex -q "$1" $blacklist || bool=true if $bool; then @@ -110,12 +115,12 @@ function RemoveDomain(){ if $versbose; then echo "::: Un-blacklisting $dom..." fi - domToRemoveList=("${domToRemoveList[@]}" $1) - modifyHost=true - fi + domToRemoveList=("${domToRemoveList[@]}" $1) + modifyHost=true + fi } -function ModifyHostFile(){ +function ModifyHostFile(){ if $addmode; then #add domains to the hosts file if [[ -r $blacklist ]];then @@ -124,28 +129,25 @@ function ModifyHostFile(){ echo ":::" echo -n "::: Modifying HOSTS file to blacklist $numberOf domain${plural}..." if [[ -n $piholeIPv6 ]];then - cat $blacklist | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $adList - else - cat $blacklist | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >>$adList - fi - + cat $blacklist | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $adList + else + cat $blacklist | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >>$adList + fi fi else - echo ":::" - for dom in "${domToRemoveList[@]}" - do - #we need to remove the domains from the blacklist file and the host file - echo "::: $dom" - echo -n "::: removing from HOSTS file..." - echo $dom | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /[^.]'{}'(?!.)/;' $adList - echo " done!" - echo -n "::: removing from blackist.txt..." - echo $dom | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' $blacklist - echo " done!" - done - fi - + for dom in "${domToRemoveList[@]}" + do + #we need to remove the domains from the blacklist file and the host file + echo "::: $dom" + echo -n "::: removing from HOSTS file..." + echo "$dom" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /[^.]'{}'(?!.)/;' $adList + echo " done!" + echo -n "::: removing from blackist.txt..." + echo "$dom" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' $blacklist + echo " done!" + done + fi } function Reload() { @@ -157,7 +159,7 @@ function Reload() { if [[ $dnsmasqPid ]]; then # service already running - reload config - sudo kill -HUP $dnsmasqPid + sudo kill -HUP "$dnsmasqPid" else # service not running, start it up sudo service dnsmasq start @@ -170,17 +172,17 @@ function Reload() { for var in "$@" do case "$var" in - "-nr"| "--noreload" ) reload=false;; + "-nr"| "--noreload" ) reload=false;; "-d" | "--delmode" ) addmode=false;; "-f" | "--force" ) force=true;; "-q" | "--quiet" ) versbose=false;; - * ) HandleOther $var;; + * ) HandleOther "$var";; esac done PopBlacklistFile -if $modifyHost || $force; then +if $modifyHost || $force; then ModifyHostFile else if $versbose; then diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh index ebed8684..58bf300b 100755 --- a/advanced/Scripts/chronometer.sh +++ b/advanced/Scripts/chronometer.sh @@ -73,9 +73,9 @@ function outputJSON(){ CalcQueriesToday CalcblockedToday CalcPercentBlockedToday - + CalcBlockedDomains - + printf '{"domains_being_blocked":"%s","dns_queries_today":"%s","ads_blocked_today":"%s","ads_percentage_today":"%s"}\n' "$blockedDomainsTotal" "$queriesToday" "$blockedToday" "$percentBlockedToday" } @@ -88,44 +88,45 @@ function normalChrono(){ echo " $(ifconfig eth0 | awk '/inet addr/ {print $2}' | cut -d':' -f2)" echo "" uptime | cut -d' ' -f11- - uptime -p + #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."}' echo "-------------------------------" # Uncomment to continually read the log file and display the current domain being blocked #tail -f /var/log/pihole.log | awk '/\/etc\/pihole\/gravity.list/ {if ($7 != "address" && $7 != "name" && $7 != "/etc/pihole/gravity.list") print $7; else;}' - + #uncomment next 4 lines to use original query count calculation #today=$(date "+%b %e") #todaysQueryCount=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ {print $7}' | wc -l) #todaysQueryCountV4=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ && /\[A\]/ {print $7}' | wc -l) #todaysQueryCountV6=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ && /\[AAAA\]/ {print $7}' | wc -l) - - + + CalcQueriesToday CalcblockedToday CalcPercentBlockedToday - + CalcBlockedDomains - + echo "Blocking: $blockedDomainsTotal" #below commented line does not add up to todaysQueryCount #echo "Queries: $todaysQueryCountV4 / $todaysQueryCountV6" echo "Queries: $queriesToday" #same total calculation as dashboard echo "Pi-holed: $blockedToday ($percentBlockedToday%)" - + sleep 5 done } function displayHelp(){ - echo "Displays stats about your piHole!" - echo " " - echo "Usage: chronometer.sh [optional:-j]" - echo "Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds" - echo " " - echo "Options:" - echo " -j, --json output stats as JSON formatted string" - echo " -h, --help display this help text" - + echo "::: Displays stats about your piHole!" + echo ":::" + echo "::: Usage: sudo pihole.sh -c [optional:-j]" + echo "::: Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds" + echo ":::" + echo "::: Options:" + echo "::: -j, --json output stats as JSON formatted string" + echo "::: -h, --help display this help text" + exit 1 } @@ -137,7 +138,7 @@ for var in "$@" do case "$var" in "-j" | "--json" ) outputJSON;; - "-h" | "--help" ) displayHelp;; + "-h" | "--help" ) displayHelp;; * ) exit 1;; esac done diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh new file mode 100755 index 00000000..03d1498a --- /dev/null +++ b/advanced/Scripts/piholeDebug.sh @@ -0,0 +1,310 @@ +#!/usr/bin/env bash +# Pi-hole: A black hole for Internet advertisements +# (c) 2015, 2016 by Jacob Salmela +# Network-wide ad blocking via your Raspberry Pi +# http://pi-hole.net +# Generates pihole_debug.log in /var/log/ to be used for troubleshooting. +# +# Pi-hole is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. + +# Nate Brandeburg +# nate@ubiquisoft.com +# 3/24/2016 + +######## GLOBAL VARS ######## +DEBUG_LOG="/var/log/pihole_debug.log" +DNSMASQFILE="/etc/dnsmasq.conf" +PIHOLECONFFILE="/etc/dnsmasq.d/01-pihole.conf" +LIGHTTPDFILE="/etc/lighttpd/lighttpd.conf" +GRAVITYFILE="/etc/pihole/gravity.list" +HOSTSFILE="/etc/hosts" +WHITELISTFILE="/etc/pihole/whitelist.txt" +BLACKLISTFILE="/etc/pihole/blacklist.txt" +ADLISTSFILE="/etc/pihole/adlists.list" +PIHOLELOG="/var/log/pihole.log" +WHITELISTMATCHES="/tmp/whitelistmatches.list" + + +######## FIRST CHECK ######## +# Must be root to debug +if [[ $EUID -eq 0 ]]; then + echo "::: You are root... Beginning debug!" +else + echo "::: Sudo will be used for debugging." + # Check if sudo is actually installed + if [[ $(dpkg-query -s sudo) ]]; then + export SUDO="sudo" + else + echo "::: Please install sudo or run this as root." + exit 1 + fi +fi + +# Ensure the file exists, create if not, clear if exists. +if [ ! -f "$DEBUG_LOG" ]; then + $SUDO touch $DEBUG_LOG + $SUDO chmod 644 $DEBUG_LOG + $SUDO chown "$USER":root $DEBUG_LOG +else + truncate -s 0 $DEBUG_LOG +fi + +### Private functions exist here ### +function compareWhitelist { + if [ ! -f "$WHITELISTMATCHES" ]; then + $SUDO touch $WHITELISTMATCHES + $SUDO chmod 644 $WHITELISTMATCHES + $SUDO chown "$USER":root $WHITELISTMATCHES + else + truncate -s 0 $WHITELISTMATCHES + fi + + echo "#######################################" >> $DEBUG_LOG + echo "######## Whitelist Comparison #########" >> $DEBUG_LOG + echo "#######################################" >> $DEBUG_LOG + while read -r line; do + TMP=$(grep -w ".* $line$" "$GRAVITYFILE") + if [ ! -z "$TMP" ]; then + echo "$TMP" >> $DEBUG_LOG + echo "$TMP" >> $WHITELISTMATCHES + fi + done < "$WHITELISTFILE" + echo >> $DEBUG_LOG +} + +function compareBlacklist { + echo "#######################################" >> $DEBUG_LOG + echo "######## Blacklist Comparison #########" >> $DEBUG_LOG + echo "#######################################" >> $DEBUG_LOG + while read -r line; do + if [ ! -z "$line" ]; then + grep -w ".* $line$" "$GRAVITYFILE" >> $DEBUG_LOG + fi + done < "$BLACKLISTFILE" + echo >> $DEBUG_LOG +} + +function testNslookup { + TESTURL="doubleclick.com" + echo "#######################################" >> $DEBUG_LOG + echo "############ NSLookup Test ############" >> $DEBUG_LOG + echo "#######################################" >> $DEBUG_LOG + # Find a blocked url that has not been whitelisted. + if [ -s "$WHITELISTMATCHES" ]; then + while read -r line; do + CUTURL=${line#*" "} + if [ "$CUTURL" != "Pi-Hole.IsWorking.OK" ]; then + while read -r line2; do + CUTURL2=${line2#*" "} + if [ "$CUTURL" != "$CUTURL2" ]; then + TESTURL="$CUTURL" + break 2 + fi + done < "$WHITELISTMATCHES" + fi + done < "$GRAVITYFILE" + fi + + echo "NSLOOKUP of $TESTURL from PiHole:" >> $DEBUG_LOG + nslookup "$TESTURL" >> $DEBUG_LOG + echo >> $DEBUG_LOG + echo "NSLOOKUP of $TESTURL from 8.8.8.8:" >> $DEBUG_LOG + nslookup "$TESTURL" 8.8.8.8 >> $DEBUG_LOG + echo >> $DEBUG_LOG +} + +function checkProcesses { + echo "#######################################" >> $DEBUG_LOG + echo "########### Processes Check ###########" >> $DEBUG_LOG + echo "#######################################" >> $DEBUG_LOG + echo ":::" + echo "::: Logging status of lighttpd and dnsmasq..." + PROCESSES=( lighttpd dnsmasq ) + for i in "${PROCESSES[@]}" + do + echo "" >> $DEBUG_LOG + echo -n $i >> "$DEBUG_LOG" + echo " processes status:" >> $DEBUG_LOG + $SUDO systemctl -l status $i >> "$DEBUG_LOG" + done +} + +### END FUNCTIONS ### + +### Check Pi internet connections ### +# Log the IP addresses of this Pi +IPADDR=$($SUDO ifconfig | perl -nle 's/dr:(\S+)/print $1/e') +echo "::: Writing local IPs to debug log" +echo "IP Addresses of this Pi:" >> $DEBUG_LOG +echo "$IPADDR" >> $DEBUG_LOG +echo >> $DEBUG_LOG + +# Check if we can connect to the local gateway +GATEWAY_CHECK=$(ping -q -w 1 -c 1 "$(ip r | grep default | cut -d ' ' -f 3)" > /dev/null && echo ok || echo error) +echo "Gateway check:" >> $DEBUG_LOG +echo "$GATEWAY_CHECK" >> $DEBUG_LOG +echo >> $DEBUG_LOG + +compareWhitelist +compareBlacklist +testNslookup +checkProcesses + +echo "::: Writing dnsmasq.conf to debug log..." +echo "#######################################" >> $DEBUG_LOG +echo "############### Dnsmasq ###############" >> $DEBUG_LOG +echo "#######################################" >> $DEBUG_LOG +if [ -e "$DNSMASQFILE" ] +then + #cat $DNSMASQFILE >> $DEBUG_LOG + while read -r line; do + if [ ! -z "$line" ]; then + [[ "$line" =~ ^#.*$ ]] && continue + echo "$line" >> $DEBUG_LOG + fi + done < "$DNSMASQFILE" + echo >> $DEBUG_LOG +else + echo "No dnsmasq.conf file found!" >> $DEBUG_LOG + printf ":::\tNo dnsmasq.conf file found!\n" +fi + +echo "::: Writing 01-pihole.conf to debug log..." +echo "#######################################" >> $DEBUG_LOG +echo "########### 01-pihole.conf ############" >> $DEBUG_LOG +echo "#######################################" >> $DEBUG_LOG +if [ -e "$PIHOLECONFFILE" ] +then + #cat "$PIHOLECONFFILE" >> $DEBUG_LOG + while read -r line; do + if [ ! -z "$line" ]; then + [[ "$line" =~ ^#.*$ ]] && continue + echo "$line" >> $DEBUG_LOG + fi + done < "$PIHOLECONFFILE" + echo >> $DEBUG_LOG +else + echo "No 01-pihole.conf file found!" >> $DEBUG_LOG + printf ":::\tNo 01-pihole.conf file found\n" +fi + +echo "::: Writing lighttpd.conf to debug log..." +echo "#######################################" >> $DEBUG_LOG +echo "############ lighttpd.conf ############" >> $DEBUG_LOG +echo "#######################################" >> $DEBUG_LOG +if [ -e "$LIGHTTPDFILE" ] +then + #cat "$PIHOLECONFFILE" >> $DEBUG_LOG + while read -r line; do + if [ ! -z "$line" ]; then + [[ "$line" =~ ^#.*$ ]] && continue + echo "$line" >> $DEBUG_LOG + fi + done < "$LIGHTTPDFILE" + echo >> $DEBUG_LOG +else + echo "No lighttpd.conf file found!" >> $DEBUG_LOG + printf ":::\tNo lighttpd.conf file found\n" +fi + +echo "::: Writing size of gravity.list to debug log..." +echo "#######################################" >> $DEBUG_LOG +echo "############ gravity.list #############" >> $DEBUG_LOG +echo "#######################################" >> $DEBUG_LOG +if [ -e "$GRAVITYFILE" ] +then + wc -l "$GRAVITYFILE" >> $DEBUG_LOG + echo >> $DEBUG_LOG +else + echo "No gravity.list file found!" >> $DEBUG_LOG + printf ":::\tNo gravity.list file found\n" +fi + +# Write the hostname output to compare against entries in /etc/hosts, which is logged next +echo "Hostname of this pihole is: " >> $DEBUG_LOG +hostname >> $DEBUG_LOG + +echo "::: Writing hosts file to debug log..." +echo "#######################################" >> $DEBUG_LOG +echo "################ Hosts ################" >> $DEBUG_LOG +echo "#######################################" >> $DEBUG_LOG +if [ -e "$HOSTSFILE" ] +then + cat "$HOSTSFILE" >> $DEBUG_LOG + echo >> $DEBUG_LOG +else + echo "No hosts file found!" >> $DEBUG_LOG + printf ":::\tNo hosts file found!\n" +fi + +### PiHole application specific logging ### +echo "::: Writing whitelist to debug log..." +echo "#######################################" >> $DEBUG_LOG +echo "############## Whitelist ##############" >> $DEBUG_LOG +echo "#######################################" >> $DEBUG_LOG +if [ -e "$WHITELISTFILE" ] +then + cat "$WHITELISTFILE" >> $DEBUG_LOG + echo >> $DEBUG_LOG +else + echo "No whitelist.txt file found!" >> $DEBUG_LOG + printf ":::\tNo whitelist.txt file found!\n" +fi + +echo "::: Writing blacklist to debug log..." +echo "#######################################" >> $DEBUG_LOG +echo "############## Blacklist ##############" >> $DEBUG_LOG +echo "#######################################" >> $DEBUG_LOG +if [ -e "$BLACKLISTFILE" ] +then + cat "$BLACKLISTFILE" >> $DEBUG_LOG + echo >> $DEBUG_LOG +else + echo "No blacklist.txt file found!" >> $DEBUG_LOG + printf ":::\tNo blacklist.txt file found!\n" +fi + +echo "::: Writing adlists.list to debug log..." +echo "#######################################" >> $DEBUG_LOG +echo "############ adlists.list #############" >> $DEBUG_LOG +echo "#######################################" >> $DEBUG_LOG +if [ -e "$ADLISTSFILE" ] +then + cat "$ADLISTSFILE" >> $DEBUG_LOG + echo >> $DEBUG_LOG +else + echo "No adlists.list file found... using adlists.default!" >> $DEBUG_LOG + printf ":::\tNo adlists.list file found... using adlists.default!\n" +fi + + +# Continuously append the pihole.log file to the pihole_debug.log file +function dumpPiHoleLog { + trap '{ echo -e "\nFinishing debug write from interrupt... Quitting!" ; exit 1; }' INT + echo -e "::: Writing current pihole traffic to debug log...\n:::\tTry loading any/all sites that you are having trouble with now... \n:::\t(Press ctrl+C to finish)" + echo "#######################################" >> $DEBUG_LOG + echo "############# pihole.log ##############" >> $DEBUG_LOG + echo "#######################################" >> $DEBUG_LOG + if [ -e "$PIHOLELOG" ] + then + while true; do + tail -f "$PIHOLELOG" >> $DEBUG_LOG + echo >> $DEBUG_LOG + done + else + echo "No pihole.log file found!" >> $DEBUG_LOG + printf ":::\tNo pihole.log file found!\n" + fi +} + +# Anything to be done after capturing of pihole.log terminates +function finalWork { + echo "::: Finshed debugging!" +} +trap finalWork EXIT + +### Method calls for additional logging ### +dumpPiHoleLog diff --git a/advanced/Scripts/piholeLogFlush.sh b/advanced/Scripts/piholeLogFlush.sh index bbcf1ade..db97f8cb 100755 --- a/advanced/Scripts/piholeLogFlush.sh +++ b/advanced/Scripts/piholeLogFlush.sh @@ -10,4 +10,6 @@ # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. +echo -n "::: Flushing /var/log/pihole.log ..." truncate -s 0 /var/log/pihole.log +echo "... done!" diff --git a/advanced/Scripts/setupLCD.sh b/advanced/Scripts/setupLCD.sh old mode 100644 new mode 100755 diff --git a/advanced/Scripts/updateDashboard.sh b/advanced/Scripts/updateDashboard.sh old mode 100644 new mode 100755 index edf04896..6955683d --- a/advanced/Scripts/updateDashboard.sh +++ b/advanced/Scripts/updateDashboard.sh @@ -63,7 +63,7 @@ make_repo() { update_repo() { # pull the latest commits cd "$WEB_INTERFACE_DIR" - git pull + git pull } main diff --git a/advanced/Scripts/whitelist.sh b/advanced/Scripts/whitelist.sh index 853c3b79..1d33e41a 100755 --- a/advanced/Scripts/whitelist.sh +++ b/advanced/Scripts/whitelist.sh @@ -11,38 +11,45 @@ # (at your option) any later version. if [[ $# = 0 ]]; then - echo "Immediately whitelists one or more domains in the hosts file" - echo " " - echo "Usage: whitelist.sh domain1 [domain2 ...]" - echo " " - echo "Options:" - echo " -d, --delmode Remove domains from the whitelist" - echo " -nr, --noreload Update Whitelist without refreshing dnsmasq" - echo " -f, --force Force updating of the hosts files, even if there are no changes" - echo " -q, --quiet output is less verbose" + echo "::: Immediately whitelists one or more domains in the hosts file" + echo ":::" + echo "::: Usage: sudo pihole.sh -w domain1 [domain2 ...]" + echo ":::" + echo "::: Options:" + echo "::: -d, --delmode Remove domains from the whitelist" + echo "::: -nr, --noreload Update Whitelist without refreshing dnsmasq" + echo "::: -f, --force Force updating of the hosts files, even if there are no changes" + echo "::: -q, --quiet output is less verbose" exit 1 fi #globals -whitelist=/etc/pihole/whitelist.txt -adList=/etc/pihole/gravity.list +basename=pihole +piholeDir=/etc/$basename +adList=$piholeDir/gravity.list +whitelist=$piholeDir/whitelist.txt reload=true addmode=true force=false versbose=true + domList=() domToRemoveList=() -piholeIPfile=/tmp/piholeIP piholeIPv6file=/etc/pihole/.useIPv6 # Otherwise, the IP address can be taken directly from the machine, which will happen when the script is run by the user and not the installation script IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}') -piholeIPCIDR=$(ip -o -f inet addr show dev $IPv4dev | awk '{print $4}' | awk 'END {print}') +piholeIPCIDR=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}') piholeIP=${piholeIPCIDR%/*} modifyHost=false +# After setting defaults, check if there's local overrides +if [[ -r $piholeDir/pihole.conf ]];then + echo "::: Local calibration requested..." + . $piholeDir/pihole.conf +fi if [[ -f $piholeIPv6file ]];then # If the file exists, then the user previously chose to use IPv6 in the automated installer @@ -50,13 +57,12 @@ if [[ -f $piholeIPv6file ]];then fi -function HandleOther(){ +function HandleOther(){ #check validity of domain - validDomain=$(echo $1 | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/') - + validDomain=$(echo "$1" | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/') if [ -z "$validDomain" ]; then echo "::: $1 is not a valid argument or domain name" - else + else domList=("${domList[@]}" $validDomain) fi } @@ -65,13 +71,13 @@ function PopWhitelistFile(){ #check whitelist file exists, and if not, create it if [[ ! -f $whitelist ]];then touch $whitelist - fi + fi for dom in "${domList[@]}" - do + do if $addmode; then - AddDomain $dom + AddDomain "$dom" else - RemoveDomain $dom + RemoveDomain "$dom" fi done } @@ -79,27 +85,27 @@ function PopWhitelistFile(){ function AddDomain(){ #| sed 's/\./\\./g' bool=false - + grep -Ex -q "$1" $whitelist || bool=true if $bool; then #domain not found in the whitelist file, add it! if $versbose; then - echo -n "::: Adding $1 to whitelist.txt..." + echo -n "::: Adding $1 to $whitelist..." fi - echo $1 >> $whitelist + echo "$1" >> $whitelist modifyHost=true if $versbose; then echo " done!" fi else if $versbose; then - echo "::: $1 already exists in whitelist.txt, no need to add!" + echo "::: $1 already exists in $whitelist, no need to add!" fi fi } function RemoveDomain(){ - + bool=false grep -Ex -q "$1" $whitelist || bool=true if $bool; then @@ -113,11 +119,11 @@ function RemoveDomain(){ #echo "::: Un-whitelisting $dom..." #fi domToRemoveList=("${domToRemoveList[@]}" $1) - modifyHost=true - fi + modifyHost=true + fi } -function ModifyHostFile(){ +function ModifyHostFile(){ if $addmode; then #remove domains in from hosts file if [[ -r $whitelist ]];then @@ -126,36 +132,36 @@ function ModifyHostFile(){ plural=; [[ "$numberOf" != "1" ]] && plural=s echo ":::" echo -n "::: Modifying HOSTS file to whitelist $numberOf domain${plural}..." - awk -F':' '{print $1}' $whitelist | while read line; do echo "$piholeIP $line"; done > /etc/pihole/whitelist.tmp - awk -F':' '{print $1}' $whitelist | while read line; do echo "$piholeIPv6 $line"; done >> /etc/pihole/whitelist.tmp + awk -F':' '{print $1}' $whitelist | while read -r line; do echo "$piholeIP $line"; done > /etc/pihole/whitelist.tmp + awk -F':' '{print $1}' $whitelist | while read -r line; do echo "$piholeIPv6 $line"; done >> /etc/pihole/whitelist.tmp echo "l" >> /etc/pihole/whitelist.tmp - grep -F -x -v -f /etc/pihole/whitelist.tmp /etc/pihole/gravity.list > /etc/pihole/gravity.tmp - rm /etc/pihole/gravity.list - mv /etc/pihole/gravity.tmp /etc/pihole/gravity.list - rm /etc/pihole/whitelist.tmp + grep -F -x -v -f $piholeDir/whitelist.tmp $adList > $piholeDir/gravity.tmp + rm $adList + mv $piholeDir/gravity.tmp $adList + rm $piholeDir/whitelist.tmp echo " done!" - + fi else #we need to add the removed domains to the hosts file echo ":::" echo "::: Modifying HOSTS file to un-whitelist domains..." for rdom in "${domToRemoveList[@]}" - do + do if [[ -n $piholeIPv6 ]];then echo -n "::: Un-whitelisting $rdom on IPv4 and IPv6..." - echo $rdom | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $adList + echo "$rdom" | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $adList echo " done!" else echo -n "::: Un-whitelisting $rdom on IPv4" - echo $rdom | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >>$adList + echo "$rdom" | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >>$adList echo " done!" fi - echo -n "::: Removing $rdom from whitelist.txt..." - echo $rdom| sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' $whitelist + echo -n "::: Removing $rdom from $whitelist..." + echo "$rdom" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' $whitelist echo " done!" done - fi + fi } function Reload() { @@ -166,7 +172,7 @@ function Reload() { if [[ $dnsmasqPid ]]; then # service already running - reload config - sudo kill -HUP $dnsmasqPid + sudo kill -HUP "$dnsmasqPid" else # service not running, start it up sudo service dnsmasq start @@ -179,11 +185,11 @@ function Reload() { for var in "$@" do case "$var" in - "-nr"| "--noreload" ) reload=false;; + "-nr"| "--noreload" ) reload=false;; "-d" | "--delmode" ) addmode=false;; "-f" | "--force" ) force=true;; "-q" | "--quiet" ) versbose=false;; - * ) HandleOther $var;; + * ) HandleOther "$var";; esac done diff --git a/advanced/bash-completion/pihole b/advanced/bash-completion/pihole new file mode 100644 index 00000000..e2c70558 --- /dev/null +++ b/advanced/bash-completion/pihole @@ -0,0 +1,12 @@ +_pihole() +{ + local cur prev opts + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + opts="whitelist blacklist debug flush updateDashboard updateGravity setupLCD chronometer uninstall help" + + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 +} +complete -F _pihole pihole \ No newline at end of file diff --git a/advanced/dnsmasq.conf.original b/advanced/dnsmasq.conf.original index 598d6390..9e4cc92e 100644 --- a/advanced/dnsmasq.conf.original +++ b/advanced/dnsmasq.conf.original @@ -27,8 +27,8 @@ # Replies which are not DNSSEC signed may be legitimate, because the domain # is unsigned, or may be forgeries. Setting this option tells dnsmasq to -# check that an unsigned reply is OK, by finding a secure proof that a DS -# record somewhere between the root and the domain does not exist. +# check that an unsigned reply is OK, by finding a secure proof that a DS +# record somewhere between the root and the domain does not exist. # The cost of setting this is that even queries in unsigned domains will need # one or more extra DNS queries to verify. #dnssec-check-unsigned @@ -183,11 +183,11 @@ #dhcp-range=1234::2, 1234::500, 64, 12h # Do Router Advertisements, BUT NOT DHCP for this subnet. -#dhcp-range=1234::, ra-only +#dhcp-range=1234::, ra-only # Do Router Advertisements, BUT NOT DHCP for this subnet, also try and -# add names to the DNS for the IPv6 address of SLAAC-configured dual-stack -# hosts. Use the DHCPv4 lease to derive the name, network segment and +# add names to the DNS for the IPv6 address of SLAAC-configured dual-stack +# hosts. Use the DHCPv4 lease to derive the name, network segment and # MAC address and assume that the host will also have an # IPv6 address calculated using the SLAAC alogrithm. #dhcp-range=1234::, ra-names @@ -210,9 +210,9 @@ #dhcp-range=1234::, ra-stateless, ra-names # Do router advertisements for all subnets where we're doing DHCPv6 -# Unless overriden by ra-stateless, ra-names, et al, the router +# Unless overriden by ra-stateless, ra-names, et al, the router # advertisements will have the M and O bits set, so that the clients -# get addresses and configuration from DHCPv6, and the A bit reset, so the +# get addresses and configuration from DHCPv6, and the A bit reset, so the # clients don't use SLAAC addresses. #enable-ra @@ -278,11 +278,11 @@ # any machine with Ethernet address starting 11:22:33: #dhcp-host=11:22:33:*:*:*,set:red -# Give a fixed IPv6 address and name to client with +# Give a fixed IPv6 address and name to client with # DUID 00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2 # Note the MAC addresses CANNOT be used to identify DHCPv6 clients. # Note also the they [] around the IPv6 address are obilgatory. -#dhcp-host=id:00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2, fred, [1234::5] +#dhcp-host=id:00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2, fred, [1234::5] # Ignore any clients which are not specified in dhcp-host lines # or /etc/ethers. Equivalent to ISC "deny unknown-clients". @@ -338,7 +338,7 @@ # Send DHCPv6 option. Note [] around IPv6 addresses. #dhcp-option=option6:dns-server,[1234::77],[1234::88] -# Send DHCPv6 option for namservers as the machine running +# Send DHCPv6 option for namservers as the machine running # dnsmasq and another. #dhcp-option=option6:dns-server,[::],[1234::88] @@ -645,4 +645,4 @@ #conf-dir=/etc/dnsmasq.d,.bak # Include all files in a directory which end in .conf -#conf-dir=/etc/dnsmasq.d/*.conf +#conf-dir=/etc/dnsmasq.d/*.conf diff --git a/advanced/index.js b/advanced/index.js new file mode 100644 index 00000000..c9da5aff --- /dev/null +++ b/advanced/index.js @@ -0,0 +1 @@ +var x = "Pi-hole: A black hole for Internet advertisements." diff --git a/advanced/lighttpd.conf b/advanced/lighttpd.conf index 5a662ffa..124371a9 100644 --- a/advanced/lighttpd.conf +++ b/advanced/lighttpd.conf @@ -53,4 +53,6 @@ $HTTP["url"] =~ "^/admin/" { $HTTP["url"] =~ "^(?!/admin)/.*" { # Create a response header for debugging using curl -I setenv.add-response-header = ( "X-Pi-hole" => "A black hole for Internet advertisements." ) + # rewrite only js requests + url.rewrite = ("(.*).js" => "pihole/index.js") } diff --git a/advanced/pihole.cron b/advanced/pihole.cron index 83b431a4..9d390143 100644 --- a/advanced/pihole.cron +++ b/advanced/pihole.cron @@ -10,7 +10,7 @@ # (at your option) any later version. # Pi-hole: Update the ad sources once a week on Sunday at 01:59 -# Download any updates from the ad lists +# Download any updates from the adlists 59 1 * * 7 root /usr/local/bin/gravity.sh # Pi-hole: Update the Web interface shortly after gravity runs diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 7365104d..cd408887 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -40,7 +40,7 @@ c=$(( columns / 2 )) # Find IP used to route to outside world IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}') -IPv4addr=$(ip -o -f inet addr show dev $IPv4dev | awk '{print $4}' | awk 'END {print}') +IPv4addr=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}') IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}') availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1) @@ -64,27 +64,20 @@ else fi -if [ -d "/etc/pihole" ]; then - # Likely an existing install - upgrade=true - else - upgrade=false -fi - ####### FUNCTIONS ########## -###All credit for the below function goes to http://fitnr.com/showing-a-bash-spinner.html -spinner() { +spinner() +{ local pid=$1 - - spin='-\|/' - i=0 - while $SUDO kill -0 $pid 2>/dev/null - do - i=$(( (i+1) %4 )) - printf "\b${spin:$i:1}" - sleep .1 - done - printf "\b" + local delay=0.50 + local spinstr='/-\|' + while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do + local temp=${spinstr#?} + printf " [%c] " "$spinstr" + local spinstr=$temp${spinstr%"$temp"} + sleep $delay + printf "\b\b\b\b\b\b" + done + printf " \b\b\b\b" } backupLegacyPihole() { @@ -92,12 +85,17 @@ backupLegacyPihole() { if [[ -f /etc/dnsmasq.d/adList.conf ]];then echo "::: Original Pi-hole detected. Initiating sub space transport" $SUDO mkdir -p /etc/pihole/original/ - $SUDO mv /etc/dnsmasq.d/adList.conf /etc/pihole/original/adList.conf.$(date "+%Y-%m-%d") - $SUDO mv /etc/dnsmasq.conf /etc/pihole/original/dnsmasq.conf.$(date "+%Y-%m-%d") - $SUDO mv /etc/resolv.conf /etc/pihole/original/resolv.conf.$(date "+%Y-%m-%d") - $SUDO mv /etc/lighttpd/lighttpd.conf /etc/pihole/original/lighttpd.conf.$(date "+%Y-%m-%d") - $SUDO mv /var/www/pihole/index.html /etc/pihole/original/index.html.$(date "+%Y-%m-%d") - $SUDO mv /usr/local/bin/gravity.sh /etc/pihole/original/gravity.sh.$(date "+%Y-%m-%d") + $SUDO mv /etc/dnsmasq.d/adList.conf /etc/pihole/original/adList.conf."$(date "+%Y-%m-%d")" + $SUDO mv /etc/dnsmasq.conf /etc/pihole/original/dnsmasq.conf."$(date "+%Y-%m-%d")" + $SUDO mv /etc/resolv.conf /etc/pihole/original/resolv.conf."$(date "+%Y-%m-%d")" + $SUDO mv /etc/lighttpd/lighttpd.conf /etc/pihole/original/lighttpd.conf."$(date "+%Y-%m-%d")" + $SUDO mv /var/www/pihole/index.html /etc/pihole/original/index.html."$(date "+%Y-%m-%d")" + if [ ! -d /opt/pihole ]; then + $SUDO mkdir /opt/pihole + $SUDO chown "$USER":root /opt/pihole + $SUDO chmod u+srwx /opt/pihole + fi + $SUDO mv /opt/pihole/gravity.sh /etc/pihole/original/gravity.sh."$(date "+%Y-%m-%d")" else : fi @@ -111,7 +109,7 @@ welcomeDialogs() { whiptail --msgbox --backtitle "Plea" --title "Free and open source" "The Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" $r $c # Explain the need for a static address - whiptail --msgbox --backtitle "Initating network interface" --title "Static IP Needed" "The Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly. + whiptail --msgbox --backtitle "Initating network interface" --title "Static IP Needed" "The Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly. In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." $r $c } @@ -119,12 +117,12 @@ welcomeDialogs() { verifyFreeDiskSpace() { # 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.) requiredFreeBytes=51200 - - existingFreeBytes=`df -lk / 2>&1 | awk '{print $4}' | head -2 | tail -1` - if ! [[ "$existingFreeBytes" =~ ^([0-9])+$ ]]; then - existingFreeBytes=`df -lk /dev 2>&1 | awk '{print $4}' | head -2 | tail -1` + + existingFreeBytes=$(df -lk / 2>&1 | awk '{print $4}' | head -2 | tail -1) + if ! [[ "$existingFreeBytes" =~ ^([0-9])+$ ]]; then + existingFreeBytes=$(df -lk /dev 2>&1 | awk '{print $4}' | head -2 | tail -1) fi - + if [[ $existingFreeBytes -lt $requiredFreeBytes ]]; then whiptail --msgbox --backtitle "Insufficient Disk Space" --title "Insufficient Disk Space" "\nYour system appears to be low on disk space. pi-hole recomends a minimum of $requiredFreeBytes Bytes.\nYou only have $existingFreeBytes Free.\n\nIf this is a new install you may need to expand your disk.\n\nTry running:\n 'sudo raspi-config'\nChoose the 'expand file system option'\n\nAfter rebooting, run this installation again.\n\ncurl -L install.pi-hole.net | bash\n" $r $c echo "$existingFreeBytes is less than $requiredFreeBytes" @@ -153,23 +151,23 @@ chooseInterface() { interfaceCount=$(echo "$availableInterfaces" | wc -l) chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface" $r $c $interfaceCount) chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) - if [[ $? = 0 ]];then + if [[ $? = 0 ]]; then for desiredInterface in $chooseInterfaceOptions do - piholeInterface=$desiredInterface - echo "::: Using interface: $piholeInterface" - echo ${piholeInterface} > /tmp/piholeINT + piholeInterface=$desiredInterface + echo "::: Using interface: $piholeInterface" + echo "${piholeInterface}" > /tmp/piholeINT done else echo "::: Cancel selected, exiting...." exit 1 fi - + } cleanupIPv6() { # Removes IPv6 indicator file if we are not using IPv6 - if [ -f "/etc/pihole/.useIPv6" ] && [ ! $useIPv6 ]; then + if [ -f "/etc/pihole/.useIPv6" ] && [ ! "$useIPv6" ]; then rm /etc/pihole/.useIPv6 fi } @@ -184,11 +182,11 @@ use4andor6() { for choice in $choices do case $choice in - IPv4 ) useIPv4=true;; - IPv6 ) useIPv6=true;; + IPv4 ) useIPv4=true;; + IPv6 ) useIPv6=true;; esac done - + if [ $useIPv4 ] && [ ! $useIPv6 ]; then getStaticIPv4Settings setStaticIPv4 @@ -230,8 +228,8 @@ useIPv6dialog() { getStaticIPv4Settings() { # Ask if the user wants to use DHCP settings as their static IP if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address? - IP address: $IPv4addr - Gateway: $IPv4gw" $r $c) then + IP address: $IPv4addr + Gateway: $IPv4gw" $r $c) then # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict. whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that. If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want. @@ -244,41 +242,41 @@ getStaticIPv4Settings() { until [[ $ipSettingsCorrect = True ]] do # Ask for the IPv4 address - IPv4addr=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" $r $c $IPv4addr 3>&1 1>&2 2>&3) + IPv4addr=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" $r $c "$IPv4addr" 3>&1 1>&2 2>&3) if [[ $? = 0 ]];then - echo "::: Your static IPv4 address: $IPv4addr" - # Ask for the gateway - IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" $r $c $IPv4gw 3>&1 1>&2 2>&3) - if [[ $? = 0 ]];then - echo "::: Your static IPv4 gateway: $IPv4gw" - # Give the user a chance to review their settings before moving on - if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct? - IP address: $IPv4addr - Gateway: $IPv4gw" $r $c)then - # If the settings are correct, then we need to set the piholeIP - # Saving it to a temporary file us to retrieve it later when we run the gravity.sh script - echo ${IPv4addr%/*} > /tmp/piholeIP - echo $piholeInterface > /tmp/piholeINT - # After that's done, the loop ends and we move on - ipSettingsCorrect=True - else - # If the settings are wrong, the loop continues - ipSettingsCorrect=False - fi + echo "::: Your static IPv4 address: $IPv4addr" + # Ask for the gateway + IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" $r $c "$IPv4gw" 3>&1 1>&2 2>&3) + if [[ $? = 0 ]];then + echo "::: Your static IPv4 gateway: $IPv4gw" + # Give the user a chance to review their settings before moving on + if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct? + IP address: $IPv4addr + Gateway: $IPv4gw" $r $c)then + # If the settings are correct, then we need to set the piholeIP + # Saving it to a temporary file us to retrieve it later when we run the gravity.sh script + echo "${IPv4addr%/*}" > /tmp/piholeIP + echo "$piholeInterface" > /tmp/piholeINT + # After that's done, the loop ends and we move on + ipSettingsCorrect=True else - # Cancelling gateway settings window + # If the settings are wrong, the loop continues ipSettingsCorrect=False - echo "::: Cancel selected. Exiting..." - exit 1 fi else - # Cancelling IPv4 settings window + # Cancelling gateway settings window ipSettingsCorrect=False echo "::: Cancel selected. Exiting..." exit 1 fi + else + # Cancelling IPv4 settings window + ipSettingsCorrect=False + echo "::: Cancel selected. Exiting..." + exit 1 + fi done - # End the if statement for DHCP vs. static + # End the if statement for DHCP vs. static fi } @@ -292,12 +290,12 @@ setDHCPCD() { setStaticIPv4() { # Tries to set the IPv4 address - if grep -q $IPv4addr $dhcpcdFile; then + if grep -q "$IPv4addr" $dhcpcdFile; then # address already set, noop : else setDHCPCD - $SUDO ip addr replace dev $piholeInterface $IPv4addr + $SUDO ip addr replace dev "$piholeInterface" "$IPv4addr" echo ":::" echo "::: Setting IP to $IPv4addr. You may need to restart after the install is complete." echo ":::" @@ -308,7 +306,7 @@ function valid_ip() { local ip=$1 local stat=1 - + if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then OIFS=$IFS IFS='.' @@ -324,98 +322,88 @@ function valid_ip() setDNS(){ DNSChoseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." $r $c 6) DNSChooseOptions=(Google "" on - OpenDNS "" off - Level3 "" off - Norton "" off - Comodo "" off - Custom "" off) + OpenDNS "" off + Level3 "" off + Norton "" off + Comodo "" off + Custom "" off) DNSchoices=$("${DNSChoseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty) if [[ $? = 0 ]];then case $DNSchoices in - Google) - echo "::: Using Google DNS servers." - piholeDNS1="8.8.8.8" - piholeDNS2="8.8.4.4" - ;; - OpenDNS) - echo "::: Using OpenDNS servers." - piholeDNS1="208.67.222.222" - piholeDNS2="208.67.220.220" - ;; - Level3) - echo "::: Using Level3 servers." - piholeDNS1="4.2.2.1" - piholeDNS2="4.2.2.2" - ;; - Norton) - echo "::: Using Norton ConnectSafe servers." - piholeDNS1="199.85.126.10" - piholeDNS2="199.85.127.10" - ;; - Comodo) - echo "::: Using Comodo Secure servers." - piholeDNS1="8.26.56.26" - piholeDNS2="8.20.247.20" - ;; - Custom) - until [[ $DNSSettingsCorrect = True ]] - do - - strInvalid="Invalid" - - if [ ! $piholeDNS1 ]; then - if [ ! $piholeDNS2 ]; then - prePopulate="" - else - prePopulate=", $piholeDNS2" - fi - elif [ $piholeDNS1 ] && [ ! $piholeDNS2 ]; then - prePopulate="$piholeDNS1" - elif [ $piholeDNS1 ] && [ $piholeDNS2 ]; then - prePopulate="$piholeDNS1, $piholeDNS2" - fi - - piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" $r $c "$prePopulate" 3>&1 1>&2 2>&3) - if [[ $? = 0 ]];then - piholeDNS1=$(echo $piholeDNS | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}') - piholeDNS2=$(echo $piholeDNS | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}') - - if ! valid_ip $piholeDNS1 || [ ! $piholeDNS1 ]; then - piholeDNS1=$strInvalid - fi - - if ! valid_ip $piholeDNS2 && [ $piholeDNS2 ]; then - piholeDNS2=$strInvalid - fi - + Google) + echo "::: Using Google DNS servers." + piholeDNS1="8.8.8.8" + piholeDNS2="8.8.4.4" + ;; + OpenDNS) + echo "::: Using OpenDNS servers." + piholeDNS1="208.67.222.222" + piholeDNS2="208.67.220.220" + ;; + Level3) + echo "::: Using Level3 servers." + piholeDNS1="4.2.2.1" + piholeDNS2="4.2.2.2" + ;; + Norton) + echo "::: Using Norton ConnectSafe servers." + piholeDNS1="199.85.126.10" + piholeDNS2="199.85.127.10" + ;; + Comodo) + echo "::: Using Comodo Secure servers." + piholeDNS1="8.26.56.26" + piholeDNS2="8.20.247.20" + ;; + Custom) + until [[ $DNSSettingsCorrect = True ]] + do + strInvalid="Invalid" + if [ ! $piholeDNS1 ]; then + if [ ! $piholeDNS2 ]; then + prePopulate="" else - echo "::: Cancel selected, exiting...." - exit 1 + prePopulate=", $piholeDNS2" fi - - if [[ $piholeDNS1 == $strInvalid ]] || [[ $piholeDNS2 == $strInvalid ]]; then - whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $piholeDNS1\n DNS Server 2: $piholeDNS2" $r $c - - if [[ $piholeDNS1 == $strInvalid ]]; then - piholeDNS1="" - fi - - if [[ $piholeDNS2 == $strInvalid ]]; then - piholeDNS2="" - fi - + elif [ $piholeDNS1 ] && [ ! $piholeDNS2 ]; then + prePopulate="$piholeDNS1" + elif [ $piholeDNS1 ] && [ $piholeDNS2 ]; then + prePopulate="$piholeDNS1, $piholeDNS2" + fi + piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" $r $c "$prePopulate" 3>&1 1>&2 2>&3) + if [[ $? = 0 ]];then + piholeDNS1=$(echo "$piholeDNS" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}') + piholeDNS2=$(echo "$piholeDNS" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}') + if ! valid_ip "$piholeDNS1" || [ ! "$piholeDNS1" ]; then + piholeDNS1=$strInvalid + fi + if ! valid_ip "$piholeDNS2" && [ "$piholeDNS2" ]; then + piholeDNS2=$strInvalid + fi + else + echo "::: Cancel selected, exiting...." + exit 1 + fi + if [[ $piholeDNS1 == "$strInvalid" ]] || [[ $piholeDNS2 == "$strInvalid" ]]; then + whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $piholeDNS1\n DNS Server 2: $piholeDNS2" $r $c + if [[ $piholeDNS1 == "$strInvalid" ]]; then + piholeDNS1="" + fi + if [[ $piholeDNS2 == "$strInvalid" ]]; then + piholeDNS2="" + fi + DNSSettingsCorrect=False + else + if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $piholeDNS1\n DNS Server 2: $piholeDNS2" $r $c) then + DNSSettingsCorrect=True + else + # If the settings are wrong, the loop continues DNSSettingsCorrect=False - else - if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $piholeDNS1\n DNS Server 2: $piholeDNS2" $r $c) then - DNSSettingsCorrect=True - else - # If the settings are wrong, the loop continues - DNSSettingsCorrect=False - fi fi - done - ;; - esac + fi + done + ;; + esac else echo "::: Cancel selected. Exiting..." exit 1 @@ -423,61 +411,81 @@ setDNS(){ } versionCheckDNSmasq(){ - # Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory - dnsFile1="/etc/dnsmasq.conf" - dnsFile2="/etc/dnsmasq.conf.orig" - dnsSearch="addn-hosts=/etc/pihole/gravity.list" - - defaultFile="/etc/.pihole/advanced/dnsmasq.conf.original" - newFileToInstall="/etc/.pihole/advanced/01-pihole.conf" - newFileFinalLocation="/etc/dnsmasq.d/01-pihole.conf" - - if [ -f $dnsFile1 ]; then - echo -n "::: Existing dnsmasq.conf found..." - if grep -q $dnsSearch $dnsFile1; then - echo " it is from a previous pi-hole install." - echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..." - $SUDO mv -f $dnsFile1 $dnsFile2 - echo " done." - echo -n "::: Restoring default dnsmasq.conf..." - $SUDO cp $defaultFile $dnsFile1 - echo " done." - else - echo " it is not a pi-hole file, leaving alone!" - fi - else - echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..." - $SUDO cp $defaultFile $dnsFile1 - echo " done." - fi - - echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..." - $SUDO cp $newFileToInstall $newFileFinalLocation - echo " done." - $SUDO sed -i "s/@INT@/$piholeInterface/" $newFileFinalLocation - if [[ "$piholeDNS1" != "" ]]; then - $SUDO sed -i "s/@DNS1@/$piholeDNS1/" $newFileFinalLocation - else - $SUDO sed -i '/^server=@DNS1@/d' $newFileFinalLocation - fi - if [[ "$piholeDNS2" != "" ]]; then - $SUDO sed -i "s/@DNS2@/$piholeDNS2/" $newFileFinalLocation - else - $SUDO sed -i '/^server=@DNS2@/d' $newFileFinalLocation - fi + # Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory + dnsFile1="/etc/dnsmasq.conf" + dnsFile2="/etc/dnsmasq.conf.orig" + dnsSearch="addn-hosts=/etc/pihole/gravity.list" + defaultFile="/etc/.pihole/advanced/dnsmasq.conf.original" + newFileToInstall="/etc/.pihole/advanced/01-pihole.conf" + newFileFinalLocation="/etc/dnsmasq.d/01-pihole.conf" + + if [ -f $dnsFile1 ]; then + echo -n "::: Existing dnsmasq.conf found..." + if grep -q $dnsSearch $dnsFile1; then + echo " it is from a previous pi-hole install." + echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..." + $SUDO mv -f $dnsFile1 $dnsFile2 + echo " done." + echo -n "::: Restoring default dnsmasq.conf..." + $SUDO cp $defaultFile $dnsFile1 + echo " done." + else + echo " it is not a pi-hole file, leaving alone!" + fi + else + echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..." + $SUDO cp $defaultFile $dnsFile1 + echo " done." + fi + + echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..." + $SUDO cp $newFileToInstall $newFileFinalLocation + echo " done." + $SUDO sed -i "s/@INT@/$piholeInterface/" $newFileFinalLocation + if [[ "$piholeDNS1" != "" ]]; then + $SUDO sed -i "s/@DNS1@/$piholeDNS1/" $newFileFinalLocation + else + $SUDO sed -i '/^server=@DNS1@/d' $newFileFinalLocation + fi + if [[ "$piholeDNS2" != "" ]]; then + $SUDO sed -i "s/@DNS2@/$piholeDNS2/" $newFileFinalLocation + else + $SUDO sed -i '/^server=@DNS2@/d' $newFileFinalLocation + fi } installScripts() { # Install the scripts from /etc/.pihole to their various locations $SUDO echo ":::" - $SUDO echo -n "::: Installing scripts..." - $SUDO cp /etc/.pihole/gravity.sh /usr/local/bin/gravity.sh - $SUDO cp /etc/.pihole/advanced/Scripts/chronometer.sh /usr/local/bin/chronometer.sh - $SUDO cp /etc/.pihole/advanced/Scripts/whitelist.sh /usr/local/bin/whitelist.sh - $SUDO cp /etc/.pihole/advanced/Scripts/blacklist.sh /usr/local/bin/blacklist.sh - $SUDO cp /etc/.pihole/advanced/Scripts/piholeLogFlush.sh /usr/local/bin/piholeLogFlush.sh - $SUDO cp /etc/.pihole/advanced/Scripts/updateDashboard.sh /usr/local/bin/updateDashboard.sh - $SUDO chmod 755 /usr/local/bin/{gravity,chronometer,whitelist,blacklist,piholeLogFlush,updateDashboard}.sh + $SUDO echo -n "::: Installing scripts to /opt/pihole..." + if [ ! -d /opt/pihole ]; then + $SUDO mkdir /opt/pihole + $SUDO chown "$USER":root /opt/pihole + $SUDO chmod u+srwx /opt/pihole + fi + $SUDO cp /etc/.pihole/gravity.sh /opt/pihole/gravity.sh + $SUDO cp /etc/.pihole/advanced/Scripts/chronometer.sh /opt/pihole/chronometer.sh + $SUDO cp /etc/.pihole/advanced/Scripts/whitelist.sh /opt/pihole/whitelist.sh + $SUDO cp /etc/.pihole/advanced/Scripts/blacklist.sh /opt/pihole/blacklist.sh + $SUDO cp /etc/.pihole/advanced/Scripts/piholeDebug.sh /opt/pihole/piholeDebug.sh + $SUDO cp /etc/.pihole/advanced/Scripts/piholeLogFlush.sh /opt/pihole/piholeLogFlush.sh + $SUDO cp /etc/.pihole/advanced/Scripts/updateDashboard.sh /opt/pihole/updateDashboard.sh + $SUDO cp /etc/.pihole/automated\ install/uninstall.sh /opt/pihole/uninstall.sh + $SUDO cp /etc/.pihole/advanced/Scripts/setupLCD.sh /opt/pihole/setupLCD.sh + $SUDO chmod 755 /opt/pihole/{gravity,chronometer,whitelist,blacklist,piholeLogFlush,updateDashboard,uninstall,setupLCD}.sh + $SUDO cp /etc/.pihole/pihole /usr/local/bin/pihole + $SUDO chmod 755 /usr/local/bin/pihole + $SUDO cp /etc/.pihole/advanced/bash-completion/pihole /etc/bash_completion.d/pihole + . /etc/bash_completion.d/pihole + + #Tidy up /usr/local/bin directory if installing over previous install. + oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug) + for i in "${oldFiles[@]}"; do + if [ -f "/usr/local/bin/$i.sh" ]; then + $SUDO rm /usr/local/bin/"$i".sh + fi + done + $SUDO echo " done." } @@ -486,7 +494,11 @@ installConfigs() { $SUDO echo ":::" $SUDO echo "::: Installing configs..." versionCheckDNSmasq - $SUDO mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig + if [ ! -d "/etc/lighttpd" ]; then + $SUDO mkdir /etc/lighttpd + $SUDO chown "$USER":root /etc/lighttpd + $SUDO mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig + fi $SUDO cp /etc/.pihole/advanced/lighttpd.conf /etc/lighttpd/lighttpd.conf } @@ -504,44 +516,41 @@ checkForDependencies() { #requiring user input (e.g password for phpmyadmin see #218) #We'll change the logic up here, to check to see if there are any updates availible and # if so, advise the user to run apt-get update/upgrade at their own discretion - #Check to see if apt-get update has already been run today # it needs to have been run at least once on new installs! timestamp=$(stat -c %Y /var/cache/apt/) - timestampAsDate=$(date -d @$timestamp "+%b %e") + timestampAsDate=$(date -d @"$timestamp" "+%b %e") today=$(date "+%b %e") if [ ! "$today" == "$timestampAsDate" ]; then - #update package lists - echo ":::" - echo -n "::: apt-get update has not been run today. Running now..." - $SUDO apt-get -qq update & spinner $! - echo " done!" - fi + #update package lists echo ":::" - echo -n "::: Checking apt-get for upgraded packages...." - updatesToInstall=$($SUDO apt-get -s -o Debug::NoLocking=true upgrade | grep -c ^Inst) + echo -n "::: apt-get update has not been run today. Running now..." + $SUDO apt-get -qq update & spinner $! echo " done!" + fi + echo ":::" + echo -n "::: Checking apt-get for upgraded packages...." + updatesToInstall=$($SUDO apt-get -s -o Debug::NoLocking=true upgrade | grep -c ^Inst) + echo " done!" + echo ":::" + if [[ $updatesToInstall -eq "0" ]]; then + echo "::: Your pi is up to date! Continuing with pi-hole installation..." + else + echo "::: There are $updatesToInstall updates availible for your pi!" + echo "::: We recommend you run 'sudo apt-get upgrade' after installing Pi-Hole! " echo ":::" - if [[ $updatesToInstall -eq "0" ]]; then - echo "::: Your pi is up to date! Continuing with pi-hole installation..." - else - echo "::: There are $updatesToInstall updates availible for your pi!" - echo "::: We recommend you run 'sudo apt-get upgrade' after installing Pi-Hole! " - echo ":::" - fi + fi echo ":::" echo "::: Checking dependencies:" - dependencies=( dnsutils bc toilet figlet dnsmasq lighttpd php5-common php5-cgi php5 git curl unzip wget ) - for i in "${dependencies[@]}" - do - : + dependencies=( dnsutils bc toilet figlet dnsmasq lighttpd php5-common php5-cgi php5 git curl unzip wget ) + for i in "${dependencies[@]}"; do echo -n "::: Checking for $i..." - if [ $(dpkg-query -W -f='${Status}' $i 2>/dev/null | grep -c "ok installed") -eq 0 ]; then + if [ "$(dpkg-query -W -f='${Status}' "$i" 2>/dev/null | grep -c "ok installed")" -eq 0 ]; then echo -n " Not found! Installing...." - $SUDO apt-get -y -qq install $i > /dev/null & spinner $! + $SUDO apt-get -y -qq install "$i" > /dev/null & spinner $! echo " done!" else echo " already installed!" @@ -571,18 +580,18 @@ getGitFiles() { is_repo() { # If the directory does not have a .git folder it is not a repo echo -n "::: Checking $1 is a repo..." - if [ -d "$1/.git" ]; then - echo " OK!" - return 1 - fi - echo " not found!!" - return 0 + if [ -d "$1/.git" ]; then + echo " OK!" + return 1 + fi + echo " not found!!" + return 0 } make_repo() { # Remove the non-repod interface and clone the interface echo -n "::: Cloning $2 into $1..." - $SUDO rm -rf $1 + $SUDO rm -rf "$1" $SUDO git clone -q "$2" "$1" > /dev/null & spinner $! echo " done!" } @@ -590,7 +599,7 @@ make_repo() { update_repo() { # Pull the latest commits echo -n "::: Updating repo in $1..." - cd "$1" + cd "$1" || exit $SUDO git pull -q > /dev/null & spinner $! echo " done!" } @@ -618,8 +627,12 @@ installPiholeWeb() { $SUDO echo " Existing page detected, not overwriting" else $SUDO mkdir /var/www/html/pihole - $SUDO mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig - $SUDO cp /etc/.pihole/advanced/index.html /var/www/html/pihole/index.html + if [ -f /var/www/html/index.lighttpd.html ]; then + $SUDO mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig + else + printf "\n:::\tNo default index.lighttpd.html file found... not backing up" + fi + $SUDO cp /etc/.pihole/advanced/index.* /var/www/html/pihole/. $SUDO echo " done!" fi } @@ -635,16 +648,13 @@ installCron() { runGravity() { # Rub gravity.sh to build blacklists $SUDO echo ":::" - $SUDO echo "::: Preparing to run gravity.sh to refresh hosts..." + $SUDO echo "::: Preparing to run gravity.sh to refresh hosts..." if ls /etc/pihole/list* 1> /dev/null 2>&1; then - echo "::: Cleaning up previous install (preserving whitelist/blacklist)" + echo "::: Cleaning up previous install (preserving whitelist/blacklist)" $SUDO rm /etc/pihole/list.* fi - #Don't run as SUDO, this was causing issues echo "::: Running gravity.sh" - echo ":::" - - /usr/local/bin/gravity.sh + $SUDO /opt/pihole/gravity.sh } setUser(){ @@ -653,7 +663,7 @@ setUser(){ if id -u pihole > /dev/null 2>&1; then echo "::: User 'pihole' already exists" else - echo "::: User 'pihole' doesn't exist. Creating..." + echo "::: User 'pihole' doesn't exist. Creating..." $SUDO useradd -r -s /usr/sbin/nologin pihole fi } @@ -664,6 +674,9 @@ installPihole() { stopServices setUser $SUDO mkdir -p /etc/pihole/ + if [ ! -d "/var/www/html" ]; then + $SUDO mkdir -p /var/www/html + fi $SUDO chown www-data:www-data /var/www/html $SUDO chmod 775 /var/www/html $SUDO usermod -a -G www-data pihole @@ -682,12 +695,12 @@ displayFinalMessage() { # Final completion message to user whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using: -$IPv4addr -$piholeIPv6 + $IPv4addr + $piholeIPv6 -If you set a new IP address, you should restart the Pi. + If you set a new IP address, you should restart the Pi. -The install log is in /etc/pihole." $r $c + The install log is in /etc/pihole." $r $c } ######## SCRIPT ############ diff --git a/automated install/uninstall.sh b/automated install/uninstall.sh old mode 100644 new mode 100755 index ee4e80a0..484a544d --- a/automated install/uninstall.sh +++ b/automated install/uninstall.sh @@ -12,62 +12,135 @@ # Must be root to uninstall if [[ $EUID -eq 0 ]];then - echo "You are root." + echo "::: You are root." else - echo "sudo will be used for the install." + echo "::: Sudo will be used for the uninstall." # Check if it is actually installed # If it isn't, exit because the unnstall cannot complete if [[ $(dpkg-query -s sudo) ]];then export SUDO="sudo" else - echo "Please install sudo or run this as root." + echo "::: Please install sudo or run this as root." exit 1 fi fi +spinner() +{ + local pid=$1 + local delay=0.50 + local spinstr='/-\|' + while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do + local temp=${spinstr#?} + printf " [%c] " "$spinstr" + local spinstr=$temp${spinstr%"$temp"} + sleep $delay + printf "\b\b\b\b\b\b" + done + printf " \b\b\b\b" +} + +function removeAndPurge { + # Purge dependencies +echo ":::" + # Nate 3/28/2016 - Removed `php5-cgi` and `php5` as they are removed with php5-common + dependencies=( dnsutils bc toilet figlet dnsmasq lighttpd php5-common git curl unzip wget ) + for i in "${dependencies[@]}"; do + if [ "$(dpkg-query -W --showformat='${Status}\n' "$i" 2> /dev/null | grep -c "ok installed")" -eq 1 ]; then + while true; do + read -rp "::: Do you wish to remove $i from your system? [y/n]: " yn + case $yn in + [Yy]* ) printf ":::\tRemoving %s..." "$i"; $SUDO apt-get -y remove --purge "$i" &> /dev/null & spinner $!; printf "done!\n"; break;; + [Nn]* ) printf ":::\tSkipping %s" "$i\n"; break;; + * ) printf "::: You must answer yes or no!\n";; + esac + done + else + printf ":::\tPackage %s not installed... Not removing.\n" "$i" + fi + done + + # Remove dependency config files + echo "::: Removing dnsmasq config files..." + $SUDO rm /etc/dnsmasq.conf /etc/dnsmasq.conf.orig /etc/dnsmasq.d/01-pihole.conf &> /dev/null + + # Take care of any additional package cleaning + printf "::: Auto removing remaining dependencies..." + $SUDO apt-get -y autoremove &> /dev/null & spinner $!; printf "done!\n"; + printf "::: Auto cleaning remaining dependencies..." + $SUDO apt-get -y autoclean &> /dev/null & spinner $!; printf "done!\n"; + + # Call removeNoPurge to remove PiHole specific files + removeNoPurge +} + +function removeNoPurge { + echo ":::" + # Only web directories/files that are created by pihole should be removed. + echo "::: Removing the Pi-hole Web server files..." + $SUDO rm -rf /var/www/html/admin &> /dev/null + $SUDO rm -rf /var/www/html/pihole &> /dev/null + $SUDO rm /var/www/html/index.lighttpd.orig &> /dev/null + + # If the web directory is empty after removing these files, then the parent html folder can be removed. + if [ -d "/var/www/html" ]; then + if [[ ! "$(ls -A /var/www/html)" ]]; then + $SUDO rm -rf /var/www/html &> /dev/null + fi + fi + + # Attempt to preserve backwards compatibility with older versions + # to guarantee no additional changes were made to /etc/crontab after + # the installation of pihole, /etc/crontab.pihole should be permanently + # preserved. + if [[ -f /etc/crontab.orig ]]; then + echo "::: Initial Pi-hole cron detected. Restoring the default system cron..." + $SUDO mv /etc/crontab /etc/crontab.pihole + $SUDO mv /etc/crontab.orig /etc/crontab + $SUDO service cron restart + fi + + # Attempt to preserve backwards compatibility with older versions + if [[ -f /etc/cron.d/pihole ]];then + echo "::: Removing cron.d/pihole..." + $SUDO rm /etc/cron.d/pihole &> /dev/null + fi + + echo "::: Removing config files and scripts..." + if [ ! "$(dpkg-query -W --showformat='${Status}\n' lighttpd 2> /dev/null | grep -c "ok installed")" -eq 1 ]; then + $SUDO rm -rf /etc/lighttpd/ &> /dev/null + else + if [ -f /etc/lighttpd/lighttpd.conf.orig ]; then + $SUDO mv /etc/lighttpd/lighttpd.conf.orig /etc/lighttpd/lighttpd.conf + fi + fi + + $SUDO rm /etc/dnsmasq.d/adList.conf &> /dev/null + $SUDO rm /etc/dnsmasq.d/01-pihole.conf &> /dev/null + $SUDO rm -rf /var/log/*pihole* &> /dev/null + $SUDO rm -rf /etc/pihole/ &> /dev/null + $SUDO rm -rf /etc/.pihole/ &> /dev/null + $SUDO rm -rf /opt/pihole/ &> /dev/null + $SUDO rm /usr/local/bin/pihole &> /dev/null + $SUDO rm /etc/bash_completion.d/pihole + + echo ":::" + printf "::: Finished removing PiHole from your system. Sorry to see you go!\n" + printf "::: Reach out to us at https://github.com/pi-hole/pi-hole/issues if you need help\n" + printf "::: Reinstall by simpling running\n:::\n:::\tcurl -L https://install.pi-hole.net | bash\n:::\n::: at any time!\n:::\n" + printf "::: PLEASE RESET YOUR DNS ON YOUR ROUTER/CLIENTS TO RESTORE INTERNET CONNECTIVITY!\n" +} ######### SCRIPT ########### -$SUDO apt-get -y remove --purge dnsutils bc toilet -$SUDO apt-get -y remove --purge dnsmasq -$SUDO apt-get -y remove --purge lighttpd php5-common php5-cgi php5 +echo "::: Preparing to remove packages, be sure that each may be safely removed depending on your operating system." +echo "::: (SAFE TO REMOVE ALL ON RASPBIAN)" +while true; do + read -rp "::: Do you wish to purge PiHole's dependencies from your OS? (You will be prompted for each package) [y/n]: " yn + case $yn in + [Yy]* ) removeAndPurge; break;; + + [Nn]* ) removeNoPurge; break;; + esac +done -# Only web directories/files that are created by pihole should be removed. -echo "Removing the Pi-hole Web server files..." -$SUDO rm -rf /var/www/html/admin -$SUDO rm -rf /var/www/html/pihole -$SUDO rm /var/www/html/index.lighttpd.orig -# If the web directory is empty after removing these files, then the parent html folder can be removed. -if [[ ! "$(ls -A /var/www/html)" ]]; then - $SUDO rm -rf /var/www/html -fi - -echo "Removing dnsmasq config files..." -$SUDO rm /etc/dnsmasq.conf /etc/dnsmasq.conf.orig - -# Attempt to preserve backwards compatibility with older versions -# to guarantee no additional changes were made to /etc/crontab after -# the installation of pihole, /etc/crontab.pihole should be permanently -# preserved. -if [[ -f /etc/crontab.orig ]]; then - echo "Initial Pi-hole cron detected. Restoring the default system cron..." - $SUDO mv /etc/crontab /etc/crontab.pihole - $SUDO mv /etc/crontab.orig /etc/crontab - $SUDO service cron restart -fi - -# Attempt to preserve backwards compatibility with older versions -if [[ -f /etc/cron.d/pihole ]];then - echo "Removing cron.d/pihole..." - $SUDO rm /etc/cron.d/pihole -fi - -echo "Removing config files and scripts..." -$SUDO rm /etc/dnsmasq.conf -$SUDO rm -rf /etc/lighttpd/ -$SUDO rm /var/log/pihole.log -$SUDO rm /usr/local/bin/gravity.sh -$SUDO rm /usr/local/bin/chronometer.sh -$SUDO rm /usr/local/bin/whitelist.sh -$SUDO rm /usr/local/bin/piholeLogFlush.sh -$SUDO rm -rf /etc/pihole/ diff --git a/gravity.sh b/gravity.sh index 321aec27..80f80553 100755 --- a/gravity.sh +++ b/gravity.sh @@ -16,14 +16,14 @@ if [[ $EUID -eq 0 ]];then echo "::: You are root." else echo "::: sudo will be used." - # Check if it is actually installed - # If it isn't, exit because the install cannot complete - if [[ $(dpkg-query -s sudo) ]];then + # Check if it is actually installed + # If it isn't, exit because the install cannot complete + if [[ $(dpkg-query -s sudo) ]];then export SUDO="sudo" - else + else echo "::: Please install sudo or run this script as root." - exit 1 - fi + exit 1 + fi fi piholeIPfile=/tmp/piholeIP @@ -31,8 +31,8 @@ piholeIPv6file=/etc/pihole/.useIPv6 adListFile=/etc/pihole/adlists.list adListDefault=/etc/pihole/adlists.default -whitelistScript=/usr/local/bin/whitelist.sh -blacklistScript=/usr/local/bin/blacklist.sh +whitelistScript=/opt/pihole/whitelist.sh +blacklistScript=/opt/pihole/blacklist.sh if [[ -f $piholeIPfile ]];then # If the file exists, it means it was exported from the installation script and we should use that value instead of detecting it in this script @@ -41,7 +41,7 @@ if [[ -f $piholeIPfile ]];then else # Otherwise, the IP address can be taken directly from the machine, which will happen when the script is run by the user and not the installation script IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}') - piholeIPCIDR=$(ip -o -f inet addr show dev $IPv4dev | awk '{print $4}' | awk 'END {print}') + piholeIPCIDR=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}') piholeIP=${piholeIPCIDR%/*} fi @@ -50,22 +50,20 @@ if [[ -f $piholeIPv6file ]];then piholeIPv6=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }') fi - - - # Variables for various stages of downloading and formatting the list +## Nate 3/26/2016 - Commented unused variables basename=pihole piholeDir=/etc/$basename adList=$piholeDir/gravity.list -blacklist=$piholeDir/blacklist.txt -whitelist=$piholeDir/whitelist.txt -latentWhitelist=$piholeDir/latentWhitelist.txt +#blacklist=$piholeDir/blacklist.txt +#whitelist=$piholeDir/whitelist.txt +#latentWhitelist=$piholeDir/latentWhitelist.txt justDomainsExtension=domains matterandlight=$basename.0.matterandlight.txt supernova=$basename.1.supernova.txt eventHorizon=$basename.2.eventHorizon.txt accretionDisc=$basename.3.accretionDisc.txt -eyeOfTheNeedle=$basename.4.wormhole.txt +#eyeOfTheNeedle=$basename.4.wormhole.txt # After setting defaults, check if there's local overrides if [[ -r $piholeDir/pihole.conf ]];then @@ -73,22 +71,20 @@ if [[ -r $piholeDir/pihole.conf ]];then . $piholeDir/pihole.conf fi - -spinner(){ - local pid=$1 - local delay=0.001 - local spinstr='/-\|' - - spin='-\|/' - i=0 - while $SUDO kill -0 $pid 2>/dev/null - do - i=$(( (i+1) %4 )) - printf "\b${spin:$i:1}" - sleep .1 - done - printf "\b" +spinner() { + local pid=$1 + local delay=0.50 + local spinstr='/-|' + while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do + local temp=${spinstr#?} + printf " [%c] " "$spinstr" + local spinstr=$temp${spinstr%"$temp"} + sleep $delay + printf "\b\b\b\b\b\b" + done + printf " \b\b\b\b" } + ########################### # collapse - begin formation of pihole function gravity_collapse() { @@ -99,7 +95,7 @@ function gravity_collapse() { #custom file found, use this instead of default echo -n "::: Custom adList file detected. Reading..." sources=() - while read -a line; do + while read -r line; do #Do not read commented out or blank lines if [[ $line = \#* ]] || [[ ! $line ]]; then echo "" > /dev/null @@ -107,12 +103,12 @@ function gravity_collapse() { sources+=($line) fi done < $adListFile - echo " done!" + echo " done!" else #no custom file found, use defaults! echo -n "::: No custom adlist file detected, reading from default file..." - sources=() - while read -a line; do + sources=() + while read -r line; do #Do not read commented out or blank lines if [[ $line = \#* ]] || [[ ! $line ]]; then echo "" > /dev/null @@ -120,8 +116,8 @@ function gravity_collapse() { sources+=($line) fi done < $adListDefault - echo " done!" - fi + echo " done!" + fi # Create the pihole resource directory if it doesn't exist. Future files will be stored here if [[ -d $piholeDir ]];then @@ -129,12 +125,12 @@ function gravity_collapse() { # Will update later, needed for existing installs, new installs should # create this directory as non-root $SUDO chmod 777 $piholeDir - find "$piholeDir" -type f -exec $SUDO chmod 666 {} \; & spinner $! - echo "." + echo ":::" + echo "::: Existing pihole directory found" else - echo -n "::: Creating pihole directory..." - mkdir $piholeDir & spinner $! - echo " done!" + echo "::: Creating pihole directory..." + mkdir $piholeDir + $SUDO chmod 777 $piholeDir fi } @@ -146,7 +142,7 @@ function gravity_patternCheck() { # Some of the blocklists are copyright, they need to be downloaded # and stored as is. They can be processed for content after they # have been saved. - cp $patternBuffer $saveLocation + cp "$patternBuffer" "$saveLocation" echo " List updated, transport successful!" else # curl didn't download any host files, probably because of the date check @@ -169,17 +165,16 @@ function gravity_transport() { fi # Silently curl url - curl -s $cmd_ext $heisenbergCompensator -A "$agent" $url > $patternBuffer + curl -s $cmd_ext $heisenbergCompensator -A "$agent" $url > $patternBuffer # Check for list updates - gravity_patternCheck $patternBuffer - + gravity_patternCheck "$patternBuffer" # Cleanup - rm -f $patternBuffer + rm -f "$patternBuffer" } # spinup - main gravity function function gravity_spinup() { - echo "::: " + echo ":::" # Loop through domain list. Download each one and remove commented lines (lines beginning with '# 'or '/') and # blank lines for ((i = 0; i < "${#sources[@]}"; i++)) do @@ -198,17 +193,17 @@ function gravity_spinup() { # Use a case statement to download lists that need special cURL commands # to complete properly and reset the user agent when required case "$domain" in - "adblock.mahakala.is") - agent='Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0' - cmd_ext="-e http://forum.xda-developers.com/" - ;; + "adblock.mahakala.is") + agent='Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0' + cmd_ext="-e http://forum.xda-developers.com/" + ;; - "pgl.yoyo.org") - cmd_ext="-d mimetype=plaintext -d hostformat=hosts" - ;; + "pgl.yoyo.org") + cmd_ext="-d mimetype=plaintext -d hostformat=hosts" + ;; - # Default is a simple request - *) cmd_ext="" + # Default is a simple request + *) cmd_ext="" esac gravity_transport "$url" "$cmd_ext" "$agent" done @@ -216,55 +211,46 @@ function gravity_spinup() { # Schwarzchild - aggregate domains to one list and add blacklisted domains function gravity_Schwarzchild() { - echo "::: " + echo "::: " # Find all active domains and compile them into one file and remove CRs echo -n "::: Aggregating list of domains..." - truncate -s 0 $piholeDir/$matterandlight & spinner $! + truncate -s 0 $piholeDir/$matterandlight & spinner $! for i in "${activeDomains[@]}" do - cat $i |tr -d '\r' >> $piholeDir/$matterandlight + cat "$i" | tr -d '\r' >> $piholeDir/$matterandlight done echo " done!" - } - function gravity_Blacklist(){ # Append blacklist entries if they exist echo -n "::: Running blacklist script to update HOSTS file...." $blacklistScript -f -nr -q > /dev/null & spinner $! - + numBlacklisted=$(wc -l < "/etc/pihole/blacklist.txt") plural=; [[ "$numBlacklisted" != "1" ]] && plural=s - echo " $numBlacklisted domain${plural} blacklisted!" - - + echo " $numBlacklisted domain${plural} blacklisted!" } - function gravity_Whitelist() { - echo ":::" + echo ":::" # Prevent our sources from being pulled into the hole plural=; [[ "${sources[@]}" != "1" ]] && plural=s - echo -n "::: Adding ${#sources[@]} ad list source${plural} to the whitelist..." - + echo -n "::: Adding ${#sources[@]} adlist source${plural} to the whitelist..." + urls=() - for url in ${sources[@]} + for url in "${sources[@]}" do tmp=$(echo "$url" | awk -F '/' '{print $3}') urls=("${urls[@]}" $tmp) done echo " done!" - + echo -n "::: Running whitelist script to update HOSTS file...." - $whitelistScript -f -nr -q ${urls[@]} > /dev/null & spinner $! - + $whitelistScript -f -nr -q "${urls[@]}" > /dev/null & spinner $! numWhitelisted=$(wc -l < "/etc/pihole/whitelist.txt") plural=; [[ "$numWhitelisted" != "1" ]] && plural=s - echo " $numWhitelisted domain${plural} whitelisted!" - - - + echo " $numWhitelisted domain${plural} whitelisted!" } function gravity_unique() { @@ -277,20 +263,21 @@ function gravity_unique() { } function gravity_hostFormat() { - # Format domain list as "192.168.x.x domain.com" + # Format domain list as "192.168.x.x domain.com" echo "::: Formatting domains into a HOSTS file..." - # If there is a value in the $piholeIPv6, then IPv6 will be used, so the awk command modified to create a line for both protocols - if [[ -n $piholeIPv6 ]];then - #Add dummy domain Pi-Hole.IsWorking.OK to the top of gravity.list to make ping result return a friendlier looking domain! - echo -e "$piholeIP Pi-Hole.IsWorking.OK \n$piholeIPv6 Pi-Hole.IsWorking.OK" > $piholeDir/$accretionDisc - cat $piholeDir/$eventHorizon | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $piholeDir/$accretionDisc - - else - # Otherwise, just create gravity.list as normal using IPv4 - #Add dummy domain Pi-Hole.IsWorking.OK to the top of gravity.list to make ping result return a friendlier looking domain! - echo -e "$piholeIP Pi-Hole.IsWorking.OK" > $piholeDir/$accretionDisc - cat $piholeDir/$eventHorizon | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >> $piholeDir/$accretionDisc - fi + hostname=$( $piholeDir/$accretionDisc + cat $piholeDir/$eventHorizon | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $piholeDir/$accretionDisc + else + # Otherwise, just create gravity.list as normal using IPv4 + # Add hostname and dummy domain to the top of gravity.list to make ping result return a friendlier looking domain! Also allows for an easy way to access the Pi-hole admin console (pi.hole/admin) + echo -e "$piholeIP $hostname\n$piholeIP pi.hole" > $piholeDir/$accretionDisc + cat $piholeDir/$eventHorizon | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >> $piholeDir/$accretionDisc + fi + # Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it cp $piholeDir/$accretionDisc $adList } @@ -301,49 +288,52 @@ function gravity_blackbody() { for file in $piholeDir/*.$justDomainsExtension do # If list is in active array then leave it (noop) else rm the list - if [[ " ${activeDomains[@]} " =~ " ${file} " ]]; then + if [[ " ${activeDomains[@]} " =~ ${file} ]]; then : else - rm -f $file + rm -f "$file" fi done } function gravity_advanced() { - - # Remove comments and print only the domain name # Most of the lists downloaded are already in hosts file format but the spacing/formating is not contigious # This helps with that and makes it easier to read # It also helps with debugging so each stage of the script can be researched more in depth echo -n "::: Formatting list of domains to remove comments...." awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' $piholeDir/$matterandlight | sed -nr -e 's/\.{2,}/./g' -e '/\./p' > $piholeDir/$supernova & spinner $! - echo " done!" - + echo " done!" + numberOf=$(wc -l < $piholeDir/$supernova) echo "::: $numberOf domains being pulled in by gravity..." - + gravity_unique - } function gravity_reload() { #Clear no longer needed files... echo ":::" echo -n "::: Cleaning up un-needed files..." - $SUDO rm /etc/pihole/pihole.* + $SUDO rm $piholeDir/pihole.*.txt echo " done!" - + # Reload hosts file echo ":::" echo -n "::: Refresh lists in dnsmasq..." + + #ensure /etc/dnsmasq.d/01-pihole.conf is pointing at the correct list! + #First escape forward slashes in the path: + adList=${adList//\//\\\/} + #Now replace the line in dnsmasq file + $SUDO sed -i "s/^addn-hosts.*/addn-hosts=$adlist/" /etc/dnsmasq.d/01-pihole.conf dnsmasqPid=$(pidof dnsmasq) find "$piholeDir" -type f -exec $SUDO chmod 666 {} \; & spinner $! if [[ $dnsmasqPid ]]; then # service already running - reload config - $SUDO kill -HUP $dnsmasqPid & spinner $! + $SUDO kill -HUP "$dnsmasqPid" & spinner $! else # service not running, start it up $SUDO service dnsmasq start & spinner $! diff --git a/pihole b/pihole new file mode 100755 index 00000000..66f967dc --- /dev/null +++ b/pihole @@ -0,0 +1,113 @@ +#!/bin/bash +# Pi-hole: A black hole for Internet advertisements +# (c) 2015, 2016 by Jacob Salmela +# Network-wide ad blocking via your Raspberry Pi +# http://pi-hole.net +# Controller for all pihole scripts and functions. +# +# Pi-hole is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. + +# Must be root to use this tool +if [[ $EUID -eq 0 ]];then + echo "::: You are root." +else + echo "::: Sudo will be used for this tool." + # Check if it is actually installed + # If it isn't, exit because the pihole cannot be invoked without privileges. + if [[ $(dpkg-query -s sudo) ]];then + export SUDO="sudo" + else + echo "::: Please install sudo or run this as root." + exit 1 + fi +fi + +function whitelistFunc { + shift + $SUDO /opt/pihole/whitelist.sh "$@" + exit 1 +} + +function blacklistFunc { + shift + $SUDO /opt/pihole/blacklist.sh "$@" + exit 1 +} + +function debugFunc { + $SUDO /opt/pihole/piholeDebug.sh + exit 1 +} + +function flushFunc { + $SUDO /opt/pihole/piholeLogFlush.sh + exit 1 +} + +function updateDashboardFunc { + $SUDO /opt/pihole/updateDashboard.sh + exit 1 +} + +function updateGravityFunc { + $SUDO /opt/pihole/gravity.sh + exit 1 +} + +function setupLCDFunction { + $SUDO /opt/pihole/setupLCD.sh + exit 1 +} + +function chronometerFunc { + $SUDO /opt/pihole/chronometer.sh + exit 1 +} + + +function uninstallFunc { + $SUDO /opt/pihole/uninstall.sh + exit 1 +} + +function helpFunc { + echo "::: Control all PiHole specific functions!" + echo ":::" + echo "::: Usage: pihole.sh [options]" + printf ":::\tAdd -h after -w (whitelist), -b (blacklist), or -c (chronometer) for more information on usage\n" + echo ":::" + echo "::: Options:" + echo "::: -w, whitelist Whitelist domains" + echo "::: -b, blacklist Blacklist domains" + echo "::: -d, debug Start a debugging session if having trouble" + echo "::: -f, flush Flush the pihole.log file" + echo "::: -u, updateDashboard Update the web dashboard manually" + echo "::: -g, updateGravity Update the list of ad-serving domains" + echo "::: -s, setupLCD Automatically configures the Pi to use the 2.8 LCD screen to display stats on it" + echo "::: -c, chronometer Calculates stats and displays to an LCD" + echo "::: -h, help Show this help dialog" + echo "::: uninstall Uninstall Pi-Hole from your system!" + exit 1 +} + +if [[ $# = 0 ]]; then + helpFunc +fi + +# Handle redirecting to specific functions based on arguments +case "$1" in +"-w" | "whitelist" ) whitelistFunc "$@";; +"-b" | "blacklist" ) blacklistFunc "$@";; +"-d" | "debug" ) debugFunc;; +"-f" | "flush" ) flushFunc;; +"-u" | "updateDashboard" ) updateDashboardFunc;; +"-g" | "updateGravity" ) updateGravityFunc;; +"-s" | "setupLCD" ) setupLCDFunction;; +"-c" | "chronometer" ) chronometerFunc;; +"-h" | "help" ) helpFunc;; +"uninstall" ) uninstallFunc;; +* ) helpFunc;; +esac