_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]):**
**In raising this issue, I confirm the following (please check boxes, eg [X]) Failure to fill the template will close your issue:**
- [] 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*
- [] 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)).
- [] 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*
- [] 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?:**
- [] 1 (very unfamiliar)
- [] 2
- [] 3
- [] 4
- [] 5
- [] 6
- [] 7
- [] 8
- [] 9
- [] 10 (very familiar)
- [] 1 (very unfamiliar)
- [] 2
- [] 3
- [] 4
- [] 5
- [] 6
- [] 7
- [] 8
- [] 9
- [] 10 (very familiar)
---
**[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`:**
`http://termbin.com/<something>`
_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._
@ -8,17 +8,15 @@ Works on most Debian and CentOS/RHEL based distributions!
1. Install Raspbian
2. Run the command below (downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
If you wish to read over the script before running it, then after the `wget` command, do `nano basic-install.sh` to open a text viewer
If you wish to read over the script before running it, then after the [`wget`](https://linux.die.net/man/1/wget) command, run `nano basic-install.sh` to open the file in a text viewer.
Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](http://pi-hole.net/faq/can-i-set-the-pi-hole-to-be-the-dns-server-at-my-router-so-i-dont-have-to-change-settings-for-my-devices/) and then any device that connects to your network will have ads blocked without any further configuration. Alternatively, you can manually set each device to [use the Raspberry Pi as its DNS server](http://pi-hole.net/faq/how-do-i-use-the-pi-hole-as-my-dns-server/).
@ -34,7 +32,7 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
## Pi-hole Is Free, But Powered By Your Donations
Send a one-time donation or sign up for Optimal.com's service using our link below to provide us with a small portion of the monthly fee.
Send a one-time donation using our link below to provide us with a small portion of the monthly fee.
- [![Join the chat at https://gitter.im/pi-hole/pi-hole](https://badges.gitter.im/pi-hole/pi-hole.svg)](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## Technical Details
The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement. You can also [replace ads with any image you want](http://pi-hole.net/faq/is-it-possible-to-change-the-blank-page-that-takes-place-of-the-ads-to-something-else/) since it is just a simple Webpage taking place of the ads.
#### Other Operating Systems
This script will work for other UNIX-like systems with some slight **modifications**. As long as you can install `dnsmasq` and a Webserver, it should work OK. The automated install is only for a clean install of a Debian family or Fedora based system, such as the Raspberry Pi. If there are other platforms you'd like supported, let us know.
### Gravity
The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)).
The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)). This script is controlled by the `pihole` command. Please run `pihole -h` to see what commands can be run via `pihole`.
## Web Interface
@ -67,13 +70,13 @@ The [Web interface](https://github.com/jacobsalmela/AdminLTE#pi-hole-admin-dashb
### Whitelist and blacklist
Domains can be whitelisted and blacklisted using two pre-installed scripts. See [the wiki page](https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting) for more details ![Whitelist editor in the Web interface](http://i.imgur.com/ogu2ewg.png)
Domains can be whitelisted and blacklisted using either the web interface or the command line. See [the wiki page](https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting) for more details ![Whitelist editor in the Web interface](http://i.imgur.com/ogu2ewg.png)
## API
A basic read-only API can be accessed at `/admin/api.php`. It returns the following JSON:
```json
```json
{
"domains_being_blocked": "136708",
"dns_queries_today": "18108",
@ -119,7 +122,3 @@ You can view [real-time stats](http://pi-hole.net/faq/install-the-real-time-lcd-
- [Pi-hole on Ubuntu](http://www.boyter.org/2015/12/pi-hole-ubuntu-14-04/)
- [Catchpoint: iOS 9 Ad Blocking](http://blog.catchpoint.com/2015/09/14/ad-blocking-apple/)
## Other Operating Systems
This script will work for other UNIX-like systems with some slight **modifications**. As long as you can install `dnsmasq` and a Webserver, it should work OK. The automated install is only for a clean install of a Debian based system, such as the Raspberry Pi.
# 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.
#rootcheck
if[[$EUID -eq 0]];then
echo"::: You are root."
else
echo"::: sudo will be used."
# Check if it is actually installed
# If it isn't, exit because the install cannot complete
if[ -x "$(command -v sudo)"];then
exportSUDO="sudo"
else
echo"::: Please install sudo or run this script as root."
exit1
fi
fi
function 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"
exit1
}
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
function HandleOther(){
#check validity of domain
validDomain=$(echo"$1"| perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/')
if[ -z "$validDomain"];then
echo"::: $1 is not a valid argument or domain name"
else
domList=("${domList[@]}"${validDomain})
fi
}
function PopBlacklistFile(){
#check blacklist file exists, and if not, create it
if[[ ! -f ${blacklist}]];then
touch ${blacklist}
fi
for dom in "${domList[@]}";do
if"$addmode";then
AddDomain "$dom"
else
RemoveDomain "$dom"
fi
done
}
function 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
}
function 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
}
function 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}..."
echo"No adlists.list file found... using adlists.default!" >> ${DEBUG_LOG}
printf":::\tNo adlists.list file found... using adlists.default!\n"
fi
files_check "${DNSMASQFILE}"
files_check "${DNSMASQCONFFILE}"
files_check "${WHITELISTFILE}"
files_check "${BLACKLISTFILE}"
files_check "${ADLISTFILE}"
header_write "Analyzing gravity.list"
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
function dumpPiHoleLog {
dumpPiHoleLog(){
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)"
# 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.
#rootcheck
if[[$EUID -eq 0]];then
echo"::: You are root."
else
echo"::: sudo will be used."
# Check if it is actually installed
# If it isn't, exit because the install cannot complete
if[ -x "$(command -v sudo)"];then
exportSUDO="sudo"
else
echo"::: Please install sudo or run this script as root."
exit1
fi
fi
function 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"
exit1
}
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
function HandleOther(){
#check validity of domain
validDomain=$(echo"$1"| perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/')
if[ -z "$validDomain"];then
echo"::: $1 is not a valid argument or domain name"
else
domList=("${domList[@]}"${validDomain})
fi
}
function 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
}
function AddDomain(){
#| sed 's/\./\\./g'
bool=false
grep -Ex -q "$1"${whitelist}||bool=true
if${bool};then
#domain not found in the whitelist file, add it!
if${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
}
function 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
}
function 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}..."
echo"::: $numberOf unique domains trapped in the event horizon."
}
functiongravity_hostFormat(){
gravity_hostFormat(){
# Format domain list as "192.168.x.x domain.com"
echo"::: Formatting domains into a HOSTS file..."
if[[ -f /etc/hostname ]];then
hostname=$(</etc/hostname)
elif[ -x "$(command -v hostname)"];then
hostname=$(hostname -f)
else
echo"::: Error: Unable to determine fully qualified domain name of host"
fi
# 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
# 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)
# Otherwise, just create gravity.list as normal using IPv4
# Add hostname and dummy domain to the top of gravity.list to make ping result return a friendlier looking domain! Also allows for an easy way to access the Pi-hole admin console (pi.hole/admin)