diff --git a/advanced/01-pihole.conf b/advanced/01-pihole.conf index af46e918..502293bf 100644 --- a/advanced/01-pihole.conf +++ b/advanced/01-pihole.conf @@ -22,9 +22,6 @@ addn-hosts=/etc/pihole/gravity.list addn-hosts=/etc/pihole/black.list addn-hosts=/etc/pihole/local.list -user=pihole -group=pihole - domain-needed localise-queries diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh index 977d1552..1bfe5e21 100644 --- a/advanced/Scripts/piholeCheckout.sh +++ b/advanced/Scripts/piholeCheckout.sh @@ -167,7 +167,7 @@ checkout() { echo " ${TICK} Branch ${2} exists" echo "${2}" > /etc/pihole/ftlbranch FTLinstall "${binary}" - start_service pihole-FTL + restart_service pihole-FTL enable_service pihole-FTL else echo " ${CROSS} Requested branch \"${2}\" is not available" diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh index 281425bf..15c005b8 100755 --- a/advanced/Scripts/piholeDebug.sh +++ b/advanced/Scripts/piholeDebug.sh @@ -76,7 +76,7 @@ WEB_SERVER_CONFIG_DIRECTORY="/etc/lighttpd" HTML_DIRECTORY="/var/www/html" WEB_GIT_DIRECTORY="${HTML_DIRECTORY}/admin" #BLOCK_PAGE_DIRECTORY="${HTML_DIRECTORY}/pihole" -SHM_DIRECTORY="/var/run/shm" +SHM_DIRECTORY="/dev/shm" # Files required by Pi-hole # https://discourse.pi-hole.net/t/what-files-does-pi-hole-use/1684 @@ -269,6 +269,9 @@ compare_local_version_to_git_version() { # The commit they are on local remote_commit remote_commit=$(git describe --long --dirty --tags --always) + # Status of the repo + local local_status + local_status=$(git status -s) # echo this information out to the user in a nice format # If the current version matches what pihole -v produces, the user is up-to-date if [[ "${remote_version}" == "$(pihole -v | awk '/${search_term}/ {print $6}' | cut -d ')' -f1)" ]]; then @@ -291,6 +294,16 @@ compare_local_version_to_git_version() { fi # echo the current commit log_write "${INFO} Commit: ${remote_commit}" + # if `local_status` is non-null, then the repo is not clean, display details here + if [[ ${local_status} ]]; then + #Replace new lines in the status with 12 spaces to make the output cleaner + log_write "${INFO} Status: ${local_status//$'\n'/'\n '}" + local local_diff + local_diff=$(git diff) + if [[ ${local_diff} ]]; then + log_write "${INFO} Diff: ${local_diff//$'\n'/'\n '}" + fi + fi # If git status failed, else # Return an error message diff --git a/advanced/Templates/pihole-FTL.service b/advanced/Templates/pihole-FTL.service index d19e2bd5..9eb183ed 100644 --- a/advanced/Templates/pihole-FTL.service +++ b/advanced/Templates/pihole-FTL.service @@ -33,6 +33,8 @@ start() { mkdir -p /var/run/pihole mkdir -p /var/log/pihole chown pihole:pihole /var/run/pihole /var/log/pihole + # Remove possible leftovers from previous pihole-FTL processes + rm -f /dev/shm/FTL-* 2> /dev/null rm /var/run/pihole/FTL.sock 2> /dev/null # Ensure that permissions are set so that pihole-FTL can edit all necessary files chown pihole:pihole /run/pihole-FTL.pid /run/pihole-FTL.port diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index f2887bc7..110399f8 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -52,9 +52,12 @@ lighttpdConfig=/etc/lighttpd/lighttpd.conf # This is a file used for the colorized output coltable=/opt/pihole/COL_TABLE +# Root of the web server +webroot="/var/www/html" + # We store several other directories and webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git" -webInterfaceDir="/var/www/html/admin" +webInterfaceDir="${webroot}/admin" piholeGitUrl="https://github.com/pi-hole/pi-hole.git" PI_HOLE_LOCAL_REPO="/etc/.pihole" # These are the names of pi-holes files, stored in an array @@ -62,6 +65,7 @@ PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update versi # This directory is where the Pi-hole scripts will be installed PI_HOLE_INSTALL_DIR="/opt/pihole" PI_HOLE_CONFIG_DIR="/etc/pihole" +PI_HOLE_BLOCKPAGE_DIR="${webroot}/pihole" useUpdateVars=false adlistFile="/etc/pihole/adlists.list" @@ -129,6 +133,9 @@ else OVER="\\r\\033[K" fi +# Define global binary variable +binary="tbd" + # A simple function that just echoes out our logo in ASCII format # This lets users know that it is a Pi-hole, LLC product show_ascii_berry() { @@ -870,6 +877,13 @@ setStaticIPv4() { # Local, named variables local IFCFG_FILE local CONNECTION_NAME + + # If a static interface is already configured, we are done. + if [[ -r "/etc/sysconfig/network/ifcfg-${PIHOLE_INTERFACE}" ]]; then + if grep -q '^BOOTPROTO=.static.' "/etc/sysconfig/network/ifcfg-${PIHOLE_INTERFACE}"; then + return 0 + fi + fi # For the Debian family, if dhcpcd.conf exists, if [[ -f "/etc/dhcpcd.conf" ]]; then # configure networking via dhcpcd @@ -1348,8 +1362,9 @@ installConfigs() { echo "${DNS_SERVERS}" > "${PI_HOLE_CONFIG_DIR}/dns-servers.conf" # Install empty file if it does not exist - if [[ ! -f "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" ]]; then - if ! install -o pihole -g pihole -m 664 /dev/null "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" &>/dev/null; then + if [[ ! -r "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" ]]; then + install -d -m 0755 ${PI_HOLE_CONFIG_DIR} + if ! install -o pihole -m 664 /dev/null "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" &>/dev/null; then printf " %bError: Unable to initialize configuration file %s/pihole-FTL.conf\\n" "${COL_LIGHT_RED}" "${PI_HOLE_CONFIG_DIR}" return 1 fi @@ -1377,7 +1392,7 @@ installConfigs() { # Make sure the external.conf file exists, as lighttpd v1.4.50 crashes without it touch /etc/lighttpd/external.conf # if there is a custom block page in the html/pihole directory, replace 404 handler in lighttpd config - if [[ -f "/var/www/html/pihole/custom.php" ]]; then + if [[ -f "${PI_HOLE_BLOCKPAGE_DIR}/custom.php" ]]; then sed -i 's/^\(server\.error-handler-404\s*=\s*\).*$/\1"pihole\/custom\.php"/' /etc/lighttpd/lighttpd.conf fi # Make the directories if they do not exist and set the owners @@ -1442,9 +1457,9 @@ stop_service() { } # Start/Restart service passed in as argument -start_service() { +restart_service() { # Local, named variables - local str="Starting ${1} service" + local str="Restarting ${1} service" printf " %b %s..." "${INFO}" "${str}" # If systemctl exists, if is_command systemctl ; then @@ -1643,13 +1658,13 @@ installPiholeWeb() { local str="Creating directory for blocking page, and copying files" printf " %b %s..." "${INFO}" "${str}" # Install the directory - install -d /var/www/html/pihole + install -d -m 0755 ${PI_HOLE_BLOCKPAGE_DIR} # and the blockpage - install -D ${PI_HOLE_LOCAL_REPO}/advanced/{index,blockingpage}.* /var/www/html/pihole/ + install -D ${PI_HOLE_LOCAL_REPO}/advanced/{index,blockingpage}.* ${PI_HOLE_BLOCKPAGE_DIR}/ # Remove superseded file - if [[ -e "/var/www/html/pihole/index.js" ]]; then - rm "/var/www/html/pihole/index.js" + if [[ -e "${PI_HOLE_BLOCKPAGE_DIR}/index.js" ]]; then + rm "${PI_HOLE_BLOCKPAGE_DIR}/index.js" fi printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}" @@ -1657,9 +1672,9 @@ installPiholeWeb() { local str="Backing up index.lighttpd.html" printf " %b %s..." "${INFO}" "${str}" # If the default index file exists, - if [[ -f "/var/www/html/index.lighttpd.html" ]]; then + if [[ -f "${webroot}/index.lighttpd.html" ]]; then # back it up - mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig + mv ${webroot}/index.lighttpd.html ${webroot}/index.lighttpd.orig printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}" # Otherwise, else @@ -1674,7 +1689,7 @@ installPiholeWeb() { # Make the .d directory if it doesn't exist mkdir -p /etc/sudoers.d/ # and copy in the pihole sudoers file - cp ${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole.sudo /etc/sudoers.d/pihole + install -m 0640 ${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole.sudo /etc/sudoers.d/pihole # Add lighttpd user (OS dependent) to sudoers file echo "${LIGHTTPD_USER} ALL=NOPASSWD: /usr/local/bin/pihole" >> /etc/sudoers.d/pihole @@ -1869,15 +1884,15 @@ installPihole() { # If the user wants to install the Web interface, if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then - if [[ ! -d "/var/www/html" ]]; then + if [[ ! -d "${webroot}" ]]; then # make the Web directory if necessary - mkdir -p /var/www/html + install -d -m 0755 ${webroot} fi if [[ "${INSTALL_WEB_SERVER}" == true ]]; then # Set the owner and permissions - chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html - chmod 775 /var/www/html + chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} ${webroot} + chmod 0775 ${webroot} # Give pihole access to the Web server group usermod -a -G ${LIGHTTPD_GROUP} pihole # If the lighttpd command is executable, @@ -1914,8 +1929,9 @@ installPihole() { installCron # Install the logrotate file installLogrotate - # Check if FTL is installed - FTLdetect || printf " %b FTL Engine not installed\\n" "${CROSS}" + # Check if dnsmasq is present. If so, disable it and back up any possible + # config file + disable_dnsmasq # Configure the firewall if [[ "${useUpdateVars}" == false ]]; then configureFirewall @@ -2138,7 +2154,6 @@ clone_or_update_repos() { # Download FTL binary to random temp directory and install FTL binary FTLinstall() { # Local, named variables - local binary="${1}" local latesttag local str="Downloading and Installing FTL" printf " %b %s..." "${INFO}" "${str}" @@ -2186,33 +2201,17 @@ FTLinstall() { # Before stopping FTL, we download the macvendor database curl -sSL "https://ftl.pi-hole.net/macvendor.db" -o "${PI_HOLE_CONFIG_DIR}/macvendor.db" || true - # Stop FTL + # Stop pihole-FTL service if available stop_service pihole-FTL &> /dev/null + # Install the new version with the correct permissions install -T -m 0755 "${binary}" /usr/bin/pihole-FTL + # Move back into the original directory the user was in popd > /dev/null || { printf "Unable to return to original directory after FTL binary download.\\n"; return 1; } - # Install the FTL service + + # Installed the FTL service printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}" - # dnsmasq can now be stopped and disabled if it exists - if which dnsmasq &> /dev/null; then - if check_service_active "dnsmasq";then - printf " %b FTL can now resolve DNS Queries without dnsmasq running separately\\n" "${INFO}" - stop_service dnsmasq - disable_service dnsmasq - fi - fi - - # Backup existing /etc/dnsmasq.conf if present and ensure that - # /etc/dnsmasq.conf contains only "conf-dir=/etc/dnsmasq.d" - local conffile="/etc/dnsmasq.conf" - if [[ -f "${conffile}" ]]; then - printf " %b Backing up %s to %s.old\\n" "${INFO}" "${conffile}" "${conffile}" - mv "${conffile}" "${conffile}.old" - fi - # Create /etc/dnsmasq.conf - echo "conf-dir=/etc/dnsmasq.d" > "${conffile}" - return 0 # Otherwise, else @@ -2232,6 +2231,27 @@ FTLinstall() { fi } +disable_dnsmasq() { + # dnsmasq can now be stopped and disabled if it exists + if which dnsmasq &> /dev/null; then + if check_service_active "dnsmasq";then + printf " %b FTL can now resolve DNS Queries without dnsmasq running separately\\n" "${INFO}" + stop_service dnsmasq + disable_service dnsmasq + fi + fi + + # Backup existing /etc/dnsmasq.conf if present and ensure that + # /etc/dnsmasq.conf contains only "conf-dir=/etc/dnsmasq.d" + local conffile="/etc/dnsmasq.conf" + if [[ -f "${conffile}" ]]; then + printf " %b Backing up %s to %s.old\\n" "${INFO}" "${conffile}" "${conffile}" + mv "${conffile}" "${conffile}.old" + fi + # Create /etc/dnsmasq.conf + echo "conf-dir=/etc/dnsmasq.d" > "${conffile}" +} + get_binary_name() { # This gives the machine architecture which may be different from the OS architecture... local machine @@ -2389,7 +2409,7 @@ FTLdetect() { printf "\\n %b FTL Checks...\\n\\n" "${INFO}" if FTLcheckUpdate ; then - FTLinstall "${binary}" || return 1 + FTLinstall || return 1 fi } @@ -2549,6 +2569,11 @@ main() { else LIGHTTPD_ENABLED=false fi + # Check if FTL is installed - do this early on as FTL is a hard dependency for Pi-hole + if ! FTLdetect; then + printf " %b FTL Engine not installed\\n" "${CROSS}" + exit 1 + fi # Install and log everything to a file installPihole | tee -a /proc/$$/fd/3 @@ -2579,7 +2604,7 @@ main() { if [[ "${INSTALL_WEB_SERVER}" == true ]]; then if [[ "${LIGHTTPD_ENABLED}" == true ]]; then - start_service lighttpd + restart_service lighttpd enable_service lighttpd else printf " %b Lighttpd is disabled, skipping service restart\\n" "${INFO}" @@ -2594,7 +2619,7 @@ main() { # Fixes a problem reported on Ubuntu 18.04 where trying to start # the service before enabling causes installer to exit enable_service pihole-FTL - start_service pihole-FTL + restart_service pihole-FTL # Download and compile the aggregated block list runGravity diff --git a/pihole b/pihole index fff3417d..84a5623f 100755 --- a/pihole +++ b/pihole @@ -144,6 +144,10 @@ Time: elif [[ "${1}" == "0" ]]; then # Disable Pi-hole + if grep -cq "BLOCKING_ENABLED=false" "${setupVars}"; then + echo -e " ${INFO} Blocking already disabled, nothing to do" + exit 0 + fi if [[ -e "${gravitylist}" ]]; then mv "${gravitylist}" "${gravitylist}.bck" echo "" > "${gravitylist}" @@ -193,6 +197,10 @@ Time: fi else # Enable Pi-hole + if grep -cq "BLOCKING_ENABLED=true" "${setupVars}"; then + echo -e " ${INFO} Blocking already enabled, nothing to do" + exit 0 + fi echo -e " ${INFO} Enabling blocking" local str="Pi-hole Enabled" diff --git a/test/test_automated_install.py b/test/test_automated_install.py index a2593d83..853048d1 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -481,10 +481,10 @@ def test_FTL_download_aarch64_no_errors(Pihole): ''' confirms only aarch64 package is downloaded for FTL engine ''' - # mock uname to return generic platform download_binary = Pihole.run(''' source /opt/pihole/basic-install.sh - FTLinstall pihole-FTL-aarch64-linux-gnu + binary="pihole-FTL-aarch64-linux-gnu" + FTLinstall ''') expected_stdout = tick_box + ' Downloading and Installing FTL' assert expected_stdout in download_binary.stdout @@ -495,10 +495,26 @@ def test_FTL_download_unknown_fails_no_errors(Pihole): ''' confirms unknown binary is not downloaded for FTL engine ''' - # mock uname to return generic platform download_binary = Pihole.run(''' source /opt/pihole/basic-install.sh - FTLinstall pihole-FTL-mips + binary="pihole-FTL-mips" + FTLinstall + ''') + expected_stdout = cross_box + ' Downloading and Installing FTL' + assert expected_stdout in download_binary.stdout + error1 = 'Error: URL https://github.com/pi-hole/FTL/releases/download/' + assert error1 in download_binary.stdout + error2 = 'not found' + assert error2 in download_binary.stdout + + +def test_FTL_download_binary_unset_no_errors(Pihole): + ''' + confirms unset binary variable does not download FTL engine + ''' + download_binary = Pihole.run(''' + source /opt/pihole/basic-install.sh + FTLinstall ''') expected_stdout = cross_box + ' Downloading and Installing FTL' assert expected_stdout in download_binary.stdout