1
0
mirror of https://github.com/pi-hole/pi-hole synced 2025-01-03 12:40:56 +00:00

Merge pull request #874 from pi-hole/development

Next release 2.9.5
This commit is contained in:
Dan Schaper 2016-10-29 17:01:51 -07:00 committed by GitHub
commit 69e3a45083
23 changed files with 1585 additions and 1676 deletions

3
.codeclimate.yml Normal file
View File

@ -0,0 +1,3 @@
engines:
shellcheck:
enabled: true

38
.gitattributes vendored Normal file
View File

@ -0,0 +1,38 @@
# FROM https://github.com/libgit2/libgit2sharp
# Text files that should be normalized to LF in odb.
*.cs text diff=csharp
*.config text
*.sln text
*.csproj text
*.md text
*.sh text
*.ps1 text
*.cmd text
*.bat text
*.markdown text
*.msbuild text
Lib/* binary
GitHub.Tests.Integration/Resources/* binary
# Binary files that should not be normalized or diffed
*.png binary
*.jpg binary
*.gif binary
*.pfx binary
*.snk binary
*.dll binary
*.exe binary
*.lib binary
*.exp binary
*.pdb binary
*.sdf binary
*.7z binary
# Catch all for anything we forgot. Add rules if you get CRLF -> LF warnings.
* text=auto

View File

@ -1,23 +1,21 @@
_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._ **In raising this issue, I confirm the following (please check boxes, eg [X]) Failure to fill the template will close your issue:**
**In raising this issue, I confirm the following (please check boxes, eg [X]):** - [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md).
- [] The issue I am reporting can be *replicated*
- [ ] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md). - [] The issue I'm reporting isn't a duplicate (see [FAQs](https://github.com/pi-hole/pi-hole/wiki/FAQs), [closed issues](https://github.com/pi-hole/pi-hole/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), and [open issues](https://github.com/pi-hole/pi-hole/issues)).
- [ ] The issue I am reporting can be *replicated*
- [ ] The issue I'm reporting isn't a duplicate (see [FAQs](https://github.com/pi-hole/pi-hole/wiki/FAQs), [closed issues](https://github.com/pi-hole/pi-hole/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), and [open issues](https://github.com/pi-hole/pi-hole/issues)).
**How familiar are you with the codebase?:** **How familiar are you with the codebase?:**
- [ ] 1 (very unfamiliar) - [] 1 (very unfamiliar)
- [ ] 2 - [] 2
- [ ] 3 - [] 3
- [ ] 4 - [] 4
- [ ] 5 - [] 5
- [ ] 6 - [] 6
- [ ] 7 - [] 7
- [ ] 8 - [] 8
- [ ] 9 - [] 9
- [ ] 10 (very familiar) - [] 10 (very familiar)
--- ---
**[FEATURE REQUEST | QUESTION | OTHER]:** **[FEATURE REQUEST | QUESTION | OTHER]:**
@ -40,3 +38,5 @@ _{replace this section with your content or delete if not a FEATURE REQUEST/QUES
**(Optional) Debug Log generated by `pihole -d`:** **(Optional) Debug Log generated by `pihole -d`:**
`http://termbin.com/<something>` `http://termbin.com/<something>`
_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._

View File

@ -1,25 +1,26 @@
_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._ **By submitting this pull request, I confirm the following (please check boxes, eg [X])Failure to fill the template will close your PR:**
**By submitting this pull request, I confirm the following (please check boxes, eg [X]):** - [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md).
- [] I have checked that [another pull request](https://github.com/pi-hole/pi-hole/pulls) for this purpose does not exist.
- [ ] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md). - [] I have considered, and confirmed that this submission will be valuable to others.
- [ ] I have checked that [another pull request](https://github.com/pi-hole/pi-hole/pulls) for this purpose does not exist. - [] I accept that this submission may not be used, and the pull request closed at the will of the maintainer.
- [ ] I have considered, and confirmed that this submission will be valuable to others. - [] I give this submission freely, and claim no ownership to its content.
- [ ] I accept that this submission may not be used, and the pull request closed at the will of the maintainer.
- [ ] I give this submission freely, and claim no ownership to its content.
**How familiar are you with the codebase?:** **How familiar are you with the codebase?:**
- [ ] 1 (very unfamiliar) - [] 1 (very unfamiliar)
- [ ] 2 - [] 2
- [ ] 3 - [] 3
- [ ] 4 - [] 4
- [ ] 5 - [] 5
- [ ] 6 - [] 6
- [ ] 7 - [] 7
- [ ] 8 - [] 8
- [ ] 9 - [] 9
- [ ] 10 (very familiar) - [] 10 (very familiar)
--- ---
_{replace this line with your pull request content}_ _{replace this line with your pull request content}_
_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._

View File

@ -1,4 +1,4 @@
[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=3011939)](https://www.bountysource.com/trackers/3011939-pi-hole-pi-hole?utm_source=3011939&utm_medium=shield&utm_campaign=TRACKER_BADGE) [![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=3011939)](https://www.bountysource.com/trackers/3011939-pi-hole-pi-hole?utm_source=3011939&utm_medium=shield&utm_campaign=TRACKER_BADGE) [![Code Climate](https://codeclimate.com/github/pi-hole/pi-hole/badges/gpa.svg)](https://codeclimate.com/github/pi-hole/pi-hole)
# Automated Install # Automated Install

View File

@ -42,9 +42,6 @@ https://raw.githubusercontent.com/quidsup/notrack/master/trackers.txt
# Block the BBC News website Breaking News banner # Block the BBC News website Breaking News banner
#https://raw.githubusercontent.com/BreakingTheNews/BreakingTheNews.github.io/master/hosts #https://raw.githubusercontent.com/BreakingTheNews/BreakingTheNews.github.io/master/hosts
# List of known C&C malware servers (see https://github.com/pi-hole/pi-hole/issues/528)
https://ransomwaretracker.abuse.ch/downloads/RW_DOMBL.txt
# 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
#https://raw.githubusercontent.com/Dawsey21/Lists/master/main-blacklist.txt #https://raw.githubusercontent.com/Dawsey21/Lists/master/main-blacklist.txt

View File

@ -9,53 +9,41 @@
# 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.
# If you want dnsmasq to read another file, as well as /etc/hosts, use ###############################################################################
# this. # FILE AUTOMATICALLY POPULATED BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
# #
# IF YOU WISH TO CHANGE THE UPSTREAM SERVERS, CHANGE THEM IN: #
# /etc/pihole/setupVars.conf #
# #
# ANY OTHER CHANGES SHOULD BE MADE IN A SEPERATE CONFIG FILE #
# OR IN /etc/dnsmasq.conf #
###############################################################################
address=/pi.hole/@IPv4@
address=/pi.hole/@IPv6@
address=/@HOSTNAME@/@IPv4@
address=/@HOSTNAME@/@IPv6@
addn-hosts=/etc/pihole/gravity.list addn-hosts=/etc/pihole/gravity.list
# The following two options make you a better netizen, since they
# tell dnsmasq to filter out queries which the public DNS cannot
# answer, and which load the servers (especially the root servers)
# unnecessarily. If you have a dial-on-demand link they also stop
# these requests from bringing up the link unnecessarily.
# Never forward plain names (without a dot or domain part)
domain-needed domain-needed
# Never forward addresses in the non-routed address spaces.
bogus-priv bogus-priv
# If you don't want dnsmasq to read /etc/resolv.conf or any other
# file, getting its servers from this file instead (see below), then
# uncomment this.
no-resolv no-resolv
# Add other name servers here, with domain specs if they are for
# non-public domains.
server=@DNS1@ server=@DNS1@
server=@DNS2@ server=@DNS2@
# If you want dnsmasq to listen for DHCP and DNS requests only on
# specified interfaces (and the loopback) give the name of the
# interface (eg eth0) here.
interface=@INT@ interface=@INT@
# Or which to listen on by address (remember to include 127.0.0.1 if
# you use this.)
listen-address=127.0.0.1
# Set the cachesize here.
cache-size=10000 cache-size=10000
# For debugging purposes, log each DNS query as it passes through
# dnsmasq.
log-queries log-queries
log-facility=/var/log/pihole.log log-facility=/var/log/pihole.log
# Normally responses which come from /etc/hosts and the DHCP lease
# file have Time-To-Live set as zero, which conventionally means
# do not cache further. If you are happy to trade lower load on the
# server for potentially stale date, you can set a time-to-live (in
# seconds) here.
local-ttl=300 local-ttl=300
# This allows it to continue functioning without being blocked by syslog, and allows syslog to use dnsmasq for DNS queries without risking deadlock
log-async log-async

View File

@ -1,230 +0,0 @@
#!/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
# Blacklists domains
#
# 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.
helpFunc()
{
echo "::: Immediately blacklists one or more domains in the hosts file"
echo ":::"
echo ":::"
echo "::: Usage: pihole -b domain1 [domain2 ...]"
echo "::: Options:"
echo "::: -d, --delmode Remove domains from the blacklist"
echo "::: -nr, --noreload Update blacklist without refreshing dnsmasq"
echo "::: -f, --force Force updating of the hosts files, even if there are no changes"
echo "::: -q, --quiet output is less verbose"
echo "::: -h, --help Show this help dialog"
echo "::: -l, --list Display your blacklisted domains"
exit 1
}
if [[ $# = 0 ]]; then
helpFunc
fi
#globals
basename=pihole
piholeDir=/etc/${basename}
adList=${piholeDir}/gravity.list
blacklist=${piholeDir}/blacklist.txt
reload=true
addmode=true
force=false
verbose=true
domList=()
domToRemoveList=()
piholeIPfile=/etc/pihole/piholeIP
piholeIPv6file=/etc/pihole/.useIPv6
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
piholeIP=$(cat ${piholeIPfile})
#rm $piholeIPfile
else
# Otherwise, the IP address can be taken directly from the machine, which will happen when the script is run by the user and not the installation script
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
piholeIPCIDR=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
piholeIP=${piholeIPCIDR%/*}
fi
modifyHost=false
# After setting defaults, check if there's local overrides
if [[ -r ${piholeDir}/pihole.conf ]];then
echo "::: Local calibration requested..."
. ${piholeDir}/pihole.conf
fi
if [[ -f ${piholeIPv6file} ]];then
# If the file exists, then the user previously chose to use IPv6 in the automated installer
piholeIPv6=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
fi
HandleOther(){
#check validity of domain
validDomain=$(echo "$1" | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/')
if [ -z "$validDomain" ]; then
echo "::: $1 is not a valid argument or domain name"
else
domList=("${domList[@]}" ${validDomain})
fi
}
PopBlacklistFile(){
#check blacklist file exists, and if not, create it
if [[ ! -f ${blacklist} ]];then
touch ${blacklist}
fi
for dom in "${domList[@]}"; do
if "$addmode"; then
AddDomain "$dom"
else
RemoveDomain "$dom"
fi
done
}
AddDomain(){
#| sed 's/\./\\./g'
bool=false
grep -Ex -q "$1" ${blacklist} || bool=true
if ${bool}; then
#domain not found in the blacklist file, add it!
if ${verbose}; then
echo -n "::: Adding $1 to blacklist file..."
fi
echo "$1" >> ${blacklist}
modifyHost=true
echo " done!"
else
if ${verbose}; then
echo "::: $1 already exists in $blacklist! No need to add"
fi
fi
}
RemoveDomain(){
bool=false
grep -Ex -q "$1" ${blacklist} || bool=true
if ${bool}; then
#Domain is not in the blacklist file, no need to Remove
if ${verbose}; then
echo "::: $1 is NOT blacklisted! No need to remove"
fi
else
#Domain is in the blacklist file, add to a temporary array
if ${verbose}; then
echo "::: Un-blacklisting $dom..."
fi
domToRemoveList=("${domToRemoveList[@]}" $1)
modifyHost=true
fi
}
ModifyHostFile(){
if ${addmode}; then
#add domains to the hosts file
if [[ -r ${blacklist} ]];then
numberOf=$(cat ${blacklist} | sed '/^\s*$/d' | wc -l)
plural=; [[ "$numberOf" != "1" ]] && plural=s
echo ":::"
echo -n "::: Modifying HOSTS file to blacklist $numberOf domain${plural}..."
if [[ -n ${piholeIPv6} ]];then
cat ${blacklist} | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> ${adList}
else
cat ${blacklist} | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >>${adList}
fi
fi
else
echo ":::"
for dom in "${domToRemoveList[@]}"
do
#we need to remove the domains from the blacklist file and the host file
echo "::: $dom"
echo -n "::: removing from HOSTS file..."
echo "$dom" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /[^.]'{}'(?!.)/;' ${adList}
echo " done!"
echo -n "::: removing from blackist.txt..."
echo "$dom" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' ${blacklist}
echo " done!"
done
fi
}
Reload() {
# Reload hosts file
echo ":::"
echo -n "::: Refresh lists in dnsmasq..."
dnsmasqPid=$(pidof dnsmasq)
if [[ ${dnsmasqPid} ]]; then
# service already running - reload config
if [ -x "$(command -v systemctl)" ]; then
systemctl restart dnsmasq
else
service dnsmasq restart
fi
else
# service not running, start it up
if [ -x "$(command -v systemctl)" ]; then
systemctl start dnsmasq
else
service dnsmasq start
fi
fi
echo " done!"
}
DisplayBlist() {
verbose=false
echo -e " Displaying Gravity Affected Domains \n"
count=1
while IFS= read -r AD
do
echo "${count}: $AD"
count=$((count+1))
done < "$blacklist"
}
###################################################
for var in "$@"
do
case "$var" in
"-nr"| "--noreload" ) reload=false;;
"-d" | "--delmode" ) addmode=false;;
"-f" | "--force" ) force=true;;
"-q" | "--quiet" ) verbose=false;;
"-h" | "--help" ) helpFunc;;
"-l" | "--list" ) DisplayBlist;;
* ) HandleOther "$var";;
esac
done
PopBlacklistFile
if ${modifyHost} || ${force}; then
ModifyHostFile
else
if ${verbose}; then
echo "::: No changes need to be made"
fi
exit 1
fi
if ${reload}; then
Reload
fi

View File

@ -17,11 +17,11 @@ gravity="/etc/pihole/gravity.list"
today=$(date "+%b %e") today=$(date "+%b %e")
CalcBlockedDomains(){ CalcBlockedDomains() {
CheckIPv6 CheckIPv6
if [ -e "$gravity" ]; then if [ -e "${gravity}" ]; then
#Are we IPV6 or IPV4? #Are we IPV6 or IPV4?
if [[ -n ${piholeIPv6} ]];then if [[ -n ${piholeIPv6} ]]; then
#We are IPV6 #We are IPV6
blockedDomainsTotal=$(wc -l /etc/pihole/gravity.list | awk '{print $1/2}') blockedDomainsTotal=$(wc -l /etc/pihole/gravity.list | awk '{print $1/2}')
else else
@ -33,43 +33,43 @@ CalcBlockedDomains(){
fi fi
} }
CalcQueriesToday(){ CalcQueriesToday() {
if [ -e "$piLog" ];then if [ -e "${piLog}" ]; then
queriesToday=$(cat "$piLog" | grep "$today" | awk '/query/ {print $6}' | wc -l) queriesToday=$(cat "${piLog}" | grep "${today}" | awk '/query/ {print $6}' | wc -l)
else else
queriesToday="Err." queriesToday="Err."
fi fi
} }
CalcblockedToday(){ CalcblockedToday() {
if [ -e "$piLog" ] && [ -e "$gravity" ];then if [ -e "${piLog}" ] && [ -e "${gravity}" ];then
blockedToday=$(cat ${piLog} | awk '/\/etc\/pihole\/gravity.list/ && !/address/ {print $6}' | wc -l) blockedToday=$(cat ${piLog} | awk '/\/etc\/pihole\/gravity.list/ && !/address/ {print $6}' | wc -l)
else else
blockedToday="Err." blockedToday="Err."
fi fi
} }
CalcPercentBlockedToday(){ CalcPercentBlockedToday() {
if [ "$queriesToday" != "Err." ] && [ "$blockedToday" != "Err." ]; then if [ "${queriesToday}" != "Err." ] && [ "${blockedToday}" != "Err." ]; then
if [ "$queriesToday" != 0 ]; then #Fixes divide by zero error :) if [ "${queriesToday}" != 0 ]; then #Fixes divide by zero error :)
#scale 2 rounds the number down, so we'll do scale 4 and then trim the last 2 zeros #scale 2 rounds the number down, so we'll do scale 4 and then trim the last 2 zeros
percentBlockedToday=$(echo "scale=4; $blockedToday/$queriesToday*100" | bc) percentBlockedToday=$(echo "scale=4; ${blockedToday}/${queriesToday}*100" | bc)
percentBlockedToday=$(sed 's/.\{2\}$//' <<< "$percentBlockedToday") percentBlockedToday=$(sed 's/.\{2\}$//' <<< "${percentBlockedToday}")
else else
percentBlockedToday=0 percentBlockedToday=0
fi fi
fi fi
} }
CheckIPv6(){ CheckIPv6() {
piholeIPv6file="/etc/pihole/.useIPv6" piholeIPv6file="/etc/pihole/.useIPv6"
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
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
} }
outputJSON(){ outputJSON() {
CalcQueriesToday CalcQueriesToday
CalcblockedToday CalcblockedToday
CalcPercentBlockedToday CalcPercentBlockedToday
@ -79,9 +79,8 @@ outputJSON(){
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"
} }
normalChrono(){ normalChrono() {
for (( ; ; )) for (( ; ; )); do
do
clear clear
# Displays a colorful Pi-hole logo # Displays a colorful Pi-hole logo
echo " ___ _ _ _" echo " ___ _ _ _"
@ -111,26 +110,27 @@ normalChrono(){
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
} }
displayHelp(){ displayHelp() {
echo "::: Displays stats about your piHole!" cat << EOM
echo ":::" ::: Displays stats about your piHole!
echo "::: Usage: sudo pihole -c [optional:-j]" :::
echo "::: Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds" ::: Usage: sudo pihole -c [optional:-j]
echo ":::" ::: Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds
echo "::: Options:" :::
echo "::: -j, --json output stats as JSON formatted string" ::: Options:
echo "::: -h, --help display this help text" ::: -j, --json output stats as JSON formatted string
::: -h, --help display this help text
EOM
exit 1 exit 1
} }
@ -138,11 +138,10 @@ if [[ $# = 0 ]]; then
normalChrono normalChrono
fi fi
for var in "$@" 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

166
advanced/Scripts/list.sh Normal file
View File

@ -0,0 +1,166 @@
#!/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
# Whitelists and blacklists domains
#
# 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.
#globals
basename=pihole
piholeDir=/etc/${basename}
whitelist=${piholeDir}/whitelist.txt
blacklist=${piholeDir}/blacklist.txt
reload=false
addmode=true
verbose=true
domList=()
domToRemoveList=()
listMain=""
listAlt=""
helpFunc() {
if [[ ${listMain} == ${whitelist} ]]; then
letter="w"
word="white"
else
letter="b"
word="black"
fi
cat << EOM
::: Immediately ${word}lists one or more domains in the hosts file
:::
::: Usage: pihole -${letter} domain1 [domain2 ...]
:::
::: Options:
::: -d, --delmode Remove domains from the ${word}list
::: -nr, --noreload Update ${word}list without refreshing dnsmasq
::: -q, --quiet output is less verbose
::: -h, --help Show this help dialog
::: -l, --list Display your ${word}listed domains
EOM
exit 1
}
HandleOther(){
#check validity of domain
validDomain=$(echo "$1" | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/')
if [ -z "${validDomain}" ]; then
echo "::: $1 is not a valid argument or domain name"
else
domList=("${domList[@]}" ${validDomain})
fi
}
PoplistFile() {
#check whitelist file exists, and if not, create it
if [[ ! -f ${whitelist} ]]; then
touch ${whitelist}
fi
for dom in "${domList[@]}"; do
# Logic : If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other
if ${addmode}; then
AddDomain "${dom}" "${listMain}"
RemoveDomain "${dom}" "${listAlt}"
else
RemoveDomain "${dom}" "${listMain}"
fi
done
}
AddDomain() {
list="$2"
bool=true
#Is the domain in the list we want to add it to?
grep -Ex -q "$1" ${list} > /dev/null 2>&1 || bool=false
if [[ "${bool}" == false ]]; then
#domain not found in the whitelist file, add it!
if [[ "${verbose}" == true ]]; then
echo "::: Adding $1 to $list..."
fi
reload=true
# Add it to the list we want to add it to
echo "$1" >> ${list}
else
if [[ "${verbose}" == true ]]; then
echo "::: ${1} already exists in ${list}, no need to add!"
fi
fi
}
RemoveDomain() {
list="$2"
bool=true
#Is it in the other list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
grep -Ex -q "$1" ${list} > /dev/null 2>&1 || bool=false
if [[ "${bool}" == true ]]; then
# Remove it from the other one
echo "::: Removing $1 from $list..."
echo "$1" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' ${list}
reload=true
else
if [[ "${verbose}" == true ]]; then
echo "::: ${1} does not exist in ${list}, no need to remove!"
fi
fi
}
Reload() {
# Reload hosts file
pihole -g -sd
}
Displaylist() {
if [[ ${listMain} == ${whitelist} ]]; then
string="gravity resistant domains"
else
string="domains caught in the sinkhole"
fi
verbose=false
echo -e " Displaying $string \n"
count=1
while IFS= read -r RD; do
echo "${count}: ${RD}"
count=$((count+1))
done < "${listMain}"
exit 0;
}
for var in "$@"; do
case "${var}" in
"-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";;
"-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";;
"-nr"| "--noreload" ) reload=false;;
"-d" | "--delmode" ) addmode=false;;
"-f" | "--force" ) force=true;;
"-q" | "--quiet" ) verbose=false;;
"-h" | "--help" ) helpFunc;;
"-l" | "--list" ) Displaylist;;
* ) HandleOther "${var}";;
esac
done
shift
if [[ $# = 0 ]]; then
helpFunc
fi
PoplistFile
if ${reload}; then
Reload
fi

View File

@ -13,452 +13,381 @@
set -o pipefail set -o pipefail
######## GLOBAL VARS ######## ######## GLOBAL VARS ########
VARSFILE="/etc/pihole/setupVars.conf"
DEBUG_LOG="/var/log/pihole_debug.log" DEBUG_LOG="/var/log/pihole_debug.log"
DNSMASQFILE="/etc/dnsmasq.conf" DNSMASQFILE="/etc/dnsmasq.conf"
PIHOLECONFFILE="/etc/dnsmasq.d/01-pihole.conf" DNSMASQCONFFILE="/etc/dnsmasq.d/01-pihole.conf"
LIGHTTPDFILE="/etc/lighttpd/lighttpd.conf" LIGHTTPDFILE="/etc/lighttpd/lighttpd.conf"
LIGHTTPDERRFILE="/var/log/lighttpd/error.log" LIGHTTPDERRFILE="/var/log/lighttpd/error.log"
GRAVITYFILE="/etc/pihole/gravity.list" GRAVITYFILE="/etc/pihole/gravity.list"
HOSTSFILE="/etc/hosts"
WHITELISTFILE="/etc/pihole/whitelist.txt" WHITELISTFILE="/etc/pihole/whitelist.txt"
BLACKLISTFILE="/etc/pihole/blacklist.txt" BLACKLISTFILE="/etc/pihole/blacklist.txt"
ADLISTSFILE="/etc/pihole/adlists.list" ADLISTFILE="/etc/pihole/adlists.list"
PIHOLELOG="/var/log/pihole.log" PIHOLELOG="/var/log/pihole.log"
WHITELISTMATCHES="/tmp/whitelistmatches.list" WHITELISTMATCHES="/tmp/whitelistmatches.list"
IPV6_READY=false
# Header info and introduction # Header info and introduction
echo "::: Beginning Pi-hole debug at $(date)!" cat << EOM
echo "::: This debugging process will collect information from your running configuration," ::: Beginning Pi-hole debug at $(date)!
echo "::: and optionally upload the generated log to a unique and random directory on" :::
echo "::: Termbin.com. NOTE: All log files auto-delete after 1 month and you are the only" ::: This process collects information from your Pi-hole, and optionally uploads
echo "::: person who is given the unique URL. Please consider where you post this link." ::: it to a unique and random directory on tricorder.pi-hole.net.
echo "::: " :::
::: NOTE: All log files auto-delete after 24 hours and ONLY the Pi-hole developers
::: can access your data via the given token. We have taken these extra steps to
######## FIRST CHECK ######## ::: secure your data and will work to further reduce any personal information gathered.
# Must be root to debug :::
if [[ "$EUID" -eq 0 ]]; then ::: Please read and note any issues, and follow any directions advised during this process.
echo "::: Script is executing as root user..." EOM
else
echo "::: Non-root user detected..."
# Check if sudo is actually installed
if [ -x "$(command -v sudo)" ]; then
export SUDO="sudo"
echo "::: sudo command located, debug will run under sudo."
else
echo "::: Unable to locate sudo command. Please install sudo or run this as root."
exit 1
fi
fi
# Ensure the file exists, create if not, clear if exists. # Ensure the file exists, create if not, clear if exists.
if [ ! -f "$DEBUG_LOG" ]; then truncate --size=0 "${DEBUG_LOG}"
${SUDO} touch ${DEBUG_LOG} chmod 644 ${DEBUG_LOG}
${SUDO} chmod 644 ${DEBUG_LOG} chown "$USER":pihole ${DEBUG_LOG}
${SUDO} chown "$USER":root ${DEBUG_LOG}
else source ${VARSFILE}
truncate -s 0 ${DEBUG_LOG}
fi
### Private functions exist here ### ### Private functions exist here ###
function log_write { log_write() {
echo "$1" >> "${DEBUG_LOG}" echo "${1}" >> "${DEBUG_LOG}"
} }
function version_check { log_echo() {
log_write "############################################################" case ${1} in
log_write "########## Installed Versions ##########" -n)
log_write "############################################################" echo -n "::: ${2}"
log_write "${2}"
echo "::: Detecting Pi-hole installed versions." ;;
pi_hole_ver="$(cd /etc/.pihole/ && git describe --tags --abbrev=0)" \ -r)
&& log_write "Pi-hole Version: $pi_hole_ver" || log_write "Pi-hole git repository not detected." echo "::: ${2}"
admin_ver="$(cd /var/www/html/admin && git describe --tags --abbrev=0)" \ log_write "${2}"
&& log_write "WebUI Version: $admin_ver" || log_write "Pi-hole Admin Pages git repository not detected." ;;
-l)
echo "::: Writing lighttpd version to logfile." echo "${2}"
light_ver="$(lighttpd -v |& head -n1)" && log_write "${light_ver}" || log_write "lighttpd not installed." log_write "${2}"
;;
echo "::: Writing PHP version to logfile." *)
php_ver="$(php -v |& head -n1)" && log_write "${php_ver}" || log_write "PHP not installed." echo "::: ${1}"
log_write "${1}"
esac
} }
function distro_check { header_write() {
echo "############################################################" >> ${DEBUG_LOG} log_echo ""
echo "######## Installed OS Distribution #########" >> ${DEBUG_LOG} log_echo "${1}"
echo "############################################################" >> ${DEBUG_LOG} log_write ""
echo "::: Checking installed OS Distribution release."
TMP=$(cat /etc/*release || echo "Failed to find release")
echo "::: Writing OS Distribution release to logfile."
echo "$TMP" >> ${DEBUG_LOG}
echo >> ${DEBUG_LOG}
} }
function ip_check { file_parse() {
echo "############################################################" >> ${DEBUG_LOG} while read -r line; do
echo "######## IP Address Information #########" >> ${DEBUG_LOG} if [ ! -z "${line}" ]; then
echo "############################################################" >> ${DEBUG_LOG} [[ "${line}" =~ ^#.*$ || ! "${line}" ]] && continue
log_write "${line}"
fi
done < "${1}"
log_write ""
}
echo "::: Writing local IPs to logfile" block_parse() {
IPADDR="$(ip a | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "inet") print $(i+1) }')" log_write "${1}"
echo "$IPADDR" >> ${DEBUG_LOG} }
IP6ADDR="$(ip a | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "inet6") print $(i+1) }')" \ lsof_parse() {
&& echo "$IP6ADDR" >> ${DEBUG_LOG} || echo "No IPv6 addresses found." >> ${DEBUG_LOG} local user
echo >> ${DEBUG_LOG} local process
echo "::: Locating default gateway and checking connectivity" user=$(echo ${1} | cut -f 3 -d ' ' | cut -c 2-)
GATEWAY=$(ip r | grep default | cut -d ' ' -f 3) process=$(echo ${1} | cut -f 2 -d ' ' | cut -c 2-)
if [[ $? = 0 ]] [[ ${2} -eq ${process} ]] \
then && echo "::: Correctly configured." \
echo "::: Pinging default IPv4 gateway..." || log_echo "::: Failure: Incorrectly configured daemon."
GATEWAY_CHECK=$(ping -q -w 3 -c 3 -n "${GATEWAY}" | tail -n3)
if [[ $? = 0 ]]
then
echo "IPv4 Gateway check:" >> ${DEBUG_LOG}
else
echo "IPv4 Gateway check failed:" >> ${DEBUG_LOG}
fi
echo "$GATEWAY_CHECK" >> ${DEBUG_LOG}
echo >> ${DEBUG_LOG}
echo "::: Pinging Internet via IPv4..." log_write "Found user ${user} with process ${process}"
INET_CHECK=$(ping -q -w 5 -c 3 -n 8.8.8.8 | tail -n3) }
if [[ $? = 0 ]]
then
echo "IPv4 Internet check:" >> ${DEBUG_LOG}
else
echo "IPv4 Internet check failed:" >> ${DEBUG_LOG}
fi
echo "$INET_CHECK" >> ${DEBUG_LOG}
echo >> ${DEBUG_LOG}
fi
GATEWAY6=$(ip -6 r | grep default | cut -d ' ' -f 3)
if [[ $? = 0 ]]
then
echo "::: Pinging default IPv6 gateway..."
GATEWAY6_CHECK=$(ping6 -q -w 3 -c 3 -n "${GATEWAY6}" | tail -n3)
if [[ $? = 0 ]]
then
echo "IPv6 Gateway check:" >> ${DEBUG_LOG}
else
echo "IPv6 Gateway check failed:" >> ${DEBUG_LOG}
fi
echo "::: Pinging Internet via IPv6..." version_check() {
GATEWAY6_CHECK=$(ping6 -q -w 3 -c 3 -n 2001:4860:4860::8888 | tail -n3) header_write "Detecting Installed Package Versions:"
if [[ $? = 0 ]]
then
echo "IPv6 Internet check:" >> ${DEBUG_LOG}
else
echo "IPv6 Internet check failed:" >> ${DEBUG_LOG}
fi
local error_found
error_found=0
local pi_hole_ver="$(cd /etc/.pihole/ && git describe --tags --abbrev=0)" \
&& log_echo -r "Pi-hole: $pi_hole_ver" || (log_echo "Pi-hole git repository not detected." && error_found=1)
local admin_ver="$(cd /var/www/html/admin && git describe --tags --abbrev=0)" \
&& log_echo -r "WebUI: $admin_ver" || (log_echo "Pi-hole Admin Pages git repository not detected." && error_found=1)
local light_ver="$(lighttpd -v |& head -n1 | cut -d " " -f1)" \
&& log_echo -r "${light_ver}" || (log_echo "lighttpd not installed." && error_found=1)
local php_ver="$(php -v |& head -n1)" \
&& log_echo -r "${php_ver}" || (log_echo "PHP not installed." && error_found=1)
return "${error_found}"
}
files_check() {
#Check non-zero length existence of ${1}
header_write "Detecting existence of ${1}:"
local search_file="${1}"
if [[ -s ${search_file} ]]; then
echo "::: File exists"
file_parse "${search_file}"
return 0
else
log_echo "${1} not found!"
return 1
fi
echo ":::"
}
source_file() {
local file_found=$(files_check "${1}") \
&& (source "${1}" &> /dev/null && echo "${file_found} and was successfully sourced") \
|| log_echo -l "${file_found} and could not be sourced"
}
distro_check() {
local soft_fail
header_write "Detecting installed OS Distribution"
soft_fail=0
local distro="$(cat /etc/*release)" && block_parse "${distro}" || (log_echo "Distribution details not found." && soft_fail=1)
return "${soft_fail}"
}
processor_check() {
header_write "Checking processor variety"
log_write $(uname -m) && return 0 || return 1
}
ipv6_check() {
# Check if system is IPv6 enabled, for use in other functions
if [[ $IPv6_address ]]; then
ls /proc/net/if_inet6 &>/dev/null && IPV6_READY=true
return 0
else
return 1
fi
}
ip_check() {
header_write "IP Address Information"
# Get the current interface for Internet traffic
# Check if IPv6 enabled
local IPv6_interface
local IPv4_interface
ipv6_check && IPv6_interface=${piholeInterface:-$(ip -6 r | grep default | cut -d ' ' -f 5)}
# If declared in setupVars.conf use it, otherwise defer to default
# http://stackoverflow.com/questions/2013547/assigning-default-values-to-shell-variables-with-a-single-command-in-bash
IPv4_interface=${piholeInterface:-$(ip r | grep default | cut -d ' ' -f 5)}
if [[ IPV6_READY ]]; then
local IPv6_addr_list="$(ip a | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "inet6") print $(i+1) }')" \
&& (log_write "${IPv6_addr_list}" && echo "::: IPv6 addresses located") \
|| log_echo "No IPv6 addresses found."
local IPv6_def_gateway=$(ip -6 r | grep default | cut -d ' ' -f 3)
if [[ $? = 0 ]] && [[ -n ${IPv6_def_gateway} ]]; then
echo -n "::: Pinging default IPv6 gateway: "
local IPv6_def_gateway_check="$(ping6 -q -W 3 -c 3 -n "${IPv6_def_gateway}" -I "${IPv6_interface}"| tail -n3)" \
&& echo "Gateway Responded." \
|| echo "Gateway did not respond."
block_parse "${IPv6_def_gateway_check}"
echo -n "::: Pinging Internet via IPv6: "
local IPv6_inet_check=$(ping6 -q -W 3 -c 3 -n 2001:4860:4860::8888 -I "${IPv6_interface}"| tail -n3) \
&& echo "Query responded." \
|| echo "Query did not respond."
block_parse "${IPv6_inet_check}"
else else
GATEWAY_CHECK="No IPv6 Gateway Detected" log_echo="No IPv6 Gateway Detected"
fi fi
echo "$GATEWAY_CHECK" >> ${DEBUG_LOG}
local IPv4_addr_list="$(ip a | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "inet") print $(i+1) }')" \
&& (block_parse "${IPv4_addr_list}" && echo "::: IPv4 addresses located")\
|| log_echo "No IPv4 addresses found."
echo >> ${DEBUG_LOG} local IPv4_def_gateway=$(ip r | grep default | cut -d ' ' -f 3)
if [[ $? = 0 ]]; then
echo -n "::: Pinging default IPv4 gateway: "
local IPv4_def_gateway_check="$(ping -q -w 3 -c 3 -n "${IPv4_def_gateway}" -I "${IPv4_interface}" | tail -n3)" \
&& echo "Gateway responded." \
|| echo "Gateway did not respond."
block_parse "${IPv4_def_gateway_check}"
echo -n "::: Pinging Internet via IPv4: "
local IPv4_inet_check="$(ping -q -w 5 -c 3 -n 8.8.8.8 -I "${IPv4_interface}" | tail -n3)" \
&& echo "Query responded." \
|| echo "Query did not respond."
block_parse "${IPv4_inet_check}"
fi
fi
} }
function hostnameCheck { port_check() {
echo "############################################################" >> ${DEBUG_LOG} local lsof_value
echo "######## Hostname Information #########" >> ${DEBUG_LOG}
echo "############################################################" >> ${DEBUG_LOG}
echo "::: Writing locally configured hostnames to logfile" lsof_value=$(lsof -i ${1}:${2} -FcL | tr '\n' ' ') \
# Write the hostname output to compare against entries in /etc/hosts, which is logged next && lsof_parse "${lsof_value}" "${3}" \
echo "This Pi-hole is: $(hostname)" >> ${DEBUG_LOG} || log_echo "Failure: IPv${1} Port not in use"
echo "::: Writing hosts file to debug log..."
echo "### Hosts ###" >> ${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
} }
function portCheck { daemon_check() {
echo "############################################################" >> ${DEBUG_LOG} # Check for daemon ${1} on port ${2}
echo "######## Open Port Information #########" >> ${DEBUG_LOG} header_write "Daemon Process Information"
echo "############################################################" >> ${DEBUG_LOG}
echo "::: Detecting local server port 80 and 53 processes." echo "::: Checking ${2} port for ${1} listener."
${SUDO} lsof -i :80 >> ${DEBUG_LOG} if [[ ${IPV6_READY} ]]; then
${SUDO} lsof -i :53 >> ${DEBUG_LOG} port_check 6 "${2}" "${1}"
echo >> ${DEBUG_LOG} fi
lsof_value=$(lsof -i 4:${2} -FcL | tr '\n' ' ') \
port_check 4 "${2}" "${1}"
} }
function testResolver { testResolver() {
echo "############################################################" >> ${DEBUG_LOG} header_write "Resolver Functions Check"
echo "############ Resolver Functions Check ############" >> ${DEBUG_LOG}
echo "############################################################" >> ${DEBUG_LOG}
# Find a blocked url that has not been whitelisted. # Find a blocked url that has not been whitelisted.
TESTURL="doubleclick.com" TESTURL="doubleclick.com"
if [ -s "$WHITELISTMATCHES" ]; then if [ -s "${WHITELISTMATCHES}" ]; then
while read -r line; do while read -r line; do
CUTURL=${line#*" "} CUTURL=${line#*" "}
if [ "$CUTURL" != "Pi-Hole.IsWorking.OK" ]; then if [ "${CUTURL}" != "Pi-Hole.IsWorking.OK" ]; then
while read -r line2; do while read -r line2; do
CUTURL2=${line2#*" "} CUTURL2=${line2#*" "}
if [ "$CUTURL" != "$CUTURL2" ]; then if [ "${CUTURL}" != "${CUTURL2}" ]; then
TESTURL="$CUTURL" TESTURL="${CUTURL}"
break 2 break 2
fi fi
done < "$WHITELISTMATCHES" done < "${WHITELISTMATCHES}"
fi fi
done < "$GRAVITYFILE" done < "${GRAVITYFILE}"
fi fi
echo "Resolution of $TESTURL from Pi-hole:" >> ${DEBUG_LOG} log_write "Resolution of ${TESTURL} from Pi-hole:"
LOCALDIG=$(dig "$TESTURL" @127.0.0.1) LOCALDIG=$(dig "${TESTURL}" @127.0.0.1)
if [[ $? = 0 ]] if [[ $? = 0 ]]; then
then log_write "${LOCALDIG}"
echo "$LOCALDIG" >> ${DEBUG_LOG}
else else
echo "Failed to resolve $TESTURL on Pi-hole" >> ${DEBUG_LOG} log_write "Failed to resolve ${TESTURL} on Pi-hole"
fi fi
echo >> ${DEBUG_LOG} log_write ""
echo "Resolution of $TESTURL from 8.8.8.8:" >> ${DEBUG_LOG} log_write "Resolution of ${TESTURL} from 8.8.8.8:"
REMOTEDIG=$(dig "$TESTURL" @8.8.8.8) REMOTEDIG=$(dig "${TESTURL}" @8.8.8.8)
if [[ $? = 0 ]] if [[ $? = 0 ]]; then
then log_write "${REMOTEDIG}"
echo "$REMOTEDIG" >> ${DEBUG_LOG}
else else
echo "Failed to resolve $TESTURL on 8.8.8.8" >> ${DEBUG_LOG} log_write "Failed to resolve ${TESTURL} on 8.8.8.8"
fi fi
echo >> ${DEBUG_LOG} log_write ""
echo "Pi-hole dnsmasq specific records lookups" >> ${DEBUG_LOG} log_write "Pi-hole dnsmasq specific records lookups"
echo "Cache Size:" >> ${DEBUG_LOG} log_write "Cache Size:"
dig +short chaos txt cachesize.bind >> ${DEBUG_LOG} dig +short chaos txt cachesize.bind >> ${DEBUG_LOG}
echo "Insertions count:" >> ${DEBUG_LOG} log_write "Upstream Servers:"
dig +short chaos txt insertions.bind >> ${DEBUG_LOG} dig +short chaos txt servers.bind >> ${DEBUG_LOG}
echo "Evictions count:" >> ${DEBUG_LOG} log_write ""
dig +short chaos txt evictions.bind >> ${DEBUG_LOG}
echo "Misses count:" >> ${DEBUG_LOG}
dig +short chaos txt misses.bind >> ${DEBUG_LOG}
echo "Hits count:" >> ${DEBUG_LOG}
dig +short chaos txt hits.bind >> ${DEBUG_LOG}
echo "Auth count:" >> ${DEBUG_LOG}
dig +short chaos txt auth.bind >> ${DEBUG_LOG}
echo "Upstream Servers:" >> ${DEBUG_LOG}
dig +short chaos txt servers.bind >> ${DEBUG_LOG}
echo >> ${DEBUG_LOG}
} }
function checkProcesses { checkProcesses() {
echo "#######################################" >> ${DEBUG_LOG} header_write "Processes Check"
echo "########### Processes Check ###########" >> ${DEBUG_LOG}
echo "#######################################" >> ${DEBUG_LOG} echo "::: Logging status of lighttpd and dnsmasq..."
echo ":::"
echo "::: Logging status of lighttpd and dnsmasq..."
PROCESSES=( lighttpd dnsmasq ) PROCESSES=( lighttpd dnsmasq )
for i in "${PROCESSES[@]}" for i in "${PROCESSES[@]}"; do
do log_write ""
echo "" >> ${DEBUG_LOG} log_write "${i}"
echo -n "$i" >> "$DEBUG_LOG" log_write " processes status:"
echo " processes status:" >> ${DEBUG_LOG} systemctl -l status "${i}" >> "${DEBUG_LOG}"
${SUDO} systemctl -l status "$i" >> "$DEBUG_LOG"
done done
echo >> ${DEBUG_LOG} log_write ""
} }
function debugLighttpd { debugLighttpd() {
echo "::: Writing lighttpd to debug log..." echo "::: Checking for necessary lighttpd files."
echo "#######################################" >> ${DEBUG_LOG} files_check "${LIGHTTPDFILE}"
echo "############ lighttpd.conf ############" >> ${DEBUG_LOG} files_check "${LIGHTTPDERRFILE}"
echo "#######################################" >> ${DEBUG_LOG} echo ":::"
if [ -e "$LIGHTTPDFILE" ]
then
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
if [ -e "$LIGHTTPDERRFILE" ]
then
echo "#######################################" >> ${DEBUG_LOG}
echo "######### lighttpd error.log ##########" >> ${DEBUG_LOG}
echo "#######################################" >> ${DEBUG_LOG}
cat "$LIGHTTPDERRFILE" >> ${DEBUG_LOG}
else
echo "No lighttpd error.log file found!" >> ${DEBUG_LOG}
printf ":::\tNo lighttpd error.log file found\n"
fi
echo >> ${DEBUG_LOG}
} }
### END FUNCTIONS ### ### END FUNCTIONS ###
version_check # Gather version of required packages / repositories
distro_check version_check || echo "REQUIRED FILES MISSING"
# Check for newer setupVars storage file
source_file "/etc/pihole/setupVars.conf"
# Gather information about the running distribution
distro_check || echo "Distro Check soft fail"
# Gather processor type
processor_check || echo "Processor Check soft fail"
ip_check ip_check
hostnameCheck
portCheck daemon_check lighttpd http
daemon_check dnsmasq domain
checkProcesses checkProcesses
testResolver testResolver
debugLighttpd debugLighttpd
echo "::: Writing dnsmasq.conf to debug log..." files_check "${DNSMASQFILE}"
echo "#######################################" >> ${DEBUG_LOG} files_check "${DNSMASQCONFFILE}"
echo "############### Dnsmasq ###############" >> ${DEBUG_LOG} files_check "${WHITELISTFILE}"
echo "#######################################" >> ${DEBUG_LOG} files_check "${BLACKLISTFILE}"
if [ -e "$DNSMASQFILE" ] files_check "${ADLISTFILE}"
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
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 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
### Pi-hole application specific logging ### header_write "Analyzing gravity.list"
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
while read -r line; do
if [ ! -z "$line" ]; then
[[ "$line" =~ ^#.*$ ]] && continue
echo "$line" >> ${DEBUG_LOG}
fi
done < "$ADLISTSFILE"
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
gravity_length=$(wc -l "${GRAVITYFILE}") \
&& log_write "${GRAVITYFILE} is ${gravity_length} lines long." \
|| log_echo "Warning: No gravity.list file found!"
# Continuously append the pihole.log file to the pihole_debug.log file # Continuously append the pihole.log file to the pihole_debug.log file
function dumpPiHoleLog { dumpPiHoleLog() {
trap '{ echo -e "\n::: Finishing debug write from interrupt... Quitting!" ; exit 1; }' INT trap '{ echo -e "\n::: Finishing debug write from interrupt... Quitting!" ; exit 1; }' INT
echo -e "::: Writing current Pi-hole 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 "::: "
echo "#######################################" >> ${DEBUG_LOG} echo "::: --= User Action Required =--"
echo "############# pihole.log ##############" >> ${DEBUG_LOG} echo -e "::: Try loading a site that you are having trouble with now from a client web browser.. \n:::\t(Press CTRL+C to finish logging.)"
echo "#######################################" >> ${DEBUG_LOG} header_write "pihole.log"
if [ -e "$PIHOLELOG" ] if [ -e "${PIHOLELOG}" ]; then
then
while true; do while true; do
tail -f "$PIHOLELOG" >> ${DEBUG_LOG} tail -f "${PIHOLELOG}" >> ${DEBUG_LOG}
echo >> ${DEBUG_LOG} log_write ""
done done
else else
echo "No pihole.log file found!" >> ${DEBUG_LOG} log_write "No pihole.log file found!"
printf ":::\tNo pihole.log file found!\n" printf ":::\tNo pihole.log file found!\n"
fi fi
} }
# Anything to be done after capturing of pihole.log terminates # Anything to be done after capturing of pihole.log terminates
function finalWork { finalWork() {
echo "::: Finshed debugging!" local tricorder
echo "::: The debug log can be uploaded to Termbin.com for easier sharing." echo "::: Finshed debugging!"
read -r -p "::: Would you like to upload the log? [y/N] " response echo "::: The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
case ${response} in read -r -p "::: Would you like to upload the log? [y/N] " response
[yY][eE][sS]|[yY]) case ${response} in
TERMBIN=$(cat /var/log/pihole_debug.log | nc termbin.com 9999) [yY][eE][sS]|[yY])
;; tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
*) ;;
echo "::: Log will NOT be uploaded to Termbin." *)
;; echo "::: Log will NOT be uploaded to tricorder."
esac ;;
esac
# Check if termbin.com is reachable. When it's not, point to local log instead # Check if tricorder.pi-hole.net is reachable and provide token.
if [ -n "$TERMBIN" ] if [ -n "${tricorder}" ]; then
then echo "::: Your debug token is : ${tricorder}"
echo "::: Debug log can be found at : $TERMBIN" echo "::: Please contact the Pi-hole team with your token to being assistance."
else echo "::: Thank you."
echo "::: Debug log can be found at : /var/log/pihole_debug.log" fi
fi echo "::: Debug log can be found at : /var/log/pihole_debug.log"
} }
trap finalWork EXIT trap finalWork EXIT

View File

@ -15,28 +15,28 @@
# Borrowed from adafruit-pitft-helper < borrowed from raspi-config # Borrowed from adafruit-pitft-helper < borrowed from raspi-config
# https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L324-L334 # https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L324-L334
getInitSys() { getInitSys() {
if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
SYSTEMD=1 SYSTEMD=1
elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
SYSTEMD=0 SYSTEMD=0
else else
echo "Unrecognised init system" echo "Unrecognised init system"
return 1 return 1
fi fi
} }
# Borrowed from adafruit-pitft-helper: # Borrowed from adafruit-pitft-helper:
# https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L274-L285 # https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L274-L285
autoLoginPiToConsole() { autoLoginPiToConsole() {
if [ -e /etc/init.d/lightdm ]; then if [ -e /etc/init.d/lightdm ]; then
if [ ${SYSTEMD} -eq 1 ]; then if [ ${SYSTEMD} -eq 1 ]; then
systemctl set-default multi-user.target systemctl set-default multi-user.target
ln -fs /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/getty@tty1.service ln -fs /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/getty@tty1.service
else else
update-rc.d lightdm disable 2 update-rc.d lightdm disable 2
sed /etc/inittab -i -e "s/1:2345:respawn:\/sbin\/getty --noclear 38400 tty1/1:2345:respawn:\/bin\/login -f pi tty1 <\/dev\/tty1 >\/dev\/tty1 2>&1/" sed /etc/inittab -i -e "s/1:2345:respawn:\/sbin\/getty --noclear 38400 tty1/1:2345:respawn:\/bin\/login -f pi tty1 <\/dev\/tty1 >\/dev\/tty1 2>&1/"
fi fi
fi fi
} }
######### SCRIPT ########### ######### SCRIPT ###########

142
advanced/Scripts/update.sh Normal file
View File

@ -0,0 +1,142 @@
#!/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
# Whitelists domains
#
# 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.
# Variables
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
webInterfaceDir="/var/www/html/admin"
piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
piholeFilesDir="/etc/.pihole"
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"
}
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
echo ":::"
echo "::: Checking for existing repository..."
if is_repo "${1}"; then
update_repo "${1}"
else
make_repo "${1}" "${2}"
fi
}
is_repo() {
# Use git to check if directory is currently under VCS
echo -n "::: Checking $1 is a repo..."
cd "${1}" &> /dev/null || return 1
git status &> /dev/null && echo " OK!"; return 0 || echo " not found!"; return 1
}
make_repo() {
# Remove the non-repod interface and clone the interface
echo -n "::: Cloning $2 into $1..."
rm -rf "${1}"
git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
echo " done!"
}
update_repo() {
# Pull the latest commits
echo -n "::: Updating repo in $1..."
cd "${1}" || exit 1
git stash -q > /dev/null & spinner $!
git pull -q > /dev/null & spinner $!
echo " done!"
}
if [ ! -d "/etc/.pihole" ]; then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
fi
if [ ! -d "/var/www/html/admin" ]; then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
fi
echo "::: Checking for updates..."
piholeVersion=$(pihole -v -p -c)
piholeVersionLatest=$(pihole -v -p -l)
webVersion=$(pihole -v -a -c)
webVersionLatest=$(pihole -v -a -l)
echo ":::"
echo "::: Pi-hole version is $piholeVersion (Latest version is $piholeVersionLatest)"
echo "::: Web Admin version is $webVersion (Latest version is $webVersionLatest)"
echo ":::"
# Logic
# If latest versions are blank - we've probably hit Github rate limit (stop running `pihole -up so often!):
# Update anyway
# If Core up to date AND web up to date:
# Do nothing
# If Core up to date AND web NOT up to date:
# Pull web repo
# If Core NOT up to date AND web up to date:
# pull pihole repo, run install --unattended -- reconfigure
# if Core NOT up to date AND web NOT up to date:
# pull pihole repo run install --unattended
if [[ ${piholeVersion} == ${piholeVersionLatest} && ${webVersion} == ${webVersionLatest} ]]; then
echo "::: Everything is up to date!"
echo ""
exit 0
elif [[ ${piholeVersion} == ${piholeVersionLatest} && ${webVersion} != ${webVersionLatest} ]]; then
echo "::: Pi-hole Web Admin files out of date"
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
echo ":::"
webVersion=$(pihole -v -a -c)
echo "::: Web Admin version is now at ${webVersion}"
echo "::: If you had made any changes in '/var/www/html/admin', they have been stashed using 'git stash'"
echo ""
elif [[ ${piholeVersion} != ${piholeVersionLatest} && ${webVersion} == ${webVersionLatest} ]]; then
echo "::: Pi-hole core files out of date"
getGitFiles ${piholeFilesDir} ${piholeGitUrl}
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended
echo ":::"
piholeVersion=$(pihole -v -p -c)
echo "::: Pi-hole version is now at ${piholeVersion}"
echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
echo ""
elif [[ ${piholeVersion} != ${piholeVersionLatest} && ${webVersion} != ${webVersionLatest} ]]; then
echo "::: Updating Everything"
getGitFiles ${piholeFilesDir} ${piholeGitUrl}
/etc/.pihole/automated\ install/basic-install.sh --unattended
webVersion=$(pihole -v -a -c)
piholeVersion=$(pihole -v -p -c)
echo ":::"
echo "::: Pi-hole version is now at ${piholeVersion}"
echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
echo ":::"
echo "::: Pi-hole version is now at ${piholeVersion}"
echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
echo ""
fi

View File

@ -3,18 +3,98 @@
# (c) 2015, 2016 by Jacob Salmela # (c) 2015, 2016 by Jacob Salmela
# Network-wide ad blocking via your Raspberry Pi # Network-wide ad blocking via your Raspberry Pi
# http://pi-hole.net # http://pi-hole.net
# Whitelists domains # shows version numbers
# #
# Pi-hole is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
# 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.
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0) # Flags:
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0) latest=false
current=false
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//') normalOutput() {
webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//') piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0)
echo "::: Pi-hole version is $piholeVersion (Latest version is $piholeVersionLatest)" piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
echo "::: Web-Admin version is $webVersion (Latest version is $webVersionLatest)" webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
echo "::: Pi-hole version is ${piholeVersion} (Latest version is ${piholeVersionLatest})"
echo "::: Web-Admin version is ${webVersion} (Latest version is ${webVersionLatest})"
}
webOutput() {
for var in "$@"; do
case "${var}" in
"-l" | "--latest" ) latest=true;;
"-c" | "--current" ) current=true;;
* ) echo "::: Invalid Option!"; exit 1;
esac
done
if [[ "${latest}" == true && "${current}" == false ]]; then
webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
echo ${webVersionLatest}
elif [[ "${latest}" == false && "${current}" == true ]]; then
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0)
echo ${webVersion}
else
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0)
webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
echo "::: Web-Admin version is $webVersion (Latest version is $webVersionLatest)"
fi
}
coreOutput() {
for var in "$@"; do
case "${var}" in
"-l" | "--latest" ) latest=true;;
"-c" | "--current" ) current=true;;
* ) echo "::: Invalid Option!"; exit 1;
esac
done
if [[ "${latest}" == true && "${current}" == false ]]; then
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
echo ${piholeVersionLatest}
elif [[ "${latest}" == false && "${current}" == true ]]; then
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
echo ${piholeVersion}
else
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
echo "::: Pi-hole version is $piholeVersion (Latest version is $piholeVersionLatest)"
fi
}
helpFunc() {
cat << EOM
:::
::: Show Pi-hole/Web Admin versions
:::
::: Usage: pihole -v [ -a | -p ] [ -l | -c ]
:::
::: Options:
::: -a, --admin Show both current and latest versions of web admin
::: -p, --pihole Show both current and latest versions of Pi-hole core files
::: -l, --latest (Only after -a | -p) Return only latest version
::: -c, --current (Only after -a | -p) Return only current version
::: -h, --help Show this help dialog
:::
EOM
exit 1
}
if [[ $# = 0 ]]; then
normalOutput
fi
for var in "$@"; do
case "${var}" in
"-a" | "--admin" ) shift; webOutput "$@";;
"-p" | "--pihole" ) shift; coreOutput "$@" ;;
"-h" | "--help" ) helpFunc;;
esac
done

View File

@ -1,248 +0,0 @@
#!/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
# Whitelists domains
#
# 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.
helpFunc()
{
echo "::: Immediately whitelists one or more domains in the hosts file"
echo ":::"
echo "::: Usage: pihole -w domain1 [domain2 ...]"
echo ":::"
echo "::: Options:"
echo "::: -d, --delmode Remove domains from the whitelist"
echo "::: -nr, --noreload Update Whitelist without refreshing dnsmasq"
echo "::: -f, --force Force updating of the hosts files, even if there are no changes"
echo "::: -q, --quiet output is less verbose"
echo "::: -h, --help Show this help dialog"
echo "::: -l, --list Display your whitelisted domains"
exit 1
}
if [[ $# = 0 ]]; then
helpFunc
fi
#globals
basename=pihole
piholeDir=/etc/${basename}
adList=${piholeDir}/gravity.list
whitelist=${piholeDir}/whitelist.txt
reload=true
addmode=true
force=false
verbose=true
domList=()
domToRemoveList=()
piholeIPfile=/etc/pihole/piholeIP
piholeIPv6file=/etc/pihole/.useIPv6
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
piholeIP=$(cat ${piholeIPfile})
#rm $piholeIPfile
else
# Otherwise, the IP address can be taken directly from the machine, which will happen when the script is run by the user and not the installation script
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
piholeIPCIDR=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
piholeIP=${piholeIPCIDR%/*}
fi
modifyHost=false
# After setting defaults, check if there's local overrides
if [[ -r ${piholeDir}/pihole.conf ]];then
echo "::: Local calibration requested..."
. ${piholeDir}/pihole.conf
fi
if [[ -f ${piholeIPv6file} ]];then
# If the file exists, then the user previously chose to use IPv6 in the automated installer
piholeIPv6=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
fi
HandleOther(){
#check validity of domain
validDomain=$(echo "$1" | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/')
if [ -z "$validDomain" ]; then
echo "::: $1 is not a valid argument or domain name"
else
domList=("${domList[@]}" ${validDomain})
fi
}
PopWhitelistFile(){
#check whitelist file exists, and if not, create it
if [[ ! -f ${whitelist} ]];then
touch ${whitelist}
fi
for dom in "${domList[@]}"
do
if ${addmode}; then
AddDomain "$dom"
else
RemoveDomain "$dom"
fi
done
}
AddDomain(){
#| sed 's/\./\\./g'
bool=false
grep -Ex -q "$1" ${whitelist} || bool=true
if ${bool}; then
#domain not found in the whitelist file, add it!
if ${verbose}; then
echo -n "::: Adding $1 to $whitelist..."
fi
echo "$1" >> ${whitelist}
modifyHost=true
if ${verbose}; then
echo " done!"
fi
else
if ${verbose}; then
echo "::: $1 already exists in $whitelist, no need to add!"
fi
fi
}
RemoveDomain(){
bool=false
grep -Ex -q "$1" ${whitelist} || bool=true
if ${bool}; then
#Domain is not in the whitelist file, no need to Remove
if ${verbose}; then
echo "::: $1 is NOT whitelisted! No need to remove"
fi
else
#Domain is in the whitelist file, add to a temporary array and remove from whitelist file
#if $verbose; then
#echo "::: Un-whitelisting $dom..."
#fi
domToRemoveList=("${domToRemoveList[@]}" $1)
modifyHost=true
fi
}
ModifyHostFile(){
if ${addmode}; then
#remove domains in from hosts file
if [[ -r ${whitelist} ]];then
# Remove whitelist entries
numberOf=$(cat ${whitelist} | sed '/^\s*$/d' | wc -l)
plural=; [[ "$numberOf" != "1" ]] && plural=s
echo ":::"
echo -n "::: Modifying HOSTS file to whitelist $numberOf domain${plural}..."
awk -F':' '{print $1}' ${whitelist} | while read -r line; do echo "$piholeIP $line"; done > /etc/pihole/whitelist.tmp
awk -F':' '{print $1}' ${whitelist} | while read -r line; do echo "$piholeIPv6 $line"; done >> /etc/pihole/whitelist.tmp
echo "l" >> /etc/pihole/whitelist.tmp
grep -F -x -v -f ${piholeDir}/whitelist.tmp ${adList} > ${piholeDir}/gravity.tmp
rm ${adList}
mv ${piholeDir}/gravity.tmp ${adList}
rm ${piholeDir}/whitelist.tmp
echo " done!"
fi
else
#we need to add the removed domains to the hosts file
echo ":::"
echo "::: Modifying HOSTS file to un-whitelist domains..."
for rdom in "${domToRemoveList[@]}"
do
if grep -q "$rdom" /etc/pihole/*.domains; then
echo "::: AdLists contain $rdom, re-adding block"
if [[ -n ${piholeIPv6} ]];then
echo -n "::: Restoring block for $rdom on IPv4 and IPv6..."
echo "$rdom" | awk -v ipv4addr="$piholeIP" -v ipv6addr="$piholeIPv6" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> ${adList}
echo " done!"
else
echo -n "::: Restoring block for $rdom on IPv4..."
echo "$rdom" | awk -v ipv4addr="$piholeIP" '{sub(/\r$/,""); print ipv4addr" "$0}' >>${adList}
echo " done!"
fi
fi
echo -n "::: Removing $rdom from $whitelist..."
echo "$rdom" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' ${whitelist}
echo " done!"
done
fi
}
Reload() {
# Reload hosts file
echo ":::"
echo -n "::: Refresh lists in dnsmasq..."
dnsmasqPid=$(pidof dnsmasq)
if [[ ${dnsmasqPid} ]]; then
# service already running - reload config
if [ -x "$(command -v systemctl)" ]; then
systemctl restart dnsmasq
else
service dnsmasq restart
fi
else
# service not running, start it up
if [ -x "$(command -v systemctl)" ]; then
systemctl start dnsmasq
else
service dnsmasq start
fi
fi
echo " done!"
}
DisplayWlist() {
verbose=false
echo -e " Displaying Gravity Resistant Domains \n"
count=1
while IFS= read -r RD
do
echo "${count}: $RD"
count=$((count+1))
done < "$whitelist"
}
###################################################
for var in "$@"
do
case "$var" in
"-nr"| "--noreload" ) reload=false;;
"-d" | "--delmode" ) addmode=false;;
"-f" | "--force" ) force=true;;
"-q" | "--quiet" ) verbose=false;;
"-h" | "--help" ) helpFunc;;
"-l" | "--list" ) DisplayWlist;;
* ) HandleOther "$var";;
esac
done
PopWhitelistFile
if ${modifyHost} || ${force}; then
ModifyHostFile
else
if ${verbose}; then
echo ":::"
echo "::: No changes need to be made"
fi
exit 1
fi
if ${reload}; then
Reload
fi

View File

@ -1,12 +1,11 @@
_pihole() _pihole() {
{ local cur prev opts
local cur prev opts COMPREPLY=()
COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}"
cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}"
prev="${COMP_WORDS[COMP_CWORD-1]}" opts="blacklist chronometer debug flush help query reconfigure setupLCD uninstall updateGravity updatePihole version whitelist"
opts="blacklist chronometer debug flush help query reconfigure setupLCD uninstall updateGravity updatePihole version whitelist"
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0 return 0
} }
complete -F _pihole pihole complete -F _pihole pihole

View File

@ -12,6 +12,7 @@
server.modules = ( server.modules = (
"mod_access", "mod_access",
"mod_accesslog", "mod_accesslog",
"mod_auth",
"mod_expire", "mod_expire",
"mod_compress", "mod_compress",
"mod_redirect", "mod_redirect",
@ -52,10 +53,14 @@ $HTTP["url"] =~ "^/admin/" {
) )
} }
# Rewite js requests, must be out of $HTTP block due to bug #2526
url.rewrite = ( "^(?!/admin/).*\.js$" => "pihole/index.js" )
# If the URL does not start with /admin, then it is a query for an ad domain # If the URL does not start with /admin, then it is a query for an ad domain
$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")
} }
# Add user chosen options held in external file
include_shell "cat external.conf 2>/dev/null"

View File

@ -11,6 +11,7 @@
server.modules = ( server.modules = (
"mod_access", "mod_access",
"mod_auth",
"mod_fastcgi", "mod_fastcgi",
"mod_accesslog", "mod_accesslog",
"mod_expire", "mod_expire",
@ -69,10 +70,14 @@ $HTTP["url"] =~ "^/admin/" {
setenv.add-response-header = ( "X-Pi-hole" => "The Pi-hole Web interface is working!" ) setenv.add-response-header = ( "X-Pi-hole" => "The Pi-hole Web interface is working!" )
} }
# Rewite js requests, must be out of $HTTP block due to bug #2526
url.rewrite = ( "^(?!/admin/).*\.js$" => "pihole/index.js" )
# If the URL does not start with /admin, then it is a query for an ad domain # If the URL does not start with /admin, then it is a query for an ad domain
$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")
} }
# Add user chosen options held in external file
include_shell "cat external.conf 2>/dev/null"

View File

@ -8,6 +8,11 @@
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# 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.
#
# This file is under source-control of the Pi-hole installation and update
# scripts, any changes made to this file will be overwritten when the softare
# is updated or re-installed. Please make any changes to the appropriate crontab
# or other cron file snippets.
# 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 adlists # Download any updates from the adlists
@ -16,10 +21,6 @@
# Pi-hole: Update Pi-hole! Uncomment to enable auto update # Pi-hole: Update Pi-hole! Uncomment to enable auto update
#30 2 * * 7 root /usr/local/bin/pihole updatePihole #30 2 * * 7 root /usr/local/bin/pihole updatePihole
# Pi-hole: Parse the log file before it is flushed and save the stats to a database
# This will be used for a historical view of your Pi-hole's performance
#50 23 * * * root /usr/local/bin/dailyLog.sh # note: this is outdated
# Pi-hole: Flush the log daily at 00:00 so it doesn't get out of control # Pi-hole: Flush the log daily at 00:00 so it doesn't get out of control
# Stats will be viewable in the Web interface thanks to the cron job above # Stats will be viewable in the Web interface thanks to the cron job above
00 00 * * * root /usr/local/bin/pihole flush 00 00 * * * root /usr/local/bin/pihole flush

File diff suppressed because it is too large Load Diff

View File

@ -11,29 +11,29 @@
# (at your option) any later version. # (at your option) any later version.
# 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 uninstall." 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 [ -x "$(command -v sudo)" ];then if [ -x "$(command -v 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
# Compatability # Compatability
if [ -x "$(command -v rpm)" ];then if [ -x "$(command -v rpm)" ]; then
# Fedora Family # Fedora Family
if [ -x "$(command -v dnf)" ];then if [ -x "$(command -v dnf)" ]; then
PKG_MANAGER="dnf" PKG_MANAGER="dnf"
else else
PKG_MANAGER="yum" PKG_MANAGER="yum"
fi fi
PKG_REMOVE="$PKG_MANAGER remove -y" PKG_REMOVE="${PKG_MANAGER} remove -y"
PIHOLE_DEPS=( bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common git curl unzip wget findutils ) PIHOLE_DEPS=( bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common git curl unzip wget findutils )
package_check() { package_check() {
rpm -qa | grep ^$1- > /dev/null rpm -qa | grep ^$1- > /dev/null
@ -41,10 +41,10 @@ if [ -x "$(command -v rpm)" ];then
package_cleanup() { package_cleanup() {
${SUDO} ${PKG_MANAGER} -y autoremove ${SUDO} ${PKG_MANAGER} -y autoremove
} }
elif [ -x "$(command -v apt-get)" ];then elif [ -x "$(command -v apt-get)" ]; then
# Debian Family # Debian Family
PKG_MANAGER="apt-get" PKG_MANAGER="apt-get"
PKG_REMOVE="$PKG_MANAGER -y remove --purge" PKG_REMOVE="${PKG_MANAGER} -y remove --purge"
PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd php5-common git curl unzip wget ) PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd php5-common git curl unzip wget )
package_check() { package_check() {
dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -c "ok installed" dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -c "ok installed"
@ -58,37 +58,36 @@ else
exit exit
fi fi
spinner() spinner() {
{ local pid=$1
local pid=$1 local delay=0.50
local delay=0.50 local spinstr='/-\|'
local spinstr='/-\|' while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do local temp=${spinstr#?}
local temp=${spinstr#?} printf " [%c] " "${spinstr}"
printf " [%c] " "$spinstr" local spinstr=${temp}${spinstr%"$temp}"}
local spinstr=${temp}${spinstr%"$temp"} sleep ${delay}
sleep ${delay} printf "\b\b\b\b\b\b"
printf "\b\b\b\b\b\b" done
done printf " \b\b\b\b"
printf " \b\b\b\b"
} }
function removeAndPurge { removeAndPurge() {
# Purge dependencies # Purge dependencies
echo ":::" echo ":::"
for i in "${PIHOLE_DEPS[@]}"; do for i in "${PIHOLE_DEPS[@]}"; do
package_check ${i} > /dev/null package_check ${i} > /dev/null
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
while true; do while true; do
read -rp "::: Do you wish to remove $i from your system? [y/n]: " yn read -rp "::: Do you wish to remove ${i} from your system? [y/n]: " yn
case ${yn} in case ${yn} in
[Yy]* ) printf ":::\tRemoving %s..." "$i"; ${SUDO} ${PKG_REMOVE} "$i" &> /dev/null & spinner $!; printf "done!\n"; break;; [Yy]* ) printf ":::\tRemoving %s..." "${i}"; ${SUDO} ${PKG_REMOVE} "${i}" &> /dev/null & spinner $!; printf "done!\n"; break;;
[Nn]* ) printf ":::\tSkipping %s" "$i\n"; break;; [Nn]* ) printf ":::\tSkipping %s" "${i}\n"; break;;
* ) printf "::: You must answer yes or no!\n";; * ) printf "::: You must answer yes or no!\n";;
esac esac
done done
else else
printf ":::\tPackage %s not installed... Not removing.\n" "$i" printf ":::\tPackage %s not installed... Not removing.\n" "${i}"
fi fi
done done
@ -104,7 +103,7 @@ echo ":::"
removeNoPurge removeNoPurge
} }
function removeNoPurge { removeNoPurge() {
echo ":::" echo ":::"
# Only web directories/files that are created by pihole should be removed. # Only web directories/files that are created by pihole should be removed.
echo "::: Removing the Pi-hole Web server files..." echo "::: Removing the Pi-hole Web server files..."

View File

@ -13,36 +13,38 @@
# Run this script as root or under sudo # Run this script as root or under sudo
echo ":::" echo ":::"
helpFunc() helpFunc() {
{ cat << EOM
echo "::: Pull in domains from adlists" ::: Pull in domains from adlists
echo ":::" :::
echo "::: Usage: pihole -g" ::: Usage: pihole -g
echo ":::" :::
echo "::: Options:" ::: Options:
echo "::: -f, --force Force lists to be downloaded, even if they don't need updating." ::: -f, --force Force lists to be downloaded, even if they don't need updating.
echo "::: -h, --help Show this help dialog" ::: -h, --help Show this help dialog
EOM
exit 1 exit 1
} }
adListFile=/etc/pihole/adlists.list adListFile=/etc/pihole/adlists.list
adListDefault=/etc/pihole/adlists.default adListDefault=/etc/pihole/adlists.default
whitelistScript=/opt/pihole/whitelist.sh whitelistScript="pihole -w"
blacklistScript=/opt/pihole/blacklist.sh whitelistFile=/etc/pihole/whitelist.txt
blacklistFile=/etc/pihole/blacklist.txt
#Source the setupVars from install script for the IP #Source the setupVars from install script for the IP
setupVars=/etc/pihole/setupVars.conf setupVars=/etc/pihole/setupVars.conf
if [[ -f ${setupVars} ]];then if [[ -f ${setupVars} ]];then
. /etc/pihole/setupVars.conf . /etc/pihole/setupVars.conf
else else
echo "::: WARNING: /etc/pihole/setupVars.conf missing. Possible installation failure." echo "::: WARNING: /etc/pihole/setupVars.conf missing. Possible installation failure."
echo "::: Please run 'pihole -r', and choose the 'reconfigure' option to reconfigure." echo "::: Please run 'pihole -r', and choose the 'reconfigure' option to reconfigure."
exit 1 exit 1
fi fi
#Remove the /* from the end of the IPv4addr. #Remove the /* from the end of the IPv4addr.
IPv4addr=${IPv4_address%/*} IPv4_address=${IPv4_address%/*}
# Variables for various stages of downloading and formatting the list # Variables for various stages of downloading and formatting the list
basename=pihole basename=pihole
@ -51,12 +53,15 @@ adList=${piholeDir}/gravity.list
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 preEventHorizon=list.preEventHorizon
eventHorizon=${basename}.2.supernova.txt
accretionDisc=${basename}.3.accretionDisc.txt accretionDisc=${basename}.3.accretionDisc.txt
skipDownload=false
# Warn users still using pihole.conf that it no longer has any effect (I imagine about 2 people use it) # Warn users still using pihole.conf that it no longer has any effect (I imagine about 2 people use it)
if [[ -r ${piholeDir}/pihole.conf ]];then if [[ -r ${piholeDir}/pihole.conf ]]; then
echo "::: pihole.conf file no longer supported. Over-rides in this file are ignored." echo "::: pihole.conf file no longer supported. Over-rides in this file are ignored."
fi fi
########################### ###########################
@ -92,31 +97,17 @@ gravity_collapse() {
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
if [[ -d ${piholeDir} ]];then
# Temporary hack to allow non-root access to pihole directory
# Will update later, needed for existing installs, new installs should
# create this directory as non-root
chmod 777 ${piholeDir}
echo ":::"
echo "::: Existing pihole directory found"
else
echo "::: Creating pihole directory..."
mkdir ${piholeDir}
chmod 777 ${piholeDir}
fi
} }
# patternCheck - check to see if curl downloaded any new files. # patternCheck - check to see if curl downloaded any new files.
gravity_patternCheck() { gravity_patternCheck() {
patternBuffer=$1 patternBuffer=$1
# check if the patternbuffer is a non-zero length file # check if the patternbuffer is a non-zero length file
if [[ -s "$patternBuffer" ]];then if [[ -s "${patternBuffer}" ]]; then
# 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" mv "${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
@ -135,51 +126,49 @@ gravity_transport() {
heisenbergCompensator="" heisenbergCompensator=""
if [[ -r ${saveLocation} ]]; then if [[ -r ${saveLocation} ]]; then
# if domain has been saved, add file for date check to only download newer # if domain has been saved, add file for date check to only download newer
heisenbergCompensator="-z $saveLocation" heisenbergCompensator="-z ${saveLocation}"
fi fi
# Silently curl url # Silently curl url
curl -s -L ${cmd_ext} ${heisenbergCompensator} -A "$agent" ${url} > ${patternBuffer} curl -s -L ${cmd_ext} ${heisenbergCompensator} -A "${agent}" ${url} > ${patternBuffer}
# Check for list updates # Check for list updates
gravity_patternCheck "$patternBuffer" gravity_patternCheck "${patternBuffer}"
# Cleanup
rm -f "$patternBuffer"
} }
# spinup - main gravity function # spinup - main gravity function
gravity_spinup() { 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 url=${sources[$i]}
url=${sources[$i]} # Get just the domain from the URL
# Get just the domain from the URL domain=$(echo "${url}" | cut -d'/' -f3)
domain=$(echo "$url" | cut -d'/' -f3)
# Save the file as list.#.domain # Save the file as list.#.domain
saveLocation=${piholeDir}/list.${i}.${domain}.${justDomainsExtension} saveLocation=${piholeDir}/list.${i}.${domain}.${justDomainsExtension}
activeDomains[$i]=${saveLocation} activeDomains[$i]=${saveLocation}
agent="Mozilla/10.0" agent="Mozilla/10.0"
echo -n "::: Getting $domain list..." # Use a case statement to download lists that need special cURL commands
# to complete properly and reset the user agent when required
case "${domain}" in
"adblock.mahakala.is")
agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'
cmd_ext="-e http://forum.xda-developers.com/"
;;
# Use a case statement to download lists that need special cURL commands "pgl.yoyo.org")
# to complete properly and reset the user agent when required cmd_ext="-d mimetype=plaintext -d hostformat=hosts"
case "$domain" in ;;
"adblock.mahakala.is")
agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'
cmd_ext="-e http://forum.xda-developers.com/"
;;
"pgl.yoyo.org")
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" if [[ "${skipDownload}" == false ]]; then
echo -n "::: Getting $domain list..."
gravity_transport "$url" "$cmd_ext" "$agent"
fi
done done
} }
@ -189,74 +178,89 @@ gravity_Schwarzchild() {
# 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} truncate -s 0 ${piholeDir}/${matterAndLight}
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!"
} }
gravity_Blacklist(){ gravity_Blacklist() {
# Append blacklist entries if they exist # Append blacklist entries to eventHorizon if they exist
echo -n "::: Running blacklist script to update HOSTS file...." if [[ -f "${blacklistFile}" ]]; then
${blacklistScript} -f -nr -q > /dev/null numBlacklisted=$(wc -l < "${blacklistFile}")
plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
echo -n "::: BlackListing $numBlacklisted domain${plural}..."
cat ${blacklistFile} >> ${piholeDir}/${eventHorizon}
echo " done!"
else
echo "::: Nothing to blacklist!"
fi
numBlacklisted=$(wc -l < "/etc/pihole/blacklist.txt")
plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
echo " $numBlacklisted domain${plural} blacklisted!"
} }
gravity_Whitelist() { gravity_Whitelist() {
#${piholeDir}/${eventHorizon})
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[@]} adlist source${plural} to the whitelist..." echo -n "::: Adding 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...." # Ensure adlist domains are in whitelist.txt
${whitelistScript} -f -nr -q "${urls[@]}" > /dev/null ${whitelistScript} -nr -q "${urls[@]}" > /dev/null
numWhitelisted=$(wc -l < "/etc/pihole/whitelist.txt")
plural=; [[ "$numWhitelisted" != "1" ]] && plural=s # Check whitelist.txt exists.
echo " $numWhitelisted domain${plural} whitelisted!" if [[ -f "${whitelistFile}" ]]; then
# Remove anything in whitelist.txt from the Event Horizon
numWhitelisted=$(wc -l < "${whitelistFile}")
plural=; [[ "$numWhitelisted" != "1" ]] && plural=s
echo -n "::: Whitelisting $numWhitelisted domain${plural}..."
#print everything from preEventHorizon into eventHorizon EXCEPT domains in whitelist.txt
grep -F -x -v -f ${whitelistFile} ${piholeDir}/${preEventHorizon} > ${piholeDir}/${eventHorizon}
echo " done!"
else
echo "::: Nothing to whitelist!"
fi
} }
gravity_unique() { gravity_unique() {
# Sort and remove duplicates # Sort and remove duplicates
echo -n "::: Removing duplicate domains...." echo -n "::: Removing duplicate domains...."
sort -u ${piholeDir}/${supernova} > ${piholeDir}/${eventHorizon} sort -u ${piholeDir}/${supernova} > ${piholeDir}/${preEventHorizon}
echo " done!" echo " done!"
numberOf=$(wc -l < ${piholeDir}/${eventHorizon}) numberOf=$(wc -l < ${piholeDir}/${preEventHorizon})
echo "::: $numberOf unique domains trapped in the event horizon." echo "::: $numberOf unique domains trapped in the event horizon."
} }
gravity_hostFormat() { 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 [[ -f /etc/hostname ]]; then # Check vars from setupVars.conf to see if we're using IPv4, IPv6, Or both.
hostname=$(</etc/hostname) if [[ -n "${IPv4_address}" && -n "${IPv6_address}" ]];then
elif [ -x "$(command -v hostname)" ]; then
hostname=$(hostname -f) # Both IPv4 and IPv6
else cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPv4_address" -v ipv6addr="$IPv6_address" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
echo "::: Error: Unable to determine fully qualified domain name of host"
fi elif [[ -n "${IPv4_address}" && -z "${IPv6_address}" ]];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
if [[ -n "${IPv6_address}" ]];then # Only IPv4
# Add hostname and dummy domain to the top of gravity.list to make ping result return a friendlier looking domain! Also allows for an easy way to access the Pi-hole admin console (pi.hole/admin) cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPv4_address" '{sub(/\r$/,""); print ipv4addr" "$0}' >> ${piholeDir}/${accretionDisc}
echo -e "$IPv4addr $hostname\n$IPv6_address $hostname\n$IPv4addr pi.hole\n$IPv6_address pi.hole" > ${piholeDir}/${accretionDisc}
cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPv4addr" -v ipv6addr="$IPv6_address" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc} elif [[ -z "${IPv4_address}" && -n "${IPv6_address}" ]];then
else
# Otherwise, just create gravity.list as normal using IPv4 # Only IPv6
# 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 ipv6addr="$IPv6_address" '{sub(/\r$/,""); print ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
echo -e "$IPv4addr $hostname\n$IPv4addr pi.hole" > ${piholeDir}/${accretionDisc}
cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPv4addr" '{sub(/\r$/,""); print ipv4addr" "$0}' >> ${piholeDir}/${accretionDisc} elif [[ -z "${IPv4_address}" && -z "${IPv6_address}" ]];then
fi echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
exit 1
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}
@ -265,13 +269,12 @@ gravity_hostFormat() {
# blackbody - remove any remnant files from script processes # blackbody - remove any remnant files from script processes
gravity_blackbody() { gravity_blackbody() {
# Loop through list files # Loop through list files
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
} }
@ -289,7 +292,7 @@ gravity_advanced() {
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
} }
@ -303,44 +306,26 @@ gravity_reload() {
# Reload hosts file # Reload hosts file
echo ":::" echo ":::"
echo -n "::: Refresh lists in dnsmasq..." echo "::: Refresh lists in dnsmasq..."
#ensure /etc/dnsmasq.d/01-pihole.conf is pointing at the correct list! #ensure /etc/dnsmasq.d/01-pihole.conf is pointing at the correct list!
#First escape forward slashes in the path: #First escape forward slashes in the path:
adList=${adList//\//\\\/} adList=${adList//\//\\\/}
#Now replace the line in dnsmasq file #Now replace the line in dnsmasq file
sed -i "s/^addn-hosts.*/addn-hosts=$adList/" /etc/dnsmasq.d/01-pihole.conf # sed -i "s/^addn-hosts.*/addn-hosts=$adList/" /etc/dnsmasq.d/01-pihole.conf
find "$piholeDir" -type f -exec chmod 666 {} \;
dnsmasqPid=$(pidof dnsmasq) pihole restartdns
if [[ ${dnsmasqPid} ]]; then
# service already running - reload config
if [ -x "$(command -v systemctl)" ]; then
systemctl restart dnsmasq
else
service dnsmasq restart
fi
else
# service not running, start it up
if [ -x "$(command -v systemctl)" ]; then
systemctl start dnsmasq
else
service dnsmasq start
fi
fi
} }
for var in "$@"; do
for var in "$@" case "${var}" in
do "-f" | "--force" ) forceGrav=true;;
case "$var" in "-h" | "--help" ) helpFunc;;
"-f" | "--force" ) forceGrav=true;; "-sd" | "--skip-download" ) skipDownload=true;;
"-h" | "--help" ) helpFunc;; esac
esac
done done
if [[ ${forceGrav} == true ]]; then if [[ "${forceGrav}" == true ]]; then
echo -n "::: Deleting exising list cache..." echo -n "::: Deleting exising list cache..."
rm /etc/pihole/list.* rm /etc/pihole/list.*
echo " done!" echo " done!"
@ -350,10 +335,19 @@ fi
cp /etc/.pihole/adlists.default /etc/pihole/adlists.default cp /etc/.pihole/adlists.default /etc/pihole/adlists.default
gravity_collapse gravity_collapse
gravity_spinup gravity_spinup
gravity_Schwarzchild if [[ "${skipDownload}" == false ]]; then
gravity_advanced gravity_Schwarzchild
gravity_hostFormat gravity_advanced
gravity_blackbody else
echo "::: Using cached Event Horizon list..."
numberOf=$(wc -l < ${piholeDir}/${preEventHorizon})
echo "::: $numberOf unique domains trapped in the event horizon."
fi
gravity_Whitelist gravity_Whitelist
gravity_Blacklist gravity_Blacklist
gravity_hostFormat
gravity_blackbody
gravity_reload gravity_reload
pihole status

