mirror of
https://github.com/pi-hole/pi-hole.git
synced 2024-12-26 06:40:17 +00:00
Merge pull request #1074 from pi-hole/development
[RELEASE] Pi-hole Core 2.11
This commit is contained in:
commit
b8545eb1df
14 changed files with 736 additions and 297 deletions
|
@ -15,6 +15,9 @@
|
||||||
<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" />
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -30,7 +30,7 @@ is_repo() {
|
||||||
git status --short &> /dev/null
|
git status --short &> /dev/null
|
||||||
rc=$?
|
rc=$?
|
||||||
cd "${curdir}" &> /dev/null || return 1
|
cd "${curdir}" &> /dev/null || return 1
|
||||||
return $rc
|
return "${rc}"
|
||||||
}
|
}
|
||||||
|
|
||||||
prep_repo() {
|
prep_repo() {
|
||||||
|
@ -46,26 +46,24 @@ make_repo() {
|
||||||
local remoteRepo="${2}"
|
local remoteRepo="${2}"
|
||||||
local directory="${1}"
|
local directory="${1}"
|
||||||
|
|
||||||
(prep_repo "${directory}" && git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null)
|
(prep_repo "${directory}" && git clone -q --depth 1 "${remoteRepo}" "${directory}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
update_repo() {
|
update_repo() {
|
||||||
local directory="${1}"
|
local directory="${1}"
|
||||||
local curdir
|
local curdir
|
||||||
# Pull the latest commits
|
|
||||||
|
|
||||||
curdir="${PWD}"
|
curdir="${PWD}"
|
||||||
cd "${directory}" &> /dev/null || return 1
|
cd "${directory}" &> /dev/null || return 1
|
||||||
|
# Pull the latest commits
|
||||||
# Stash all files not tracked for later retrieval
|
# Stash all files not tracked for later retrieval
|
||||||
git stash --all --quiet &> /dev/null
|
git stash --all --quiet
|
||||||
# Force a clean working directory for cloning
|
# Force a clean working directory for cloning
|
||||||
git clean --force -d &> /dev/null
|
git clean --force -d
|
||||||
# Fetch latest changes and apply
|
# Fetch latest changes and apply
|
||||||
git pull --quiet &> /dev/null
|
git pull --quiet
|
||||||
cd "${curdir}" &> /dev/null || return 1
|
cd "${curdir}" &> /dev/null || return 1
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getGitFiles() {
|
getGitFiles() {
|
||||||
|
@ -86,33 +84,59 @@ getGitFiles() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GitCheckUpdateAvail() {
|
||||||
|
local directory="${1}"
|
||||||
|
curdir=$PWD;
|
||||||
|
cd "${directory}"
|
||||||
|
|
||||||
|
# Fetch latest changes in this repo
|
||||||
|
git fetch --quiet origin
|
||||||
|
status="$(git status -sb)"
|
||||||
|
|
||||||
|
# Change back to original directory
|
||||||
|
cd "${curdir}"
|
||||||
|
|
||||||
|
if [[ $status == *"behind"* ]]; then
|
||||||
|
# Local branch is behind remote branch -> Update
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
# Local branch is up-to-date or in a situation
|
||||||
|
# where this updater cannot be used (like on a
|
||||||
|
# branch that exists only locally)
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
local pihole_version_current
|
local pihole_version_current
|
||||||
local pihole_version_latest
|
|
||||||
local web_version_current
|
local web_version_current
|
||||||
local web_version_latest
|
|
||||||
|
|
||||||
if ! is_repo "${PI_HOLE_FILES_DIR}" || ! is_repo "${ADMIN_INTERFACE_DIR}" ; then #This is unlikely
|
#This is unlikely
|
||||||
|
if ! is_repo "${PI_HOLE_FILES_DIR}" || ! is_repo "${ADMIN_INTERFACE_DIR}" ; then
|
||||||
echo "::: Critical Error: One or more Pi-Hole repos are missing from system!"
|
echo "::: Critical Error: One or more Pi-Hole repos are missing from system!"
|
||||||
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
|
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "::: Checking for updates..."
|
echo "::: Checking for updates..."
|
||||||
# Checks Pi-hole version string in format vX.X.X
|
|
||||||
pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)"
|
|
||||||
pihole_version_latest="$(/usr/local/bin/pihole version --pihole --latest)"
|
|
||||||
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
|
|
||||||
web_version_latest="$(/usr/local/bin/pihole version --admin --latest)"
|
|
||||||
|
|
||||||
if [[ "${pihole_version_latest}" == "-1" || "${web_version_latest}" == "-1" ]]; then
|
if GitCheckUpdateAvail "${PI_HOLE_FILES_DIR}" ; then
|
||||||
echo "*** Unable to contact GitHub for latest version. Please try again later, contact support if this continues."
|
core_update=true
|
||||||
exit 1
|
echo "::: Pi-hole Core: update available"
|
||||||
|
else
|
||||||
|
core_update=false
|
||||||
|
echo "::: Pi-hole Core: up to date"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if GitCheckUpdateAvail "${ADMIN_INTERFACE_DIR}" ; then
|
||||||
|
web_update=true
|
||||||
|
echo "::: Web Interface: update available"
|
||||||
|
else
|
||||||
|
web_update=false
|
||||||
|
echo "::: Web Interface: up to date"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Logic
|
# 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:
|
# If Core up to date AND web up to date:
|
||||||
# Do nothing
|
# Do nothing
|
||||||
# If Core up to date AND web NOT up to date:
|
# If Core up to date AND web NOT up to date:
|
||||||
|
@ -122,46 +146,40 @@ main() {
|
||||||
# if Core NOT up to date AND web NOT up to date:
|
# if Core NOT up to date AND web NOT up to date:
|
||||||
# pull pihole repo run install --unattended
|
# pull pihole repo run install --unattended
|
||||||
|
|
||||||
if [[ "${pihole_version_current}" == "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
|
if ! ${core_update} && ! ${web_update} ; then
|
||||||
echo ":::"
|
|
||||||
echo "::: Pi-hole version is $pihole_version_current"
|
|
||||||
echo "::: Web Admin version is $web_version_current"
|
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo "::: Everything is up to date!"
|
echo "::: Everything is up to date!"
|
||||||
exit 0
|
exit 0
|
||||||
|
|
||||||
elif [[ "${pihole_version_current}" == "${pihole_version_latest}" ]] && [[ "${web_version_current}" < "${web_version_latest}" ]]; then
|
elif ! ${core_update} && ${web_update} ; then
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo "::: Pi-hole Web Admin files out of date"
|
echo "::: Pi-hole Web Admin files out of date"
|
||||||
getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
|
getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
|
||||||
|
|
||||||
web_updated=true
|
elif ${core_update} && ! ${web_update} ; then
|
||||||
|
echo ":::"
|
||||||
elif [[ "${pihole_version_current}" < "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
|
|
||||||
echo "::: Pi-hole core files out of date"
|
echo "::: Pi-hole core files out of date"
|
||||||
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
|
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
|
||||||
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
|
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
|
||||||
core_updated=true
|
|
||||||
|
|
||||||
elif [[ "${pihole_version_current}" < "${pihole_version_latest}" ]] && [[ "${web_version_current}" < "${web_version_latest}" ]]; then
|
elif ${core_update} && ${web_update} ; then
|
||||||
|
echo ":::"
|
||||||
echo "::: Updating Everything"
|
echo "::: Updating Everything"
|
||||||
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
|
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
|
||||||
/etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
|
/etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
|
||||||
web_updated=true
|
|
||||||
core_updated=true
|
|
||||||
else
|
else
|
||||||
echo "*** Update script has malfunctioned, fallthrough reached. Please contact support"
|
echo "*** Update script has malfunctioned, fallthrough reached. Please contact support"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${web_updated}" == true ]]; then
|
if [[ "${web_update}" == true ]]; then
|
||||||
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
|
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo "::: Web Admin version is now at ${web_version_current}"
|
echo "::: Web Admin version is now at ${web_version_current}"
|
||||||
echo "::: If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
|
echo "::: If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${core_updated}" == true ]]; then
|
if [[ "${core_update}" == true ]]; then
|
||||||
pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)"
|
pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)"
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo "::: Pi-hole version is now at ${pihole_version_current}"
|
echo "::: Pi-hole version is now at ${pihole_version_current}"
|
||||||
|
|
0
advanced/Scripts/version.sh
Normal file → Executable file
0
advanced/Scripts/version.sh
Normal file → Executable file
|
@ -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
|
if [[ "${args[3]}" != "none" ]]; then
|
||||||
echo "PIHOLE_DNS_2=${args[3]}" >> /etc/pihole/setupVars.conf
|
change_setting "PIHOLE_DNS_2" "${args[3]}"
|
||||||
else
|
else
|
||||||
echo "PIHOLE_DNS_2=" >> /etc/pihole/setupVars.conf
|
change_setting "PIHOLE_DNS_2" ""
|
||||||
fi
|
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
|
|
||||||
echo "server=${args[3]}" >> /etc/dnsmasq.d/01-pihole.conf
|
|
||||||
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
|
||||||
|
|
||||||
|
ProcessDnsmasqSettings
|
||||||
|
|
||||||
# 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,87 +173,122 @@ 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
|
|
||||||
|
ProcessDHCPSettings() {
|
||||||
|
|
||||||
|
if [[ "${DHCP_ACTIVE}" == "true" ]]; then
|
||||||
|
|
||||||
|
source "${setupVars}"
|
||||||
|
interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//")
|
||||||
|
|
||||||
|
# Use eth0 as fallback interface
|
||||||
|
if [ -z ${interface} ]; then
|
||||||
|
interface="eth0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${PIHOLE_DOMAIN}" == "" ]]; then
|
||||||
|
PIHOLE_DOMAIN="local"
|
||||||
|
change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${DHCP_LEASETIME}" == "0" ]]; then
|
||||||
|
leasetime="infinite"
|
||||||
|
elif [[ "${DHCP_LEASETIME}" == "" ]]; then
|
||||||
|
leasetime="24h"
|
||||||
|
change_setting "DHCP_LEASETIME" "${leasetime}"
|
||||||
|
else
|
||||||
|
leasetime="${DHCP_LEASETIME}h"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 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
|
||||||
|
#quiet-dhcp6
|
||||||
|
#enable-ra
|
||||||
|
dhcp-option=option6:dns-server,[::]
|
||||||
|
dhcp-range=::100,::1ff,constructor:${interface},ra-names,slaac,${leasetime}
|
||||||
|
ra-param=*,0,0
|
||||||
|
" > "${dhcpconfig}"
|
||||||
|
|
||||||
|
else
|
||||||
|
rm "${dhcpconfig}"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
EnableDHCP(){
|
EnableDHCP(){
|
||||||
|
|
||||||
# Remove setting from file (create backup setupVars.conf.bak)
|
change_setting "DHCP_ACTIVE" "true"
|
||||||
sed -i.bak '/DHCP_/d;' /etc/pihole/setupVars.conf
|
change_setting "DHCP_START" "${args[2]}"
|
||||||
echo "DHCP_ACTIVE=true" >> /etc/pihole/setupVars.conf
|
change_setting "DHCP_END" "${args[3]}"
|
||||||
echo "DHCP_START=${args[2]}" >> /etc/pihole/setupVars.conf
|
change_setting "DHCP_ROUTER" "${args[4]}"
|
||||||
echo "DHCP_END=${args[3]}" >> /etc/pihole/setupVars.conf
|
change_setting "DHCP_LEASETIME" "${args[5]}"
|
||||||
echo "DHCP_ROUTER=${args[4]}" >> /etc/pihole/setupVars.conf
|
change_setting "PIHOLE_DOMAIN" "${args[6]}"
|
||||||
|
|
||||||
# Remove setting from file
|
# Remove possible old setting from file
|
||||||
sed -i '/dhcp-/d;/quiet-dhcp/d;' /etc/dnsmasq.d/01-pihole.conf
|
delete_dnsmasq_setting "dhcp-"
|
||||||
# Save setting to file
|
delete_dnsmasq_setting "quiet-dhcp"
|
||||||
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
|
ProcessDHCPSettings
|
||||||
# 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
|
RestartDNS
|
||||||
}
|
}
|
||||||
|
|
||||||
DisableDHCP(){
|
DisableDHCP(){
|
||||||
|
|
||||||
# Remove setting from file (create backup setupVars.conf.bak)
|
change_setting "DHCP_ACTIVE" "false"
|
||||||
sed -i.bak '/DHCP_ACTIVE/d;' /etc/pihole/setupVars.conf
|
|
||||||
echo "DHCP_ACTIVE=false" >> /etc/pihole/setupVars.conf
|
|
||||||
|
|
||||||
# Remove setting from file
|
# Remove possible old setting from file
|
||||||
sed -i '/dhcp-/d;/quiet-dhcp/d;' /etc/dnsmasq.d/01-pihole.conf
|
delete_dnsmasq_setting "dhcp-"
|
||||||
|
delete_dnsmasq_setting "quiet-dhcp"
|
||||||
|
|
||||||
|
ProcessDHCPSettings
|
||||||
|
|
||||||
RestartDNS
|
RestartDNS
|
||||||
}
|
}
|
||||||
|
|
||||||
SetWebUILayout(){
|
SetWebUILayout(){
|
||||||
|
|
||||||
# Remove setting from file (create backup setupVars.conf.bak)
|
change_setting "WEBUIBOXEDLAYOUT" "${args[2]}"
|
||||||
sed -i.bak '/WEBUIBOXEDLAYOUT/d;' /etc/pihole/setupVars.conf
|
|
||||||
echo "WEBUIBOXEDLAYOUT=${args[2]}" >> /etc/pihole/setupVars.conf
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDNSDomainName(){
|
SetPrivacyMode(){
|
||||||
|
|
||||||
# Remove setting from file (create backup setupVars.conf.bak)
|
if [[ "${args[2]}" == "true" ]] ; then
|
||||||
sed -i.bak '/PIHOLE_DOMAIN/d;' /etc/pihole/setupVars.conf
|
change_setting "API_PRIVACY_MODE" "true"
|
||||||
# Save setting to file
|
else
|
||||||
echo "PIHOLE_DOMAIN=${args[2]}" >> /etc/pihole/setupVars.conf
|
change_setting "API_PRIVACY_MODE" "false"
|
||||||
|
fi
|
||||||
# Replace within actual dnsmasq config file
|
|
||||||
sed -i '/domain=/d;' /etc/dnsmasq.d/01-pihole.conf
|
|
||||||
echo "domain=${args[2]}" >> /etc/dnsmasq.d/01-pihole.conf
|
|
||||||
|
|
||||||
# Restart dnsmasq to load new configuration
|
|
||||||
RestartDNS
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
args=("$@")
|
||||||
|
|
||||||
case "${args[1]}" in
|
case "${args[1]}" in
|
||||||
"-p" | "password" ) SetWebPassword;;
|
"-p" | "password" ) SetWebPassword;;
|
||||||
"-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
|
"-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
|
||||||
|
@ -245,7 +304,7 @@ case "${args[1]}" in
|
||||||
"disabledhcp" ) DisableDHCP;;
|
"disabledhcp" ) DisableDHCP;;
|
||||||
"layout" ) SetWebUILayout;;
|
"layout" ) SetWebUILayout;;
|
||||||
"-h" | "--help" ) helpFunc;;
|
"-h" | "--help" ) helpFunc;;
|
||||||
"domainname" ) SetDNSDomainName;;
|
"privacymode" ) SetPrivacyMode;;
|
||||||
"resolve" ) ResolutionSettings;;
|
"resolve" ) ResolutionSettings;;
|
||||||
* ) helpFunc;;
|
* ) helpFunc;;
|
||||||
esac
|
esac
|
||||||
|
@ -256,3 +315,4 @@ if [[ $# = 0 ]]; then
|
||||||
helpFunc
|
helpFunc
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
136
advanced/blockingpage.css
Normal file
136
advanced/blockingpage.css
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/* CSS Reset */
|
||||||
|
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; }
|
||||||
|
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
|
||||||
|
body { line-height: 1; }
|
||||||
|
ol, ul { list-style: none; }
|
||||||
|
blockquote, q { quotes: none; }
|
||||||
|
blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
|
||||||
|
table { border-collapse: collapse; border-spacing: 0; }
|
||||||
|
html { height: 100%; overflow-x: hidden; }
|
||||||
|
|
||||||
|
/* General Style */
|
||||||
|
a { color: rgba(0,60,120,0.95); text-decoration: none; } /* 1E3C5A */
|
||||||
|
a:hover { color: rgba(210,120,0,0.95); transition-duration: .2s; } /* 255, 128, 0 */
|
||||||
|
divs a { border-bottom: 1px dashed rgba(30,60,90,0.3); }
|
||||||
|
b { font-weight: bold; }
|
||||||
|
i { font-style: italic; }
|
||||||
|
|
||||||
|
footer, pre, td { font-family: monospace; padding-left: 15px; }
|
||||||
|
/*body, header { background: #E1E1E1; }*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-image: -webkit-linear-gradient(top, rgba(240,240,240,0.95), rgba(190,190,190,0.95));
|
||||||
|
background-image: linear-gradient(to bottom, rgba(240,240,240,0.95), rgba(190,190,190,0.95));
|
||||||
|
background-attachment: fixed;
|
||||||
|
color: rgba(64,64,64,0.95);
|
||||||
|
font: 14px, sans-serif;
|
||||||
|
line-height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
min-width: 320px;
|
||||||
|
width: 100%;
|
||||||
|
text-shadow: 0 1px rgba(255,255,255,0.6);
|
||||||
|
display: table;
|
||||||
|
table-layout: fixed;
|
||||||
|
border: 1px solid rgba(0,0,0,0.25);
|
||||||
|
border-top-color: rgba(255,255,255,0.85);
|
||||||
|
border-style: solid none;
|
||||||
|
background-image: -webkit-linear-gradient(top, rgba(240,240,240,0.95), rgba(220,220,220,0.95));
|
||||||
|
background-image: linear-gradient(to bottom, rgba(240,240,240,0.95), rgba(220,220,220,0.95));
|
||||||
|
box-shadow: 0 0 1px 1px rgba(0,0,0,0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1, header div {
|
||||||
|
display: table-cell;
|
||||||
|
color: inherit;
|
||||||
|
font-weight: bold;
|
||||||
|
vertical-align: middle;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: bold;
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px 0;
|
||||||
|
text-indent: 32px;
|
||||||
|
background: url("http://pi.hole/admin/img/logo.svg") left no-repeat;
|
||||||
|
background-size: 30px 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 a, h1 a:hover { color: inherit; }
|
||||||
|
header .alt { width: 85px; font-size: 0.8em; padding-right: 4px; text-align: right; line-height: 1.25em; }
|
||||||
|
.active { color: green; }
|
||||||
|
.inactive { color: red; }
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: block;
|
||||||
|
width: 80%;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 1em;
|
||||||
|
background-color: rgba(255,255,255,0.85);
|
||||||
|
margin: 8px auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid rgba(0,0,0,0.25);
|
||||||
|
box-shadow: 4px 4px rgba(0,0,0,0.1);
|
||||||
|
line-height: 1.2em;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 { /* Rgba is shared with .transparent th */
|
||||||
|
font: 1.15em sans-serif;
|
||||||
|
background-color: rgba(255,0,0,0.4);
|
||||||
|
text-shadow: none;
|
||||||
|
line-height: 1.1em;
|
||||||
|
padding-bottom: 1px;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
background: -webkit-linear-gradient(left, rgba(0,0,0,0.25), transparent 80%) no-repeat;
|
||||||
|
background: linear-gradient(to right, rgba(0,0,0,0.25), transparent 80%) no-repeat;
|
||||||
|
background-size: 100% 1px;
|
||||||
|
background-position: 0 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2:first-child { margin-top: 0; }
|
||||||
|
h2 ~ *:not(h2) { margin-left: 4px; }
|
||||||
|
li { padding: 2px 0; }
|
||||||
|
li::before { content: "\00BB\00a0"; }
|
||||||
|
li a { position: relative; top: 1px; } /* Center bullet-point arrows */
|
||||||
|
|
||||||
|
/* Button Style */
|
||||||
|
.buttons a, button, input, .transparent th a { /* Swapped rgba is shared with input[type='url'] */
|
||||||
|
display: inline-block;
|
||||||
|
color: rgba(32,32,32,0.9);
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
text-shadow: 0 1px rgba(255,255,255,0.2);
|
||||||
|
line-height: 0.86em;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 4px 8px;
|
||||||
|
background: #FAFAFA;
|
||||||
|
background-image: -webkit-linear-gradient(top, rgba(255,255,255,0.05), rgba(0,0,0,0.05));
|
||||||
|
background-image: linear-gradient(to bottom, rgba(255,255,255,0.05), rgba(0,0,0,0.05));
|
||||||
|
border: 1px solid rgba(0,0,0,0.25);
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 1px 0 rgba(0,0,0,0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons { white-space: nowrap; width: 100%; display: table; }
|
||||||
|
.buttons33 { white-space: nowrap; width: 33.333%; display: table; text-align: center; margin-left: 33.333% }
|
||||||
|
.mini a { width: 50%; }
|
||||||
|
a.safe { background-color: rgba(0,220,0,0.5); }
|
||||||
|
button.safe { background-color: rgba(0,220,0,0.5); }
|
||||||
|
a.warn { background-color: rgba(220,0,0,0.5); }
|
||||||
|
|
||||||
|
.blocked a, .mini a { display: table-cell; }
|
||||||
|
.blocked a.safe50 { width: 50%; background-color: rgba(0,220,0,0.5); }
|
||||||
|
.blocked a.safe33 { width: 33.333%; background-color: rgba(0,220,0,0.5); }
|
||||||
|
|
||||||
|
/* Types of text */
|
||||||
|
.msg { white-space: pre; overflow: auto; -webkit-overflow-scrolling: touch; display: block; line-height: 1.2em; font-weight: bold; font-size: 1.15em; margin: 4px 8px 8px 8px; white-space: pre-line; }
|
||||||
|
|
||||||
|
footer { font-size: 0.8em; text-align: center; width: 87%; margin: 4px auto; }
|
|
@ -1,12 +0,0 @@
|
||||||
# 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
|
|
||||||
# Swap file config
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
CONF_SWAPSIZE=500
|
|
|
@ -1,7 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<script>window.close();</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
162
advanced/index.php
Normal file
162
advanced/index.php
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
<?php
|
||||||
|
/* Detailed Pi-Hole Block Page: Show "Website Blocked" if user browses to site, but not to image/file requests based on the work of WaLLy3K for DietPi & Pi-Hole */
|
||||||
|
|
||||||
|
$uri = escapeshellcmd($_SERVER['REQUEST_URI']);
|
||||||
|
$serverName = escapeshellcmd($_SERVER['SERVER_NAME']);
|
||||||
|
|
||||||
|
// Retrieve server URI extension (EG: jpg, exe, php)
|
||||||
|
$uriExt = pathinfo($uri, PATHINFO_EXTENSION);
|
||||||
|
|
||||||
|
// Define which URL extensions get rendered as "Website Blocked"
|
||||||
|
$webExt = array('asp', 'htm', 'html', 'php', 'rss', 'xml');
|
||||||
|
|
||||||
|
if(in_array($uriExt, $webExt) || empty($uriExt))
|
||||||
|
{
|
||||||
|
// Requested resource has an extension listed in $webExt
|
||||||
|
// or no extension (index access to some folder incl. the root dir)
|
||||||
|
$showPage = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Something else
|
||||||
|
$showPage = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle incoming URI types
|
||||||
|
if (!$showPage)
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>window.close();</script></head>
|
||||||
|
<body>
|
||||||
|
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<?php
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Pi-Hole version
|
||||||
|
$piHoleVersion = exec('cd /etc/.pihole/ && git describe --tags --abbrev=0');
|
||||||
|
|
||||||
|
// Don't show the URI if it is the root directory
|
||||||
|
if($uri == "/")
|
||||||
|
{
|
||||||
|
$uri = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<meta charset='UTF-8'/>
|
||||||
|
<title>Website Blocked</title>
|
||||||
|
<link rel='stylesheet' href='http://pi.hole/pihole/blockingpage.css'/>
|
||||||
|
<link rel='shortcut icon' href='http://pi.hole/admin/img/favicon.png' type='image/png'/>
|
||||||
|
<meta name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0, user-scalable=no'/>
|
||||||
|
<meta name='robots' content='noindex,nofollow'/>
|
||||||
|
</head>
|
||||||
|
<body id="body">
|
||||||
|
<header>
|
||||||
|
<h1><a href='/'>Website Blocked</a></h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<div>Access to the following site has been blocked:<br/>
|
||||||
|
<span class='pre msg'><?php echo $serverName.$uri; ?></span></div>
|
||||||
|
<div>If you have an ongoing use for this website, please ask the owner of the Pi-hole in your network to have it whitelisted.</div>
|
||||||
|
<input id="domain" type="hidden" value="<?php echo $serverName; ?>">
|
||||||
|
<input id="quiet" type="hidden" value="yes">
|
||||||
|
<button id="btnSearch" class="buttons blocked" type="button" style="visibility: hidden;"></button>
|
||||||
|
This page is blocked because it is explicitly contained within the following block list(s):
|
||||||
|
<pre id="output" style="width: 100%; height: 100%;" hidden="true"></pre><br/>
|
||||||
|
<div class='buttons blocked'>
|
||||||
|
<a class='safe33' href='javascript:history.back()'>Go back</a>
|
||||||
|
<a class='safe33' id="whitelisting">Whitelist this page</a>
|
||||||
|
<a class='safe33' href='javascript:window.close()'>Close window</a>
|
||||||
|
</div>
|
||||||
|
<div style="width: 98%; text-align: center; padding: 10px;" hidden="true" id="whitelistingform">Password required!<br/>
|
||||||
|
<form>
|
||||||
|
<input name="list" type="hidden" value="white"><br/>
|
||||||
|
Domain:<br/>
|
||||||
|
<input name="domain" value="<?php echo $serverName ?>" disabled><br/><br/>
|
||||||
|
Password:<br/>
|
||||||
|
<input type="password" id="pw" name="pw"><br/><br/>
|
||||||
|
<button class="buttons33 safe" id="btnAdd" type="button">Whitelist</button>
|
||||||
|
</form><br/>
|
||||||
|
<pre id="whitelistingoutput" style="width: 100%; height: 100%; padding: 5px;" hidden="true"></pre><br/>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer>Generated <?php echo date('D g:i A, M d'); ?> by Pi-hole <?php echo $piHoleVersion; ?></footer>
|
||||||
|
<script src="http://pi.hole/admin/scripts/vendor/jquery.min.js"></script>
|
||||||
|
<script src="http://pi.hole/admin/scripts/pi-hole/js/queryads.js"></script>
|
||||||
|
<script>
|
||||||
|
function inIframe () {
|
||||||
|
try {
|
||||||
|
return window.self !== window.top;
|
||||||
|
} catch (e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to detect if page is loaded within iframe
|
||||||
|
if(inIframe())
|
||||||
|
{
|
||||||
|
// Within iframe
|
||||||
|
// hide content of page
|
||||||
|
$('#body').hide();
|
||||||
|
// remove background
|
||||||
|
document.body.style.backgroundImage = "none";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Query adlists
|
||||||
|
$( "#btnSearch" ).click();
|
||||||
|
}
|
||||||
|
|
||||||
|
$( "#whitelisting" ).on( "click", function(){ $( "#whitelistingform" ).removeAttr( "hidden" ); });
|
||||||
|
|
||||||
|
function add() {
|
||||||
|
var domain = $("#domain");
|
||||||
|
var pw = $("#pw");
|
||||||
|
if(domain.val().length === 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "admin/scripts/pi-hole/php/add.php",
|
||||||
|
method: "post",
|
||||||
|
data: {"domain":domain.val(), "list":"white", "pw":pw.val()},
|
||||||
|
success: function(response) {
|
||||||
|
$( "#whitelistingoutput" ).removeAttr( "hidden" );
|
||||||
|
if(response.indexOf("Pi-hole blocking") !== -1)
|
||||||
|
{
|
||||||
|
// Reload page after 5 seconds
|
||||||
|
setTimeout(function(){window.location.reload(1);}, 5000);
|
||||||
|
$( "#whitelistingoutput" ).html("---> Success <---<br/>You may have to flush your DNS cache");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$( "#whitelistingoutput" ).html("---> "+response+" <---");
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
error: function(jqXHR, exception) {
|
||||||
|
$( "#whitelistingoutput" ).removeAttr( "hidden" );
|
||||||
|
$( "#whitelistingoutput" ).html("---> Unknown Error <---");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Handle enter button for adding domains
|
||||||
|
$(document).keypress(function(e) {
|
||||||
|
if(e.which === 13 && $("#pw").is(":focus")) {
|
||||||
|
add();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle buttons
|
||||||
|
$("#btnAdd").on("click", function() {
|
||||||
|
add();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -21,7 +21,7 @@ server.modules = (
|
||||||
)
|
)
|
||||||
|
|
||||||
server.document-root = "/var/www/html"
|
server.document-root = "/var/www/html"
|
||||||
server.error-handler-404 = "pihole/index.html"
|
server.error-handler-404 = "pihole/index.php"
|
||||||
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
||||||
server.errorlog = "/var/log/lighttpd/error.log"
|
server.errorlog = "/var/log/lighttpd/error.log"
|
||||||
server.pid-file = "/var/run/lighttpd.pid"
|
server.pid-file = "/var/run/lighttpd.pid"
|
||||||
|
|
|
@ -22,7 +22,7 @@ server.modules = (
|
||||||
)
|
)
|
||||||
|
|
||||||
server.document-root = "/var/www/html"
|
server.document-root = "/var/www/html"
|
||||||
server.error-handler-404 = "pihole/index.html"
|
server.error-handler-404 = "pihole/index.php"
|
||||||
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
||||||
server.errorlog = "/var/log/lighttpd/error.log"
|
server.errorlog = "/var/log/lighttpd/error.log"
|
||||||
server.pid-file = "/var/run/lighttpd.pid"
|
server.pid-file = "/var/run/lighttpd.pid"
|
||||||
|
|
|
@ -21,6 +21,7 @@ set -e
|
||||||
tmpLog=/tmp/pihole-install.log
|
tmpLog=/tmp/pihole-install.log
|
||||||
instalLogLoc=/etc/pihole/install.log
|
instalLogLoc=/etc/pihole/install.log
|
||||||
setupVars=/etc/pihole/setupVars.conf
|
setupVars=/etc/pihole/setupVars.conf
|
||||||
|
lighttpdConfig=/etc/lighttpd/lighttpd.conf
|
||||||
|
|
||||||
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
|
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
|
||||||
webInterfaceDir="/var/www/html/admin"
|
webInterfaceDir="/var/www/html/admin"
|
||||||
|
@ -35,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 ))
|
||||||
|
@ -50,35 +51,12 @@ 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 [ -x "$(command -v sudo)" ]; 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) ]]; then
|
if command -v apt-get &> /dev/null; then
|
||||||
#Debian Family
|
#Debian Family
|
||||||
#############################################
|
#############################################
|
||||||
PKG_MANAGER="apt-get"
|
PKG_MANAGER="apt-get"
|
||||||
PKG_CACHE="/var/lib/apt/lists/"
|
|
||||||
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
|
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
|
||||||
PKG_INSTALL="${PKG_MANAGER} --yes --no-install-recommends install"
|
PKG_INSTALL="${PKG_MANAGER} --yes --no-install-recommends install"
|
||||||
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
|
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
|
||||||
|
@ -97,35 +75,29 @@ if [[ $(command -v apt-get) ]]; then
|
||||||
LIGHTTPD_CFG="lighttpd.conf.debian"
|
LIGHTTPD_CFG="lighttpd.conf.debian"
|
||||||
DNSMASQ_USER="dnsmasq"
|
DNSMASQ_USER="dnsmasq"
|
||||||
|
|
||||||
package_check_install() {
|
elif command -v rpm &> /dev/null; then
|
||||||
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
|
|
||||||
}
|
|
||||||
elif [ $(command -v rpm) ]; then
|
|
||||||
# Fedora Family
|
# Fedora Family
|
||||||
if [ $(command -v dnf) ]; then
|
if command -v dnf &> /dev/null; then
|
||||||
PKG_MANAGER="dnf"
|
PKG_MANAGER="dnf"
|
||||||
else
|
else
|
||||||
PKG_MANAGER="yum"
|
PKG_MANAGER="yum"
|
||||||
fi
|
fi
|
||||||
PKG_CACHE="/var/cache/${PKG_MANAGER}"
|
|
||||||
UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
|
# Fedora and family update cache on every PKG_INSTALL call, no need for a separate update.
|
||||||
|
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}..."
|
||||||
|
# Clean out the directory if it exists for git to clone into
|
||||||
|
if [[ -d "${directory}" ]]; then
|
||||||
rm -rf "${directory}"
|
rm -rf "${directory}"
|
||||||
git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null
|
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
|
||||||
|
git pull -q &> /dev/null || return $?
|
||||||
echo " done!"
|
echo " done!"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
getGitFiles() {
|
getGitFiles() {
|
||||||
|
@ -173,22 +160,23 @@ 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() {
|
||||||
# Find IP used to route to outside world
|
# Find IP used to route to outside world
|
||||||
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
|
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
|
||||||
IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
|
IPV4_ADDRESS=$(ip route get 8.8.8.8| awk '{print $7}')
|
||||||
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
|
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
|
||||||
}
|
}
|
||||||
|
|
||||||
get_available_interfaces() {
|
get_available_interfaces() {
|
||||||
# Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
|
# Get available UP interfaces.
|
||||||
availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
|
availableInterfaces=$(ip -o link | grep "state UP" | awk '{print $2}' | cut -d':' -f1 | cut -d'@' -f1)
|
||||||
}
|
}
|
||||||
|
|
||||||
welcomeDialogs() {
|
welcomeDialogs() {
|
||||||
|
@ -247,6 +235,11 @@ chooseInterface() {
|
||||||
# Loop sentinel variable
|
# Loop sentinel variable
|
||||||
local firstLoop=1
|
local firstLoop=1
|
||||||
|
|
||||||
|
if [[ $(echo ${availableInterfaces} | wc -l) -eq 1 ]]; then
|
||||||
|
PIHOLE_INTERFACE=${availableInterfaces}
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
mode="OFF"
|
mode="OFF"
|
||||||
if [[ ${firstLoop} -eq 1 ]]; then
|
if [[ ${firstLoop} -eq 1 ]]; then
|
||||||
|
@ -273,8 +266,11 @@ chooseInterface() {
|
||||||
|
|
||||||
useIPv6dialog() {
|
useIPv6dialog() {
|
||||||
# Show the IPv6 address used for blocking
|
# Show the IPv6 address used for blocking
|
||||||
IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
|
IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | grep -v "unreachable" | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
|
||||||
|
|
||||||
|
if [[ ! -z "${IPV6_ADDRESS}" ]]; then
|
||||||
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
|
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -412,7 +408,7 @@ setStaticIPv4() {
|
||||||
echo "USERCTL=no"
|
echo "USERCTL=no"
|
||||||
}> "${IFCFG_FILE}"
|
}> "${IFCFG_FILE}"
|
||||||
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
|
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
|
||||||
if [ -x "$(command -v nmcli)" ];then
|
if command -v nmcli &> /dev/null;then
|
||||||
# Tell NetworkManager to read our new sysconfig file
|
# Tell NetworkManager to read our new sysconfig file
|
||||||
nmcli con load "${IFCFG_FILE}" > /dev/null
|
nmcli con load "${IFCFG_FILE}" > /dev/null
|
||||||
fi
|
fi
|
||||||
|
@ -540,7 +536,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
|
||||||
|
@ -672,7 +668,7 @@ stop_service() {
|
||||||
# Can softfail, as process may not be installed when this is called
|
# Can softfail, as process may not be installed when this is called
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo -n "::: Stopping ${1} service..."
|
echo -n "::: Stopping ${1} service..."
|
||||||
if [ -x "$(command -v systemctl)" ]; then
|
if command -v systemctl &> /dev/null; then
|
||||||
systemctl stop "${1}" &> /dev/null || true
|
systemctl stop "${1}" &> /dev/null || true
|
||||||
else
|
else
|
||||||
service "${1}" stop &> /dev/null || true
|
service "${1}" stop &> /dev/null || true
|
||||||
|
@ -685,7 +681,7 @@ start_service() {
|
||||||
# This should not fail, it's an error if it does
|
# This should not fail, it's an error if it does
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo -n "::: Starting ${1} service..."
|
echo -n "::: Starting ${1} service..."
|
||||||
if [ -x "$(command -v systemctl)" ]; then
|
if command -v systemctl &> /dev/null; then
|
||||||
systemctl restart "${1}" &> /dev/null
|
systemctl restart "${1}" &> /dev/null
|
||||||
else
|
else
|
||||||
service "${1}" restart &> /dev/null
|
service "${1}" restart &> /dev/null
|
||||||
|
@ -697,7 +693,7 @@ enable_service() {
|
||||||
# Enable service so that it will start with next reboot
|
# Enable service so that it will start with next reboot
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo -n "::: Enabling ${1} service to start on reboot..."
|
echo -n "::: Enabling ${1} service to start on reboot..."
|
||||||
if [ -x "$(command -v systemctl)" ]; then
|
if command -v systemctl &> /dev/null; then
|
||||||
systemctl enable "${1}" &> /dev/null
|
systemctl enable "${1}" &> /dev/null
|
||||||
else
|
else
|
||||||
update-rc.d "${1}" defaults &> /dev/null
|
update-rc.d "${1}" defaults &> /dev/null
|
||||||
|
@ -709,19 +705,13 @@ update_pacakge_cache() {
|
||||||
#Running apt-get update/upgrade with minimal output can cause some issues with
|
#Running apt-get update/upgrade with minimal output can cause some issues with
|
||||||
#requiring user input (e.g password for phpmyadmin see #218)
|
#requiring user input (e.g password for phpmyadmin see #218)
|
||||||
|
|
||||||
#Check to see if apt-get update has already been run today
|
#Update package cache on apt based OSes. Do this every time since
|
||||||
#it needs to have been run at least once on new installs!
|
#it's quick and packages can be updated at any time.
|
||||||
timestamp=$(stat -c %Y ${PKG_CACHE})
|
|
||||||
timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
|
|
||||||
today=$(date "+%b %e")
|
|
||||||
|
|
||||||
if [ ! "${today}" == "${timestampAsDate}" ]; then
|
|
||||||
#update package lists
|
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
|
echo -n "::: Updating local cache of available packages..."
|
||||||
${UPDATE_PKG_CACHE} &> /dev/null
|
${UPDATE_PKG_CACHE} &> /dev/null
|
||||||
echo " done!"
|
echo " done!"
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_package_updates_available() {
|
notify_package_updates_available() {
|
||||||
|
@ -732,6 +722,7 @@ notify_package_updates_available() {
|
||||||
updatesToInstall=$(eval "${PKG_COUNT}")
|
updatesToInstall=$(eval "${PKG_COUNT}")
|
||||||
echo " done!"
|
echo " done!"
|
||||||
echo ":::"
|
echo ":::"
|
||||||
|
if [[ -d "/lib/modules/$(uname -r)" ]]; then
|
||||||
if [[ ${updatesToInstall} -eq "0" ]]; then
|
if [[ ${updatesToInstall} -eq "0" ]]; then
|
||||||
echo "::: Your system is up to date! Continuing with Pi-hole installation..."
|
echo "::: Your system is up to date! Continuing with Pi-hole installation..."
|
||||||
else
|
else
|
||||||
|
@ -739,22 +730,54 @@ notify_package_updates_available() {
|
||||||
echo "::: We recommend you update your OS after installing Pi-Hole! "
|
echo "::: We recommend you update your OS after installing Pi-Hole! "
|
||||||
echo ":::"
|
echo ":::"
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
echo "::: Kernel update detected, please reboot your system and try again if your installation fails."
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install_dependent_packages() {
|
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!"
|
||||||
done
|
else
|
||||||
|
echo " added to install list!"
|
||||||
|
installArray+=("${i}")
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
if [[ ${#installArray[@]} -gt 0 ]]; then
|
||||||
|
debconf-apt-progress -- ${PKG_INSTALL} "${installArray[@]}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
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() {
|
||||||
|
@ -776,11 +799,11 @@ installPiholeWeb() {
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo "::: Installing pihole custom index page..."
|
echo "::: Installing pihole custom index page..."
|
||||||
if [ -d "/var/www/html/pihole" ]; then
|
if [ -d "/var/www/html/pihole" ]; then
|
||||||
if [ -f "/var/www/html/pihole/index.html" ]; then
|
if [ -f "/var/www/html/pihole/index.php" ]; then
|
||||||
echo "::: Existing index.html detected, not overwriting"
|
echo "::: Existing index.php detected, not overwriting"
|
||||||
else
|
else
|
||||||
echo -n "::: index.html missing, replacing... "
|
echo -n "::: index.php missing, replacing... "
|
||||||
cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
|
cp /etc/.pihole/advanced/index.php /var/www/html/pihole/
|
||||||
echo " done!"
|
echo " done!"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -792,6 +815,14 @@ installPiholeWeb() {
|
||||||
echo " done!"
|
echo " done!"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -f "/var/www/html/pihole/blockingpage.css" ]; then
|
||||||
|
echo "::: Existing blockingpage.css detected, not overwriting"
|
||||||
|
else
|
||||||
|
echo -n "::: index.css missing, replacing... "
|
||||||
|
cp /etc/.pihole/advanced/blockingpage.css /var/www/html/pihole
|
||||||
|
echo " done!"
|
||||||
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
mkdir /var/www/html/pihole
|
mkdir /var/www/html/pihole
|
||||||
if [ -f /var/www/html/index.lighttpd.html ]; then
|
if [ -f /var/www/html/index.lighttpd.html ]; then
|
||||||
|
@ -852,16 +883,23 @@ create_pihole_user() {
|
||||||
|
|
||||||
configureFirewall() {
|
configureFirewall() {
|
||||||
# Allow HTTP and DNS traffic
|
# Allow HTTP and DNS traffic
|
||||||
if [ -x "$(command -v firewall-cmd)" ]; then
|
if firewall-cmd --state &> /dev/null; then
|
||||||
firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
|
echo "::: Configuring FirewallD for httpd and dnsmasq.."
|
||||||
&& firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
|
firewall-cmd --permanent --add-port=80/tcp --add-port=53/tcp --add-port=53/udp
|
||||||
elif [ -x "$(command -v iptables)" ]; then
|
firewall-cmd --reload
|
||||||
|
# Check for proper kernel modules to prevent failure
|
||||||
|
elif modinfo ip_tables &> /dev/null; then
|
||||||
|
# If chain Policy is not ACCEPT or last Rule is not ACCEPT
|
||||||
|
# then check and insert our Rules above the DROP/REJECT Rule.
|
||||||
|
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.."
|
echo "::: Configuring iptables for httpd and dnsmasq.."
|
||||||
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
|
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 -A INPUT -p tcp -m tcp --dport 53 -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 -A INPUT -p udp -m udp --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 firewall detected.. skipping firewall configuration."
|
echo "::: No active firewall detected.. skipping firewall configuration."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,6 +916,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() {
|
||||||
|
@ -937,7 +987,7 @@ updatePihole() {
|
||||||
|
|
||||||
|
|
||||||
checkSelinux() {
|
checkSelinux() {
|
||||||
if [ -x "$(command -v getenforce)" ]; then
|
if command -v getenforce &> /dev/null; then
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo -n "::: SELinux Support Detected... Mode: "
|
echo -n "::: SELinux Support Detected... Mode: "
|
||||||
enforceMode=$(getenforce)
|
enforceMode=$(getenforce)
|
||||||
|
@ -957,29 +1007,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%/*}
|
Your Admin Webpage login password is ${1:-"NOT SET"}" ${r} ${c}
|
||||||
IPv6: ${IPV6_ADDRESS}
|
|
||||||
|
|
||||||
If you set a new IP address, you should restart the Pi.
|
|
||||||
|
|
||||||
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() {
|
||||||
|
@ -1019,6 +1058,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
|
||||||
|
@ -1061,8 +1122,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
|
||||||
|
|
16
pihole
16
pihole
|
@ -23,7 +23,8 @@ if [[ ! $EUID -eq 0 ]];then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
webpageFunc() {
|
webpageFunc() {
|
||||||
/opt/pihole/webpage.sh "$@"
|
source /opt/pihole/webpage.sh
|
||||||
|
main "$@"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +186,19 @@ piholeLogging() {
|
||||||
}
|
}
|
||||||
|
|
||||||
piholeStatus() {
|
piholeStatus() {
|
||||||
|
if [[ $(netstat -plnt | grep -c ':53 ') > 0 ]]; then
|
||||||
|
if [[ "${1}" != "web" ]] ; then
|
||||||
|
echo "::: DNS service is running"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ "${1}" == "web" ]] ; then
|
||||||
|
echo "-1";
|
||||||
|
else
|
||||||
|
echo "::: DNS service is NOT running"
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then
|
if [[ $(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then
|
||||||
#list is commented out
|
#list is commented out
|
||||||
if [[ "${1}" == "web" ]] ; then
|
if [[ "${1}" == "web" ]] ; then
|
||||||
|
|
|
@ -71,13 +71,11 @@ def test_configureFirewall_firewalld_no_errors(Pihole):
|
||||||
source /opt/pihole/basic-install.sh
|
source /opt/pihole/basic-install.sh
|
||||||
configureFirewall
|
configureFirewall
|
||||||
''')
|
''')
|
||||||
expected_stdout = '::: Configuring firewalld for httpd and dnsmasq.'
|
expected_stdout = '::: Configuring FirewallD for httpd and dnsmasq.'
|
||||||
assert expected_stdout in configureFirewall.stdout
|
assert expected_stdout in configureFirewall.stdout
|
||||||
firewall_calls = Pihole.run('cat /var/log/firewall-cmd').stdout
|
firewall_calls = Pihole.run('cat /var/log/firewall-cmd').stdout
|
||||||
assert 'firewall-cmd --state' in firewall_calls
|
assert 'firewall-cmd --state' in firewall_calls
|
||||||
assert 'firewall-cmd --permanent --add-port=80/tcp' in firewall_calls
|
assert 'firewall-cmd --permanent --add-port=80/tcp --add-port=53/tcp --add-port=53/udp' in firewall_calls
|
||||||
assert 'firewall-cmd --permanent --add-port=53/tcp' in firewall_calls
|
|
||||||
assert 'firewall-cmd --permanent --add-port=53/udp' in firewall_calls
|
|
||||||
assert 'firewall-cmd --reload' in firewall_calls
|
assert 'firewall-cmd --reload' in firewall_calls
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue