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/README.md b/README.md index b7f4f249..60c54f87 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Network-wide ad blocking via your own Linux hardware

-The Pi-hole is a [DNS sinkhole](https://en.wikipedia.org/wiki/DNS_Sinkhole) that protects your devices from unwanted content, without installing any client-side software. +The Pi-hole[®](https://pi-hole.net/trademark-rules-and-brand-guidelines/) is a [DNS sinkhole](https://en.wikipedia.org/wiki/DNS_Sinkhole) that protects your devices from unwanted content, without installing any client-side software. - **Easy-to-install**: our versatile installer walks you through the process, and [takes less than ten minutes](https://www.youtube.com/watch?v=vKWjx1AQYgs) - **Resolute**: content is blocked in _non-browser locations_, such as ad-laden mobile apps and smart TVs @@ -27,7 +27,7 @@ Those who want to get started quickly and conveniently, may install Pi-hole usin #### `curl -sSL https://install.pi-hole.net | bash` ## Alternative Install Methods -[Piping to `bash` is controversial](https://pi-hole.net/2016/07/25/curling-and-piping-to-bash), as it prevents you from [reading code that is about to run](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) on your system. Therefore, we provide these alternative installation methods which allow code review before installation: +[Piping to `bash` is controversial](https://pi-hole.net/2016/07/25/curling-and-piping-to-bash), as it prevents you from [reading code that is about to run](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) on your system. Therefore, we provide these alternative installation methods which allow code review before installation: ### Method 1: Clone our repository and run ``` @@ -60,16 +60,22 @@ Make no mistake: **your support is absolutely vital to help keep us innovating!* ### Donations Sending a donation using our links below is **extremely helpful** in offsetting a portion of our monthly expenses: - PP Donate via PayPal
BTC Bitcoin Address: 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL +- PP Donate via PayPal
+- BTC [Bitcoin](https://commerce.coinbase.com/checkout/fb7facaf-bebd-46be-bb77-b358f4546763): +3MDPzjXu2hjw5sGLJvKUi1uXbvQPzVrbpF
+- BTC [Bitcoin Cash](https://commerce.coinbase.com/checkout/fb7facaf-bebd-46be-bb77-b358f4546763): qzqsz4aju2eecc6uhs7tus4vlwhhela24sdruf4qp5
+- BTC [Ethereum](https://commerce.coinbase.com/checkout/fb7facaf-bebd-46be-bb77-b358f4546763): 0x79d4e90A4a0C732819526c93e21A3F1356A2FAe1 ### Alternative support -If you'd rather not donate (_which is okay!_), there are other ways you can help support us: +If you'd rather not [donate](https://pi-hole.net/donate/) (_which is okay!_), there are other ways you can help support us: -- [Digital Ocean](http://www.digitalocean.com/?refcode=344d234950e1) affiliate link -- [Vultr](http://www.vultr.com/?ref=7190426) affiliate link -- [UNIXstickers.com](http://unixstickers.refr.cc/jacobs) affiliate link -- [Pi-hole Swag Store](https://pi-hole.net/shop/) +- [Digital Ocean](http://www.digitalocean.com/?refcode=344d234950e1) _affiliate link_ +- [UNIXstickers.com](http://unixstickers.refr.cc/jacobs) _save $5 when you spend $9 using our affiliate link_ +- [Pi-hole Swag Store](https://pi-hole.net/shop/) _affiliate link_ +- [Amazon](http://www.amazon.com/exec/obidos/redirect-home/pihole09-20) _affiliate link_ +- [Ho-ost](https://clients.ho-ost.com/aff.php?aff=19) _save 50% with our affiliate link_ +- [DNS Made Easy](https://cp.dnsmadeeasy.com/u/133706) _affiliate link_ +- [Vultr](http://www.vultr.com/?ref=7190426) _affiliate link_ - Spreading the word about our software, and how you have benefited from it ### Contributing via GitHub @@ -127,7 +133,7 @@ You can read our [Core Feature Breakdown](https://github.com/pi-hole/pi-hole/wik ### The Web Interface Dashboard This [optional dashboard](https://github.com/pi-hole/AdminLTE) allows you to view stats, change settings, and configure your Pi-hole. It's the power of the Command Line Interface, with none of the learning curve! -Pi-hole Dashboard +Pi-hole Dashboard Some notable features include: * Mobile friendly interface @@ -142,11 +148,11 @@ Some notable features include: There are several ways to [access the dashboard](https://discourse.pi-hole.net/t/how-do-i-access-pi-holes-dashboard-admin-interface/3168): 1. `http:///admin/` -2. `http:/pi.hole/admin/` (when using Pi-hole as your DNS server) +2. `http://pi.hole/admin/` (when using Pi-hole as your DNS server) 3. `http://pi.hole/` (when using Pi-hole as your DNS server) -## The Faster-Than-Light Engine -The [FTL Engine](https://github.com/pi-hole/FTL) is a lightweight, purpose-built daemon used to provide statistics needed for the Web Interface, and its API can be easily integrated into your own projects. As the name implies, FTL does this all *very quickly*! +## Faster-than-light Engine +FTLDNS[™](https://pi-hole.net/trademark-rules-and-brand-guidelines/) is a lightweight, purpose-built daemon used to provide statistics needed for the Web Interface, and its API can be easily integrated into your own projects. As the name implies, FTLDNS does this all *very quickly*! Some of the statistics you can integrate include: * Total number of domains being blocked @@ -194,6 +200,7 @@ While quite outdated at this point, [this original blog post about Pi-hole](http - [Magic Mirror with DNS Filtering](https://zonksec.com/blog/magic-mirror-dns-filtering/#dnssoftware) - [Pi-hole Droid: Android client](https://github.com/friimaind/pi-hole-droid) - [Windows DNS Swapper](https://github.com/roots84/DNS-Swapper), see [#1400](https://github.com/pi-hole/pi-hole/issues/1400) +- [Pi-hole Visualizer](https://www.reddit.com/r/pihole/comments/82ikgb/pihole_visualizer_update/) ----- ## Coverage diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh index e7bc244e..589bb76e 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/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh index c878aa23..94ff3fb3 100755 --- a/advanced/Scripts/piholeDebug.sh +++ b/advanced/Scripts/piholeDebug.sh @@ -592,7 +592,7 @@ ping_gateway() { # Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only, # on the pihole interface, and tail the last three lines of the output # If pinging the gateway is not successful, - if ! ${cmd} -c 3 -W 2 -n ${gateway} -I ${PIHOLE_INTERFACE} >/dev/null; then + if ! ${cmd} -c 1 -W 2 -n ${gateway} -I ${PIHOLE_INTERFACE} >/dev/null; then # let the user know log_write "${CROSS} ${COL_RED}Gateway did not respond.${COL_NC} ($FAQ_GATEWAY)\n" # and return an error code @@ -613,7 +613,7 @@ ping_internet() { ping_ipv4_or_ipv6 "${protocol}" log_write "* Checking Internet connectivity via IPv${protocol}..." # Try to ping the address 3 times - if ! ${cmd} -W 2 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} >/dev/null; then + if ! ${cmd} -c 1 -W 2 -n ${public_address} -I ${PIHOLE_INTERFACE} >/dev/null; then # if it's unsuccessful, show an error log_write "${CROSS} ${COL_RED}Cannot reach the Internet.${COL_NC}\n" return 1 @@ -958,7 +958,7 @@ list_files_in_dir() { "${PIHOLE_WEB_SERVER_ERROR_LOG_FILE}") make_array_from_file "${dir_to_parse}/${each_file}" 25 ;; # Same for the FTL log - "${PIHOLE_FTL_LOG}") make_array_from_file "${dir_to_parse}/${each_file}" 25 + "${PIHOLE_FTL_LOG}") head_tail_log "${dir_to_parse}/${each_file}" 35 ;; # parse the file into an array in case we ever need to analyze it line-by-line *) make_array_from_file "${dir_to_parse}/${each_file}"; @@ -991,6 +991,34 @@ show_content_of_pihole_files() { show_content_of_files_in_dir "${LOG_DIRECTORY}" } +head_tail_log() { + # The file being processed + local filename="${1}" + # The number of lines to use for head and tail + local qty="${2}" + local head_line + local tail_line + # Put the current Internal Field Separator into another variable so it can be restored later + OLD_IFS="$IFS" + # Get the lines that are in the file(s) and store them in an array for parsing later + IFS=$'\r\n' + local log_head=() + log_head=( $(head -n ${qty} ${filename}) ) + log_write " ${COL_CYAN}-----head of $(basename ${filename})------${COL_NC}" + for head_line in "${log_head[@]}"; do + log_write " ${head_line}" + done + log_write "" + local log_tail=() + log_tail=( $(tail -n ${qty} ${filename}) ) + log_write " ${COL_CYAN}-----tail of $(basename ${filename})------${COL_NC}" + for tail_line in "${log_tail[@]}"; do + log_write " ${tail_line}" + done + # Set the IFS back to what it was + IFS="$OLD_IFS" +} + analyze_gravity_list() { echo_current_diagnostic "Gravity list" local head_line diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index c8a2bffb..d2b31948 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,23 +83,15 @@ 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}" @@ -147,82 +145,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..21623eea 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}" @@ -135,6 +149,10 @@ ProcessDNSSettings() { let COUNTER=COUNTER+1 done + if [ ! -z "${LOCAL_DNS_PORT}" ]; then + add_dnsmasq_setting "server" "127.0.0.1#${LOCAL_DNS_PORT}" + fi + delete_dnsmasq_setting "domain-needed" if [[ "${DNS_FQDN_REQUIRED}" == true ]]; then @@ -505,36 +523,55 @@ 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 +} +SetLocalDNSport() { + # Ensure port is a natural number { 0, 1, 2, 3, ... } + if [[ "${1}" == "0" ]]; then + delete_setting "LOCAL_DNS_PORT" + ProcessDNSSettings + elif [[ "${1}" =~ ^[0-9]+$ ]]; then + change_setting "LOCAL_DNS_PORT" "${1}" + ProcessDNSSettings + 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;; + "localdnsport" ) SetLocalDNSport "$3";; + * ) 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 2429c6f3..b9a23a72 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -173,7 +173,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 psmisc 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}) @@ -183,8 +183,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() { @@ -217,7 +215,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 @@ -226,7 +224,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 @@ -1028,6 +1025,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" @@ -1156,7 +1157,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 @@ -1170,7 +1170,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 @@ -1188,13 +1187,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 @@ -1202,6 +1200,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) @@ -1328,27 +1355,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 "" @@ -1375,7 +1381,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} @@ -1434,7 +1440,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'" @@ -1453,7 +1459,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 @@ -1474,7 +1480,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" @@ -1584,8 +1590,6 @@ installPihole() { installScripts # configs, installConfigs - # and create the log file - CreateLogFile # If the user wants to install the dashboard, if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then # do so @@ -1631,8 +1635,6 @@ updatePihole() { installScripts # Install config files installConfigs - # Create the log file - CreateLogFile # If the user wants to install the dasboard, if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then # do so @@ -1795,15 +1797,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}" @@ -1835,15 +1871,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) @@ -1902,37 +1932,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_SERVER}" == true ]]; then stop_service lighttpd fi @@ -2125,8 +2216,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_SERVER}" == true ]]; then @@ -2188,6 +2282,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 395ea548..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" @@ -345,13 +347,18 @@ gravity_ParseFileIntoDomains() { # Scanning for "^IPv4$" is too slow with large (1M) lists on low-end hardware echo -ne " ${INFO} Format: URL" - awk '{ - # Remove URL protocol, optional "username:password@", and ":?/;" - if ($0 ~ /[:?\/;]/) { gsub(/(^.*:\/\/(.*:.*@)?|[:?\/;].*)/, "", $0) } - # Remove lines which are only IPv4 addresses - if ($0 ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) { $0="" } - if ($0) { print $0 } - }' "${source}" 2> /dev/null > "${destination}" + awk ' + # Remove URL scheme, optional "username:password@", and ":?/;" + # The scheme must be matched carefully to avoid blocking the wrong URL + # in cases like: + # http://www.evil.com?http://www.good.com + # See RFC 3986 section 3.1 for details. + /[:?\/;]/ { gsub(/(^[a-zA-Z][a-zA-Z0-9+.-]*:\/\/(.*:.*@)?|[:?\/;].*)/, "", $0) } + # Skip lines which are only IPv4 addresses + /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ { next } + # Print if nonempty + length { print } + ' "${source}" 2> /dev/null > "${destination}" echo -e "${OVER} ${TICK} Format: URL" else @@ -508,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 @@ -567,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