289
pihole
View File

@ -12,193 +12,198 @@
# Must be root to use this tool # Must be root to use this tool
if [[ ! $EUID -eq 0 ]];then if [[ ! $EUID -eq 0 ]];then
if [ -x "$(command -v sudo)" ];then if [ -x "$(command -v sudo)" ];then
echo "::: Elevating to root with sudo" exec sudo bash "$0" "$@"
exec sudo bash "$0" "$@" exit $?
exit $? else
else echo "::: sudo is needed to run pihole commands. Please run this script as root or install sudo."
echo "::: sudo is needed to run pihole commands. Please run this script as root or install sudo." exit 1
exit 1 fi
fi
fi fi
whitelistFunc() { whitelistFunc() {
shift /opt/pihole/list.sh "$@"
/opt/pihole/whitelist.sh "$@" exit 0
exit 0
} }
blacklistFunc() { blacklistFunc() {
shift /opt/pihole/list.sh "$@"
/opt/pihole/blacklist.sh "$@" exit 0
exit 0
} }
debugFunc() { debugFunc() {
/opt/pihole/piholeDebug.sh /opt/pihole/piholeDebug.sh
exit 0 exit 0
} }
flushFunc() { flushFunc() {
/opt/pihole/piholeLogFlush.sh /opt/pihole/piholeLogFlush.sh
exit 0 exit 0
} }
updatePiholeFunc() { updatePiholeFunc() {
/opt/pihole/update.sh
if [ ! -d "/etc/.pihole" ]; then #This is unlikely exit 0
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
fi
if [ ! -d "/var/www/html/admin" ]; then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
fi
echo "::: Checking for updates..."
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0)
webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
echo "::: Pi-hole version is $piholeVersion (Latest version is $piholeVersionLatest)"
echo "::: Web Admin version is $webVersion (Latest version is $webVersionLatest)"
echo ":::"
if [[ ${piholeVersion} == ${piholeVersionLatest} ]] ; then
echo "::: Pi-hole Base files are already up to date! Version: ${piholeVersionLatest}"
echo "::: No need to update!"
echo ":::"
if [[ ${webVersion} == ${webVersionLatest} ]] ; then
echo "::: Web Admin files are already up to date!"
echo "::: No need to update!"
echo ":::"
else
echo "::: An Update is available for the Web Admin!"
echo ":::"
echo "::: Fetching latest changes from GitHub..."
cd /var/www/html/admin
git pull origin master
echo ":::"
echo "::: Pi-hole Web Admin has been updated to ${webVersion}"
echo "::: See https://changes.pi-hole.net for details"
fi
else
echo -n "::: An update is available for "
if [[ ${webVersion} == ${webVersionLatest} ]] ; then
echo " Pi-Hole!"
else
echo " Pi-Hole base files and the Web Admin. Both will be updated!"
fi
echo "::: Fetching latest changes from GitHub..."
cd /etc/.pihole
git pull origin master
/etc/.pihole/automated\ install/basic-install.sh --unattended
echo ":::"
echo "::: Pi-hole has been updated to version ${piholeVersionLatest}"
if [[ ${webVersion} != ${webVersionLatest} ]] ; then
echo "::: Web Admin has been updated to version ${webVersionLatest}"
fi
echo ":::"
echo "::: See https://changes.pi-hole.net for details"
fi
exit 0
} }
reconfigurePiholeFunc() { reconfigurePiholeFunc() {
/etc/.pihole/automated\ install/basic-install.sh --reconfigure /etc/.pihole/automated\ install/basic-install.sh --reconfigure
exit 0; exit 0;
} }
updateGravityFunc() { updateGravityFunc() {
/opt/pihole/gravity.sh "$@" /opt/pihole/gravity.sh "$@"
exit 0 exit 0
} }
setupLCDFunction() { setupLCDFunction() {
/opt/pihole/setupLCD.sh /opt/pihole/setupLCD.sh
exit 0 exit 0
} }
queryFunc() { queryFunc() {
domain=$2 domain=$2
for list in /etc/pihole/list.* for list in /etc/pihole/list.*; do
do count=$(grep ${domain} $list | wc -l)
count=$(grep ${domain} $list | wc -l) echo "::: ${list} (${count} results)"
echo "::: ${list} (${count} results)" if [[ ${count} > 0 ]]; then
if [[ ${count} > 0 ]]; then grep ${domain} ${list}
grep ${domain} ${list} fi
fi echo ""
echo "" done
done exit 0
exit 0
} }
chronometerFunc() { chronometerFunc() {
shift shift
/opt/pihole/chronometer.sh "$@" /opt/pihole/chronometer.sh "$@"
exit 0 exit 0
} }
uninstallFunc() { uninstallFunc() {
/opt/pihole/uninstall.sh /opt/pihole/uninstall.sh
exit 0 exit 0
} }
versionFunc() { versionFunc() {
/opt/pihole/version.sh shift
exit 0 /opt/pihole/version.sh "$@"
exit 0
} }
restartDNS() {
dnsmasqPid=$(pidof dnsmasq)
if [[ ${dnsmasqPid} ]]; then
# service already running - reload config
if [ -x "$(command -v systemctl)" ]; then
systemctl restart dnsmasq
else
service dnsmasq restart
fi
else
# service not running, start it up
if [ -x "$(command -v systemctl)" ]; then
systemctl start dnsmasq
else
service dnsmasq start
fi
fi
}
piholeEnable() {
if [[ "${1}" == "0" ]] ; then
#Disable Pihole
sed -i 's/^addn-hosts/#addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
echo "::: Blocking has been disabled!"
else
#Enable pihole
echo "::: Blocking has been enabled!"
sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
fi
restartDNS
}
piholeStatus() {
if [[ $(cat /etc/dnsmasq.d/01-pihole.conf | grep "#addn-hosts=/") ]] ; then
#list is commented out
if [[ "${1}" == "web" ]] ; then
echo 0;
else
echo "::: Pi-hole blocking is Disabled";
fi
elif [[ $(cat /etc/dnsmasq.d/01-pihole.conf | grep "addn-hosts=/") ]] ; then
#list set
if [[ "${1}" == "web" ]] ; then
echo 1;
else
echo "::: Pi-hole blocking is Enabled";
fi
else
#addn-host not found
if [[ "${1}" == "web" ]] ; then
echo 99
else
echo "::: No hosts file linked to dnsmasq, adding it in enabled state"
fi
#add addn-host= to dnsmasq
echo "addn-hosts=/etc/pihole/gravity.list" >> /etc/dnsmasq.d/01-pihole.conf
restartDNS
fi
}
helpFunc() { helpFunc() {
echo "::: Control all PiHole specific functions!" cat << EOM
echo ":::" ::: Control all PiHole specific functions!
echo "::: Usage: pihole [options]" :::
echo "::: Add -h after -w (whitelist), -b (blacklist), or -c (chronometer) for more information on usage" ::: Usage: pihole [options]
echo ":::" ::: Add -h after -w (whitelist), -b (blacklist), or -c (chronometer) for more information on usage
echo "::: Options:" :::
echo "::: -w, whitelist Whitelist domains" ::: Options:
echo "::: -b, blacklist Blacklist domains" ::: -w, whitelist Whitelist domains
echo "::: -d, debug Start a debugging session if having trouble" ::: -b, blacklist Blacklist domains
echo "::: -f, flush Flush the pihole.log file" ::: -d, debug Start a debugging session if having trouble
echo "::: -up, updatePihole Update Pi-hole" ::: -f, flush Flush the pihole.log file
echo "::: -g, updateGravity Update the list of ad-serving domains" ::: -up, updatePihole Update Pi-hole
echo "::: -s, setupLCD Automatically configures the Pi to use the 2.8 LCD screen to display stats on it" ::: -g, updateGravity Update the list of ad-serving domains
echo "::: -c, chronometer Calculates stats and displays to an LCD" ::: -s, setupLCD Automatically configures the Pi to use the 2.8 LCD screen to display stats on it
echo "::: -h, help Show this help dialog" ::: -c, chronometer Calculates stats and displays to an LCD
echo "::: -v, version Show current versions" ::: -h, help Show this help dialog
echo "::: -q, query Query the adlists for a specific domain" ::: -v, version Show current versions
echo "::: uninstall Uninstall Pi-Hole from your system :(!" ::: -q, query Query the adlists for a specific domain
exit 0 ::: uninstall Uninstall Pi-Hole from your system :(!
::: status Is Pi-Hole Enabled or Disabled
::: enable Enable Pi-Hole DNS Blocking
::: disable Disable Pi-Hole DNS Blocking
::: restartdns Restart dnsmasq
EOM
exit 1
} }
if [[ $# = 0 ]]; then if [[ $# = 0 ]]; then
helpFunc helpFunc
fi fi
# Handle redirecting to specific functions based on arguments # Handle redirecting to specific functions based on arguments
case "$1" in case "${1}" in
"-w" | "whitelist" ) whitelistFunc "$@";; "-w" | "whitelist" ) whitelistFunc "$@";;
"-b" | "blacklist" ) blacklistFunc "$@";; "-b" | "blacklist" ) blacklistFunc "$@";;
"-d" | "debug" ) debugFunc;; "-d" | "debug" ) debugFunc;;
"-f" | "flush" ) flushFunc;; "-f" | "flush" ) flushFunc;;
"-up" | "updatePihole" ) updatePiholeFunc;; "-up" | "updatePihole" ) updatePiholeFunc;;
"-r" | "reconfigure" ) reconfigurePiholeFunc;; "-r" | "reconfigure" ) reconfigurePiholeFunc;;
"-g" | "updateGravity" ) updateGravityFunc "$@";; "-g" | "updateGravity" ) updateGravityFunc "$@";;
"-s" | "setupLCD" ) setupLCDFunction;; "-s" | "setupLCD" ) setupLCDFunction;;
"-c" | "chronometer" ) chronometerFunc "$@";; "-c" | "chronometer" ) chronometerFunc "$@";;
"-h" | "help" ) helpFunc;; "-h" | "help" ) helpFunc;;
"-v" | "version" ) versionFunc;; "-v" | "version" ) versionFunc "$@";;
"-q" | "query" ) queryFunc "$@";; "-q" | "query" ) queryFunc "$@";;
"uninstall" ) uninstallFunc;; "uninstall" ) uninstallFunc;;
* ) helpFunc;; "enable" ) piholeEnable 1;;
"disable" ) piholeEnable 0;;
"status" ) piholeStatus "$2";;
"restartdns" ) restartDNS;;
* ) helpFunc;;
esac esac