diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6992cce5..0dd22b42 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,8 +4,8 @@ Please read and understand the contribution guide before creating an issue or pu ## Etiquette -- Our goal for Pi-hole is **stability before features**. This means we focus on squashing critical bugs before adding new features. Often, we can do both in tandem, but bugs will take priority over a new feature. -- Pi-hole is open source and [powered by donations](https://pi-hole.net/donate/), and as such, we give our **free time** to build, maintain, and **provide user support** for this project. It would be extremely unfair for us to suffer abuse or anger for our hard work, so please take a moment to consider that. +- Our goal for Pi-hole is **stability before features**. This means we focus on squashing critical bugs before adding new features. Often, we can do both in tandem, but bugs will take priority over a new feature. +- Pi-hole is open source and [powered by donations](https://pi-hole.net/donate/), and as such, we give our **free time** to build, maintain, and **provide user support** for this project. It would be extremely unfair for us to suffer abuse or anger for our hard work, so please take a moment to consider that. - Please be considerate towards the developers and other users when raising issues or presenting pull requests. - Respect our decision(s), and do not be upset or abusive if your submission is not used. @@ -26,7 +26,7 @@ When requesting or submitting new features, first consider whether it might be u - Check the codebase to ensure that your feature doesn't already exist. - Check the pull requests to ensure that another person hasn't already submitted the feature or fix. -- Read and understand the [DCO guidelines](https://github.com/pi-hole/pi-hole/wiki/Contributing-to-the-project) for the project. +- Read and understand the [DCO guidelines](https://docs.pi-hole.net/guides/github/contributing/) for the project. ## Technical Requirements @@ -36,3 +36,77 @@ When requesting or submitting new features, first consider whether it might be u - Commit Unix line endings. - Please use the Pi-hole brand: **Pi-hole** (Take a special look at the capitalized 'P' and a low 'h' with a hyphen) - (Optional fun) keep to the theme of Star Trek/black holes/gravity. + +## Forking and Cloning from GitHub to GitHub + +1. Fork to a repo under a namespace you control, or have permission to use, for example: `https://github.com///`. You can do this from the github.com website. +2. Clone `https://github.com///` with the tool of you choice. +3. To keep your fork in sync with our repo, add an upstream remote for pi-hole/pi-hole to your repo. + + ```bash + git remote add upstream https://github.com/pi-hole/pi-hole.git + ``` + +4. Checkout the `development` branch from your fork `https://github.com///`. +5. Create a topic/branch, based on the `development` branch code. *Bonus fun to keep to the theme of Star Trek/black holes/gravity.* +6. Make your changes and commit to your topic branch in your repo. +7. Rebase your commits and squash any insignificant commits. See the notes below for an example. +8. Merge `development` your branch and fix any conflicts. +9. Open a Pull Request to merge your topic branch into our repo's `development` branch. + +- Keep in mind the technical requirements from above. + +## Forking and Cloning from GitHub to other code hosting sites + +- Forking is a GitHub concept and cannot be done from GitHub to other git-based code hosting sites. However, those sites may be able to mirror a GitHub repo. + +1. To contribute from another code hosting site, you must first complete the steps above to fork our repo to a GitHub namespace you have permission to use, for example: `https://github.com///`. +2. Create a repo in your code hosting site, for example: `https://gitlab.com///` +3. Follow the instructions from your code hosting site to create a mirror between `https://github.com///` and `https://gitlab.com///`. +4. When you are ready to create a Pull Request (PR), follow the steps `(starting at step #6)` from [Forking and Cloning from GitHub to GitHub](#forking-and-cloning-from-github-to-github) and create the PR from `https://github.com///`. + +## Notes for squashing commits with rebase + +- To rebase your commits and squash previous commits, you can use: + + ```bash + git rebase -i your_topic_branch~(number of commits to combine) + ``` + +- For more details visit [gitready.com](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) + +1. The following would combine the last four commits in the branch `mytopic`. + + ```bash + git rebase -i mytopic~4 + ``` + +2. An editor window opens with the most recent commits indicated: (edit the commands to the left of the commit ID) + + ```gitattributes + pick 9dff55b2 existing commit comments + squash ebb1a730 existing commit comments + squash 07cc5b50 existing commit comments + reword 9dff55b2 existing commit comments + ``` + +3. Save and close the editor. The next editor window opens: (edit the new commit message). *If you select reword for a commit, an additional editor window will open for you to edit the comment.* + + ```bash + new commit comments + Signed-off-by: yourname + ``` + +4. Save and close the editor for the rebase process to execute. The terminal output should say something like the following: + + ```bash + Successfully rebased and updated refs/heads/mytopic. + ``` + +5. Once you have a successful rebase, and before you sync your local clone, you have to force push origin to update your repo: + + ```bash + git push -f origin + ``` + +6. Continue on from step #7 from [Forking and Cloning from GitHub to GitHub](#forking-and-cloning-from-github-to-github) diff --git a/README.md b/README.md index 68d7c09f..6d7e5b5e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ 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. -- **Easy-to-install**: our versatile installer walks you through the process, and [takes less than ten minutes](https://www.youtube.com/watch?v=vKWjx1AQYgs) +- **Easy-to-install**: our versatile installer walks you through the process, and takes less than ten minutes - **Resolute**: content is blocked in _non-browser locations_, such as ad-laden mobile apps and smart TVs - **Responsive**: seamlessly speeds up the feel of everyday browsing by caching DNS queries - **Lightweight**: runs smoothly with [minimal hardware and software requirements](https://docs.pi-hole.net/main/prerequisites/) @@ -162,4 +162,4 @@ Some of the statistics you can integrate include: - Queries cached - Unique clients -The API can be accessed via [`telnet`](https://github.com/pi-hole/FTL), the Web (`admin/api.php`) and Command Line (`pihole -c -j`). You can out find [more details over here](https://discourse.pi-hole.net/t/pi-hole-api/1863). +The API can be accessed via [`telnet`](https://github.com/pi-hole/FTL), the Web (`admin/api.php`) and Command Line (`pihole -c -j`). You can find out [more details over here](https://discourse.pi-hole.net/t/pi-hole-api/1863). diff --git a/advanced/01-pihole.conf b/advanced/01-pihole.conf index 2c8b3749..e243e91a 100644 --- a/advanced/01-pihole.conf +++ b/advanced/01-pihole.conf @@ -34,7 +34,7 @@ server=@DNS2@ interface=@INT@ -cache-size=10000 +cache-size=@CACHE_SIZE@ log-queries log-facility=/var/log/pihole.log diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh index 98f43c3f..37fd5177 100755 --- a/advanced/Scripts/chronometer.sh +++ b/advanced/Scripts/chronometer.sh @@ -236,7 +236,7 @@ get_sys_stats() { sys_name=$(hostname) - [[ -n "$TEMPERATUREUNIT" ]] && temp_unit="$TEMPERATUREUNIT" || temp_unit="c" + [[ -n "$TEMPERATUREUNIT" ]] && temp_unit="${TEMPERATUREUNIT^^}" || temp_unit="C" # Get storage stats for partition mounted on / read -r -a disk_raw <<< "$(df -B1 / 2> /dev/null | awk 'END{ print $3,$2,$5 }')" diff --git a/advanced/Scripts/database_migration/gravity-db.sh b/advanced/Scripts/database_migration/gravity-db.sh index 70090a3b..282ea07b 100644 --- a/advanced/Scripts/database_migration/gravity-db.sh +++ b/advanced/Scripts/database_migration/gravity-db.sh @@ -110,4 +110,10 @@ upgrade_gravityDB(){ sqlite3 "${database}" < "${scriptPath}/11_to_12.sql" version=12 fi + if [[ "$version" == "12" ]]; then + # Add column date_updated to alist table + echo -e " ${INFO} Upgrading gravity database from version 12 to 13" + sqlite3 "${database}" < "${scriptPath}/12_to_13.sql" + version=13 + fi } diff --git a/advanced/Scripts/database_migration/gravity/12_to_13.sql b/advanced/Scripts/database_migration/gravity/12_to_13.sql new file mode 100644 index 00000000..d16791d6 --- /dev/null +++ b/advanced/Scripts/database_migration/gravity/12_to_13.sql @@ -0,0 +1,18 @@ +.timeout 30000 + +PRAGMA FOREIGN_KEYS=OFF; + +BEGIN TRANSACTION; + +ALTER TABLE adlist ADD COLUMN date_updated INTEGER; + +DROP TRIGGER tr_adlist_update; + +CREATE TRIGGER tr_adlist_update AFTER UPDATE OF address,enabled,comment ON adlist + BEGIN + UPDATE adlist SET date_modified = (cast(strftime('%s', 'now') as int)) WHERE id = NEW.id; + END; + +UPDATE info SET value = 13 WHERE property = 'version'; + +COMMIT; \ No newline at end of file diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh index 77a5dece..9dd818c4 100755 --- a/advanced/Scripts/list.sh +++ b/advanced/Scripts/list.sh @@ -232,6 +232,7 @@ Displaylist() { NukeList() { sqlite3 "${gravityDBfile}" "DELETE FROM domainlist WHERE type = ${typeId};" + exit 0; } GetComment() { diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh index 92d6dad7..52e11b6a 100755 --- a/advanced/Scripts/piholeDebug.sh +++ b/advanced/Scripts/piholeDebug.sh @@ -48,6 +48,7 @@ FAQ_UPDATE_PI_HOLE="${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-p FAQ_CHECKOUT_COMMAND="${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC}" FAQ_HARDWARE_REQUIREMENTS="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/${COL_NC}" FAQ_HARDWARE_REQUIREMENTS_PORTS="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/#ports${COL_NC}" +FAQ_HARDWARE_REQUIREMENTS_FIREWALLD="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/#firewalld${COL_NC}" FAQ_GATEWAY="${COL_CYAN}https://discourse.pi-hole.net/t/why-is-a-default-gateway-important-for-pi-hole/3546${COL_NC}" FAQ_ULA="${COL_CYAN}https://discourse.pi-hole.net/t/use-ipv6-ula-addresses-for-pi-hole/2127${COL_NC}" FAQ_FTL_COMPATIBILITY="${COL_CYAN}https://github.com/pi-hole/FTL#compatibility-list${COL_NC}" @@ -396,49 +397,54 @@ check_critical_program_versions() { os_check() { # This function gets a list of supported OS versions from a TXT record at versions.pi-hole.net # and determines whether or not the script is running on one of those systems - local remote_os_domain valid_os valid_version detected_os_pretty detected_os detected_version + local remote_os_domain valid_os valid_version detected_os detected_version cmdResult digReturnCode response remote_os_domain="versions.pi-hole.net" - valid_os=false - valid_version=false - detected_os_pretty=$(cat /etc/*release | grep PRETTY_NAME | cut -d '=' -f2- | tr -d '"') - detected_os="${detected_os_pretty%% *}" - detected_version=$(cat /etc/*release | grep VERSION_ID | cut -d '=' -f2- | tr -d '"') + detected_os=$(grep "\bID\b" /etc/os-release | cut -d '=' -f2 | tr -d '"') + detected_version=$(grep VERSION_ID /etc/os-release | cut -d '=' -f2 | tr -d '"') - IFS=" " read -r -a supportedOS < <(dig +short -t txt ${remote_os_domain} | tr -d '"') + cmdResult="$(dig +short -t txt ${remote_os_domain} @ns1.pi-hole.net 2>&1; echo $?)" + #Get the return code of the previous command (last line) + digReturnCode="${cmdResult##*$'\n'}" - for i in "${supportedOS[@]}" + # Extract dig response + response="${cmdResult%%$'\n'*}" + + IFS=" " read -r -a supportedOS < <(echo "${response}" | tr -d '"') + for distro_and_versions in "${supportedOS[@]}" do - os_part=$(echo "$i" | cut -d '=' -f1) - versions_part=$(echo "$i" | cut -d '=' -f2-) - - if [[ "${detected_os}" =~ ${os_part} ]]; then - valid_os=true - IFS="," read -r -a supportedVer <<<"${versions_part}" - for x in "${supportedVer[@]}" - do - if [[ "${detected_version}" =~ $x ]];then - valid_version=true - break - fi - done - break + distro_part="${distro_and_versions%%=*}" + versions_part="${distro_and_versions##*=}" + + if [[ "${detected_os^^}" =~ ${distro_part^^} ]]; then + valid_os=true + IFS="," read -r -a supportedVer <<<"${versions_part}" + for version in "${supportedVer[@]}" + do + if [[ "${detected_version}" =~ $version ]]; then + valid_version=true + break + fi + done + break fi done - # Display findings back to the user + log_write "${INFO} dig return code: ${digReturnCode}" + log_write "${INFO} dig response: ${response}" + if [ "$valid_os" = true ]; then - log_write "${TICK} Distro: ${COL_GREEN}${detected_os}${COL_NC}" + log_write "${TICK} Distro: ${COL_GREEN}${detected_os^}${COL_NC}" if [ "$valid_version" = true ]; then log_write "${TICK} Version: ${COL_GREEN}${detected_version}${COL_NC}" else log_write "${CROSS} Version: ${COL_RED}${detected_version}${COL_NC}" - log_write "${CROSS} Error: ${COL_RED}${detected_os} is supported but version ${detected_version} is currently unsupported (${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}" + log_write "${CROSS} Error: ${COL_RED}${detected_os^} is supported but version ${detected_version} is currently unsupported (${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}" fi else - log_write "${CROSS} Distro: ${COL_RED}${detected_os}${COL_NC}" - log_write "${CROSS} Error: ${COL_RED}${detected_os} is not a supported distro (${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}" + log_write "${CROSS} Distro: ${COL_RED}${detected_os^}${COL_NC}" + log_write "${CROSS} Error: ${COL_RED}${detected_os^} is not a supported distro (${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}" fi } @@ -488,6 +494,58 @@ check_selinux() { fi } +check_firewalld() { + # FirewallD ships by default on Fedora/CentOS/RHEL and enabled upon clean install + # FirewallD is not configured by the installer and is the responsibility of the user + echo_current_diagnostic "FirewallD" + # Check if FirewallD service is enabled + if command -v systemctl &> /dev/null; then + # get its status via systemctl + local firewalld_status + firewalld_status=$(systemctl is-active firewalld) + log_write "${INFO} ${COL_GREEN}Firewalld service ${firewalld_status}${COL_NC}"; + if [ "${firewalld_status}" == "active" ]; then + # test common required service ports + local firewalld_enabled_services + firewalld_enabled_services=$(firewall-cmd --list-services) + local firewalld_expected_services=("http" "dns" "dhcp" "dhcpv6") + for i in "${firewalld_expected_services[@]}"; do + if [[ "${firewalld_enabled_services}" =~ ${i} ]]; then + log_write "${TICK} ${COL_GREEN} Allow Service: ${i}${COL_NC}"; + else + log_write "${CROSS} ${COL_RED} Allow Service: ${i}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_FIREWALLD})" + fi + done + # check for custom FTL FirewallD zone + local firewalld_zones + firewalld_zones=$(firewall-cmd --get-zones) + if [[ "${firewalld_zones}" =~ "ftl" ]]; then + log_write "${TICK} ${COL_GREEN}FTL Custom Zone Detected${COL_NC}"; + # check FTL custom zone interface: lo + local firewalld_ftl_zone_interfaces + firewalld_ftl_zone_interfaces=$(firewall-cmd --zone=ftl --list-interfaces) + if [[ "${firewalld_ftl_zone_interfaces}" =~ "lo" ]]; then + log_write "${TICK} ${COL_GREEN} Local Interface Detected${COL_NC}"; + else + log_write "${CROSS} ${COL_RED} Local Interface Not Detected${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_FIREWALLD})" + fi + # check FTL custom zone port: 4711 + local firewalld_ftl_zone_ports + firewalld_ftl_zone_ports=$(firewall-cmd --zone=ftl --list-ports) + if [[ "${firewalld_ftl_zone_ports}" =~ "4711/tcp" ]]; then + log_write "${TICK} ${COL_GREEN} FTL Port 4711/tcp Detected${COL_NC}"; + else + log_write "${CROSS} ${COL_RED} FTL Port 4711/tcp Not Detected${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_FIREWALLD})" + fi + else + log_write "${CROSS} ${COL_RED}FTL Custom Zone Not Detected${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_FIREWALLD})" + fi + fi + else + log_write "${TICK} ${COL_GREEN}Firewalld service not detected${COL_NC}"; + fi +} + processor_check() { echo_current_diagnostic "Processor" # Store the processor type in a variable @@ -1021,8 +1079,8 @@ list_files_in_dir() { log_write "\\n${COL_GREEN}$(ls -ld "${dir_to_parse}"/"${each_file}")${COL_NC}" # Check if the file we want to view has a limit (because sometimes we just need a little bit of info from the file, not the entire thing) case "${dir_to_parse}/${each_file}" in - # If it's Web server error log, just give the first 25 lines - "${PIHOLE_WEB_SERVER_ERROR_LOG_FILE}") make_array_from_file "${dir_to_parse}/${each_file}" 25 + # If it's Web server error log, give the first and last 25 lines + "${PIHOLE_WEB_SERVER_ERROR_LOG_FILE}") head_tail_log "${dir_to_parse}/${each_file}" 25 ;; # Same for the FTL log "${PIHOLE_FTL_LOG}") head_tail_log "${dir_to_parse}/${each_file}" 35 @@ -1112,6 +1170,21 @@ show_db_entries() { IFS="$OLD_IFS" } +check_dhcp_servers() { + echo_current_diagnostic "Discovering active DHCP servers (takes 10 seconds)" + + OLD_IFS="$IFS" + IFS=$'\n' + local entries=() + mapfile -t entries < <(pihole-FTL dhcp-discover) + + for line in "${entries[@]}"; do + log_write " ${line}" + done + + IFS="$OLD_IFS" +} + show_groups() { show_db_entries "Groups" "SELECT id,CASE enabled WHEN '0' THEN ' 0' WHEN '1' THEN ' 1' ELSE enabled END enabled,name,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,description FROM \"group\"" "4 7 50 19 19 50" } @@ -1300,9 +1373,11 @@ check_component_versions check_critical_program_versions diagnose_operating_system check_selinux +check_firewalld processor_check check_networking check_name_resolution +check_dhcp_servers process_status parse_setup_vars check_x_headers diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh index 1f7cc728..8aaaa85a 100755 --- a/advanced/Scripts/webpage.sh +++ b/advanced/Scripts/webpage.sh @@ -44,7 +44,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 - -l, privacylevel Set privacy level (0 = lowest, 4 = highest)" + -l, privacylevel Set privacy level (0 = lowest, 3 = highest)" exit 0 } @@ -167,9 +167,11 @@ ProcessDNSSettings() { fi delete_dnsmasq_setting "domain-needed" + delete_dnsmasq_setting "expand-hosts" if [[ "${DNS_FQDN_REQUIRED}" == true ]]; then add_dnsmasq_setting "domain-needed" + add_dnsmasq_setting "expand-hosts" fi delete_dnsmasq_setting "bogus-priv" @@ -370,6 +372,9 @@ dhcp-leasefile=/etc/pihole/dhcp.leases if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}" + if [[ "${DNS_FQDN_REQUIRED}" == true ]]; then + echo "local=/${PIHOLE_DOMAIN}/" >> "${dhcpconfig}" + fi fi # Sourced from setupVars @@ -633,8 +638,8 @@ clearAudit() } SetPrivacyLevel() { - # Set privacy level. Minimum is 0, maximum is 4 - if [ "${args[2]}" -ge 0 ] && [ "${args[2]}" -le 4 ]; then + # Set privacy level. Minimum is 0, maximum is 3 + if [ "${args[2]}" -ge 0 ] && [ "${args[2]}" -le 3 ]; then changeFTLsetting "PRIVACYLEVEL" "${args[2]}" pihole restartdns reload-lists fi diff --git a/advanced/Templates/gravity.db.sql b/advanced/Templates/gravity.db.sql index fcf3489b..2aa7e8f8 100644 --- a/advanced/Templates/gravity.db.sql +++ b/advanced/Templates/gravity.db.sql @@ -31,7 +31,8 @@ CREATE TABLE adlist enabled BOOLEAN NOT NULL DEFAULT 1, date_added INTEGER NOT NULL DEFAULT (cast(strftime('%s', 'now') as int)), date_modified INTEGER NOT NULL DEFAULT (cast(strftime('%s', 'now') as int)), - comment TEXT + comment TEXT, + date_updated INTEGER ); CREATE TABLE adlist_by_group @@ -53,7 +54,7 @@ CREATE TABLE info value TEXT NOT NULL ); -INSERT INTO "info" VALUES('version','12'); +INSERT INTO "info" VALUES('version','13'); CREATE TABLE domain_audit ( @@ -85,9 +86,9 @@ CREATE TABLE client_by_group PRIMARY KEY (client_id, group_id) ); -CREATE TRIGGER tr_adlist_update AFTER UPDATE ON adlist +CREATE TRIGGER tr_adlist_update AFTER UPDATE OF address,enabled,comment ON adlist BEGIN - UPDATE adlist SET date_modified = (cast(strftime('%s', 'now') as int)) WHERE address = NEW.address; + UPDATE adlist SET date_modified = (cast(strftime('%s', 'now') as int)) WHERE id = NEW.id; END; CREATE TRIGGER tr_client_update AFTER UPDATE ON client diff --git a/advanced/bash-completion/pihole b/advanced/bash-completion/pihole index 88282b02..25208a35 100644 --- a/advanced/bash-completion/pihole +++ b/advanced/bash-completion/pihole @@ -56,11 +56,11 @@ _pihole() { ;; "privacylevel") if ( [[ "$prev2" == "admin" ]] || [[ "$prev2" == "-a" ]] ); then - opts_privacy="0 1 2 3 4" + opts_privacy="0 1 2 3" COMPREPLY=( $(compgen -W "${opts_privacy}" -- ${cur}) ) - else + else return 1 - fi + fi ;; "core"|"admin"|"ftl") if [[ "$prev2" == "checkout" ]]; then diff --git a/advanced/index.php b/advanced/index.php index 4356f0b0..ca8c35e4 100644 --- a/advanced/index.php +++ b/advanced/index.php @@ -24,7 +24,7 @@ unset($setupVars); $landPage = "../landing.php"; // Define array for hostnames to be accepted as self address for splash page -$authorizedHosts = []; +$authorizedHosts = [ "localhost" ]; if (!empty($_SERVER["FQDN"])) { // If setenv.add-environment = ("fqdn" => "true") is configured in lighttpd, // append $serverName to $authorizedHosts @@ -55,7 +55,16 @@ if ($serverName === "pi.hole" // Redirect to Web Interface exit(header("Location: /admin")); } elseif (filter_var($serverName, FILTER_VALIDATE_IP) || in_array($serverName, $authorizedHosts)) { - // Set Splash Page output + // When directly browsing via IP or authorized hostname + // Render splash/landing page based off presence of $landPage file + // Unset variables so as to not be included in $landPage or $splashPage + unset($serverName, $svPasswd, $svEmail, $authorizedHosts, $validExtTypes, $currentUrlExt, $viewPort); + // If $landPage file is present + if (is_file(getcwd()."/$landPage")) { + include $landPage; + exit(); + } + // If $landPage file was not present, Set Splash Page output $splashPage = " @@ -74,15 +83,7 @@ if ($serverName === "pi.hole" "; - - // Set splash/landing page based off presence of $landPage - $renderPage = is_file(getcwd()."/$landPage") ? include $landPage : "$splashPage"; - - // Unset variables so as to not be included in $landPage - unset($serverName, $svPasswd, $svEmail, $authorizedHosts, $validExtTypes, $currentUrlExt, $viewPort); - - // Render splash/landing page when directly browsing via IP or authorized hostname - exit($renderPage); + exit($splashPage); } elseif ($currentUrlExt === "js") { // Serve Pi-hole JavaScript for blocked domains requesting JS exit(setHeader("js").'var x = "Pi-hole: A black hole for Internet advertisements."'); @@ -305,7 +306,7 @@ setHeader();

diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index e91c2bb1..e5ffce79 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -21,6 +21,10 @@ # instead of continuing the installation with something broken set -e +# Set PATH to a usual default to assure that all basic commands are available. +# When using "su" an uncomplete PATH could be passed: https://github.com/pi-hole/pi-hole/issues/3209 +export PATH+=':/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' + ######## VARIABLES ######### # For better maintainability, we store as much information that can change in variables # This allows us to make a change in one place that can propagate to all instances of the variable @@ -80,6 +84,7 @@ IPV6_ADDRESS=${IPV6_ADDRESS} QUERY_LOGGING=true INSTALL_WEB_INTERFACE=true PRIVACY_LEVEL=0 +CACHE_SIZE=10000 if [ -z "${USER}" ]; then USER="$(id -un)" @@ -108,7 +113,6 @@ c=$(( c < 70 ? 70 : c )) ######## Undocumented Flags. Shhh ######## # These are undocumented flags; some of which we can use when repairing an installation # The runUnattended flag is one example of this -skipSpaceCheck=false reconfigure=false runUnattended=false INSTALL_WEB_SERVER=true @@ -116,7 +120,6 @@ INSTALL_WEB_SERVER=true for var in "$@"; do case "$var" in "--reconfigure" ) reconfigure=true;; - "--i_do_not_follow_recommendations" ) skipSpaceCheck=true;; "--unattended" ) runUnattended=true;; "--disable-install-webserver" ) INSTALL_WEB_SERVER=false;; esac @@ -180,59 +183,85 @@ os_check() { if [ "$PIHOLE_SKIP_OS_CHECK" != true ]; then # This function gets a list of supported OS versions from a TXT record at versions.pi-hole.net # and determines whether or not the script is running on one of those systems - local remote_os_domain valid_os valid_version detected_os_pretty detected_os detected_version display_warning + local remote_os_domain valid_os valid_version valid_response detected_os detected_version display_warning cmdResult digReturnCode response remote_os_domain="versions.pi-hole.net" - valid_os=false - valid_version=false - display_warning=true - detected_os_pretty=$(cat /etc/*release | grep PRETTY_NAME | cut -d '=' -f2- | tr -d '"') - detected_os="${detected_os_pretty%% *}" - detected_version=$(cat /etc/*release | grep VERSION_ID | cut -d '=' -f2- | tr -d '"') + detected_os=$(grep "\bID\b" /etc/os-release | cut -d '=' -f2 | tr -d '"') + detected_version=$(grep VERSION_ID /etc/os-release | cut -d '=' -f2 | tr -d '"') - IFS=" " read -r -a supportedOS < <(dig +short -t txt ${remote_os_domain} @ns1.pi-hole.net | tr -d '"') + cmdResult="$(dig +short -t txt ${remote_os_domain} @ns1.pi-hole.net 2>&1; echo $?)" + #Get the return code of the previous command (last line) + digReturnCode="${cmdResult##*$'\n'}" - if [ ${#supportedOS[@]} -eq 0 ]; then - printf " %b %bRetrieval of supported OS failed. Please contact support. %b\\n" "${CROSS}" "${COL_LIGHT_RED}" "${COL_NC}" - exit 1 + if [ ! "${digReturnCode}" == "0" ]; then + valid_response=false else - for i in "${supportedOS[@]}" - do - os_part=$(echo "$i" | cut -d '=' -f1) - versions_part=$(echo "$i" | cut -d '=' -f2-) - - if [[ "${detected_os}" =~ ${os_part} ]]; then - valid_os=true - IFS="," read -r -a supportedVer <<<"${versions_part}" - for x in "${supportedVer[@]}" - do - if [[ "${detected_version}" =~ $x ]];then - valid_version=true + # Dig returned 0 code, so get the actual response, and loop through it to determine if the detected variables above are valid + response="${cmdResult%%$'\n'*}" + # If the value of ${result} is a single 0, then this is the return code, not the response. Response is blank + if [ "${response}" == 0 ]; then + valid_response=false + fi + + IFS=" " read -r -a supportedOS < <(echo "${response}" | tr -d '"') + for distro_and_versions in "${supportedOS[@]}" + do + distro_part="${distro_and_versions%%=*}" + versions_part="${distro_and_versions##*=}" + + if [[ "${detected_os^^}" =~ ${distro_part^^} ]]; then + valid_os=true + IFS="," read -r -a supportedVer <<<"${versions_part}" + for version in "${supportedVer[@]}" + do + if [[ "${detected_version}" =~ $version ]]; then + valid_version=true + break + fi + done break - fi - done - break - fi + fi done - fi + fi - if [ "$valid_os" = true ] && [ "$valid_version" = true ]; then + if [ "$valid_os" = true ] && [ "$valid_version" = true ] && [ ! "$valid_response" = false ]; then display_warning=false fi - if [ "$display_warning" = true ]; then - printf " %b %bUnsupported OS detected: %s%b\\n" "${CROSS}" "${COL_LIGHT_RED}" "${detected_os_pretty}" "${COL_NC}" - printf " https://docs.pi-hole.net/main/prerequesites/#supported-operating-systems\\n" + if [ "$display_warning" != false ]; then + if [ "$valid_response" = false ]; then + + if [ "${digReturnCode}" -eq 0 ]; then + errStr="dig succeeded, but response was blank. Please contact support" + else + errStr="dig failed with return code ${digReturnCode}" + fi + printf " %b %bRetrieval of supported OS list failed. %s. %b\\n" "${CROSS}" "${COL_LIGHT_RED}" "${errStr}" "${COL_NC}" + printf " %bUnable to determine if the detected OS (%s %s) is supported%b\\n" "${COL_LIGHT_RED}" "${detected_os^}" "${detected_version}" "${COL_NC}" + printf " Possible causes for this include:\\n" + printf " - Firewall blocking certain DNS lookups from Pi-hole device\\n" + printf " - ns1.pi-hole.net being blocked (required to obtain TXT record from versions.pi-hole.net containing supported operating systems)\\n" + printf " - Other internet connectivity issues\\n" + else + printf " %b %bUnsupported OS detected: %s %s%b\\n" "${CROSS}" "${COL_LIGHT_RED}" "${detected_os^}" "${detected_version}" "${COL_NC}" + printf " If you are seeing this message and you do have a supported OS, please contact support.\\n" + fi + printf "\\n" + printf " %bhttps://docs.pi-hole.net/main/prerequesites/#supported-operating-systems%b\\n" "${COL_LIGHT_GREEN}" "${COL_NC}" + printf "\\n" + printf " If you wish to attempt to continue anyway, you can try one of the following commands to skip this check:\\n" printf "\\n" printf " e.g: If you are seeing this message on a fresh install, you can run:\\n" - printf " 'curl -sSL https://install.pi-hole.net | PIHOLE_SKIP_OS_CHECK=true sudo -E bash'\\n" + printf " %bcurl -sSL https://install.pi-hole.net | PIHOLE_SKIP_OS_CHECK=true sudo -E bash%b\\n" "${COL_LIGHT_GREEN}" "${COL_NC}" printf "\\n" printf " If you are seeing this message after having run pihole -up:\\n" - printf " 'PIHOLE_SKIP_OS_CHECK=true sudo -E pihole -r'\\n" + printf " %bPIHOLE_SKIP_OS_CHECK=true sudo -E pihole -r%b\\n" "${COL_LIGHT_GREEN}" "${COL_NC}" printf " (In this case, your previous run of pihole -up will have already updated the local repository)\\n" printf "\\n" + printf " It is possible that the installation will still fail at this stage due to an unsupported configuration.\\n" printf " If that is the case, you can feel free to ask the community on Discourse with the %bCommunity Help%b category:\\n" "${COL_LIGHT_RED}" "${COL_NC}" - printf " https://discourse.pi-hole.net/c/bugs-problems-issues/community-help/\\n" + printf " %bhttps://discourse.pi-hole.net/c/bugs-problems-issues/community-help/%b\\n" "${COL_LIGHT_GREEN}" "${COL_NC}" + printf "\\n" exit 1 else @@ -327,7 +356,7 @@ if is_command apt-get ; then PIHOLE_DEPS=(cron curl iputils-ping lsof netcat psmisc sudo unzip wget idn2 sqlite3 libcap2-bin dns-root-data libcap2) # 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}" "${phpVer}-xml" "${phpVer}-intl") + PIHOLE_WEB_DEPS=(lighttpd "${phpVer}-common" "${phpVer}-cgi" "${phpVer}-${phpSqlite}" "${phpVer}-xml" "${phpVer}-json" "${phpVer}-intl") # The Web server user, LIGHTTPD_USER="www-data" # group, @@ -658,53 +687,6 @@ welcomeDialogs() { In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." "${r}" "${c}" } -# We need to make sure there is enough space before installing, so there is a function to check this -verifyFreeDiskSpace() { - # 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.) - # - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables. - local str="Disk space check" - # Required space in KB - local required_free_kilobytes=51200 - # Calculate existing free space on this machine - local existing_free_kilobytes - existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}') - - # If the existing space is not an integer, - if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then - # show an error that we can't determine the free space - printf " %b %s\\n" "${CROSS}" "${str}" - printf " %b Unknown free disk space! \\n" "${INFO}" - printf " We were unable to determine available free disk space on this system.\\n" - printf " You may override this check, however, it is not recommended.\\n" - printf " The option '%b--i_do_not_follow_recommendations%b' can override this.\\n" "${COL_LIGHT_RED}" "${COL_NC}" - printf " e.g: curl -sSL https://install.pi-hole.net | bash /dev/stdin %b