Merge pull request #392 from pi-hole/development

Pi-hole v2.6
This commit is contained in:
Adam Warner 2016-04-05 00:30:20 +01:00
commit 6d9fbe8d41
20 changed files with 1066 additions and 535 deletions

View File

@ -8,4 +8,4 @@ Changes proposed in this pull request:
- -
@pihole/gravity @pi-hole/gravity

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.DS_Store

View File

@ -1,9 +1,11 @@
# Automated Install # 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) [![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 1. Install Raspbian
2. Run the command below 2. Run the command below
### ```curl -L https://install.pi-hole.net | bash``` ### ```curl -L https://install.pi-hole.net | bash```

View File

@ -5,11 +5,11 @@
# 2. run `nano /etc/pihole/adlists.list` # # 2. run `nano /etc/pihole/adlists.list` #
# 3. Uncomment or comment any of the below lists # # 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! # # 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 # See `https://github.com/StevenBlack/hosts` for details
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts 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 # ADZHOSTS list. Has been known to block legitimate domains
#http://optimate.dl.sourceforge.net/project/adzhosts/HOSTS.txt #http://optimate.dl.sourceforge.net/project/adzhosts/HOSTS.txt
# Windows 10 telemetry list - warning this one may block windows update # Windows 10 telemetry list
#https://raw.githubusercontent.com/crazy-max/HostsWindowsBlocker/master/hosts.txt #https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/hostsBlockWindowsSpy.txt
# Securemecca.com list - Also blocks "adult" sites (pornography/gambling etc) # Securemecca.com list - Also blocks "adult" sites (pornography/gambling etc)
#http://securemecca.com/Downloads/hosts.txt #http://securemecca.com/Downloads/hosts.txt
@ -40,6 +40,9 @@ http://hosts-file.net/ad_servers.txt
# Quidsup's tracker list # Quidsup's tracker list
https://raw.githubusercontent.com/quidsup/notrack/master/trackers.txt 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: # Untested Lists:
#https://raw.githubusercontent.com/reek/anti-adblock-killer/master/anti-adblock-killer-filters.txt #https://raw.githubusercontent.com/reek/anti-adblock-killer/master/anti-adblock-killer-filters.txt

110
advanced/Scripts/blacklist.sh Normal file → Executable file
View File

@ -11,39 +11,46 @@
# (at your option) any later version. # (at your option) any later version.
if [[ $# = 0 ]]; then if [[ $# = 0 ]]; then
echo "Immediately blacklists one or more domains in the hosts file" echo "::: Immediately blacklists one or more domains in the hosts file"
echo " " echo ":::"
echo "Usage: blacklist.sh domain1 [domain2 ...]" echo "::: Usage: sudo pihole.sh -b domain1 [domain2 ...]"
echo " " echo ":::"
echo "Options:" echo "::: Options:"
echo " -d, --delmode Remove domains from the blacklist" echo "::: -d, --delmode Remove domains from the blacklist"
echo " -nr, --noreload Update blacklist without refreshing dnsmasq" echo "::: -nr, --noreload Update blacklist without refreshing dnsmasq"
echo " -f, --force Force updating of the hosts files, even if there are no changes" echo "::: -f, --force Force updating of the hosts files, even if there are no changes"
echo " -q, --quiet output is less verbose" echo "::: -q, --quiet output is less verbose"
exit 1 exit 1
fi fi
#globals #globals
blacklist=/etc/pihole/blacklist.txt basename=pihole
adList=/etc/pihole/gravity.list piholeDir=/etc/$basename
adList=$piholeDir/gravity.list
blacklist=$piholeDir/blacklist.txt
reload=true reload=true
addmode=true addmode=true
force=false force=false
versbose=true versbose=true
domList=() domList=()
domToRemoveList=() domToRemoveList=()
piholeIPfile=/tmp/piholeIP
piholeIPv6file=/etc/pihole/.useIPv6 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 # 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)}') 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%/*} piholeIP=${piholeIPCIDR%/*}
modifyHost=false 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 [[ -f $piholeIPv6file ]];then
# If the file exists, then the user previously chose to use IPv6 in the automated installer # 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 fi
function HandleOther(){ function HandleOther(){
#check validity of domain #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 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)
fi fi
@ -66,13 +72,12 @@ function PopBlacklistFile(){
#check blacklist file exists, and if not, create it #check blacklist file exists, and if not, create it
if [[ ! -f $blacklist ]];then if [[ ! -f $blacklist ]];then
touch $blacklist touch $blacklist
fi fi
for dom in "${domList[@]}" for dom in "${domList[@]}"; do
do if "$addmode"; then
if $addmode; then AddDomain "$dom"
AddDomain $dom
else else
RemoveDomain $dom RemoveDomain "$dom"
fi fi
done done
} }
@ -86,18 +91,18 @@ function AddDomain(){
if $versbose; then if $versbose; then
echo -n "::: Adding $1 to blacklist file..." echo -n "::: Adding $1 to blacklist file..."
fi fi
echo $1 >> $blacklist echo "$1" >> $blacklist
modifyHost=true modifyHost=true
echo " done!" echo " done!"
else else
if $versbose; then 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
fi fi
} }
function RemoveDomain(){ function RemoveDomain(){
bool=false bool=false
grep -Ex -q "$1" $blacklist || bool=true grep -Ex -q "$1" $blacklist || bool=true
if $bool; then if $bool; then
@ -110,12 +115,12 @@ function RemoveDomain(){
if $versbose; then if $versbose; then
echo "::: Un-blacklisting $dom..." echo "::: Un-blacklisting $dom..."
fi fi
domToRemoveList=("${domToRemoveList[@]}" $1) domToRemoveList=("${domToRemoveList[@]}" $1)
modifyHost=true modifyHost=true
fi fi
} }
function ModifyHostFile(){ function ModifyHostFile(){
if $addmode; then if $addmode; then
#add domains to the hosts file #add domains to the hosts file
if [[ -r $blacklist ]];then if [[ -r $blacklist ]];then
@ -124,28 +129,25 @@ function ModifyHostFile(){
echo ":::" echo ":::"
echo -n "::: Modifying HOSTS file to blacklist $numberOf domain${plural}..." echo -n "::: Modifying HOSTS file to blacklist $numberOf domain${plural}..."
if [[ -n $piholeIPv6 ]];then if [[ -n $piholeIPv6 ]];then
cat $blacklist | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $adList cat $blacklist | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $adList
else else
cat $blacklist | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >>$adList cat $blacklist | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >>$adList
fi fi
fi fi
else else
echo ":::" echo ":::"
for dom in "${domToRemoveList[@]}" for dom in "${domToRemoveList[@]}"
do do
#we need to remove the domains from the blacklist file and the host file #we need to remove the domains from the blacklist file and the host file
echo "::: $dom" echo "::: $dom"
echo -n "::: removing from HOSTS file..." echo -n "::: removing from HOSTS file..."
echo $dom | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /[^.]'{}'(?!.)/;' $adList echo "$dom" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /[^.]'{}'(?!.)/;' $adList
echo " done!" echo " done!"
echo -n "::: removing from blackist.txt..." echo -n "::: removing from blackist.txt..."
echo $dom | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' $blacklist echo "$dom" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' $blacklist
echo " done!" echo " done!"
done done
fi fi
} }
function Reload() { function Reload() {
@ -157,7 +159,7 @@ function Reload() {
if [[ $dnsmasqPid ]]; then if [[ $dnsmasqPid ]]; then
# service already running - reload config # service already running - reload config
sudo kill -HUP $dnsmasqPid sudo kill -HUP "$dnsmasqPid"
else else
# service not running, start it up # service not running, start it up
sudo service dnsmasq start sudo service dnsmasq start
@ -170,17 +172,17 @@ function Reload() {
for var in "$@" for var in "$@"
do do
case "$var" in case "$var" in
"-nr"| "--noreload" ) reload=false;; "-nr"| "--noreload" ) reload=false;;
"-d" | "--delmode" ) addmode=false;; "-d" | "--delmode" ) addmode=false;;
"-f" | "--force" ) force=true;; "-f" | "--force" ) force=true;;
"-q" | "--quiet" ) versbose=false;; "-q" | "--quiet" ) versbose=false;;
* ) HandleOther $var;; * ) HandleOther "$var";;
esac esac
done done
PopBlacklistFile PopBlacklistFile
if $modifyHost || $force; then if $modifyHost || $force; then
ModifyHostFile ModifyHostFile
else else
if $versbose; then if $versbose; then

