diff --git a/.stickler.yml b/.stickler.yml index b96fc2e7..0eaae8cb 100644 --- a/.stickler.yml +++ b/.stickler.yml @@ -1,3 +1,6 @@ linters: shellcheck: shell: bash + phpcs: + csslint: + flake8: diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh index 21919ddf..7b189bcc 100644 --- a/advanced/Scripts/piholeCheckout.sh +++ b/advanced/Scripts/piholeCheckout.sh @@ -19,7 +19,6 @@ source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" # setupVars set in basic-install.sh source "${setupVars}" -update="false" coltable="/opt/pihole/COL_TABLE" source ${coltable} @@ -33,89 +32,6 @@ check_download_exists() { fi } -FTLinstall() { - # Download and install FTL binary - local binary - binary="${1}" - local path - path="${2}" - local str - str="Installing FTL" - echo -ne " ${INFO} ${str}..." - - if curl -sSL --fail "https://ftl.pi-hole.net/${path}" -o "/tmp/${binary}"; then - # Get sha1 of the binary we just downloaded for verification. - curl -sSL --fail "https://ftl.pi-hole.net/${path}.sha1" -o "/tmp/${binary}.sha1" - # Check if we just downloaded text, or a binary file. - cd /tmp || return 1 - if sha1sum --status --quiet -c "${binary}".sha1; then - echo -n "transferred... " - stop_service pihole-FTL &> /dev/null - install -T -m 0755 "/tmp/${binary}" "/usr/bin/pihole-FTL" - rm "/tmp/${binary}" "/tmp/${binary}.sha1" - start_service pihole-FTL &> /dev/null - echo -e "${OVER} ${TICK} ${str}" - return 0 - else - echo -e "${OVER} ${CROSS} ${str}" - echo -e " ${COL_LIGHT_RED}Error: Download of binary from ftl.pi-hole.net failed${COL_NC}" - return 1 - fi - else - echo -e "${OVER} ${CROSS} ${str}" - echo -e " ${COL_LIGHT_RED}Error: URL not found${COL_NC}" - fi -} - -get_binary_name() { - local machine - machine=$(uname -m) - - local str - str="Detecting architecture" - echo -ne " ${INFO} ${str}..." - if [[ "${machine}" == "arm"* || "${machine}" == *"aarch"* ]]; then - # ARM - local rev - rev=$(uname -m | sed "s/[^0-9]//g;") - local lib - lib=$(ldd /bin/ls | grep -E '^\s*/lib' | awk '{ print $1 }') - if [[ "${lib}" == "/lib/ld-linux-aarch64.so.1" ]]; then - echo -e "${OVER} ${TICK} Detected ARM-aarch64 architecture" - binary="pihole-FTL-aarch64-linux-gnu" - elif [[ "${lib}" == "/lib/ld-linux-armhf.so.3" ]]; then - if [[ "$rev" -gt "6" ]]; then - echo -e "${OVER} ${TICK} Detected ARM-hf architecture (armv7+)" - binary="pihole-FTL-arm-linux-gnueabihf" - else - echo -e "${OVER} ${TICK} Detected ARM-hf architecture (armv6 or lower) Using ARM binary" - binary="pihole-FTL-arm-linux-gnueabi" - fi - else - echo -e "${OVER} ${TICK} Detected ARM architecture" - binary="pihole-FTL-arm-linux-gnueabi" - fi - elif [[ "${machine}" == "ppc" ]]; then - # PowerPC - echo -e "${OVER} ${TICK} Detected PowerPC architecture" - binary="pihole-FTL-powerpc-linux-gnu" - elif [[ "${machine}" == "x86_64" ]]; then - # 64bit - echo -e "${OVER} ${TICK} Detected x86_64 architecture" - binary="pihole-FTL-linux-x86_64" - else - # Something else - we try to use 32bit executable and warn the user - if [[ ! "${machine}" == "i686" ]]; then - echo -e "${OVER} ${CROSS} ${str}... - ${COL_LIGHT_RED}Not able to detect architecture (unknown: ${machine}), trying 32bit executable - Contact support if you experience issues (e.g: FTL not running)${COL_NC}" - else - echo -e "${OVER} ${TICK} Detected 32bit (i686) architecture" - fi - binary="pihole-FTL-linux-x86_32" - fi -} - fully_fetch_repo() { # Add upstream branches to shallow clone local directory="${1}" @@ -176,11 +92,6 @@ checkout_pull_branch() { git checkout "${branch}" --quiet || return 1 echo -e "${OVER} ${TICK} $str" - - if [[ "$(git diff "${oldbranch}" | grep -c "^")" -gt "0" ]]; then - update="true" - fi - git_pull=$(git pull || return 1) if [[ "$git_pull" == *"up-to-date"* ]]; then @@ -257,7 +168,6 @@ checkout() { local path path="development/${binary}" echo "development" > /etc/pihole/ftlbranch - FTLinstall "${binary}" "${path}" elif [[ "${1}" == "master" ]] ; then # Shortcut to check out master branches echo -e " ${INFO} Shortcut \"master\" detected - checking out master branches..." @@ -272,7 +182,6 @@ checkout() { local path path="master/${binary}" echo "master" > /etc/pihole/ftlbranch - FTLinstall "${binary}" "${path}" elif [[ "${1}" == "core" ]] ; then str="Fetching branches from ${piholeGitUrl}" echo -ne " ${INFO} $str" @@ -335,7 +244,6 @@ checkout() { if check_download_exists "$path"; then echo " ${TICK} Branch ${2} exists" echo "${2}" > /etc/pihole/ftlbranch - FTLinstall "${binary}" "${path}" else echo " ${CROSS} Requested branch \"${2}\" is not available" ftlbranches=( $(git ls-remote https://github.com/pi-hole/ftl | grep 'heads' | sed 's/refs\/heads\///;s/ //g' | awk '{print $2}') ) @@ -350,7 +258,7 @@ checkout() { fi # Force updating everything - if [[ ( ! "${1}" == "web" && ! "${1}" == "ftl" ) && "${update}" == "true" ]]; then + if [[ ! "${1}" == "web" ]]; then echo -e " ${INFO} Running installer to upgrade your installation" if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then exit 0 diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index a4ada4c8..f0deab2b 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -19,6 +19,9 @@ readonly PI_HOLE_FILES_DIR="/etc/.pihole" # shellcheck disable=SC2034 PH_TEST=true +# when --check-only is passed to this script, it will not perform the actual update +CHECK_ONLY=false + # shellcheck disable=SC1090 source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" # shellcheck disable=SC1091 @@ -28,9 +31,12 @@ source "/opt/pihole/COL_TABLE" # make_repo() sourced from basic-install.sh # update_repo() source from basic-install.sh # getGitFiles() sourced from basic-install.sh +# get_binary_name() sourced from basic-install.sh +# FTLcheckUpdate() sourced from basic-install.sh GitCheckUpdateAvail() { - local directory="${1}" + local directory + directory="${1}" curdir=$PWD cd "${directory}" || return @@ -77,24 +83,16 @@ GitCheckUpdateAvail() { fi } -FTLcheckUpdate() { - local FTLversion - FTLversion=$(/usr/bin/pihole-FTL tag) - local FTLlatesttag - FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n') - - if [[ "${FTLversion}" != "${FTLlatesttag}" ]]; then - return 0 - else - return 1 - fi -} - main() { - local pihole_version_current - local web_version_current local basicError="\\n ${COL_LIGHT_RED}Unable to complete update, please contact Pi-hole Support${COL_NC}" - + local core_update + local web_update + local FTL_update + + core_update=false + web_update=false + FTL_update=false + # shellcheck disable=1090,2154 source "${setupVars}" @@ -115,24 +113,6 @@ main() { echo -e " ${INFO} Pi-hole Core:\\t${COL_LIGHT_GREEN}up to date${COL_NC}" fi - if FTLcheckUpdate ; then - FTL_update=true - echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}update available${COL_NC}" - else - FTL_update=false - echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_GREEN}up to date${COL_NC}" - fi - - # Logic: Don't update FTL when there is a core update available - # since the core update will run the installer which will itself - # re-install (i.e. update) FTL - if ${FTL_update} && ! ${core_update}; then - echo "" - echo -e " ${INFO} FTL out of date" - FTLdetect - echo "" - fi - if [[ "${INSTALL_WEB}" == true ]]; then if ! is_repo "${ADMIN_INTERFACE_DIR}" ; then echo -e "\\n ${COL_LIGHT_RED}Error: Web Admin repo is missing from system! @@ -147,82 +127,56 @@ main() { web_update=false echo -e " ${INFO} Web Interface:\\t${COL_LIGHT_GREEN}up to date${COL_NC}" fi - - # Logic - # If Core up to date AND web up to date: - # Do nothing - # If Core up to date AND web NOT up to date: - # Pull web repo - # If Core NOT up to date AND web up to date: - # pull pihole repo, run install --unattended -- reconfigure - # if Core NOT up to date AND web NOT up to date: - # pull pihole repo run install --unattended - - if ! ${core_update} && ! ${web_update} ; then - if ! ${FTL_update} ; then - echo "" - echo -e " ${TICK} Everything is up to date!" - exit 0 - fi - elif ! ${core_update} && ${web_update} ; then - echo "" - echo -e " ${INFO} Pi-hole Web Admin files out of date" - getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}" - elif ${core_update} && ! ${web_update} ; then - echo "" - echo -e " ${INFO} Pi-hole core files out of date" - getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}" - ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || \ - echo -e "${basicError}" && exit 1 - elif ${core_update} && ${web_update} ; then - echo "" - echo -e " ${INFO} Updating Pi-hole core and web admin files" - getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}" - ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --unattended || \ - echo -e "${basicError}" && exit 1 - else - echo -e " ${COL_LIGHT_RED}Update script has malfunctioned, please contact Pi-hole Support${COL_NC}" - exit 1 - fi - else # Web Admin not installed, so only verify if core is up to date - if ! ${core_update}; then - if ! ${FTL_update} ; then - echo "" - echo -e " ${INFO} Everything is up to date!" - exit 0 - fi - else - echo "" - echo -e " ${INFO} Pi-hole Core files out of date" - getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}" - ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || \ - echo -e "${basicError}" && exit 1 - fi fi - if [[ "${web_update}" == true ]]; then - web_version_current="$(/usr/local/bin/pihole version --admin --current)" + if FTLcheckUpdate > /dev/null; then + FTL_update=true + echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}update available${COL_NC}" + else + FTL_update=false + echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_GREEN}up to date${COL_NC}" + fi + + if [[ "${core_update}" == false && "${web_update}" == false && "${FTL_update}" == false ]]; then echo "" - echo -e " ${INFO} Web Admin version is now at ${web_version_current/* v/v} - ${INFO} If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'" + echo -e " ${TICK} Everything is up to date!" + exit 0 + fi + + if [[ "${CHECK_ONLY}" == true ]]; then + echo "" + exit 0 fi if [[ "${core_update}" == true ]]; then - pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)" echo "" - echo -e " ${INFO} Pi-hole version is now at ${pihole_version_current/* v/v} - ${INFO} If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'" + echo -e " ${INFO} Pi-hole core files out of date, updating local repo." + getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}" + echo -e " ${INFO} If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'" + fi + + if [[ "${web_update}" == true ]]; then + echo "" + echo -e " ${INFO} Pi-hole Web Admin files out of date, updating local repo." + getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}" + echo -e " ${INFO} If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'" fi if [[ "${FTL_update}" == true ]]; then - FTL_version_current="$(/usr/bin/pihole-FTL tag)" - echo -e "\\n ${INFO} FTL version is now at ${FTL_version_current/* v/v}" - start_service pihole-FTL - enable_service pihole-FTL + echo "" + echo -e " ${INFO} FTL out of date, it will be updated by the installer." fi + if [[ "${FTL_update}" == true || "${core_update}" == true ]]; then + ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || \ + echo -e "${basicError}" && exit 1 + fi echo "" exit 0 } +if [[ "$1" == "--check-only" ]]; then + CHECK_ONLY=true +fi + main diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh index 5eb35e97..ce6c34d2 100755 --- a/advanced/Scripts/webpage.sh +++ b/advanced/Scripts/webpage.sh @@ -13,6 +13,7 @@ readonly setupVars="/etc/pihole/setupVars.conf" readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf" readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf" +readonly FTLconf="/etc/pihole/pihole-FTL.conf" # 03 -> wildcards readonly dhcpstaticconfig="/etc/dnsmasq.d/04-pihole-static-dhcp.conf" @@ -35,7 +36,7 @@ Options: -e, email Set an administrative contact address for the Block Page -h, --help Show this help dialog -i, interface Specify dnsmasq's interface listening behavior - Add '-h' for more info on interface usage" + -l, privacylevel Set privacy level (0 = lowest, 3 = highest)" exit 0 } @@ -52,6 +53,19 @@ change_setting() { add_setting "${1}" "${2}" } +addFTLsetting() { + echo "${1}=${2}" >> "${FTLconf}" +} + +deleteFTLsetting() { + sed -i "/${1}/d" "${FTLconf}" +} + +changeFTLsetting() { + deleteFTLsetting "${1}" + addFTLsetting "${1}" "${2}" +} + add_dnsmasq_setting() { if [[ "${2}" != "" ]]; then echo "${1}=${2}" >> "${dnsmasqconfig}" @@ -505,36 +519,44 @@ audit() echo "${args[2]}" >> /etc/pihole/auditlog.list } +SetPrivacyLevel() { + # Set privacy level. Minimum is 0, maximum is 3 + if [ "${args[2]}" -ge 0 ] && [ "${args[2]}" -le 3 ]; then + changeFTLsetting "PRIVACYLEVEL" "${args[2]}" + fi +} + main() { args=("$@") case "${args[1]}" in - "-p" | "password" ) SetWebPassword;; - "-c" | "celsius" ) unit="C"; SetTemperatureUnit;; - "-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;; - "-k" | "kelvin" ) unit="K"; SetTemperatureUnit;; - "setdns" ) SetDNSServers;; - "setexcludedomains" ) SetExcludeDomains;; - "setexcludeclients" ) SetExcludeClients;; - "poweroff" ) Poweroff;; - "reboot" ) Reboot;; - "restartdns" ) RestartDNS;; - "setquerylog" ) SetQueryLogOptions;; - "enabledhcp" ) EnableDHCP;; - "disabledhcp" ) DisableDHCP;; - "layout" ) SetWebUILayout;; - "-h" | "--help" ) helpFunc;; - "privacymode" ) SetPrivacyMode;; - "resolve" ) ResolutionSettings;; - "addstaticdhcp" ) AddDHCPStaticAddress;; - "removestaticdhcp" ) RemoveDHCPStaticAddress;; - "-r" | "hostrecord" ) SetHostRecord "$3";; - "-e" | "email" ) SetAdminEmail "$3";; - "-i" | "interface" ) SetListeningMode "$@";; - "-t" | "teleporter" ) Teleporter;; - "adlist" ) CustomizeAdLists;; - "audit" ) audit;; - * ) helpFunc;; + "-p" | "password" ) SetWebPassword;; + "-c" | "celsius" ) unit="C"; SetTemperatureUnit;; + "-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;; + "-k" | "kelvin" ) unit="K"; SetTemperatureUnit;; + "setdns" ) SetDNSServers;; + "setexcludedomains" ) SetExcludeDomains;; + "setexcludeclients" ) SetExcludeClients;; + "poweroff" ) Poweroff;; + "reboot" ) Reboot;; + "restartdns" ) RestartDNS;; + "setquerylog" ) SetQueryLogOptions;; + "enabledhcp" ) EnableDHCP;; + "disabledhcp" ) DisableDHCP;; + "layout" ) SetWebUILayout;; + "-h" | "--help" ) helpFunc;; + "privacymode" ) SetPrivacyMode;; + "resolve" ) ResolutionSettings;; + "addstaticdhcp" ) AddDHCPStaticAddress;; + "removestaticdhcp" ) RemoveDHCPStaticAddress;; + "-r" | "hostrecord" ) SetHostRecord "$3";; + "-e" | "email" ) SetAdminEmail "$3";; + "-i" | "interface" ) SetListeningMode "$@";; + "-t" | "teleporter" ) Teleporter;; + "adlist" ) CustomizeAdLists;; + "audit" ) audit;; + "-l" | "privacylevel" ) SetPrivacyLevel;; + * ) helpFunc;; esac shift diff --git a/advanced/pihole-FTL.service b/advanced/pihole-FTL.service index 959b7794..ef8ee9c2 100644 --- a/advanced/pihole-FTL.service +++ b/advanced/pihole-FTL.service @@ -20,6 +20,7 @@ is_running() { ps "$(get_pid)" > /dev/null 2>&1 } + # Start the service start() { if is_running; then @@ -29,9 +30,12 @@ start() { mkdir -p /var/run/pihole mkdir -p /var/log/pihole chown pihole:pihole /var/run/pihole /var/log/pihole - rm /var/run/pihole/FTL.sock - chown pihole:pihole /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /etc/pihole + rm /var/run/pihole/FTL.sock 2> /dev/null + chown pihole:pihole /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port + chown pihole:pihole /etc/pihole /etc/pihole/dhcp.leases /var/log/pihole.log chmod 0644 /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /var/log/pihole.log + setcap CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN+eip "$(which pihole-FTL)" + echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.piholeFTL su -s /bin/sh -c "/usr/bin/pihole-FTL" "$FTLUSER" echo fi @@ -40,6 +44,7 @@ start() { # Stop the service stop() { if is_running; then + /sbin/resolvconf -d lo.piholeFTL kill "$(get_pid)" for i in {1..5}; do if ! is_running; then diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index f786d703..160039ce 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -163,7 +163,7 @@ if command -v apt-get &> /dev/null; then # These programs are stored in an array so they can be looped through later INSTALLER_DEPS=(apt-utils dialog debconf dhcpcd5 git ${iproute_pkg} whiptail) # Pi-hole itself has several dependencies that also need to be installed - PIHOLE_DEPS=(bc cron curl dnsmasq dnsutils iputils-ping lsof netcat sudo unzip wget idn2 sqlite3) + PIHOLE_DEPS=(bc cron curl dnsutils iputils-ping lsof netcat sudo unzip wget idn2 sqlite3 libcap2-bin dns-root-data resolvconf) # The Web dashboard has some that also need to be installed # It's useful to separate the two since our repos are also setup as "Core" code and "Web" code PIHOLE_WEB_DEPS=(lighttpd ${phpVer}-common ${phpVer}-cgi ${phpVer}-${phpSqlite}) @@ -173,8 +173,6 @@ if command -v apt-get &> /dev/null; then LIGHTTPD_GROUP="www-data" # and config file LIGHTTPD_CFG="lighttpd.conf.debian" - # The DNS server user - DNSMASQ_USER="dnsmasq" # A function to check... test_dpkg_lock() { @@ -207,7 +205,7 @@ elif command -v rpm &> /dev/null; then PKG_INSTALL=(${PKG_MANAGER} install -y) PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l" INSTALLER_DEPS=(dialog git iproute net-tools newt procps-ng) - PIHOLE_DEPS=(bc bind-utils cronie curl dnsmasq findutils nmap-ncat sudo unzip wget libidn2 psmisc) + PIHOLE_DEPS=(bc bind-utils cronie curl findutils nmap-ncat sudo unzip wget libidn2 psmisc) PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php php-common php-cli php-pdo) # EPEL (https://fedoraproject.org/wiki/EPEL) is required for lighttpd on CentOS if grep -qi 'centos' /etc/redhat-release; then @@ -216,7 +214,6 @@ elif command -v rpm &> /dev/null; then LIGHTTPD_USER="lighttpd" LIGHTTPD_GROUP="lighttpd" LIGHTTPD_CFG="lighttpd.conf.fedora" - DNSMASQ_USER="nobody" # If neither apt-get or rmp/dnf are found else @@ -996,6 +993,10 @@ version_check_dnsmasq() { fi echo -en " ${INFO} Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..." + # Check to see if dnsmasq directory exists (it may not due to being a fresh install and dnsmasq no longer being a dependency) + if [[ ! -d "/etc/dnsmasq.d" ]];then + mkdir "/etc/dnsmasq.d" + fi # Copy the new Pi-hole DNS config file into the dnsmasq.d directory cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location} echo -e "${OVER} ${TICK} Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf" @@ -1124,7 +1125,6 @@ stop_service() { # Stop service passed in as argument. # Can softfail, as process may not be installed when this is called local str="Stopping ${1} service" - echo "" echo -ne " ${INFO} ${str}..." if command -v systemctl &> /dev/null; then systemctl stop "${1}" &> /dev/null || true @@ -1138,7 +1138,6 @@ stop_service() { start_service() { # Local, named variables local str="Starting ${1} service" - echo "" echo -ne " ${INFO} ${str}..." # If systemctl exists, if command -v systemctl &> /dev/null; then @@ -1156,13 +1155,12 @@ start_service() { enable_service() { # Local, named variables local str="Enabling ${1} service to start on reboot" - echo "" echo -ne " ${INFO} ${str}..." # If systemctl exists, if command -v systemctl &> /dev/null; then # use that to enable the service systemctl enable "${1}" &> /dev/null - # Othwerwise, + # Otherwise, else # use update-rc.d to accomplish this update-rc.d "${1}" defaults &> /dev/null @@ -1170,6 +1168,35 @@ enable_service() { echo -e "${OVER} ${TICK} ${str}" } +# Disable service so that it will not with next reboot +disable_service() { + # Local, named variables + local str="Disabling ${1} service" + echo -ne " ${INFO} ${str}..." + # If systemctl exists, + if command -v systemctl &> /dev/null; then + # use that to disable the service + systemctl disable "${1}" &> /dev/null + # Otherwise, + else + # use update-rc.d to accomplish this + update-rc.d "${1}" disable &> /dev/null + fi + echo -e "${OVER} ${TICK} ${str}" +} + +check_service_active() { + # If systemctl exists, + if command -v systemctl &> /dev/null; then + # use that to check the status of the service + systemctl is-enabled "${1}" > /dev/null + # Otherwise, + else + # fall back to service command + service "${1}" status > /dev/null + fi +} + update_package_cache() { # Running apt-get update/upgrade with minimal output can cause some issues with # requiring user input (e.g password for phpmyadmin see #218) @@ -1296,27 +1323,6 @@ install_dependent_packages() { return 0 } -# Create logfiles if necessary -CreateLogFile() { - local str="Creating log and changing owner to dnsmasq" - echo "" - echo -ne " ${INFO} ${str}..." - # If the pihole log does not exist, - if [[ ! -f "/var/log/pihole.log" ]]; then - # Make it, - touch /var/log/pihole.log - # set the permissions, - chmod 644 /var/log/pihole.log - # and owners - chown "${DNSMASQ_USER}":root /var/log/pihole.log - echo -e "${OVER} ${TICK} ${str}" - # Otherwise, - else - # the file should already exist - echo -e " ${COL_LIGHT_GREEN}log already exists!${COL_NC}" - fi -} - # Install the Web interface dashboard installPiholeWeb() { echo "" @@ -1343,7 +1349,7 @@ installPiholeWeb() { # back it up mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig echo -e "${OVER} ${TICK} ${str}" - # Othwerwise, + # Otherwise, else # don't do anything echo -e "${OVER} ${CROSS} ${str} @@ -1402,7 +1408,7 @@ create_pihole_user() { if id -u pihole &> /dev/null; then # just show a success echo -ne "${OVER} ${TICK} ${str}" - # Othwerwise, + # Otherwise, else echo -ne "${OVER} ${CROSS} ${str}" local str="Creating user 'pihole'" @@ -1421,7 +1427,7 @@ configureFirewall() { # ask if the user wants to install Pi-hole's default firwall rules whiptail --title "Firewall in use" --yesno "We have detected a running firewall\\n\\nPi-hole currently requires HTTP and DNS port access.\\n\\n\\n\\nInstall Pi-hole default firewall rules?" ${r} ${c} || \ { echo -e " ${INFO} Not installing firewall rulesets."; return 0; } - echo -e " ${TICK} Configuring FirewallD for httpd and dnsmasq" + echo -e " ${TICK} Configuring FirewallD for httpd and pihole-FTL" # Allow HTTP and DNS traffice firewall-cmd --permanent --add-service=http --add-service=dns # Reload the firewall to apply these changes @@ -1442,7 +1448,7 @@ configureFirewall() { iptables -C INPUT -p tcp -m tcp --dport 4711:4720 -i lo -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 4711:4720 -i lo -j ACCEPT return 0 fi - # Othwerwise, + # Otherwise, else # no firewall is running echo -e " ${INFO} No active firewall detected.. skipping firewall configuration" @@ -1548,8 +1554,6 @@ installPihole() { installScripts # configs, installConfigs - # and create the log file - CreateLogFile # If the user wants to install the dashboard, if [[ "${INSTALL_WEB}" == true ]]; then # do so @@ -1585,9 +1589,7 @@ updatePihole() { # Install base files and web interface installScripts # Install config files - installConfigs - # Create the log file - CreateLogFile + installConfigs # If the user wants to install the dasboard, if [[ "${INSTALL_WEB}" == true ]]; then # do so @@ -1750,15 +1752,32 @@ FTLinstall() { fi # Move into the temp ftl directory - pushd "$(mktemp -d)" || { echo "Unable to make temporary directory for FTL binary download"; return 1; } + pushd "$(mktemp -d)" > /dev/null || { echo "Unable to make temporary directory for FTL binary download"; return 1; } # Always replace pihole-FTL.service install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/pihole-FTL.service" "/etc/init.d/pihole-FTL" + local ftlBranch + local url + local ftlBranch + + if [[ -f "/etc/pihole/ftlbranch" ]];then + ftlBranch=$( /dev/null || { echo "Unable to return to original directory after FTL binary download."; return 1; } # Install the FTL service echo -e "${OVER} ${TICK} ${str}" + # If the --resolver flag returns True (exit code 0), then we can safely stop & disable dnsmasq + if pihole-FTL --resolver > /dev/null; then + if which dnsmasq > /dev/null; then + if check_service_active "dnsmasq";then + echo " ${INFO} FTL can now resolve DNS Queries without dnsmasq running separately" + stop_service dnsmasq + disable_service dnsmasq + fi + fi + + #ensure /etc/dnsmasq.conf contains `conf-dir=/etc/dnsmasq.d` + confdir="conf-dir=/etc/dnsmasq.d" + conffile="/etc/dnsmasq.conf" + if ! grep -q "$confdir" "$conffile"; then + echo "$confdir" >> "$conffile" + fi + fi return 0 # Otherise, else # the download failed, so just go back to the original directory - popd || { echo "Unable to return to original directory after FTL binary download."; return 1; } + popd > /dev/null || { echo "Unable to return to original directory after FTL binary download."; return 1; } echo -e "${OVER} ${CROSS} ${str}" echo -e " ${COL_LIGHT_RED}Error: Download of binary from Github failed${COL_NC}" return 1 fi # Otherwise, else - popd || { echo "Unable to return to original directory after FTL binary download."; return 1; } + popd > /dev/null || { echo "Unable to return to original directory after FTL binary download."; return 1; } echo -e "${OVER} ${CROSS} ${str}" # The URL could not be found echo -e " ${COL_LIGHT_RED}Error: URL not found${COL_NC}" @@ -1790,15 +1826,9 @@ FTLinstall() { fi } -# Detect suitable FTL binary platform -FTLdetect() { - echo "" - echo -e " ${INFO} FTL Checks..." - - # Local, named variables +get_binary_name() { +# Local, named variables local machine - local binary - # Store architecture in a variable machine=$(uname -m) @@ -1857,37 +1887,86 @@ FTLdetect() { fi binary="pihole-FTL-linux-x86_32" fi +} + +FTLcheckUpdate() +{ + get_binary_name #In the next section we check to see if FTL is already installed (in case of pihole -r). #If the installed version matches the latest version, then check the installed sha1sum of the binary vs the remote sha1sum. If they do not match, then download echo -e " ${INFO} Checking for existing FTL binary..." - local ftlLoc=$(which pihole-FTL 2>/dev/null) + local ftlLoc + ftlLoc=$(which pihole-FTL 2>/dev/null) - if [[ ${ftlLoc} ]]; then - local FTLversion=$(/usr/bin/pihole-FTL tag) - local FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n') + local ftlBranch - if [[ "${FTLversion}" != "${FTLlatesttag}" ]]; then - # Install FTL - FTLinstall "${binary}" || return 1 - else - echo -e " ${INFO} Latest FTL Binary already installed (${FTLlatesttag}). Confirming Checksum..." + if [[ -f "/etc/pihole/ftlbranch" ]];then + ftlBranch=$(/dev/null) ]]; then + if pihole-FTL --resolver > /dev/null; then + stop_service pihole-FTL + else + stop_service dnsmasq + fi + else + if [[ $(which dnsmasq 2>/dev/null) ]]; then + stop_service dnsmasq + fi + fi + if [[ "${INSTALL_WEB}" == true ]]; then stop_service lighttpd fi @@ -2092,8 +2183,11 @@ main() { echo -e " ${INFO} Restarting services..." # Start services - start_service dnsmasq - enable_service dnsmasq + # Only start and enable dnsmasq if FTL does not have the --resolver switch + if ! pihole-FTL --resolver > /dev/null; then + start_service dnsmasq + enable_service dnsmasq + fi # If the Web server was installed, if [[ "${INSTALL_WEB}" == true ]]; then @@ -2155,6 +2249,10 @@ main() { echo -e "\\n ${INFO} The install log is located at: ${installLogLoc} ${COL_LIGHT_GREEN}${INSTALL_TYPE} Complete! ${COL_NC}" + if [[ "${INSTALL_TYPE}" == "Update" ]]; then + echo "" + /usr/local/bin/pihole version --current + fi } # diff --git a/gravity.sh b/gravity.sh index 011d2f8c..7fdb2723 100755 --- a/gravity.sh +++ b/gravity.sh @@ -44,6 +44,8 @@ preEventHorizon="list.preEventHorizon" skipDownload="false" +resolver="pihole-FTL" + # Source setupVars from install script setupVars="${piholeDir}/setupVars.conf" if [[ -f "${setupVars}" ]];then @@ -104,7 +106,7 @@ gravity_CheckDNSResolutionAvailable() { fi # Determine error output message - if pidof dnsmasq &> /dev/null; then + if pidof ${resolver} &> /dev/null; then echo -e " ${CROSS} DNS resolution is currently unavailable" else echo -e " ${CROSS} DNS service is not running" @@ -513,9 +515,11 @@ gravity_ParseBlacklistDomains() { if [[ -f "${piholeDir}/${whitelistMatter}" ]]; then gravity_ParseDomainsIntoHosts "${piholeDir}/${whitelistMatter}" "${piholeDir}/${accretionDisc}" + grep -c "^" "${piholeDir}/${whitelistMatter}" > "${piholeDir}/numBlocked" 2> /dev/null else # There was no whitelist file, so use preEventHorizon instead of whitelistMatter. gravity_ParseDomainsIntoHosts "${piholeDir}/${preEventHorizon}" "${piholeDir}/${accretionDisc}" + grep -c "^" "${piholeDir}/${preEventHorizon}" > "${piholeDir}/numBlocked" 2> /dev/null fi # Move the file over as /etc/pihole/gravity.list so dnsmasq can use it @@ -572,7 +576,7 @@ gravity_Cleanup() { echo -e "${OVER} ${TICK} ${str}" # Only restart DNS service if offline - if ! pidof dnsmasq &> /dev/null; then + if ! pidof ${resolver} &> /dev/null; then "${PIHOLE_COMMAND}" restartdns dnsWasOffline=true fi diff --git a/pihole b/pihole index 566a0ce4..cb75861b 100755 --- a/pihole +++ b/pihole @@ -14,6 +14,8 @@ readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf" readonly colfile="${PI_HOLE_SCRIPT_DIR}/COL_TABLE" source "${colfile}" +resolver="pihole-FTL" + # Must be root to use this tool if [[ ! $EUID -eq 0 ]];then if [[ -x "$(command -v sudo)" ]]; then @@ -69,7 +71,8 @@ flushFunc() { } updatePiholeFunc() { - "${PI_HOLE_SCRIPT_DIR}"/update.sh + shift + "${PI_HOLE_SCRIPT_DIR}"/update.sh "$@" exit 0 } @@ -332,18 +335,18 @@ restartDNS() { local svcOption svc str output status svcOption="${1:-}" - # Determine if we should reload or restart dnsmasq + # Determine if we should reload or restart restart if [[ "${svcOption}" =~ "reload" ]]; then # Using SIGHUP will NOT re-read any *.conf files - svc="killall -s SIGHUP dnsmasq" + svc="killall -s SIGHUP ${resolver}" else - # Get PID of dnsmasq to determine if it needs to start or restart - if pidof dnsmasq &> /dev/null; then + # Get PID of resolver to determine if it needs to start or restart + if pidof pihole-FTL &> /dev/null; then svcOption="restart" else svcOption="start" fi - svc="service dnsmasq ${svcOption}" + svc="service ${resolver} ${svcOption}" fi # Print output to Terminal, but not to Web Admin @@ -359,9 +362,6 @@ restartDNS() { [[ ! -t 1 ]] && local OVER="" echo -e "${OVER} ${CROSS} ${output}" fi - - # Send signal to FTL to have it re-parse the gravity files - killall -s SIGHUP pihole-FTL } piholeEnable() { @@ -621,6 +621,7 @@ Options: -q, query Query the adlists for a specified domain Add '-h' for more info on query usage -up, updatePihole Update Pi-hole subsystems + Add '--check-only' to exit script before update is performed. -v, version Show installed versions of Pi-hole, Admin Console & FTL Add '-h' for more info on version usage uninstall Uninstall Pi-hole from your system @@ -645,7 +646,7 @@ case "${1}" in "-wild" | "wildcard" ) wildcardFunc "$@";; "-d" | "debug" ) debugFunc "$@";; "-f" | "flush" ) flushFunc "$@";; - "-up" | "updatePihole" ) updatePiholeFunc;; + "-up" | "updatePihole" ) updatePiholeFunc "$@";; "-r" | "reconfigure" ) reconfigurePiholeFunc;; "-g" | "updateGravity" ) updateGravityFunc "$@";; "-c" | "chronometer" ) chronometerFunc "$@";; diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 0e961c7f..2c65c660 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -80,7 +80,7 @@ def test_configureFirewall_firewalld_running_no_errors(Pihole): source /opt/pihole/basic-install.sh configureFirewall ''') - expected_stdout = 'Configuring FirewallD for httpd and dnsmasq' + expected_stdout = 'Configuring FirewallD for httpd and pihole-FTL' assert expected_stdout in configureFirewall.stdout firewall_calls = Pihole.run('cat /var/log/firewall-cmd').stdout assert 'firewall-cmd --state' in firewall_calls