Merge branch 'development' into wildcardblacklisting

pull/1065/head
DL6ER 8 years ago
commit 2935275227
No known key found for this signature in database
GPG Key ID: BB8EC0BC77973A30

@ -15,8 +15,11 @@
<option name="USE_RELATIVE_INDENTS" value="false" /> <option name="USE_RELATIVE_INDENTS" value="false" />
</value> </value>
</option> </option>
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
</value> </value>
</option> </option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" /> <option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component> </component>
</project> </project>

@ -101,7 +101,7 @@ The [Web interface](https://github.com/pi-hole/AdminLTE#pi-hole-admin-dashboard)
### Whitelist and blacklist ### Whitelist and blacklist
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 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
<p align="center"> <p align="center">
<a href=https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting><img src="https://assets.pi-hole.net/static/controlpanel.png"></a> <a href=https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting><img src="https://assets.pi-hole.net/static/controlpanel.png"></a>
</p> </p>
@ -128,7 +128,7 @@ You can view [real-time stats](http://pi-hole.net/faq/install-the-real-time-lcd-
## Pi-hole Projects ## Pi-hole Projects
- [Pi-hole stats in your Mac's menu bar](https://getbitbar.com/plugins/Network/pi-hole.1m.py) - [Pi-hole stats in your Mac's menu bar](https://getbitbar.com/plugins/Network/pi-hole.1m.py)
- [Get LED alerts for each blocked ad](http://www.stinebaugh.info/get-led-alerts-for-each-blocked-ad-using-pi-hole/) - [Get LED alerts for each blocked ad](http://thetimmy.silvernight.org/pages/endisbutton/)
- [Pi-hole on Ubuntu 14.04 on VirtualBox](http://hbalagtas.blogspot.com/2016/02/adblocking-with-pi-hole-and-ubuntu-1404.html) - [Pi-hole on Ubuntu 14.04 on VirtualBox](http://hbalagtas.blogspot.com/2016/02/adblocking-with-pi-hole-and-ubuntu-1404.html)
- [Docker Pi-hole container (x86 and ARM)](https://hub.docker.com/r/diginc/pi-hole/) - [Docker Pi-hole container (x86 and ARM)](https://hub.docker.com/r/diginc/pi-hole/)
- [Splunk: Pi-hole Visualizser](https://splunkbase.splunk.com/app/3023/) - [Splunk: Pi-hole Visualizser](https://splunkbase.splunk.com/app/3023/)

@ -37,7 +37,7 @@ https://hosts-file.net/ad_servers.txt
#http://securemecca.com/Downloads/hosts.txt #http://securemecca.com/Downloads/hosts.txt
# Quidsup's tracker list # Quidsup's tracker list
https://raw.githubusercontent.com/quidsup/notrack/master/trackers.txt #https://raw.githubusercontent.com/quidsup/notrack/master/trackers.txt
# Block the BBC News website Breaking News banner # 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

@ -91,12 +91,37 @@ GitCheckUpdateAvail() {
# Fetch latest changes in this repo # Fetch latest changes in this repo
git fetch --quiet origin git fetch --quiet origin
status="$(git status -sb)"
# @ alone is a shortcut for HEAD. Older versions of git
# need @{0}
LOCAL="$(git rev-parse @{0})"
# The suffix @{upstream} to a branchname
# (short form <branchname>@{u}) refers
# to the branch that the branch specified
# by branchname is set to build on top of#
# (configured with branch.<name>.remote and
# branch.<name>.merge). A missing branchname
# defaults to the current one.
REMOTE="$(git rev-parse @{upstream})"
# Change back to original directory # Change back to original directory
cd "${curdir}" cd "${curdir}"
if [[ $status == *"behind"* ]]; then if [[ ${#LOCAL} == 0 ]]; then
echo "::: Error: Local revision could not be optained, ask Pi-hole support."
echo "::: Additional debugging output:"
git status
exit
fi
if [[ ${#REMOTE} == 0 ]]; then
echo "::: Error: Remote revision could not be optained, ask Pi-hole support."
echo "::: Additional debugging output:"
git status
exit
fi
if [[ "${LOCAL}" != "${REMOTE}" ]]; then
# Local branch is behind remote branch -> Update # Local branch is behind remote branch -> Update
return 0 return 0
else else

@ -9,7 +9,9 @@
# 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.
args=("$@") readonly setupVars="/etc/pihole/setupVars.conf"
readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf"
readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf"
helpFunc() { helpFunc() {
cat << EOM cat << EOM
@ -27,12 +29,34 @@ EOM
exit 0 exit 0
} }
add_setting() {
echo "${1}=${2}" >> "${setupVars}"
}
delete_setting() {
sed -i "/${1}/d" "${setupVars}"
}
change_setting() {
delete_setting "${1}"
add_setting "${1}" "${2}"
}
add_dnsmasq_setting() {
if [[ "${2}" != "" ]]; then
echo "${1}=${2}" >> "${dnsmasqconfig}"
else
echo "${1}" >> "${dnsmasqconfig}"
fi
}
delete_dnsmasq_setting() {
sed -i "/${1}/d" "${dnsmasqconfig}"
}
SetTemperatureUnit(){ SetTemperatureUnit(){
# Remove setting from file (create backup setupVars.conf.bak) change_setting "TEMPERATUREUNIT" "${unit}"
sed -i.bak '/TEMPERATUREUNIT/d' /etc/pihole/setupVars.conf
# Save setting to file
echo "TEMPERATUREUNIT=${unit}" >> /etc/pihole/setupVars.conf
} }
@ -50,66 +74,70 @@ SetWebPassword(){
exit 1 exit 1
fi fi
# Remove password from file (create backup setupVars.conf.bak)
sed -i.bak '/WEBPASSWORD/d' /etc/pihole/setupVars.conf
# Set password only if there is one to be set # Set password only if there is one to be set
if (( ${#args[2]} > 0 )) ; then if (( ${#args[2]} > 0 )) ; then
# Compute password hash twice to avoid rainbow table vulnerability # Compute password hash twice to avoid rainbow table vulnerability
hash=$(echo -n ${args[2]} | sha256sum | sed 's/\s.*$//') hash=$(echo -n ${args[2]} | sha256sum | sed 's/\s.*$//')
hash=$(echo -n ${hash} | sha256sum | sed 's/\s.*$//') hash=$(echo -n ${hash} | sha256sum | sed 's/\s.*$//')
# Save hash to file # Save hash to file
echo "WEBPASSWORD=${hash}" >> /etc/pihole/setupVars.conf change_setting "WEBPASSWORD" "${hash}"
echo "New password set" echo "New password set"
else else
echo "WEBPASSWORD=" >> /etc/pihole/setupVars.conf change_setting "WEBPASSWORD" ""
echo "Password removed" echo "Password removed"
fi fi
} }
ProcessDNSSettings() {
source "${setupVars}"
delete_dnsmasq_setting "server="
add_dnsmasq_setting "server" "${PIHOLE_DNS_1}"
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
add_dnsmasq_setting "server" "${PIHOLE_DNS_2}"
fi
delete_dnsmasq_setting "domain-needed"
if [[ "${DNS_FQDN_REQUIRED}" == true ]]; then
add_dnsmasq_setting "domain-needed"
fi
delete_dnsmasq_setting "bogus-priv"
if [[ "${DNS_BOGUS_PRIV}" == true ]]; then
add_dnsmasq_setting "bogus-priv"
fi
}
SetDNSServers(){ SetDNSServers(){
# Remove setting from file (create backup setupVars.conf.bak)
sed -i.bak '/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/DNS_FQDN_REQUIRED/d;/DNS_BOGUS_PRIV/d;' /etc/pihole/setupVars.conf
# Save setting to file # Save setting to file
echo "PIHOLE_DNS_1=${args[2]}" >> /etc/pihole/setupVars.conf change_setting "PIHOLE_DNS_1" "${args[2]}"
if [[ "${args[3]}" != "none" ]]; then
echo "PIHOLE_DNS_2=${args[3]}" >> /etc/pihole/setupVars.conf
else
echo "PIHOLE_DNS_2=" >> /etc/pihole/setupVars.conf
fi
# Replace within actual dnsmasq config file
sed -i '/server=/d;' /etc/dnsmasq.d/01-pihole.conf
echo "server=${args[2]}" >> /etc/dnsmasq.d/01-pihole.conf
if [[ "${args[3]}" != "none" ]]; then if [[ "${args[3]}" != "none" ]]; then
echo "server=${args[3]}" >> /etc/dnsmasq.d/01-pihole.conf change_setting "PIHOLE_DNS_2" "${args[3]}"
else
change_setting "PIHOLE_DNS_2" ""
fi fi
# Remove domain-needed entry
sed -i '/domain-needed/d;' /etc/dnsmasq.d/01-pihole.conf
# Readd it if required
if [[ "${args[4]}" == "domain-needed" ]]; then if [[ "${args[4]}" == "domain-needed" ]]; then
echo "domain-needed" >> /etc/dnsmasq.d/01-pihole.conf change_setting "DNS_FQDN_REQUIRED" "true"
echo "DNS_FQDN_REQUIRED=true" >> /etc/pihole/setupVars.conf
else else
# Leave it deleted if not wanted change_setting "DNS_FQDN_REQUIRED" "false"
echo "DNS_FQDN_REQUIRED=false" >> /etc/pihole/setupVars.conf
fi fi
# Remove bogus-priv entry if [[ "${args[4]}" == "bogus-priv" || "${args[5]}" == "bogus-priv" ]]; then
sed -i '/bogus-priv/d;' /etc/dnsmasq.d/01-pihole.conf change_setting "DNS_BOGUS_PRIV" "true"
# Readd it if required
if [[ "${args[5]}" == "bogus-priv" ]]; then
echo "bogus-priv" >> /etc/dnsmasq.d/01-pihole.conf
echo "DNS_BOGUS_PRIV=true" >> /etc/pihole/setupVars.conf
else else
# Leave it deleted if not wanted change_setting "DNS_BOGUS_PRIV" "false"
echo "DNS_BOGUS_PRIV=false" >> /etc/pihole/setupVars.conf
fi fi
ProcessDNSSettings
# Restart dnsmasq to load new configuration # Restart dnsmasq to load new configuration
RestartDNS RestartDNS
@ -117,18 +145,14 @@ SetDNSServers(){
SetExcludeDomains(){ SetExcludeDomains(){
# Remove setting from file (create backup setupVars.conf.bak) change_setting "API_EXCLUDE_DOMAINS" "${args[2]}"
sed -i.bak '/API_EXCLUDE_DOMAINS/d;' /etc/pihole/setupVars.conf
# Save setting to file
echo "API_EXCLUDE_DOMAINS=${args[2]}" >> /etc/pihole/setupVars.conf
} }
SetExcludeClients(){ SetExcludeClients(){
# Remove setting from file (create backup setupVars.conf.bak) change_setting "API_EXCLUDE_CLIENTS" "${args[2]}"
sed -i.bak '/API_EXCLUDE_CLIENTS/d;' /etc/pihole/setupVars.conf
# Save setting to file
echo "API_EXCLUDE_CLIENTS=${args[2]}" >> /etc/pihole/setupVars.conf
} }
Reboot(){ Reboot(){
@ -149,123 +173,152 @@ RestartDNS(){
SetQueryLogOptions(){ SetQueryLogOptions(){
# Remove setting from file (create backup setupVars.conf.bak) change_setting "API_QUERY_LOG_SHOW" "${args[2]}"
sed -i.bak '/API_QUERY_LOG_SHOW/d;' /etc/pihole/setupVars.conf
# Save setting to file
echo "API_QUERY_LOG_SHOW=${args[2]}" >> /etc/pihole/setupVars.conf
} }
EnableDHCP(){ ProcessDHCPSettings() {
# Remove setting from file (create backup setupVars.conf.bak) source "${setupVars}"
sed -i.bak '/DHCP_/d;' /etc/pihole/setupVars.conf
echo "DHCP_ACTIVE=true" >> /etc/pihole/setupVars.conf
echo "DHCP_START=${args[2]}" >> /etc/pihole/setupVars.conf
echo "DHCP_END=${args[3]}" >> /etc/pihole/setupVars.conf
echo "DHCP_ROUTER=${args[4]}" >> /etc/pihole/setupVars.conf
# Remove setting from file if [[ "${DHCP_ACTIVE}" == "true" ]]; then
sed -i '/dhcp-/d;/quiet-dhcp/d;' /etc/dnsmasq.d/01-pihole.conf
# Save setting to file
echo "dhcp-range=${args[2]},${args[3]},infinite" >> /etc/dnsmasq.d/01-pihole.conf
echo "dhcp-option=option:router,${args[4]}" >> /etc/dnsmasq.d/01-pihole.conf
# Changes the behaviour from strict RFC compliance so that DHCP requests on unknown leases from unknown hosts are not ignored. This allows new hosts to get a lease without a tedious timeout under all circumstances. It also allows dnsmasq to rebuild its lease database without each client needing to reacquire a lease, if the database is lost.
echo "dhcp-authoritative" >> /etc/dnsmasq.d/01-pihole.conf
# Use the specified file to store DHCP lease information
echo "dhcp-leasefile=/etc/pihole/dhcp.leases" >> /etc/dnsmasq.d/01-pihole.conf
# Suppress logging of the routine operation of these protocols. Errors and problems will still be logged, though.
echo "quiet-dhcp" >> /etc/dnsmasq.d/01-pihole.conf
echo "quiet-dhcp6" >> /etc/dnsmasq.d/01-pihole.conf
RestartDNS interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//")
}
DisableDHCP(){ # Use eth0 as fallback interface
if [ -z ${interface} ]; then
interface="eth0"
fi
# Remove setting from file (create backup setupVars.conf.bak) if [[ "${PIHOLE_DOMAIN}" == "" ]]; then
sed -i.bak '/DHCP_ACTIVE/d;' /etc/pihole/setupVars.conf PIHOLE_DOMAIN="local"
echo "DHCP_ACTIVE=false" >> /etc/pihole/setupVars.conf change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}"
fi
# Remove setting from file if [[ "${DHCP_LEASETIME}" == "0" ]]; then
sed -i '/dhcp-/d;/quiet-dhcp/d;' /etc/dnsmasq.d/01-pihole.conf leasetime="infinite"
elif [[ "${DHCP_LEASETIME}" == "" ]]; then
leasetime="24h"
change_setting "DHCP_LEASETIME" "${leasetime}"
else
leasetime="${DHCP_LEASETIME}h"
fi
RestartDNS # Write settings to file
echo "###############################################################################
# DHCP SERVER CONFIG FILE AUTOMATICALLY POPULATED BY PI-HOLE WEB INTERFACE. #
# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON CHANGE #
###############################################################################
dhcp-authoritative
dhcp-range=${DHCP_START},${DHCP_END},${leasetime}
dhcp-option=option:router,${DHCP_ROUTER}
dhcp-leasefile=/etc/pihole/dhcp.leases
domain=${PIHOLE_DOMAIN}
#quiet-dhcp
" > "${dhcpconfig}"
if [[ "${DHCP_IPv6}" == "true" ]]; then
echo "#quiet-dhcp6
#enable-ra
dhcp-option=option6:dns-server,[::]
dhcp-range=::100,::1ff,constructor:${interface},ra-names,slaac,${leasetime}
ra-param=*,0,0
" >> "${dhcpconfig}"
fi
else
rm "${dhcpconfig}"
fi
} }
SetWebUILayout(){ EnableDHCP(){
change_setting "DHCP_ACTIVE" "true"
change_setting "DHCP_START" "${args[2]}"
change_setting "DHCP_END" "${args[3]}"
change_setting "DHCP_ROUTER" "${args[4]}"
change_setting "DHCP_LEASETIME" "${args[5]}"
change_setting "PIHOLE_DOMAIN" "${args[6]}"
change_setting "DHCP_IPv6" "${args[7]}"
# Remove setting from file (create backup setupVars.conf.bak) # Remove possible old setting from file
sed -i.bak '/WEBUIBOXEDLAYOUT/d;' /etc/pihole/setupVars.conf delete_dnsmasq_setting "dhcp-"
echo "WEBUIBOXEDLAYOUT=${args[2]}" >> /etc/pihole/setupVars.conf delete_dnsmasq_setting "quiet-dhcp"
ProcessDHCPSettings
RestartDNS
} }
SetDNSDomainName(){ DisableDHCP(){
# Remove setting from file (create backup setupVars.conf.bak) change_setting "DHCP_ACTIVE" "false"
sed -i.bak '/PIHOLE_DOMAIN/d;' /etc/pihole/setupVars.conf
# Save setting to file
echo "PIHOLE_DOMAIN=${args[2]}" >> /etc/pihole/setupVars.conf
# Replace within actual dnsmasq config file # Remove possible old setting from file
sed -i '/domain=/d;' /etc/dnsmasq.d/01-pihole.conf delete_dnsmasq_setting "dhcp-"
echo "domain=${args[2]}" >> /etc/dnsmasq.d/01-pihole.conf delete_dnsmasq_setting "quiet-dhcp"
ProcessDHCPSettings
# Restart dnsmasq to load new configuration
RestartDNS RestartDNS
}
SetWebUILayout(){
change_setting "WEBUIBOXEDLAYOUT" "${args[2]}"
} }
SetPrivacyMode(){ SetPrivacyMode(){
# Remove setting from file (create backup setupVars.conf.bak)
sed -i.bak '/API_PRIVACY_MODE/d' /etc/pihole/setupVars.conf
# Save setting to file
if [[ "${args[2]}" == "true" ]] ; then if [[ "${args[2]}" == "true" ]] ; then
echo "API_PRIVACY_MODE=true" >> /etc/pihole/setupVars.conf change_setting "API_PRIVACY_MODE" "true"
else else
echo "API_PRIVACY_MODE=false" >> /etc/pihole/setupVars.conf change_setting "API_PRIVACY_MODE" "false"
fi fi
} }
ResolutionSettings() { ResolutionSettings() {
typ=${args[2]} typ="${args[2]}"
state=${args[3]} state="${args[3]}"
if [[ "${typ}" == "forward" ]]; then if [[ "${typ}" == "forward" ]]; then
sed -i.bak '/API_GET_UPSTREAM_DNS_HOSTNAME/d;' /etc/pihole/setupVars.conf change_setting "API_GET_UPSTREAM_DNS_HOSTNAME" "${state}"
echo "API_GET_UPSTREAM_DNS_HOSTNAME=${state}" >> /etc/pihole/setupVars.conf
elif [[ "${typ}" == "clients" ]]; then elif [[ "${typ}" == "clients" ]]; then
sed -i.bak '/API_GET_CLIENT_HOSTNAME/d;' /etc/pihole/setupVars.conf change_setting "API_GET_CLIENT_HOSTNAME" "${state}"
echo "API_GET_CLIENT_HOSTNAME=${state}" >> /etc/pihole/setupVars.conf
fi fi
} }
case "${args[1]}" in main() {
"-p" | "password" ) SetWebPassword;;
"-c" | "celsius" ) unit="C"; SetTemperatureUnit;; args=("$@")
"-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
"-k" | "kelvin" ) unit="K"; SetTemperatureUnit;; case "${args[1]}" in
"setdns" ) SetDNSServers;; "-p" | "password" ) SetWebPassword;;
"setexcludedomains" ) SetExcludeDomains;; "-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
"setexcludeclients" ) SetExcludeClients;; "-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
"reboot" ) Reboot;; "-k" | "kelvin" ) unit="K"; SetTemperatureUnit;;
"restartdns" ) RestartDNS;; "setdns" ) SetDNSServers;;
"setquerylog" ) SetQueryLogOptions;; "setexcludedomains" ) SetExcludeDomains;;
"enabledhcp" ) EnableDHCP;; "setexcludeclients" ) SetExcludeClients;;
"disabledhcp" ) DisableDHCP;; "reboot" ) Reboot;;
"layout" ) SetWebUILayout;; "restartdns" ) RestartDNS;;
"-h" | "--help" ) helpFunc;; "setquerylog" ) SetQueryLogOptions;;
"domainname" ) SetDNSDomainName;; "enabledhcp" ) EnableDHCP;;
"privacymode" ) SetPrivacyMode;; "disabledhcp" ) DisableDHCP;;
"resolve" ) ResolutionSettings;; "layout" ) SetWebUILayout;;
* ) helpFunc;; "-h" | "--help" ) helpFunc;;
esac "privacymode" ) SetPrivacyMode;;
"resolve" ) ResolutionSettings;;
shift * ) helpFunc;;
esac
if [[ $# = 0 ]]; then
helpFunc shift
fi
if [[ $# = 0 ]]; then
helpFunc
fi
}

@ -36,8 +36,8 @@ QUERY_LOGGING=true
# Find the rows and columns will default to 80x24 is it can not be detected # Find the rows and columns will default to 80x24 is it can not be detected
screen_size=$(stty size 2>/dev/null || echo 24 80) screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo $screen_size | awk '{print $1}') rows=$(echo "${screen_size}" | awk '{print $1}')
columns=$(echo $screen_size | awk '{print $2}') columns=$(echo "${screen_size}" | awk '{print $2}')
# Divide by two so the dialogs take up half of the screen, which looks nice. # Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 )) r=$(( rows / 2 ))
@ -51,28 +51,6 @@ skipSpaceCheck=false
reconfigure=false reconfigure=false
runUnattended=false runUnattended=false
######## FIRST CHECK ########
# Must be root to install
echo ":::"
if [[ ${EUID} -eq 0 ]]; then
echo "::: You are root."
else
echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
echo ":::"
echo "::: Detecting the presence of the sudo utility for continuation of this install..."
if command -v sudo &> /dev/null; then
echo "::: Utility sudo located."
exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
exit $?
else
echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
exit 1
fi
fi
# Compatibility # Compatibility
if command -v apt-get &> /dev/null; then if command -v apt-get &> /dev/null; then
@ -97,9 +75,6 @@ if command -v apt-get &> /dev/null; then
LIGHTTPD_CFG="lighttpd.conf.debian" LIGHTTPD_CFG="lighttpd.conf.debian"
DNSMASQ_USER="dnsmasq" DNSMASQ_USER="dnsmasq"
package_check_install() {
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
}
elif command -v rpm &> /dev/null; then elif command -v rpm &> /dev/null; then
# Fedora Family # Fedora Family
if command -v dnf &> /dev/null; then if command -v dnf &> /dev/null; then
@ -107,25 +82,22 @@ elif command -v rpm &> /dev/null; then
else else
PKG_MANAGER="yum" PKG_MANAGER="yum"
fi fi
# Fedora and family update cache on every PKG_INSTALL call, no need for a separate update.
# Fedora and family update cache on every PKG_INSTALL call, no need for a separate update.
UPDATE_PKG_CACHE=":" UPDATE_PKG_CACHE=":"
PKG_INSTALL="${PKG_MANAGER} install -y" PKG_INSTALL="${PKG_MANAGER} install -y"
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l" PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=(git iproute net-tools newt procps-ng) INSTALLER_DEPS=(git iproute net-tools newt procps-ng)
PIHOLE_DEPS=(bc bind-utils cronie curl dnsmasq epel-release findutils lighttpd lighttpd-fastcgi nmap-ncat php php-common php-cli sudo unzip wget) PIHOLE_DEPS=(bc bind-utils cronie curl dnsmasq findutils lighttpd lighttpd-fastcgi nmap-ncat php php-common php-cli sudo unzip wget)
if grep -q 'Fedora' /etc/redhat-release; then if ! grep -q 'Fedora' /etc/redhat-release; then
remove_deps=(epel-release); INSTALLER_DEPS=("${INSTALLER_DEPS[@]}" "epel-release");
PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
fi fi
LIGHTTPD_USER="lighttpd" LIGHTTPD_USER="lighttpd"
LIGHTTPD_GROUP="lighttpd" LIGHTTPD_GROUP="lighttpd"
LIGHTTPD_CFG="lighttpd.conf.fedora" LIGHTTPD_CFG="lighttpd.conf.fedora"
DNSMASQ_USER="nobody" DNSMASQ_USER="nobody"
package_check_install() {
rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
}
else else
echo "OS distribution not supported" echo "OS distribution not supported"
exit exit
@ -133,36 +105,51 @@ fi
####### FUNCTIONS ########## ####### FUNCTIONS ##########
is_repo() { is_repo() {
# Use git to check if directory is currently under VCS, return the value # Use git to check if directory is currently under VCS, return the value 128
# if directory is not a repo. Return 1 if directory does not exist.
local directory="${1}" local directory="${1}"
if [ -d $directory ]; then local curdir
local rc
curdir="${PWD}"
if [[ -d "${directory}" ]]; then
# git -C is not used here to support git versions older than 1.8.4 # git -C is not used here to support git versions older than 1.8.4
curdir=$PWD; cd $directory; git status --short &> /dev/null; rc=$?; cd $curdir cd "${directory}"
return $rc git status --short &> /dev/null || rc=$?
else else
# non-zero return code if directory does not exist OR is not a valid git repository # non-zero return code if directory does not exist
return 1 rc=1
fi fi
cd "${curdir}"
return "${rc:-0}"
} }
make_repo() { make_repo() {
local directory="${1}" local directory="${1}"
local remoteRepo="${2}" local remoteRepo="${2}"
# Remove the non-repod interface and clone the interface
echo -n "::: Cloning $remoteRepo into $directory..." echo -n "::: Cloning ${remoteRepo} into ${directory}..."
rm -rf "${directory}" # Clean out the directory if it exists for git to clone into
git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null if [[ -d "${directory}" ]]; then
rm -rf "${directory}"
fi
git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null || return $?
echo " done!" echo " done!"
return 0
} }
update_repo() { update_repo() {
local directory="${1}" local directory="${1}"
# Pull the latest commits # Pull the latest commits
echo -n "::: Updating repo in $1..." echo -n "::: Updating repo in ${1}..."
cd "${directory}" || exit 1 if [[ -d "${directory}" ]]; then
git stash -q &> /dev/null cd "${directory}"
git pull -q &> /dev/null git stash -q &> /dev/null || true # Okay for stash failure
echo " done!" git pull -q &> /dev/null || return $?
echo " done!"
fi
return 0
} }
getGitFiles() { getGitFiles() {
@ -173,17 +160,21 @@ getGitFiles() {
echo ":::" echo ":::"
echo "::: Checking for existing repository..." echo "::: Checking for existing repository..."
if is_repo "${directory}"; then if is_repo "${directory}"; then
update_repo "${directory}" update_repo "${directory}" || return 1
else else
make_repo "${directory}" "${remoteRepo}" make_repo "${directory}" "${remoteRepo}" || return 1
fi fi
return 0
} }
find_IPv4_information() { find_IPv4_information() {
local route
# Find IP used to route to outside world # Find IP used to route to outside world
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}') route=$(ip route get 8.8.8.8)
IPV4_ADDRESS=$(ip route get 8.8.8.8| awk '{print $7}') IPv4dev=$(awk '{for (i=1; i<=NF; i++) if ($i~/dev/) print $(i+1)}' <<< "${route}")
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}') IPV4_ADDRESS=$(awk '{print $7}' <<< "${route}")
IPv4gw=$(awk '{print $3}' <<< "${route}")
} }
get_available_interfaces() { get_available_interfaces() {
@ -247,8 +238,8 @@ chooseInterface() {
# Loop sentinel variable # Loop sentinel variable
local firstLoop=1 local firstLoop=1
if [[ $(echo ${availableInterfaces} | wc -l) -eq 1 ]]; then if [[ $(echo "${availableInterfaces}" | wc -l) -eq 1 ]]; then
PIHOLE_INTERFACE=${availableInterfaces} PIHOLE_INTERFACE="${availableInterfaces}"
return return
fi fi
@ -548,7 +539,7 @@ setLogging() {
local LogChoices local LogChoices
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6) LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
LogChooseOptions=("On (Reccomended)" "" on LogChooseOptions=("On (Recommended)" "" on
Off "" off) Off "" off)
LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1) LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
case ${LogChoices} in case ${LogChoices} in
@ -751,16 +742,45 @@ install_dependent_packages() {
# Install packages passed in via argument array # Install packages passed in via argument array
# No spinner - conflicts with set -e # No spinner - conflicts with set -e
declare -a argArray1=("${!1}") declare -a argArray1=("${!1}")
declare -a installArray
# Debian based package install - debconf will download the entire package list
# so we just create an array of packages not currently installed to cut down on the
# amount of download traffic.
# NOTE: We may be able to use this installArray in the future to create a list of package that were
# installed by us, and remove only the installed packages, and not the entire list.
if command -v debconf-apt-progress &> /dev/null; then if command -v debconf-apt-progress &> /dev/null; then
debconf-apt-progress -- ${PKG_INSTALL} "${argArray1[@]}"
else
for i in "${argArray1[@]}"; do for i in "${argArray1[@]}"; do
echo -n "::: Checking for $i..." echo -n "::: Checking for $i..."
package_check_install "${i}" &> /dev/null if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep "ok installed" &> /dev/null; then
echo " installed!" echo " installed!"
else
echo " added to install list!"
installArray+=("${i}")
fi
done done
if [[ ${#installArray[@]} -gt 0 ]]; then
debconf-apt-progress -- ${PKG_INSTALL} "${installArray[@]}"
return
fi
return 0
fi fi
#Fedora/CentOS
for i in "${argArray1[@]}"; do
echo -n "::: Checking for $i..."
if ${PKG_MANAGER} -q list installed "${i}" &> /dev/null; then
echo " installed!"
else
echo " added to install list!"
installArray+=("${i}")
fi
done
if [[ ${#installArray[@]} -gt 0 ]]; then
${PKG_INSTALL} "${installArray[@]}" &> /dev/null
return
fi
return 0
} }
CreateLogFile() { CreateLogFile() {
@ -870,11 +890,17 @@ configureFirewall() {
echo "::: Configuring FirewallD for httpd and dnsmasq.." echo "::: Configuring FirewallD for httpd and dnsmasq.."
firewall-cmd --permanent --add-port=80/tcp --add-port=53/tcp --add-port=53/udp firewall-cmd --permanent --add-port=80/tcp --add-port=53/tcp --add-port=53/udp
firewall-cmd --reload firewall-cmd --reload
elif modinfo ip_tables &> /dev/null && iptables -S INPUT | head -n1 | grep -v "ACCEPT" &> /dev/null ; then # Check for proper kernel modules to prevent failure
echo "::: Configuring iptables for httpd and dnsmasq.." elif modinfo ip_tables &> /dev/null; then
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # If chain Policy is not ACCEPT or last Rule is not ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT # then check and insert our Rules above the DROP/REJECT Rule.
iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT if iptables -S INPUT | head -n1 | grep -qv '^-P.*ACCEPT$' || iptables -S INPUT | tail -n1 | grep -qv '^-\(A\|P\).*ACCEPT$'; then
# Check chain first, otherwise a new rule will duplicate old ones
echo "::: Configuring iptables for httpd and dnsmasq.."
iptables -C INPUT -p tcp -m tcp --dport 80 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -C INPUT -p tcp -m tcp --dport 53 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT
iptables -C INPUT -p udp -m udp --dport 53 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT
fi
else else
echo "::: No active firewall detected.. skipping firewall configuration." echo "::: No active firewall detected.. skipping firewall configuration."
fi fi
@ -893,6 +919,18 @@ finalExports() {
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}" echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
echo "QUERY_LOGGING=${QUERY_LOGGING}" echo "QUERY_LOGGING=${QUERY_LOGGING}"
}>> "${setupVars}" }>> "${setupVars}"
# Look for DNS server settings which would have to be reapplied
source "${setupVars}"
source "/etc/.pihole/advanced/Scripts/webpage.sh"
if [[ "${DNS_FQDN_REQUIRED}" != "" ]] ; then
ProcessDNSSettings
fi
if [[ "${DHCP_ACTIVE}" != "" ]] ; then
ProcessDHCPSettings
fi
} }
installPihole() { installPihole() {
@ -972,29 +1010,18 @@ checkSelinux() {
} }
displayFinalMessage() { displayFinalMessage() {
if (( ${#1} > 0 )) ; then
# Final completion message to user # Final completion message to user
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using: whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*} IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS} IPv6: ${IPV6_ADDRESS:-"Not Configured"}
If you set a new IP address, you should restart the Pi. If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole. The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
The currently set password is ${1}" ${r} ${c}
else
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi. Your Admin Webpage login password is ${1:-"NOT SET"}" ${r} ${c}
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
fi
} }
update_dialogs() { update_dialogs() {
@ -1034,6 +1061,28 @@ update_dialogs() {
main() { main() {
######## FIRST CHECK ########
# Must be root to install
echo ":::"
if [[ ${EUID} -eq 0 ]]; then
echo "::: You are root."
else
echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
echo ":::"
echo "::: Detecting the presence of the sudo utility for continuation of this install..."
if command -v sudo &> /dev/null; then
echo "::: Utility sudo located."
exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
exit $?
else
echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
exit 1
fi
fi
# Check arguments for the undocumented flags # Check arguments for the undocumented flags
for var in "$@"; do for var in "$@"; do
case "$var" in case "$var" in
@ -1076,8 +1125,14 @@ main() {
echo "::: --reconfigure passed to install script. Not downloading/updating local repos" echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
else else
# Get Git files for Core and Admin # Get Git files for Core and Admin
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || \
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} { echo "!!! Unable to clone ${piholeGitUrl} into ${PI_HOLE_LOCAL_REPO}, unable to continue."; \
exit 1; \
}
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || \
{ echo "!!! Unable to clone ${webInterfaceGitUrl} into ${webInterfaceDir}, unable to continue."; \
exit 1; \
}
fi fi
if [[ ${useUpdateVars} == false ]]; then if [[ ${useUpdateVars} == false ]]; then

@ -24,7 +24,8 @@ if [[ ! $EUID -eq 0 ]];then
fi fi
webpageFunc() { webpageFunc() {
/opt/pihole/webpage.sh "$@" source /opt/pihole/webpage.sh
main "$@"
exit 0 exit 0
} }

Loading…
Cancel
Save