View File

@ -73,9 +73,9 @@ function outputJSON(){
CalcQueriesToday CalcQueriesToday
CalcblockedToday CalcblockedToday
CalcPercentBlockedToday CalcPercentBlockedToday
CalcBlockedDomains CalcBlockedDomains
printf '{"domains_being_blocked":"%s","dns_queries_today":"%s","ads_blocked_today":"%s","ads_percentage_today":"%s"}\n' "$blockedDomainsTotal" "$queriesToday" "$blockedToday" "$percentBlockedToday" 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 " $(ifconfig eth0 | awk '/inet addr/ {print $2}' | cut -d':' -f2)"
echo "" echo ""
uptime | cut -d' ' -f11- 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 "-------------------------------" echo "-------------------------------"
# Uncomment to continually read the log file and display the current domain being blocked # 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;}' #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 #uncomment next 4 lines to use original query count calculation
#today=$(date "+%b %e") #today=$(date "+%b %e")
#todaysQueryCount=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ {print $7}' | wc -l) #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) #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) #todaysQueryCountV6=$(cat /var/log/pihole.log | grep "$today" | awk '/query/ && /\[AAAA\]/ {print $7}' | wc -l)
CalcQueriesToday CalcQueriesToday
CalcblockedToday CalcblockedToday
CalcPercentBlockedToday CalcPercentBlockedToday
CalcBlockedDomains CalcBlockedDomains
echo "Blocking: $blockedDomainsTotal" echo "Blocking: $blockedDomainsTotal"
#below commented line does not add up to todaysQueryCount #below commented line does not add up to todaysQueryCount
#echo "Queries: $todaysQueryCountV4 / $todaysQueryCountV6" #echo "Queries: $todaysQueryCountV4 / $todaysQueryCountV6"
echo "Queries: $queriesToday" #same total calculation as dashboard echo "Queries: $queriesToday" #same total calculation as dashboard
echo "Pi-holed: $blockedToday ($percentBlockedToday%)" echo "Pi-holed: $blockedToday ($percentBlockedToday%)"
sleep 5 sleep 5
done done
} }
function displayHelp(){ function displayHelp(){
echo "Displays stats about your piHole!" echo "::: Displays stats about your piHole!"
echo " " echo ":::"
echo "Usage: chronometer.sh [optional:-j]" 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 "::: Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds"
echo " " echo ":::"
echo "Options:" echo "::: Options:"
echo " -j, --json output stats as JSON formatted string" echo "::: -j, --json output stats as JSON formatted string"
echo " -h, --help display this help text" echo "::: -h, --help display this help text"
exit 1 exit 1
} }
@ -137,7 +138,7 @@ for var in "$@"
do do
case "$var" in case "$var" in
"-j" | "--json" ) outputJSON;; "-j" | "--json" ) outputJSON;;
"-h" | "--help" ) displayHelp;; "-h" | "--help" ) displayHelp;;
* ) exit 1;; * ) exit 1;;
esac esac
done done

310
advanced/Scripts/piholeDebug.sh Executable file
View File

@ -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

View File

@ -10,4 +10,6 @@
# the Free Software Foundation, either version 2 of the License, or # the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
echo -n "::: Flushing /var/log/pihole.log ..."
truncate -s 0 /var/log/pihole.log truncate -s 0 /var/log/pihole.log
echo "... done!"

0
advanced/Scripts/setupLCD.sh Normal file → Executable file
View File

2
advanced/Scripts/updateDashboard.sh Normal file → Executable file
View File

