2015-11-25 21:43:59 +00:00
#!/usr/bin/env bash
2015-10-28 22:29:34 +00:00
# Pi-hole: A black hole for Internet advertisements
2016-01-30 20:12:40 +00:00
# (c) 2015, 2016 by Jacob Salmela
2015-10-28 22:29:34 +00:00
# Network-wide ad blocking via your Raspberry Pi
2016-01-30 20:12:40 +00:00
# http://pi-hole.net
# Installs Pi-hole
2015-12-06 14:31:49 +00:00
#
# 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.
2016-01-30 20:12:40 +00:00
2015-10-28 22:29:34 +00:00
# pi-hole.net/donate
2015-06-14 03:14:21 +00:00
#
2015-10-28 22:29:34 +00:00
# Install with this command (from your Pi):
2015-06-14 03:14:21 +00:00
#
2015-10-28 22:29:34 +00:00
# curl -L install.pi-hole.net | bash
2015-06-14 03:14:21 +00:00
2016-01-27 22:32:08 +00:00
2015-10-28 22:29:34 +00:00
######## VARIABLES #########
2016-01-27 22:32:08 +00:00
2015-10-31 14:19:57 +00:00
tmpLog = /tmp/pihole-install.log
2015-10-31 14:15:57 +00:00
instalLogLoc = /etc/pihole/install.log
2016-01-24 03:31:12 +00:00
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"
2016-01-23 00:13:16 +00:00
2015-10-28 22:29:34 +00:00
# Find the rows and columns
2016-01-02 23:20:33 +00:00
rows = $( tput lines)
columns = $( tput cols)
2015-10-28 22:29:34 +00:00
# Divide by two so the dialogs take up half of the screen, which looks nice.
r = $(( rows / 2 ))
c = $(( columns / 2 ))
2016-01-23 22:25:30 +00:00
######## FIRST CHECK ########
# Must be root to install
2016-01-24 16:33:53 +00:00
echo ":::"
2016-01-23 22:25:30 +00:00
if [ [ $EUID -eq 0 ] ] ; then
2016-04-03 22:25:48 +00:00
echo "::: You are root."
2015-06-21 12:50:02 +00:00
else
2016-04-03 22:25:48 +00:00
echo "::: sudo will be used for the install."
# Check if it is actually installed
# If it isn't, exit because the install cannot complete
2016-04-25 23:31:00 +00:00
if [ -x " $( command -v sudo) " ] ; then
2016-04-03 22:25:48 +00:00
export SUDO = "sudo"
else
2016-06-11 18:21:08 +00:00
echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
2016-04-03 22:25:48 +00:00
exit 1
fi
2015-06-21 12:50:02 +00:00
fi
2015-10-28 22:29:34 +00:00
2016-04-26 04:51:00 +00:00
# Compatability
if [ -x " $( command -v rpm) " ] ; then
# Fedora Family
if [ -x " $( command -v dnf) " ] ; then
PKG_MANAGER = "dnf"
else
PKG_MANAGER = "yum"
fi
PKG_CACHE = " /var/cache/ $PKG_MANAGER "
2016-05-01 06:27:46 +00:00
UPDATE_PKG_CACHE = " $PKG_MANAGER check-update -q "
PKG_UPDATE = " $PKG_MANAGER update -y "
2016-04-26 04:51:00 +00:00
PKG_INSTALL = " $PKG_MANAGER install -y "
2016-05-01 06:27:46 +00:00
PKG_COUNT = " $PKG_MANAGER check-update | grep -v ^Last | grep -c ^[a-zA-Z0-9] "
2016-05-01 16:52:46 +00:00
INSTALLER_DEPS = ( iproute procps-ng newt dhcpcd )
2016-05-04 06:24:19 +00:00
PIHOLE_DEPS = ( epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php git curl unzip wget findutils cronie )
2016-05-04 06:01:38 +00:00
LIGHTTPD_USER = "lighttpd"
LIGHTTPD_GROUP = "lighttpd"
2016-05-01 21:06:57 +00:00
LIGHTTPD_CFG = "lighttpd.conf.fedora"
2016-04-26 04:51:00 +00:00
package_check( ) {
rpm -qa | grep ^$1 - > /dev/null
}
elif [ -x " $( command -v apt-get) " ] ; then
# Debian Family
PKG_MANAGER = "apt-get"
PKG_CACHE = "/var/cache/apt"
2016-05-01 16:52:46 +00:00
UPDATE_PKG_CACHE = " $PKG_MANAGER -qq update "
2016-05-01 06:27:46 +00:00
PKG_UPDATE = " $PKG_MANAGER upgrade "
2016-05-01 16:52:46 +00:00
PKG_INSTALL = " $PKG_MANAGER -y -qq install "
2016-05-01 06:27:46 +00:00
PKG_COUNT = " $PKG_MANAGER -s -o Debug::NoLocking=true upgrade | grep -c ^Inst "
2016-05-01 00:11:37 +00:00
INSTALLER_DEPS = ( apt-utils whiptail )
2016-05-01 06:27:46 +00:00
PIHOLE_DEPS = ( dhcpcd dnsutils bc dnsmasq lighttpd php5-common php5-cgi php5 git curl unzip wget )
2016-05-04 06:01:38 +00:00
LIGHTTPD_USER = "www-data"
LIGHTTPD_GROUP = "www-data"
2016-05-01 21:06:57 +00:00
LIGHTTPD_CFG = "lighttpd.conf.debian"
2016-04-26 04:51:00 +00:00
package_check( ) {
dpkg-query -W -f= '${Status}' " $1 " 2>/dev/null | grep -c "ok installed"
}
else
echo "OS distribution not supported"
exit
fi
2015-11-08 23:21:02 +00:00
2016-01-21 17:29:44 +00:00
####### FUNCTIONS ##########
2016-03-26 21:50:05 +00:00
spinner( )
{
2016-04-03 22:25:48 +00:00
local pid = $1
2016-03-27 06:53:48 +00:00
local delay = 0.50
2016-04-03 17:10:50 +00:00
local spinstr = '/-\|'
2016-03-27 06:53:48 +00:00
while [ " $( ps a | awk '{print $1}' | grep " $pid " ) " ] ; do
2016-04-03 22:25:48 +00:00
local temp = ${ spinstr #? }
2016-03-26 21:50:05 +00:00
printf " [%c] " " $spinstr "
local spinstr = $temp ${ spinstr % " $temp " }
sleep $delay
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
2016-01-27 06:11:38 +00:00
}
2016-01-24 03:31:12 +00:00
2016-05-01 02:27:38 +00:00
findIPRoute( ) {
# Find IP used to route to outside world
IPv4dev = $( ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}' )
IPv4addr = $( ip -o -f inet addr show dev " $IPv4dev " | awk '{print $4}' | awk 'END {print}' )
IPv4gw = $( ip route get 8.8.8.8 | awk '{print $3}' )
availableInterfaces = $( ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
dhcpcdFile = /etc/dhcpcd.conf
}
2016-01-27 06:11:38 +00:00
backupLegacyPihole( ) {
2016-04-03 22:25:48 +00:00
# This function detects and backups the pi-hole v1 files. It will not do anything to the current version files.
if [ [ -f /etc/dnsmasq.d/adList.conf ] ] ; then
echo "::: Original Pi-hole detected. Initiating sub space transport"
$SUDO mkdir -p /etc/pihole/original/
$SUDO mv /etc/dnsmasq.d/adList.conf /etc/pihole/original/adList.conf." $( date "+%Y-%m-%d" ) "
$SUDO mv /etc/dnsmasq.conf /etc/pihole/original/dnsmasq.conf." $( date "+%Y-%m-%d" ) "
$SUDO mv /etc/resolv.conf /etc/pihole/original/resolv.conf." $( date "+%Y-%m-%d" ) "
$SUDO mv /etc/lighttpd/lighttpd.conf /etc/pihole/original/lighttpd.conf." $( date "+%Y-%m-%d" ) "
$SUDO mv /var/www/pihole/index.html /etc/pihole/original/index.html." $( date "+%Y-%m-%d" ) "
if [ ! -d /opt/pihole ] ; then
$SUDO mkdir /opt/pihole
$SUDO chown " $USER " :root /opt/pihole
$SUDO chmod u+srwx /opt/pihole
fi
$SUDO mv /opt/pihole/gravity.sh /etc/pihole/original/gravity.sh." $( date "+%Y-%m-%d" ) "
else
:
fi
2015-11-10 00:33:32 +00:00
}
2016-01-27 06:11:38 +00:00
welcomeDialogs( ) {
2016-04-03 22:25:48 +00:00
# Display the welcome dialog
whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "This installer will transform your Raspberry Pi into a network-wide ad blocker!" $r $c
2016-01-28 09:25:00 +00:00
2016-04-03 22:25:48 +00:00
# Support for a part-time dev
whiptail --msgbox --backtitle "Plea" --title "Free and open source" "The Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" $r $c
2016-01-28 09:25:00 +00:00
2016-04-03 22:25:48 +00:00
# Explain the need for a static address
whiptail --msgbox --backtitle "Initating network interface" --title "Static IP Needed" " The Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
2016-06-10 22:47:27 +00:00
2016-04-03 23:05:11 +00:00
In the next section, you can choose to use your current network settings ( DHCP) or to manually edit them." $r $c
2015-11-08 23:21:02 +00:00
}
2016-02-10 15:34:06 +00:00
verifyFreeDiskSpace( ) {
2016-04-03 22:25:48 +00:00
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
requiredFreeBytes = 51200
existingFreeBytes = $( df -lk / 2>& 1 | awk '{print $4}' | head -2 | tail -1)
if ! [ [ " $existingFreeBytes " = ~ ^( [ 0-9] ) +$ ] ] ; then
existingFreeBytes = $( df -lk /dev 2>& 1 | awk '{print $4}' | head -2 | tail -1)
fi
if [ [ $existingFreeBytes -lt $requiredFreeBytes ] ] ; then
whiptail --msgbox --backtitle "Insufficient Disk Space" --title "Insufficient Disk Space" " \nYour system appears to be low on disk space. pi-hole recomends a minimum of $requiredFreeBytes Bytes.\nYou only have $existingFreeBytes Free.\n\nIf this is a new install you may need to expand your disk.\n\nTry running:\n 'sudo raspi-config'\nChoose the 'expand file system option'\n\nAfter rebooting, run this installation again.\n\ncurl -L install.pi-hole.net | bash\n " $r $c
echo " $existingFreeBytes is less than $requiredFreeBytes "
echo "Insufficient free space, exiting..."
exit 1
fi
2016-02-10 15:34:06 +00:00
}
2016-01-27 06:11:38 +00:00
chooseInterface( ) {
2016-04-03 22:25:48 +00:00
# Turn the available interfaces into an array so it can be used with a whiptail dialog
interfacesArray = ( )
firstloop = 1
while read -r line
do
mode = "OFF"
if [ [ $firstloop -eq 1 ] ] ; then
firstloop = 0
mode = "ON"
fi
interfacesArray += ( " $line " "available" " $mode " )
done <<< " $availableInterfaces "
# Find out how many interfaces are available to choose from
interfaceCount = $( echo " $availableInterfaces " | wc -l)
chooseInterfaceCmd = ( whiptail --separate-output --radiolist "Choose An Interface" $r $c $interfaceCount )
chooseInterfaceOptions = $( " ${ chooseInterfaceCmd [@] } " " ${ interfacesArray [@] } " 2>& 1 >/dev/tty)
if [ [ $? = 0 ] ] ; then
for desiredInterface in $chooseInterfaceOptions
do
piholeInterface = $desiredInterface
echo " ::: Using interface: $piholeInterface "
echo " ${ piholeInterface } " > /tmp/piholeINT
done
else
echo "::: Cancel selected, exiting...."
exit 1
fi
2016-03-06 05:16:23 +00:00
2015-11-10 00:33:32 +00:00
}
2016-02-11 00:07:48 +00:00
cleanupIPv6( ) {
2016-04-03 22:25:48 +00:00
# Removes IPv6 indicator file if we are not using IPv6
if [ -f "/etc/pihole/.useIPv6" ] && [ ! " $useIPv6 " ] ; then
rm /etc/pihole/.useIPv6
fi
2016-02-11 00:07:48 +00:00
}
2015-11-08 23:21:02 +00:00
2016-01-27 06:11:38 +00:00
use4andor6( ) {
2016-04-03 22:25:48 +00:00
# Let use select IPv4 and/or IPv6
2016-04-03 23:05:11 +00:00
cmd = ( whiptail --separate-output --checklist "Select Protocols (press space to select)" $r $c 2)
2016-04-03 22:25:48 +00:00
options = ( IPv4 "Block ads over IPv4" on
IPv6 "Block ads over IPv6" off)
choices = $( " ${ cmd [@] } " " ${ options [@] } " 2>& 1 >/dev/tty)
if [ [ $? = 0 ] ] ; then
for choice in $choices
do
case $choice in
IPv4 ) useIPv4 = true; ;
IPv6 ) useIPv6 = true; ;
esac
done
if [ $useIPv4 ] && [ ! $useIPv6 ] ; then
getStaticIPv4Settings
setStaticIPv4
echo " ::: Using IPv4 on $IPv4addr "
echo "::: IPv6 will NOT be used."
fi
if [ ! $useIPv4 ] && [ $useIPv6 ] ; then
useIPv6dialog
echo "::: IPv4 will NOT be used."
echo " ::: Using IPv6 on $piholeIPv6 "
fi
if [ $useIPv4 ] && [ $useIPv6 ] ; then
getStaticIPv4Settings
setStaticIPv4
useIPv6dialog
echo " ::: Using IPv4 on $IPv4addr "
echo " ::: Using IPv6 on $piholeIPv6 "
fi
if [ ! $useIPv4 ] && [ ! $useIPv6 ] ; then
echo "::: Cannot continue, neither IPv4 or IPv6 selected"
echo "::: Exiting"
exit 1
fi
cleanupIPv6
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
2015-11-10 00:33:32 +00:00
}
2015-11-08 23:21:02 +00:00
2016-01-27 06:11:38 +00:00
useIPv6dialog( ) {
2016-04-03 22:25:48 +00:00
# Show the IPv6 address used for blocking
piholeIPv6 = $( ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }' )
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" " $piholeIPv6 will be used to block ads. " $r $c
2016-01-28 09:25:00 +00:00
2016-04-03 22:25:48 +00:00
$SUDO touch /etc/pihole/.useIPv6
2016-01-23 00:13:16 +00:00
}
2015-11-08 23:21:02 +00:00
2016-01-27 06:11:38 +00:00
getStaticIPv4Settings( ) {
2016-04-03 22:25:48 +00:00
# Ask if the user wants to use DHCP settings as their static IP
if ( whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno " Do you want to use your current network settings as a static address?
IP address: $IPv4addr
Gateway: $IPv4gw " $r $c ) then
# If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" " It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
2016-04-03 23:05:11 +00:00
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." $r $c
2016-04-26 08:10:51 +00:00
#piholeIP is saved to a permanent file so gravity.sh can use it when updating
echo " ${ IPv4addr %/* } " > /etc/pihole/piholeIP
2016-04-03 22:25:48 +00:00
# Nothing else to do since the variables are already set above
else
# Otherwise, we need to ask the user to input their desired settings.
# Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
# Start a loop to let the user enter their information with the chance to go back and edit it if necessary
until [ [ $ipSettingsCorrect = True ] ]
do
# Ask for the IPv4 address
IPv4addr = $( whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" $r $c " $IPv4addr " 3>& 1 1>& 2 2>& 3)
if [ [ $? = 0 ] ] ; then
echo " ::: Your static IPv4 address: $IPv4addr "
# Ask for the gateway
IPv4gw = $( whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" $r $c " $IPv4gw " 3>& 1 1>& 2 2>& 3)
if [ [ $? = 0 ] ] ; then
echo " ::: Your static IPv4 gateway: $IPv4gw "
# Give the user a chance to review their settings before moving on
if ( whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno " Are these settings correct?
IP address: $IPv4addr
Gateway: $IPv4gw " $r $c )then
# If the settings are correct, then we need to set the piholeIP
2016-04-21 17:46:27 +00:00
# Saving it to a temporary file us to retrieve it later when we run the gravity.sh script. piholeIP is saved to a permanent file so gravity.sh can use it when updating
echo " ${ IPv4addr %/* } " > /etc/pihole/piholeIP
2016-04-03 22:25:48 +00:00
echo " $piholeInterface " > /tmp/piholeINT
# After that's done, the loop ends and we move on
ipSettingsCorrect = True
else
# If the settings are wrong, the loop continues
ipSettingsCorrect = False
fi
else
# Cancelling gateway settings window
ipSettingsCorrect = False
echo "::: Cancel selected. Exiting..."
exit 1
fi
else
# Cancelling IPv4 settings window
ipSettingsCorrect = False
echo "::: Cancel selected. Exiting..."
exit 1
fi
done
# End the if statement for DHCP vs. static
fi
2015-11-08 23:21:02 +00:00
}
2016-01-27 06:11:38 +00:00
setDHCPCD( ) {
2016-04-03 22:25:48 +00:00
# Append these lines to dhcpcd.conf to enable a static IP
echo " ::: interface $piholeInterface
static ip_address = $IPv4addr
static routers = $IPv4gw
static domain_name_servers = $IPv4gw " | $SUDO tee -a $dhcpcdFile >/dev/null
2015-10-31 14:11:29 +00:00
}
2016-01-27 06:11:38 +00:00
setStaticIPv4( ) {
2016-04-03 22:25:48 +00:00
# Tries to set the IPv4 address
if grep -q " $IPv4addr " $dhcpcdFile ; then
# address already set, noop
:
else
setDHCPCD
$SUDO ip addr replace dev " $piholeInterface " " $IPv4addr "
echo ":::"
echo " ::: Setting IP to $IPv4addr . You may need to restart after the install is complete. "
echo ":::"
fi
2015-12-06 10:40:30 +00:00
}
2016-02-20 17:33:20 +00:00
function valid_ip( )
{
2016-04-03 22:25:48 +00:00
local ip = $1
local stat = 1
if [ [ $ip = ~ ^[ 0-9] { 1,3} \. [ 0-9] { 1,3} \. [ 0-9] { 1,3} \. [ 0-9] { 1,3} $ ] ] ; then
OIFS = $IFS
IFS = '.'
ip = ( $ip )
IFS = $OIFS
[ [ ${ ip [0] } -le 255 && ${ ip [1] } -le 255 \
&& ${ ip [2] } -le 255 && ${ ip [3] } -le 255 ] ]
stat = $?
fi
return $stat
2016-02-20 17:33:20 +00:00
}
2016-01-25 05:11:00 +00:00
setDNS( ) {
2016-04-03 22:25:48 +00:00
DNSChoseCmd = ( whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." $r $c 6)
DNSChooseOptions = ( Google "" on
OpenDNS "" off
Level3 "" off
Norton "" off
Comodo "" off
Custom "" off)
DNSchoices = $( " ${ DNSChoseCmd [@] } " " ${ DNSChooseOptions [@] } " 2>& 1 >/dev/tty)
if [ [ $? = 0 ] ] ; then
case $DNSchoices in
Google)
echo "::: Using Google DNS servers."
piholeDNS1 = "8.8.8.8"
piholeDNS2 = "8.8.4.4"
; ;
OpenDNS)
echo "::: Using OpenDNS servers."
piholeDNS1 = "208.67.222.222"
piholeDNS2 = "208.67.220.220"
; ;
Level3)
echo "::: Using Level3 servers."
piholeDNS1 = "4.2.2.1"
piholeDNS2 = "4.2.2.2"
; ;
Norton)
echo "::: Using Norton ConnectSafe servers."
piholeDNS1 = "199.85.126.10"
piholeDNS2 = "199.85.127.10"
; ;
Comodo)
echo "::: Using Comodo Secure servers."
piholeDNS1 = "8.26.56.26"
piholeDNS2 = "8.20.247.20"
; ;
Custom)
until [ [ $DNSSettingsCorrect = True ] ]
do
strInvalid = "Invalid"
if [ ! $piholeDNS1 ] ; then
if [ ! $piholeDNS2 ] ; then
prePopulate = ""
else
prePopulate = " , $piholeDNS2 "
fi
elif [ $piholeDNS1 ] && [ ! $piholeDNS2 ] ; then
prePopulate = " $piholeDNS1 "
elif [ $piholeDNS1 ] && [ $piholeDNS2 ] ; then
prePopulate = " $piholeDNS1 , $piholeDNS2 "
fi
piholeDNS = $( whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" $r $c " $prePopulate " 3>& 1 1>& 2 2>& 3)
if [ [ $? = 0 ] ] ; then
piholeDNS1 = $( echo " $piholeDNS " | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}' )
piholeDNS2 = $( echo " $piholeDNS " | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}' )
if ! valid_ip " $piholeDNS1 " || [ ! " $piholeDNS1 " ] ; then
piholeDNS1 = $strInvalid
fi
if ! valid_ip " $piholeDNS2 " && [ " $piholeDNS2 " ] ; then
piholeDNS2 = $strInvalid
fi
else
echo "::: Cancel selected, exiting...."
exit 1
fi
if [ [ $piholeDNS1 = = " $strInvalid " ] ] || [ [ $piholeDNS2 = = " $strInvalid " ] ] ; then
whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" " One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $piholeDNS1 \n DNS Server 2: $piholeDNS2 " $r $c
if [ [ $piholeDNS1 = = " $strInvalid " ] ] ; then
piholeDNS1 = ""
fi
if [ [ $piholeDNS2 = = " $strInvalid " ] ] ; then
piholeDNS2 = ""
fi
DNSSettingsCorrect = False
else
if ( whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno " Are these settings correct?\n DNS Server 1: $piholeDNS1 \n DNS Server 2: $piholeDNS2 " $r $c ) then
DNSSettingsCorrect = True
else
# If the settings are wrong, the loop continues
DNSSettingsCorrect = False
fi
fi
done
; ;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
2016-01-25 05:11:00 +00:00
}
2016-01-25 06:09:45 +00:00
versionCheckDNSmasq( ) {
2016-04-03 22:25:48 +00:00
# Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
dnsFile1 = "/etc/dnsmasq.conf"
dnsFile2 = "/etc/dnsmasq.conf.orig"
dnsSearch = "addn-hosts=/etc/pihole/gravity.list"
defaultFile = "/etc/.pihole/advanced/dnsmasq.conf.original"
newFileToInstall = "/etc/.pihole/advanced/01-pihole.conf"
newFileFinalLocation = "/etc/dnsmasq.d/01-pihole.conf"
if [ -f $dnsFile1 ] ; then
echo -n "::: Existing dnsmasq.conf found..."
if grep -q $dnsSearch $dnsFile1 ; then
echo " it is from a previous pi-hole install."
echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
$SUDO mv -f $dnsFile1 $dnsFile2
echo " done."
echo -n "::: Restoring default dnsmasq.conf..."
$SUDO cp $defaultFile $dnsFile1
echo " done."
else
echo " it is not a pi-hole file, leaving alone!"
fi
else
echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
$SUDO cp $defaultFile $dnsFile1
echo " done."
fi
echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
$SUDO cp $newFileToInstall $newFileFinalLocation
echo " done."
$SUDO sed -i " s/@INT@/ $piholeInterface / " $newFileFinalLocation
if [ [ " $piholeDNS1 " != "" ] ] ; then
$SUDO sed -i " s/@DNS1@/ $piholeDNS1 / " $newFileFinalLocation
else
$SUDO sed -i '/^server=@DNS1@/d' $newFileFinalLocation
fi
if [ [ " $piholeDNS2 " != "" ] ] ; then
$SUDO sed -i " s/@DNS2@/ $piholeDNS2 / " $newFileFinalLocation
else
$SUDO sed -i '/^server=@DNS2@/d' $newFileFinalLocation
fi
2016-05-01 23:23:33 +00:00
$SUDO sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' $dnsFile1
2016-01-25 05:04:02 +00:00
}
2016-01-27 06:11:38 +00:00
installScripts( ) {
2016-04-03 22:25:48 +00:00
# Install the scripts from /etc/.pihole to their various locations
$SUDO echo ":::"
$SUDO echo -n "::: Installing scripts to /opt/pihole..."
if [ ! -d /opt/pihole ] ; then
$SUDO mkdir /opt/pihole
$SUDO chown " $USER " :root /opt/pihole
$SUDO chmod u+srwx /opt/pihole
fi
$SUDO cp /etc/.pihole/gravity.sh /opt/pihole/gravity.sh
$SUDO cp /etc/.pihole/advanced/Scripts/chronometer.sh /opt/pihole/chronometer.sh
$SUDO cp /etc/.pihole/advanced/Scripts/whitelist.sh /opt/pihole/whitelist.sh
$SUDO cp /etc/.pihole/advanced/Scripts/blacklist.sh /opt/pihole/blacklist.sh
$SUDO cp /etc/.pihole/advanced/Scripts/piholeDebug.sh /opt/pihole/piholeDebug.sh
$SUDO cp /etc/.pihole/advanced/Scripts/piholeLogFlush.sh /opt/pihole/piholeLogFlush.sh
$SUDO cp /etc/.pihole/advanced/Scripts/updateDashboard.sh /opt/pihole/updateDashboard.sh
$SUDO cp /etc/.pihole/automated\ install/uninstall.sh /opt/pihole/uninstall.sh
$SUDO cp /etc/.pihole/advanced/Scripts/setupLCD.sh /opt/pihole/setupLCD.sh
$SUDO chmod 755 /opt/pihole/{ gravity,chronometer,whitelist,blacklist,piholeLogFlush,updateDashboard,uninstall,setupLCD} .sh
$SUDO cp /etc/.pihole/pihole /usr/local/bin/pihole
$SUDO chmod 755 /usr/local/bin/pihole
$SUDO cp /etc/.pihole/advanced/bash-completion/pihole /etc/bash_completion.d/pihole
. /etc/bash_completion.d/pihole
#Tidy up /usr/local/bin directory if installing over previous install.
oldFiles = ( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
for i in " ${ oldFiles [@] } " ; do
if [ -f " /usr/local/bin/ $i .sh " ] ; then
$SUDO rm /usr/local/bin/" $i " .sh
fi
done
$SUDO echo " done."
2015-12-03 17:25:13 +00:00
}
2016-01-27 06:11:38 +00:00
installConfigs( ) {
2016-04-03 22:25:48 +00:00
# Install the configs from /etc/.pihole to their various locations
$SUDO echo ":::"
$SUDO echo "::: Installing configs..."
versionCheckDNSmasq
if [ ! -d "/etc/lighttpd" ] ; then
$SUDO mkdir /etc/lighttpd
$SUDO chown " $USER " :root /etc/lighttpd
$SUDO mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi
2016-05-01 21:06:57 +00:00
$SUDO cp /etc/.pihole/advanced/$LIGHTTPD_CFG /etc/lighttpd/lighttpd.conf
2016-05-05 04:50:48 +00:00
$SUDO mkdir -p /var/run/lighttpd
$SUDO chown $LIGHTTPD_USER :$LIGHTTPD_GROUP /var/run/lighttpd
2016-05-02 02:39:35 +00:00
$SUDO mkdir -p /var/cache/lighttpd/compress
2016-05-04 06:01:38 +00:00
$SUDO chown $LIGHTTPD_USER :$LIGHTTPD_GROUP /var/cache/lighttpd/compress
2015-12-03 17:25:13 +00:00
}
2016-01-27 06:11:38 +00:00
stopServices( ) {
2016-04-03 22:25:48 +00:00
# Stop dnsmasq and lighttpd
$SUDO echo ":::"
$SUDO echo -n "::: Stopping services..."
#$SUDO service dnsmasq stop & spinner $! || true
2016-05-01 14:45:41 +00:00
if [ -x " $( command -v systemctl) " ] ; then
$SUDO systemctl stop lighttpd & spinner $! || true
else
$SUDO service lighttpd stop & spinner $! || true
fi
2016-04-03 22:25:48 +00:00
$SUDO echo " done."
2015-12-03 17:25:13 +00:00
}
2016-05-01 06:27:46 +00:00
installerDependencies( ) {
2016-04-03 22:25:48 +00:00
#Running apt-get update/upgrade with minimal output can cause some issues with
#requiring user input (e.g password for phpmyadmin see #218)
#We'll change the logic up here, to check to see if there are any updates availible and
# if so, advise the user to run apt-get update/upgrade at their own discretion
#Check to see if apt-get update has already been run today
# it needs to have been run at least once on new installs!
2016-04-26 04:51:00 +00:00
timestamp = $( stat -c %Y $PKG_CACHE )
2016-04-03 22:25:48 +00:00
timestampAsDate = $( date -d @" $timestamp " "+%b %e" )
today = $( date "+%b %e" )
if [ ! " $today " = = " $timestampAsDate " ] ; then
#update package lists
echo ":::"
2016-04-26 04:51:00 +00:00
echo -n " ::: $PKG_MANAGER update has not been run today. Running now... "
2016-05-01 06:27:46 +00:00
$SUDO $UPDATE_PKG_CACHE > /dev/null 2>& 1
2016-04-03 22:25:48 +00:00
echo " done!"
fi
echo ":::"
2016-05-01 06:27:46 +00:00
echo -n " ::: Checking $PKG_MANAGER for upgraded packages.... "
updatesToInstall = $( eval " $SUDO $PKG_COUNT " )
echo " done!"
2016-05-01 23:46:15 +00:00
echo ":::"
if [ [ $updatesToInstall -eq "0" ] ] ; then
2016-04-03 22:25:48 +00:00
echo "::: Your pi is up to date! Continuing with pi-hole installation..."
2016-05-01 23:46:15 +00:00
else
2016-04-03 22:25:48 +00:00
echo " ::: There are $updatesToInstall updates availible for your pi! "
2016-05-01 06:27:46 +00:00
echo " ::: We recommend you run ' $PKG_UPDATE ' after installing Pi-Hole! "
2016-04-03 22:25:48 +00:00
echo ":::"
2016-05-01 23:46:15 +00:00
fi
echo ":::"
2016-05-01 06:27:46 +00:00
echo "::: Checking installer dependencies..."
for i in " ${ INSTALLER_DEPS [@] } " ; do
echo -n " ::: Checking for $i ... "
package_check $i > /dev/null
if ! [ $? -eq 0 ] ; then
echo -n " Not found! Installing...."
$SUDO $PKG_INSTALL " $i " > /dev/null 2>& 1
echo " done!"
else
echo " already installed!"
fi
done
}
checkForDependencies( ) {
# Install dependencies for Pi-Hole
echo "::: Checking Pi-Hole dependencies:"
2016-01-24 03:31:12 +00:00
2016-04-26 04:51:00 +00:00
for i in " ${ PIHOLE_DEPS [@] } " ; do
echo -n " ::: Checking for $i ... "
package_check $i > /dev/null
if ! [ $? -eq 0 ] ; then
echo -n " Not found! Installing...."
$SUDO $PKG_INSTALL " $i " > /dev/null & spinner $!
echo " done!"
else
echo " already installed!"
fi
done
2015-12-03 17:25:13 +00:00
}
2016-01-27 06:11:38 +00:00
getGitFiles( ) {
2016-04-03 22:25:48 +00:00
# Setup git repos for base files and web admin
echo ":::"
echo "::: Checking for existing base files..."
if is_repo $piholeFilesDir ; then
make_repo $piholeFilesDir $piholeGitUrl
else
update_repo $piholeFilesDir
fi
echo ":::"
echo "::: Checking for existing web interface..."
if is_repo $webInterfaceDir ; then
make_repo $webInterfaceDir $webInterfaceGitUrl
else
update_repo $webInterfaceDir
fi
2015-12-03 17:25:13 +00:00
}
2016-01-24 03:31:12 +00:00
is_repo( ) {
2016-04-03 22:25:48 +00:00
# If the directory does not have a .git folder it is not a repo
echo -n " ::: Checking $1 is a repo... "
if [ -d " $1 /.git " ] ; then
echo " OK!"
return 1
fi
echo " not found!!"
return 0
2016-01-24 03:31:12 +00:00
}
make_repo( ) {
2016-01-27 06:11:38 +00:00
# Remove the non-repod interface and clone the interface
2016-01-24 16:33:53 +00:00
echo -n " ::: Cloning $2 into $1 ... "
2016-03-26 19:16:22 +00:00
$SUDO rm -rf " $1 "
2016-01-24 16:33:53 +00:00
$SUDO git clone -q " $2 " " $1 " > /dev/null & spinner $!
echo " done!"
2016-01-24 03:31:12 +00:00
}
update_repo( ) {
2016-01-27 06:11:38 +00:00
# Pull the latest commits
2016-01-24 16:33:53 +00:00
echo -n " ::: Updating repo in $1 ... "
2016-03-26 19:16:22 +00:00
cd " $1 " || exit
2016-01-24 03:31:12 +00:00
$SUDO git pull -q > /dev/null & spinner $!
2016-01-24 16:33:53 +00:00
echo " done!"
2016-01-24 03:31:12 +00:00
}
2016-01-27 06:11:38 +00:00
CreateLogFile( ) {
2016-04-03 22:25:48 +00:00
# Create logfiles if necessary
echo ":::"
$SUDO echo -n "::: Creating log file and changing owner to dnsmasq..."
if [ ! -f /var/log/pihole.log ] ; then
$SUDO touch /var/log/pihole.log
$SUDO chmod 644 /var/log/pihole.log
$SUDO chown dnsmasq:root /var/log/pihole.log
$SUDO echo " done!"
else
$SUDO echo " already exists!"
fi
2015-12-03 17:25:13 +00:00
}
2016-01-27 06:11:38 +00:00
installPiholeWeb( ) {
2016-04-03 22:25:48 +00:00
# Install the web interface
$SUDO echo ":::"
$SUDO echo -n "::: Installing pihole custom index page..."
if [ -d "/var/www/html/pihole" ] ; then
$SUDO echo " Existing page detected, not overwriting"
else
$SUDO mkdir /var/www/html/pihole
if [ -f /var/www/html/index.lighttpd.html ] ; then
$SUDO mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
else
printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
fi
$SUDO cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
$SUDO echo " done!"
fi
2016-04-18 03:03:12 +00:00
# Install Sudoer file
echo -n "::: Installing sudoer file..."
2016-06-10 23:51:38 +00:00
$SUDO mkdir -p /etc/sudoers.d/
2016-04-18 03:03:12 +00:00
$SUDO cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
$SUDO chmod 0440 /etc/sudoers.d/pihole
echo " done!"
2015-12-03 17:25:13 +00:00
}
2016-01-27 06:11:38 +00:00
installCron( ) {
2016-04-03 22:25:48 +00:00
# Install the cron job
$SUDO echo ":::"
$SUDO echo -n "::: Installing latest Cron script..."
$SUDO cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
$SUDO echo " done!"
2015-12-03 17:25:13 +00:00
}
2016-01-27 06:11:38 +00:00
runGravity( ) {
2016-04-03 22:25:48 +00:00
# Rub gravity.sh to build blacklists
$SUDO echo ":::"
$SUDO echo "::: Preparing to run gravity.sh to refresh hosts..."
if ls /etc/pihole/list* 1> /dev/null 2>& 1; then
echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
$SUDO rm /etc/pihole/list.*
fi
echo "::: Running gravity.sh"
$SUDO /opt/pihole/gravity.sh
2016-01-19 22:52:29 +00:00
}
2016-01-25 05:28:53 +00:00
setUser( ) {
2016-04-03 22:25:48 +00:00
# Check if user pihole exists and create if not
echo "::: Checking if user 'pihole' exists..."
if id -u pihole > /dev/null 2>& 1; then
echo "::: User 'pihole' already exists"
else
echo "::: User 'pihole' doesn't exist. Creating..."
$SUDO useradd -r -s /usr/sbin/nologin pihole
fi
2016-01-25 05:28:53 +00:00
}
2016-01-20 23:34:18 +00:00
2016-01-27 06:11:38 +00:00
installPihole( ) {
2016-04-03 22:25:48 +00:00
# Install base files and web interface
checkForDependencies # done
stopServices
setUser
$SUDO mkdir -p /etc/pihole/
if [ ! -d "/var/www/html" ] ; then
$SUDO mkdir -p /var/www/html
fi
2016-05-04 06:01:38 +00:00
$SUDO chown $LIGHTTPD_USER :$LIGHTTPD_GROUP /var/www/html
2016-04-03 22:25:48 +00:00
$SUDO chmod 775 /var/www/html
2016-05-04 06:01:38 +00:00
$SUDO usermod -a -G $LIGHTTPD_GROUP pihole
2016-05-04 06:03:07 +00:00
if [ -x " $( command -v lighty-enable-mod) " ] ; then
$SUDO lighty-enable-mod fastcgi fastcgi-php > /dev/null
else
printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
fi
2016-04-03 22:25:48 +00:00
getGitFiles
installScripts
installConfigs
CreateLogFile
installPiholeWeb
installCron
runGravity
2015-11-07 18:07:50 +00:00
}
2016-01-27 06:11:38 +00:00
displayFinalMessage( ) {
2016-04-03 22:25:48 +00:00
# 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:
2016-01-01 02:26:05 +00:00
2016-05-25 22:55:36 +00:00
IPv4: ${ IPv4addr %/* }
2016-04-03 23:05:11 +00:00
IPv6: $piholeIPv6
2016-01-01 02:26:05 +00:00
2016-04-03 23:05:11 +00:00
If you set a new IP address, you should restart the Pi.
2016-01-01 02:26:05 +00:00
2016-05-25 22:55:36 +00:00
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${ IPv4addr %/* } /admin" $r $c
2016-01-01 02:26:05 +00:00
}
2015-10-28 22:29:34 +00:00
######## SCRIPT ############
2015-11-08 23:21:02 +00:00
# Start the installer
2016-01-27 22:32:08 +00:00
$SUDO mkdir -p /etc/pihole/
2016-05-01 06:27:46 +00:00
# Install packages used by this installation script
installerDependencies
2015-11-08 23:21:02 +00:00
welcomeDialogs
2016-02-10 15:34:06 +00:00
# Verify there is enough disk space for the install
verifyFreeDiskSpace
2015-10-28 22:29:34 +00:00
# Just back up the original Pi-hole right away since it won't take long and it gets it out of the way
backupLegacyPihole
2016-05-01 02:27:38 +00:00
# Find IP used to route to outside world
findIPRoute
2015-11-10 23:28:05 +00:00
# Find interfaces and let the user choose one
2015-11-10 00:33:32 +00:00
chooseInterface
2015-11-08 23:21:02 +00:00
# Let the user decide if they want to block ads over IPv4 and/or IPv6
use4andor6
2015-10-28 22:29:34 +00:00
2016-01-25 05:11:00 +00:00
# Decide what upstream DNS Servers to use
setDNS
2015-11-07 18:07:50 +00:00
# Install and log everything to a file
installPihole | tee $tmpLog
# Move the log file into /etc/pihole for storage
2016-01-16 19:40:09 +00:00
$SUDO mv $tmpLog $instalLogLoc
2015-11-07 18:35:08 +00:00
2016-01-01 02:26:05 +00:00
displayFinalMessage
2015-11-07 19:09:23 +00:00
2016-02-06 13:02:21 +00:00
echo -n "::: Restarting services..."
2016-01-27 06:11:38 +00:00
# Start services
2016-05-01 14:45:41 +00:00
if [ -x " $( command -v systemctl) " ] ; then
$SUDO systemctl restart dnsmasq
$SUDO systemctl start lighttpd
else
$SUDO service dnsmasq restart
$SUDO service lighttpd start
fi
2016-02-06 13:02:21 +00:00
echo " done."
echo ":::"
echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
2016-05-25 22:55:36 +00:00
echo " ::: ${ IPv4addr %/* } "
2016-02-06 13:02:21 +00:00
echo " ::: $piholeIPv6 "
echo ":::"
echo "::: If you set a new IP address, you should restart the Pi."
2016-05-25 22:55:36 +00:00
echo ":::"
2016-02-06 13:04:54 +00:00
echo "::: The install log is located at: /etc/pihole/install.log"
2016-05-25 22:55:36 +00:00
echo " ::: View the web interface at http://pi.hole/admin or http:// ${ IPv4addr %/* } /admin "