@ -63,7 +63,7 @@ make_repo() {
update_repo() { update_repo() {
# pull the latest commits # pull the latest commits
cd "$WEB_INTERFACE_DIR" cd "$WEB_INTERFACE_DIR"
git pull git pull
} }
main main

View File

@ -11,38 +11,45 @@
# (at your option) any later version. # (at your option) any later version.
if [[ $# = 0 ]]; then if [[ $# = 0 ]]; then
echo "Immediately whitelists one or more domains in the hosts file" echo "::: Immediately whitelists one or more domains in the hosts file"
echo " " echo ":::"
echo "Usage: whitelist.sh domain1 [domain2 ...]" echo "::: Usage: sudo pihole.sh -w domain1 [domain2 ...]"
echo " " echo ":::"
echo "Options:" echo "::: Options:"
echo " -d, --delmode Remove domains from the whitelist" echo "::: -d, --delmode Remove domains from the whitelist"
echo " -nr, --noreload Update Whitelist without refreshing dnsmasq" echo "::: -nr, --noreload Update Whitelist without refreshing dnsmasq"
echo " -f, --force Force updating of the hosts files, even if there are no changes" echo "::: -f, --force Force updating of the hosts files, even if there are no changes"
echo " -q, --quiet output is less verbose" echo "::: -q, --quiet output is less verbose"
exit 1 exit 1
fi fi
#globals #globals
whitelist=/etc/pihole/whitelist.txt basename=pihole
adList=/etc/pihole/gravity.list piholeDir=/etc/$basename
adList=$piholeDir/gravity.list
whitelist=$piholeDir/whitelist.txt
reload=true reload=true
addmode=true addmode=true
force=false force=false
versbose=true versbose=true
domList=() domList=()
domToRemoveList=() domToRemoveList=()
piholeIPfile=/tmp/piholeIP
piholeIPv6file=/etc/pihole/.useIPv6 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 # 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)}') 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%/*} piholeIP=${piholeIPCIDR%/*}
modifyHost=false 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 [[ -f $piholeIPv6file ]];then
# If the file exists, then the user previously chose to use IPv6 in the automated installer # 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 fi
function HandleOther(){ function HandleOther(){
#check validity of domain #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 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)
fi fi
} }
@ -65,13 +71,13 @@ function PopWhitelistFile(){
#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[@]}" for dom in "${domList[@]}"
do do
if $addmode; then if $addmode; then
AddDomain $dom AddDomain "$dom"
else else
RemoveDomain $dom RemoveDomain "$dom"
fi fi
done done
} }
@ -79,27 +85,27 @@ function PopWhitelistFile(){
function AddDomain(){ function AddDomain(){
#| sed 's/\./\\./g' #| sed 's/\./\\./g'
bool=false bool=false
grep -Ex -q "$1" $whitelist || bool=true grep -Ex -q "$1" $whitelist || bool=true
if $bool; then if $bool; then
#domain not found in the whitelist file, add it! #domain not found in the whitelist file, add it!
if $versbose; then if $versbose; then
echo -n "::: Adding $1 to whitelist.txt..." echo -n "::: Adding $1 to $whitelist..."
fi fi
echo $1 >> $whitelist echo "$1" >> $whitelist
modifyHost=true modifyHost=true
if $versbose; then if $versbose; then
echo " done!" echo " done!"
fi fi
else else
if $versbose; then 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
fi fi
} }
function RemoveDomain(){ function RemoveDomain(){
bool=false bool=false
grep -Ex -q "$1" $whitelist || bool=true grep -Ex -q "$1" $whitelist || bool=true
if $bool; then if $bool; then
@ -113,11 +119,11 @@ function RemoveDomain(){
#echo "::: Un-whitelisting $dom..." #echo "::: Un-whitelisting $dom..."
#fi #fi
domToRemoveList=("${domToRemoveList[@]}" $1) domToRemoveList=("${domToRemoveList[@]}" $1)
modifyHost=true modifyHost=true
fi fi
} }
function ModifyHostFile(){ function ModifyHostFile(){
if $addmode; then if $addmode; then
#remove domains in from hosts file #remove domains in from hosts file
if [[ -r $whitelist ]];then if [[ -r $whitelist ]];then
@ -126,36 +132,36 @@ function ModifyHostFile(){
plural=; [[ "$numberOf" != "1" ]] && plural=s plural=; [[ "$numberOf" != "1" ]] && plural=s
echo ":::" echo ":::"
echo -n "::: Modifying HOSTS file to whitelist $numberOf domain${plural}..." 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 -r 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 "$piholeIPv6 $line"; done >> /etc/pihole/whitelist.tmp
echo "l" >> /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 grep -F -x -v -f $piholeDir/whitelist.tmp $adList > $piholeDir/gravity.tmp
rm /etc/pihole/gravity.list rm $adList
mv /etc/pihole/gravity.tmp /etc/pihole/gravity.list mv $piholeDir/gravity.tmp $adList
rm /etc/pihole/whitelist.tmp rm $piholeDir/whitelist.tmp
echo " done!" echo " done!"
fi fi
else else
#we need to add the removed domains to the hosts file #we need to add the removed domains to the hosts file
echo ":::" echo ":::"
echo "::: Modifying HOSTS file to un-whitelist domains..." echo "::: Modifying HOSTS file to un-whitelist domains..."
for rdom in "${domToRemoveList[@]}" for rdom in "${domToRemoveList[@]}"
do do
if [[ -n $piholeIPv6 ]];then if [[ -n $piholeIPv6 ]];then
echo -n "::: Un-whitelisting $rdom on IPv4 and IPv6..." 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!" echo " done!"
else else
echo -n "::: Un-whitelisting $rdom on IPv4" 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!" echo " done!"
fi fi
echo -n "::: Removing $rdom from whitelist.txt..." echo -n "::: Removing $rdom from $whitelist..."
echo $rdom| sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' $whitelist echo "$rdom" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' $whitelist
echo " done!" echo " done!"
done done
fi fi
} }
function Reload() { function Reload() {
@ -166,7 +172,7 @@ function Reload() {
if [[ $dnsmasqPid ]]; then if [[ $dnsmasqPid ]]; then
# service already running - reload config # service already running - reload config
sudo kill -HUP $dnsmasqPid sudo kill -HUP "$dnsmasqPid"
else else
# service not running, start it up # service not running, start it up
sudo service dnsmasq start sudo service dnsmasq start
@ -179,11 +185,11 @@ function Reload() {
for var in "$@" for var in "$@"
do do
case "$var" in case "$var" in
"-nr"| "--noreload" ) reload=false;; "-nr"| "--noreload" ) reload=false;;
"-d" | "--delmode" ) addmode=false;; "-d" | "--delmode" ) addmode=false;;
"-f" | "--force" ) force=true;; "-f" | "--force" ) force=true;;
"-q" | "--quiet" ) versbose=false;; "-q" | "--quiet" ) versbose=false;;
* ) HandleOther $var;; * ) HandleOther "$var";;
esac esac
done done

View File

@ -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

View File

@ -27,8 +27,8 @@
# Replies which are not DNSSEC signed may be legitimate, because the domain # Replies which are not DNSSEC signed may be legitimate, because the domain
# is unsigned, or may be forgeries. Setting this option tells dnsmasq to # 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 # 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. # 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 # The cost of setting this is that even queries in unsigned domains will need
# one or more extra DNS queries to verify. # one or more extra DNS queries to verify.
#dnssec-check-unsigned #dnssec-check-unsigned
@ -183,11 +183,11 @@
#dhcp-range=1234::2, 1234::500, 64, 12h #dhcp-range=1234::2, 1234::500, 64, 12h
# Do Router Advertisements, BUT NOT DHCP for this subnet. # 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 # 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 # 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 # hosts. Use the DHCPv4 lease to derive the name, network segment and
# MAC address and assume that the host will also have an # MAC address and assume that the host will also have an
# IPv6 address calculated using the SLAAC alogrithm. # IPv6 address calculated using the SLAAC alogrithm.
#dhcp-range=1234::, ra-names #dhcp-range=1234::, ra-names
@ -210,9 +210,9 @@
#dhcp-range=1234::, ra-stateless, ra-names #dhcp-range=1234::, ra-stateless, ra-names
# Do router advertisements for all subnets where we're doing DHCPv6 # 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 # 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. # clients don't use SLAAC addresses.
#enable-ra #enable-ra
@ -278,11 +278,11 @@
# any machine with Ethernet address starting 11:22:33: # any machine with Ethernet address starting 11:22:33:
#dhcp-host=11:22:33:*:*:*,set:red #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 # 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 the MAC addresses CANNOT be used to identify DHCPv6 clients.
# Note also the they [] around the IPv6 address are obilgatory. # 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 # Ignore any clients which are not specified in dhcp-host lines
# or /etc/ethers. Equivalent to ISC "deny unknown-clients". # or /etc/ethers. Equivalent to ISC "deny unknown-clients".
@ -338,7 +338,7 @@
# Send DHCPv6 option. Note [] around IPv6 addresses. # Send DHCPv6 option. Note [] around IPv6 addresses.
#dhcp-option=option6:dns-server,[1234::77],[1234::88] #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. # dnsmasq and another.
#dhcp-option=option6:dns-server,[::],[1234::88] #dhcp-option=option6:dns-server,[::],[1234::88]
@ -645,4 +645,4 @@
#conf-dir=/etc/dnsmasq.d,.bak #conf-dir=/etc/dnsmasq.d,.bak
# Include all files in a directory which end in .conf # Include all files in a directory which end in .conf
#conf-dir=/etc/dnsmasq.d/*.conf #conf-dir=/etc/dnsmasq.d/*.conf

1
advanced/index.js Normal file
View File

@ -0,0 +1 @@
var x = "Pi-hole: A black hole for Internet advertisements."

View File

@ -53,4 +53,6 @@ $HTTP["url"] =~ "^/admin/" {
$HTTP["url"] =~ "^(?!/admin)/.*" { $HTTP["url"] =~ "^(?!/admin)/.*" {
# Create a response header for debugging using curl -I # Create a response header for debugging using curl -I
setenv.add-response-header = ( "X-Pi-hole" => "A black hole for Internet advertisements." ) setenv.add-response-header = ( "X-Pi-hole" => "A black hole for Internet advertisements." )
# rewrite only js requests
url.rewrite = ("(.*).js" => "pihole/index.js")
} }

View File

@ -10,7 +10,7 @@
# (at your option) any later version. # (at your option) any later version.
# Pi-hole: Update the ad sources once a week on Sunday at 01:59 # 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 59 1 * * 7 root /usr/local/bin/gravity.sh
# Pi-hole: Update the Web interface shortly after gravity runs # Pi-hole: Update the Web interface shortly after gravity runs

View File

@ -40,7 +40,7 @@ c=$(( columns / 2 ))
# Find IP used to route to outside world # 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)}') 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}') IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1) availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1)
@ -64,27 +64,20 @@ else
fi fi
if [ -d "/etc/pihole" ]; then
# Likely an existing install
upgrade=true
else
upgrade=false
fi
####### FUNCTIONS ########## ####### FUNCTIONS ##########
###All credit for the below function goes to http://fitnr.com/showing-a-bash-spinner.html spinner()
spinner() { {
local pid=$1 local pid=$1
local delay=0.50
spin='-\|/' local spinstr='/-\|'
i=0 while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do
while $SUDO kill -0 $pid 2>/dev/null local temp=${spinstr#?}
do printf " [%c] " "$spinstr"
i=$(( (i+1) %4 )) local spinstr=$temp${spinstr%"$temp"}
printf "\b${spin:$i:1}" sleep $delay
sleep .1 printf "\b\b\b\b\b\b"
done done
printf "\b" printf " \b\b\b\b"
} }
backupLegacyPihole() { backupLegacyPihole() {
@ -92,12 +85,17 @@ backupLegacyPihole() {
if [[ -f /etc/dnsmasq.d/adList.conf ]];then if [[ -f /etc/dnsmasq.d/adList.conf ]];then
echo "::: Original Pi-hole detected. Initiating sub space transport" echo "::: Original Pi-hole detected. Initiating sub space transport"
$SUDO mkdir -p /etc/pihole/original/ $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.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/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/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 /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 /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") 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 else
: :
fi 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 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 # 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 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() { verifyFreeDiskSpace() {
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.) # 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
requiredFreeBytes=51200 requiredFreeBytes=51200
existingFreeBytes=`df -lk / 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 if ! [[ "$existingFreeBytes" =~ ^([0-9])+$ ]]; then
existingFreeBytes=`df -lk /dev 2>&1 | awk '{print $4}' | head -2 | tail -1` existingFreeBytes=$(df -lk /dev 2>&1 | awk '{print $4}' | head -2 | tail -1)
fi fi
if [[ $existingFreeBytes -lt $requiredFreeBytes ]]; then 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 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" echo "$existingFreeBytes is less than $requiredFreeBytes"
@ -153,23 +151,23 @@ chooseInterface() {
interfaceCount=$(echo "$availableInterfaces" | wc -l) interfaceCount=$(echo "$availableInterfaces" | wc -l)
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface" $r $c $interfaceCount) chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface" $r $c $interfaceCount)
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then if [[ $? = 0 ]]; then
for desiredInterface in $chooseInterfaceOptions for desiredInterface in $chooseInterfaceOptions
do do
piholeInterface=$desiredInterface piholeInterface=$desiredInterface
echo "::: Using interface: $piholeInterface" echo "::: Using interface: $piholeInterface"
echo ${piholeInterface} > /tmp/piholeINT echo "${piholeInterface}" > /tmp/piholeINT
done done
else else
echo "::: Cancel selected, exiting...." echo "::: Cancel selected, exiting...."
exit 1 exit 1
fi fi
} }
cleanupIPv6() { cleanupIPv6() {
# Removes IPv6 indicator file if we are not using IPv6 # 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 rm /etc/pihole/.useIPv6
fi fi
} }
@ -184,11 +182,11 @@ use4andor6() {
for choice in $choices for choice in $choices
do do
case $choice in case $choice in
IPv4 ) useIPv4=true;; IPv4 ) useIPv4=true;;
IPv6 ) useIPv6=true;; IPv6 ) useIPv6=true;;
esac esac
done done
if [ $useIPv4 ] && [ ! $useIPv6 ]; then if [ $useIPv4 ] && [ ! $useIPv6 ]; then
getStaticIPv4Settings getStaticIPv4Settings
setStaticIPv4 setStaticIPv4
@ -230,8 +228,8 @@ useIPv6dialog() {
getStaticIPv4Settings() { getStaticIPv4Settings() {
# Ask if the user wants to use DHCP settings as their static IP # 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? 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 IP address: $IPv4addr
Gateway: $IPv4gw" $r $c) then 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. # 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. 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. 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 ]] until [[ $ipSettingsCorrect = True ]]
do do
# Ask for the IPv4 address # 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 if [[ $? = 0 ]];then
echo "::: Your static IPv4 address: $IPv4addr" echo "::: Your static IPv4 address: $IPv4addr"
# Ask for the gateway # 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) 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 if [[ $? = 0 ]];then
echo "::: Your static IPv4 gateway: $IPv4gw" echo "::: Your static IPv4 gateway: $IPv4gw"
# Give the user a chance to review their settings before moving on # 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? if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
IP address: $IPv4addr IP address: $IPv4addr
Gateway: $IPv4gw" $r $c)then Gateway: $IPv4gw" $r $c)then
# If the settings are correct, then we need to set the piholeIP # 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 # Saving it to a temporary file us to retrieve it later when we run the gravity.sh script
echo ${IPv4addr%/*} > /tmp/piholeIP echo "${IPv4addr%/*}" > /tmp/piholeIP
echo $piholeInterface > /tmp/piholeINT echo "$piholeInterface" > /tmp/piholeINT
# After that's done, the loop ends and we move on # After that's done, the loop ends and we move on
ipSettingsCorrect=True ipSettingsCorrect=True
else
# If the settings are wrong, the loop continues
ipSettingsCorrect=False
fi
else else
# Cancelling gateway settings window # If the settings are wrong, the loop continues
ipSettingsCorrect=False ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi fi
else else
# Cancelling IPv4 settings window # Cancelling gateway settings window
ipSettingsCorrect=False ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..." echo "::: Cancel selected. Exiting..."
exit 1 exit 1
fi fi
else
# Cancelling IPv4 settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
done done
# End the if statement for DHCP vs. static # End the if statement for DHCP vs. static
fi fi
} }
@ -292,12 +290,12 @@ setDHCPCD() {
setStaticIPv4() { setStaticIPv4() {
# Tries to set the IPv4 address # Tries to set the IPv4 address
if grep -q $IPv4addr $dhcpcdFile; then if grep -q "$IPv4addr" $dhcpcdFile; then
# address already set, noop # address already set, noop
: :
else else
setDHCPCD setDHCPCD
$SUDO ip addr replace dev $piholeInterface $IPv4addr $SUDO ip addr replace dev "$piholeInterface" "$IPv4addr"
echo ":::" echo ":::"
echo "::: Setting IP to $IPv4addr. You may need to restart after the install is complete." echo "::: Setting IP to $IPv4addr. You may need to restart after the install is complete."
echo ":::" echo ":::"
@ -308,7 +306,7 @@ function valid_ip()
{ {
local ip=$1 local ip=$1
local stat=1 local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS OIFS=$IFS
IFS='.' IFS='.'
@ -324,98 +322,88 @@ function valid_ip()
setDNS(){ setDNS(){
DNSChoseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." $r $c 6) DNSChoseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." $r $c 6)
DNSChooseOptions=(Google "" on DNSChooseOptions=(Google "" on
OpenDNS "" off OpenDNS "" off
Level3 "" off Level3 "" off
Norton "" off Norton "" off
Comodo "" off Comodo "" off
Custom "" off) Custom "" off)
DNSchoices=$("${DNSChoseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty) DNSchoices=$("${DNSChoseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then if [[ $? = 0 ]];then
case $DNSchoices in case $DNSchoices in
Google) Google)
echo "::: Using Google DNS servers." echo "::: Using Google DNS servers."
piholeDNS1="8.8.8.8" piholeDNS1="8.8.8.8"
piholeDNS2="8.8.4.4" piholeDNS2="8.8.4.4"
;; ;;
OpenDNS) OpenDNS)
echo "::: Using OpenDNS servers." echo "::: Using OpenDNS servers."
piholeDNS1="208.67.222.222" piholeDNS1="208.67.222.222"
piholeDNS2="208.67.220.220" piholeDNS2="208.67.220.220"
;; ;;
Level3) Level3)
echo "::: Using Level3 servers." echo "::: Using Level3 servers."
piholeDNS1="4.2.2.1" piholeDNS1="4.2.2.1"
piholeDNS2="4.2.2.2" piholeDNS2="4.2.2.2"
;; ;;
Norton) Norton)
echo "::: Using Norton ConnectSafe servers." echo "::: Using Norton ConnectSafe servers."
piholeDNS1="199.85.126.10" piholeDNS1="199.85.126.10"
piholeDNS2="199.85.127.10" piholeDNS2="199.85.127.10"
;; ;;
Comodo) Comodo)
echo "::: Using Comodo Secure servers." echo "::: Using Comodo Secure servers."
piholeDNS1="8.26.56.26" piholeDNS1="8.26.56.26"
piholeDNS2="8.20.247.20" piholeDNS2="8.20.247.20"
;; ;;
Custom) Custom)
until [[ $DNSSettingsCorrect = True ]] until [[ $DNSSettingsCorrect = True ]]
do do
strInvalid="Invalid"
strInvalid="Invalid" if [ ! $piholeDNS1 ]; then
if [ ! $piholeDNS2 ]; then
if [ ! $piholeDNS1 ]; then prePopulate=""
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
else else
echo "::: Cancel selected, exiting...." prePopulate=", $piholeDNS2"
exit 1
fi fi
elif [ $piholeDNS1 ] && [ ! $piholeDNS2 ]; then
if [[ $piholeDNS1 == $strInvalid ]] || [[ $piholeDNS2 == $strInvalid ]]; then prePopulate="$piholeDNS1"
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 elif [ $piholeDNS1 ] && [ $piholeDNS2 ]; then
prePopulate="$piholeDNS1, $piholeDNS2"
if [[ $piholeDNS1 == $strInvalid ]]; then fi
piholeDNS1="" 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)
fi if [[ $? = 0 ]];then
piholeDNS1=$(echo "$piholeDNS" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
if [[ $piholeDNS2 == $strInvalid ]]; then piholeDNS2=$(echo "$piholeDNS" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
piholeDNS2="" if ! valid_ip "$piholeDNS1" || [ ! "$piholeDNS1" ]; then
fi 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 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 fi
done fi
;; done
esac ;;
esac
else else
echo "::: Cancel selected. Exiting..." echo "::: Cancel selected. Exiting..."
exit 1 exit 1
@ -423,61 +411,81 @@ setDNS(){
} }
versionCheckDNSmasq(){ versionCheckDNSmasq(){
# Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory # Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
dnsFile1="/etc/dnsmasq.conf" dnsFile1="/etc/dnsmasq.conf"
dnsFile2="/etc/dnsmasq.conf.orig" dnsFile2="/etc/dnsmasq.conf.orig"
dnsSearch="addn-hosts=/etc/pihole/gravity.list" dnsSearch="addn-hosts=/etc/pihole/gravity.list"
defaultFile="/etc/.pihole/advanced/dnsmasq.conf.original"
defaultFile="/etc/.pihole/advanced/dnsmasq.conf.original" newFileToInstall="/etc/.pihole/advanced/01-pihole.conf"
newFileToInstall="/etc/.pihole/advanced/01-pihole.conf" newFileFinalLocation="/etc/dnsmasq.d/01-pihole.conf"
newFileFinalLocation="/etc/dnsmasq.d/01-pihole.conf"
if [ -f $dnsFile1 ]; then
if [ -f $dnsFile1 ]; then echo -n "::: Existing dnsmasq.conf found..."
echo -n "::: Existing dnsmasq.conf found..." if grep -q $dnsSearch $dnsFile1; then
if grep -q $dnsSearch $dnsFile1; then echo " it is from a previous pi-hole install."
echo " it is from a previous pi-hole install." echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..." $SUDO mv -f $dnsFile1 $dnsFile2
$SUDO mv -f $dnsFile1 $dnsFile2 echo " done."
echo " done." echo -n "::: Restoring default dnsmasq.conf..."
echo -n "::: Restoring default dnsmasq.conf..." $SUDO cp $defaultFile $dnsFile1
$SUDO cp $defaultFile $dnsFile1 echo " done."
echo " done." else
else echo " it is not a pi-hole file, leaving alone!"
echo " it is not a pi-hole file, leaving alone!" fi
fi else
else echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..." $SUDO cp $defaultFile $dnsFile1
$SUDO cp $defaultFile $dnsFile1 echo " done."
echo " done." fi
fi
echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..." $SUDO cp $newFileToInstall $newFileFinalLocation
$SUDO cp $newFileToInstall $newFileFinalLocation echo " done."
echo " done." $SUDO sed -i "s/@INT@/$piholeInterface/" $newFileFinalLocation
$SUDO sed -i "s/@INT@/$piholeInterface/" $newFileFinalLocation if [[ "$piholeDNS1" != "" ]]; then
if [[ "$piholeDNS1" != "" ]]; then $SUDO sed -i "s/@DNS1@/$piholeDNS1/" $newFileFinalLocation
$SUDO sed -i "s/@DNS1@/$piholeDNS1/" $newFileFinalLocation else
else $SUDO sed -i '/^server=@DNS1@/d' $newFileFinalLocation
$SUDO sed -i '/^server=@DNS1@/d' $newFileFinalLocation fi
fi if [[ "$piholeDNS2" != "" ]]; then
if [[ "$piholeDNS2" != "" ]]; then $SUDO sed -i "s/@DNS2@/$piholeDNS2/" $newFileFinalLocation
$SUDO sed -i "s/@DNS2@/$piholeDNS2/" $newFileFinalLocation else
else $SUDO sed -i '/^server=@DNS2@/d' $newFileFinalLocation
$SUDO sed -i '/^server=@DNS2@/d' $newFileFinalLocation fi
fi
} }
installScripts() { installScripts() {
# Install the scripts from /etc/.pihole to their various locations # Install the scripts from /etc/.pihole to their various locations
$SUDO echo ":::" $SUDO echo ":::"
$SUDO echo -n "::: Installing scripts..." $SUDO echo -n "::: Installing scripts to /opt/pihole..."
$SUDO cp /etc/.pihole/gravity.sh /usr/local/bin/gravity.sh if [ ! -d /opt/pihole ]; then
$SUDO cp /etc/.pihole/advanced/Scripts/chronometer.sh /usr/local/bin/chronometer.sh $SUDO mkdir /opt/pihole
$SUDO cp /etc/.pihole/advanced/Scripts/whitelist.sh /usr/local/bin/whitelist.sh $SUDO chown "$USER":root /opt/pihole
$SUDO cp /etc/.pihole/advanced/Scripts/blacklist.sh /usr/local/bin/blacklist.sh $SUDO chmod u+srwx /opt/pihole
$SUDO cp /etc/.pihole/advanced/Scripts/piholeLogFlush.sh /usr/local/bin/piholeLogFlush.sh fi
$SUDO cp /etc/.pihole/advanced/Scripts/updateDashboard.sh /usr/local/bin/updateDashboard.sh $SUDO cp /etc/.pihole/gravity.sh /opt/pihole/gravity.sh
$SUDO chmod 755 /usr/local/bin/{gravity,chronometer,whitelist,blacklist,piholeLogFlush,updateDashboard}.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." $SUDO echo " done."
} }
@ -486,7 +494,11 @@ installConfigs() {
$SUDO echo ":::" $SUDO echo ":::"
$SUDO echo "::: Installing configs..." $SUDO echo "::: Installing configs..."
versionCheckDNSmasq 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 $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) #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 #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 # 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 #Check to see if apt-get update has already been run today
# it needs to have been run at least once on new installs! # it needs to have been run at least once on new installs!
timestamp=$(stat -c %Y /var/cache/apt/) timestamp=$(stat -c %Y /var/cache/apt/)
timestampAsDate=$(date -d @$timestamp "+%b %e") timestampAsDate=$(date -d @"$timestamp" "+%b %e")
today=$(date "+%b %e") today=$(date "+%b %e")
if [ ! "$today" == "$timestampAsDate" ]; then if [ ! "$today" == "$timestampAsDate" ]; then
#update package lists #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
echo ":::" echo ":::"
echo -n "::: Checking apt-get for upgraded packages...." echo -n "::: apt-get update has not been run today. Running now..."
updatesToInstall=$($SUDO apt-get -s -o Debug::NoLocking=true upgrade | grep -c ^Inst) $SUDO apt-get -qq update & spinner $!
echo " done!" 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 ":::" echo ":::"
if [[ $updatesToInstall -eq "0" ]]; then fi
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
echo ":::" echo ":::"
echo "::: Checking dependencies:" echo "::: Checking dependencies:"
dependencies=( dnsutils bc toilet figlet dnsmasq lighttpd php5-common php5-cgi php5 git curl unzip wget ) dependencies=( dnsutils bc toilet figlet dnsmasq lighttpd php5-common php5-cgi php5 git curl unzip wget )
for i in "${dependencies[@]}" for i in "${dependencies[@]}"; do
do
:
echo -n "::: Checking for $i..." 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...." 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!" echo " done!"
else else
echo " already installed!" echo " already installed!"
@ -571,18 +580,18 @@ getGitFiles() {
is_repo() { is_repo() {
# If the directory does not have a .git folder it is not a repo # If the directory does not have a .git folder it is not a repo
echo -n "::: Checking $1 is a repo..." echo -n "::: Checking $1 is a repo..."
if [ -d "$1/.git" ]; then if [ -d "$1/.git" ]; then
echo " OK!" echo " OK!"
return 1 return 1
fi fi
echo " not found!!" echo " not found!!"
return 0 return 0
} }
make_repo() { make_repo() {
# Remove the non-repod interface and clone the interface # Remove the non-repod interface and clone the interface
echo -n "::: Cloning $2 into $1..." echo -n "::: Cloning $2 into $1..."
$SUDO rm -rf $1 $SUDO rm -rf "$1"
$SUDO git clone -q "$2" "$1" > /dev/null & spinner $! $SUDO git clone -q "$2" "$1" > /dev/null & spinner $!
echo " done!" echo " done!"
} }
@ -590,7 +599,7 @@ make_repo() {
update_repo() { update_repo() {
# Pull the latest commits # Pull the latest commits
echo -n "::: Updating repo in $1..." echo -n "::: Updating repo in $1..."
cd "$1" cd "$1" || exit
$SUDO git pull -q > /dev/null & spinner $! $SUDO git pull -q > /dev/null & spinner $!
echo " done!" echo " done!"
} }
@ -618,8 +627,12 @@ installPiholeWeb() {
$SUDO echo " Existing page detected, not overwriting" $SUDO echo " Existing page detected, not overwriting"
else else
$SUDO mkdir /var/www/html/pihole $SUDO mkdir /var/www/html/pihole
$SUDO mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig if [ -f /var/www/html/index.lighttpd.html ]; then
$SUDO cp /etc/.pihole/advanced/index.html /var/www/html/pihole/index.html $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!" $SUDO echo " done!"
fi fi
} }
@ -635,16 +648,13 @@ installCron() {
runGravity() { runGravity() {
# Rub gravity.sh to build blacklists # Rub gravity.sh to build blacklists
$SUDO echo ":::" $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 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.* $SUDO rm /etc/pihole/list.*
fi fi
#Don't run as SUDO, this was causing issues
echo "::: Running gravity.sh" echo "::: Running gravity.sh"
echo ":::" $SUDO /opt/pihole/gravity.sh
/usr/local/bin/gravity.sh
} }
setUser(){ setUser(){
@ -653,7 +663,7 @@ setUser(){
if id -u pihole > /dev/null 2>&1; then if id -u pihole > /dev/null 2>&1; then
echo "::: User 'pihole' already exists" echo "::: User 'pihole' already exists"
else else
echo "::: User 'pihole' doesn't exist. Creating..." echo "::: User 'pihole' doesn't exist. Creating..."
$SUDO useradd -r -s /usr/sbin/nologin pihole $SUDO useradd -r -s /usr/sbin/nologin pihole
fi fi
} }
@ -664,6 +674,9 @@ installPihole() {
stopServices stopServices
setUser setUser
$SUDO mkdir -p /etc/pihole/ $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 chown www-data:www-data /var/www/html
$SUDO chmod 775 /var/www/html $SUDO chmod 775 /var/www/html
$SUDO usermod -a -G www-data pihole $SUDO usermod -a -G www-data pihole
@ -682,12 +695,12 @@ displayFinalMessage() {
# Final completion message to user # 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: whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
$IPv4addr $IPv4addr
$piholeIPv6 $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 ############ ######## SCRIPT ############

163
automated install/uninstall.sh Normal file → Executable file
View File

@ -12,62 +12,135 @@
# Must be root to uninstall # Must be root to uninstall
if [[ $EUID -eq 0 ]];then if [[ $EUID -eq 0 ]];then
echo "You are root." echo "::: You are root."
else else
echo "sudo will be used for the install." echo "::: Sudo will be used for the uninstall."
# Check if it is actually installed # Check if it is actually installed
# If it isn't, exit because the unnstall cannot complete # If it isn't, exit because the unnstall cannot complete
if [[ $(dpkg-query -s sudo) ]];then if [[ $(dpkg-query -s sudo) ]];then
export SUDO="sudo" export SUDO="sudo"
else else
echo "Please install sudo or run this as root." echo "::: Please install sudo or run this as root."
exit 1 exit 1
fi fi
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 ########### ######### SCRIPT ###########
$SUDO apt-get -y remove --purge dnsutils bc toilet echo "::: Preparing to remove packages, be sure that each may be safely removed depending on your operating system."
$SUDO apt-get -y remove --purge dnsmasq echo "::: (SAFE TO REMOVE ALL ON RASPBIAN)"
$SUDO apt-get -y remove --purge lighttpd php5-common php5-cgi php5 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/

View File

@ -16,14 +16,14 @@ if [[ $EUID -eq 0 ]];then
echo "::: You are root." echo "::: You are root."
else else
echo "::: sudo will be used." echo "::: sudo will be used."
# Check if it is actually installed # Check if it is actually installed
# If it isn't, exit because the install cannot complete # If it isn't, exit because the install cannot complete
if [[ $(dpkg-query -s sudo) ]];then if [[ $(dpkg-query -s sudo) ]];then
export SUDO="sudo" export SUDO="sudo"
else else
echo "::: Please install sudo or run this script as root." echo "::: Please install sudo or run this script as root."
exit 1 exit 1
fi fi
fi fi
piholeIPfile=/tmp/piholeIP piholeIPfile=/tmp/piholeIP
@ -31,8 +31,8 @@ piholeIPv6file=/etc/pihole/.useIPv6
adListFile=/etc/pihole/adlists.list adListFile=/etc/pihole/adlists.list
adListDefault=/etc/pihole/adlists.default adListDefault=/etc/pihole/adlists.default
whitelistScript=/usr/local/bin/whitelist.sh whitelistScript=/opt/pihole/whitelist.sh
blacklistScript=/usr/local/bin/blacklist.sh blacklistScript=/opt/pihole/blacklist.sh
if [[ -f $piholeIPfile ]];then 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 # 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 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 # 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)}') 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%/*} piholeIP=${piholeIPCIDR%/*}
fi 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) }') piholeIPv6=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
fi fi
# Variables for various stages of downloading and formatting the list # Variables for various stages of downloading and formatting the list
## Nate 3/26/2016 - Commented unused variables
basename=pihole basename=pihole
piholeDir=/etc/$basename piholeDir=/etc/$basename
adList=$piholeDir/gravity.list adList=$piholeDir/gravity.list
blacklist=$piholeDir/blacklist.txt #blacklist=$piholeDir/blacklist.txt
whitelist=$piholeDir/whitelist.txt #whitelist=$piholeDir/whitelist.txt
latentWhitelist=$piholeDir/latentWhitelist.txt #latentWhitelist=$piholeDir/latentWhitelist.txt
justDomainsExtension=domains justDomainsExtension=domains
matterandlight=$basename.0.matterandlight.txt matterandlight=$basename.0.matterandlight.txt
supernova=$basename.1.supernova.txt supernova=$basename.1.supernova.txt
eventHorizon=$basename.2.eventHorizon.txt eventHorizon=$basename.2.eventHorizon.txt
accretionDisc=$basename.3.accretionDisc.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 # After setting defaults, check if there's local overrides
if [[ -r $piholeDir/pihole.conf ]];then if [[ -r $piholeDir/pihole.conf ]];then
@ -73,22 +71,20 @@ if [[ -r $piholeDir/pihole.conf ]];then
. $piholeDir/pihole.conf . $piholeDir/pihole.conf
fi fi
spinner() {
spinner(){ local pid=$1
local pid=$1 local delay=0.50
local delay=0.001 local spinstr='/-|'
local spinstr='/-\|' while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do
local temp=${spinstr#?}
spin='-\|/' printf " [%c] " "$spinstr"
i=0 local spinstr=$temp${spinstr%"$temp"}
while $SUDO kill -0 $pid 2>/dev/null sleep $delay
do printf "\b\b\b\b\b\b"
i=$(( (i+1) %4 )) done
printf "\b${spin:$i:1}" printf " \b\b\b\b"
sleep .1
done
printf "\b"
} }
########################### ###########################
# collapse - begin formation of pihole # collapse - begin formation of pihole
function gravity_collapse() { function gravity_collapse() {
@ -99,7 +95,7 @@ function gravity_collapse() {
#custom file found, use this instead of default #custom file found, use this instead of default
echo -n "::: Custom adList file detected. Reading..." echo -n "::: Custom adList file detected. Reading..."
sources=() sources=()
while read -a line; do while read -r line; do
#Do not read commented out or blank lines #Do not read commented out or blank lines
if [[ $line = \#* ]] || [[ ! $line ]]; then if [[ $line = \#* ]] || [[ ! $line ]]; then
echo "" > /dev/null echo "" > /dev/null
@ -107,12 +103,12 @@ function gravity_collapse() {
sources+=($line) sources+=($line)
fi fi
done < $adListFile done < $adListFile
echo " done!" echo " done!"
else else
#no custom file found, use defaults! #no custom file found, use defaults!
echo -n "::: No custom adlist file detected, reading from default file..." echo -n "::: No custom adlist file detected, reading from default file..."
sources=() sources=()
while read -a line; do while read -r line; do
#Do not read commented out or blank lines #Do not read commented out or blank lines
if [[ $line = \#* ]] || [[ ! $line ]]; then if [[ $line = \#* ]] || [[ ! $line ]]; then
echo "" > /dev/null echo "" > /dev/null
@ -120,8 +116,8 @@ function gravity_collapse() {
sources+=($line) sources+=($line)
fi fi
done < $adListDefault done < $adListDefault
echo " done!" echo " done!"
fi fi
# Create the pihole resource directory if it doesn't exist. Future files will be stored here # Create the pihole resource directory if it doesn't exist. Future files will be stored here
if [[ -d $piholeDir ]];then if [[ -d $piholeDir ]];then
@ -129,12 +125,12 @@ function gravity_collapse() {
# Will update later, needed for existing installs, new installs should # Will update later, needed for existing installs, new installs should
# create this directory as non-root # create this directory as non-root
$SUDO chmod 777 $piholeDir $SUDO chmod 777 $piholeDir
find "$piholeDir" -type f -exec $SUDO chmod 666 {} \; & spinner $! echo ":::"
echo "." echo "::: Existing pihole directory found"
else else
echo -n "::: Creating pihole directory..." echo "::: Creating pihole directory..."
mkdir $piholeDir & spinner $! mkdir $piholeDir
echo " done!" $SUDO chmod 777 $piholeDir
fi fi
} }
@ -146,7 +142,7 @@ function gravity_patternCheck() {
# Some of the blocklists are copyright, they need to be downloaded # Some of the blocklists are copyright, they need to be downloaded
# and stored as is. They can be processed for content after they # and stored as is. They can be processed for content after they
# have been saved. # have been saved.
cp $patternBuffer $saveLocation cp "$patternBuffer" "$saveLocation"
echo " List updated, transport successful!" echo " List updated, transport successful!"
else else
# curl didn't download any host files, probably because of the date check # curl didn't download any host files, probably because of the date check
@ -169,17 +165,16 @@ function gravity_transport() {
fi fi
# Silently curl url # 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 # Check for list updates
gravity_patternCheck $patternBuffer gravity_patternCheck "$patternBuffer"
# Cleanup # Cleanup
rm -f $patternBuffer rm -f "$patternBuffer"
} }
# spinup - main gravity function # spinup - main gravity function
function gravity_spinup() { function gravity_spinup() {
echo "::: " echo ":::"
# Loop through domain list. Download each one and remove commented lines (lines beginning with '# 'or '/') and # blank lines # Loop through domain list. Download each one and remove commented lines (lines beginning with '# 'or '/') and # blank lines
for ((i = 0; i < "${#sources[@]}"; i++)) for ((i = 0; i < "${#sources[@]}"; i++))
do do
@ -198,17 +193,17 @@ function gravity_spinup() {
# Use a case statement to download lists that need special cURL commands # Use a case statement to download lists that need special cURL commands
# to complete properly and reset the user agent when required # to complete properly and reset the user agent when required
case "$domain" in case "$domain" in
"adblock.mahakala.is") "adblock.mahakala.is")
agent='Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0' agent='Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0'
cmd_ext="-e http://forum.xda-developers.com/" cmd_ext="-e http://forum.xda-developers.com/"
;; ;;
"pgl.yoyo.org") "pgl.yoyo.org")
cmd_ext="-d mimetype=plaintext -d hostformat=hosts" cmd_ext="-d mimetype=plaintext -d hostformat=hosts"
;; ;;
# Default is a simple request # Default is a simple request
*) cmd_ext="" *) cmd_ext=""
esac esac
gravity_transport "$url" "$cmd_ext" "$agent" gravity_transport "$url" "$cmd_ext" "$agent"
done done
@ -216,55 +211,46 @@ function gravity_spinup() {
# Schwarzchild - aggregate domains to one list and add blacklisted domains # Schwarzchild - aggregate domains to one list and add blacklisted domains
function gravity_Schwarzchild() { function gravity_Schwarzchild() {
echo "::: " echo "::: "
# Find all active domains and compile them into one file and remove CRs # Find all active domains and compile them into one file and remove CRs
echo -n "::: Aggregating list of domains..." echo -n "::: Aggregating list of domains..."
truncate -s 0 $piholeDir/$matterandlight & spinner $! truncate -s 0 $piholeDir/$matterandlight & spinner $!
for i in "${activeDomains[@]}" for i in "${activeDomains[@]}"
do do
cat $i |tr -d '\r' >> $piholeDir/$matterandlight cat "$i" | tr -d '\r' >> $piholeDir/$matterandlight
done done
echo " done!" echo " done!"
} }
function gravity_Blacklist(){ function gravity_Blacklist(){
# Append blacklist entries if they exist # Append blacklist entries if they exist
echo -n "::: Running blacklist script to update HOSTS file...." echo -n "::: Running blacklist script to update HOSTS file...."
$blacklistScript -f -nr -q > /dev/null & spinner $! $blacklistScript -f -nr -q > /dev/null & spinner $!
numBlacklisted=$(wc -l < "/etc/pihole/blacklist.txt") numBlacklisted=$(wc -l < "/etc/pihole/blacklist.txt")
plural=; [[ "$numBlacklisted" != "1" ]] && plural=s plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
echo " $numBlacklisted domain${plural} blacklisted!" echo " $numBlacklisted domain${plural} blacklisted!"
} }
function gravity_Whitelist() { function gravity_Whitelist() {
echo ":::" echo ":::"
# Prevent our sources from being pulled into the hole # Prevent our sources from being pulled into the hole
plural=; [[ "${sources[@]}" != "1" ]] && plural=s 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=() urls=()
for url in ${sources[@]} for url in "${sources[@]}"
do do
tmp=$(echo "$url" | awk -F '/' '{print $3}') tmp=$(echo "$url" | awk -F '/' '{print $3}')
urls=("${urls[@]}" $tmp) urls=("${urls[@]}" $tmp)
done done
echo " done!" echo " done!"
echo -n "::: Running whitelist script to update HOSTS file...." 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") numWhitelisted=$(wc -l < "/etc/pihole/whitelist.txt")
plural=; [[ "$numWhitelisted" != "1" ]] && plural=s plural=; [[ "$numWhitelisted" != "1" ]] && plural=s
echo " $numWhitelisted domain${plural} whitelisted!" echo " $numWhitelisted domain${plural} whitelisted!"
} }
function gravity_unique() { function gravity_unique() {
@ -277,20 +263,21 @@ function gravity_unique() {
} }
function gravity_hostFormat() { 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..." 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 hostname=$(</etc/hostname)
if [[ -n $piholeIPv6 ]];then # 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
#Add dummy domain Pi-Hole.IsWorking.OK to the top of gravity.list to make ping result return a friendlier looking domain! if [[ -n $piholeIPv6 ]];then
echo -e "$piholeIP Pi-Hole.IsWorking.OK \n$piholeIPv6 Pi-Hole.IsWorking.OK" > $piholeDir/$accretionDisc # 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)
cat $piholeDir/$eventHorizon | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $piholeDir/$accretionDisc echo -e "$piholeIP $hostname\n$piholeIPv6 $hostname\n$piholeIP pi.hole\n$piholeIPv6 pi.hole" > $piholeDir/$accretionDisc
cat $piholeDir/$eventHorizon | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> $piholeDir/$accretionDisc
else else
# Otherwise, just create gravity.list as normal using IPv4 # 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! # 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 Pi-Hole.IsWorking.OK" > $piholeDir/$accretionDisc echo -e "$piholeIP $hostname\n$piholeIP pi.hole" > $piholeDir/$accretionDisc
cat $piholeDir/$eventHorizon | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >> $piholeDir/$accretionDisc cat $piholeDir/$eventHorizon | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >> $piholeDir/$accretionDisc
fi fi
# Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it # Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
cp $piholeDir/$accretionDisc $adList cp $piholeDir/$accretionDisc $adList
} }
@ -301,49 +288,52 @@ function gravity_blackbody() {
for file in $piholeDir/*.$justDomainsExtension for file in $piholeDir/*.$justDomainsExtension
do do
# If list is in active array then leave it (noop) else rm the list # If list is in active array then leave it (noop) else rm the list
if [[ " ${activeDomains[@]} " =~ " ${file} " ]]; then if [[ " ${activeDomains[@]} " =~ ${file} ]]; then
: :
else else
rm -f $file rm -f "$file"
fi fi
done done
} }
function gravity_advanced() { function gravity_advanced() {
# Remove comments and print only the domain name # 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 # 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 # 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 # 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...." 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 $! 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) numberOf=$(wc -l < $piholeDir/$supernova)
echo "::: $numberOf domains being pulled in by gravity..." echo "::: $numberOf domains being pulled in by gravity..."
gravity_unique gravity_unique
} }
function gravity_reload() { function gravity_reload() {
#Clear no longer needed files... #Clear no longer needed files...
echo ":::" echo ":::"
echo -n "::: Cleaning up un-needed files..." echo -n "::: Cleaning up un-needed files..."
$SUDO rm /etc/pihole/pihole.* $SUDO rm $piholeDir/pihole.*.txt
echo " done!" echo " done!"
# Reload hosts file # Reload hosts file
echo ":::" echo ":::"
echo -n "::: Refresh lists in dnsmasq..." 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) dnsmasqPid=$(pidof dnsmasq)
find "$piholeDir" -type f -exec $SUDO chmod 666 {} \; & spinner $! find "$piholeDir" -type f -exec $SUDO chmod 666 {} \; & spinner $!
if [[ $dnsmasqPid ]]; then if [[ $dnsmasqPid ]]; then
# service already running - reload config # service already running - reload config
$SUDO kill -HUP $dnsmasqPid & spinner $! $SUDO kill -HUP "$dnsmasqPid" & spinner $!
else else
# service not running, start it up # service not running, start it up
$SUDO service dnsmasq start & spinner $! $SUDO service dnsmasq start & spinner $!

113
pihole Executable file
View File

@ -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