diff --git a/.editorconfig b/.editorconfig
index ee415d1f..a50f2f70 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,4 +1,4 @@
-# EditorConfig is awesome: http://EditorConfig.org
+# EditorConfig is awesome: https://editorconfig.org/
# top-most EditorConfig file
root = true
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 41564b65..7509e923 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -10,7 +10,7 @@
- [ ] It is compatible with the [EUPL 1.2 license](https://opensource.org/licenses/EUPL-1.1)
- [ ] I have squashed any insignificant commits. ([`git rebase`](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html))
-Please make sure you [Sign Off](https://github.com/pi-hole/pi-hole/wiki/How-to-signoff-your-commits.) all commits. Pi-hole enforces the [DCO](https://github.com/pi-hole/pi-hole/wiki/Contributing-to-the-project).
+Please make sure you [Sign Off](https://docs.pi-hole.net/guides/github/how-to-signoff/) all commits. Pi-hole enforces the [DCO](https://docs.pi-hole.net/guides/github/contributing/).
---
**What does this PR aim to accomplish?:**
diff --git a/.stickler.yml b/.stickler.yml
index 0eaae8cb..ab98025e 100644
--- a/.stickler.yml
+++ b/.stickler.yml
@@ -2,5 +2,4 @@ linters:
shellcheck:
shell: bash
phpcs:
- csslint:
flake8:
diff --git a/README.md b/README.md
index 97459442..3613321f 100644
--- a/README.md
+++ b/README.md
@@ -66,12 +66,10 @@ Sending a donation using our links below is **extremely helpful** in offsetting
### Alternative support
If you'd rather not [donate](https://pi-hole.net/donate/) (_which is okay!_), there are other ways you can help support us:
- [Patreon](https://patreon.com/pihole) _Become a patron for rewards_
-- [Digital Ocean](http://www.digitalocean.com/?refcode=344d234950e1) _affiliate link_
+- [Digital Ocean](https://www.digitalocean.com/?refcode=344d234950e1) _affiliate link_
- [Stickermule](https://www.stickermule.com/unlock?ref_id=9127301701&utm_medium=link&utm_source=invite) _earn a $10 credit after your first purchase_
-- [Pi-hole Swag Store](https://pi-hole.net/shop/) _affiliate link_
-- [Amazon](http://www.amazon.com/exec/obidos/redirect-home/pihole09-20) _affiliate link_
+- [Amazon](https://www.amazon.com/exec/obidos/redirect-home/pihole09-20) _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
@@ -97,7 +95,6 @@ While we are primarily reachable on our Feature Requests
@@ -165,48 +162,22 @@ The API can be accessed via [`telnet`](https://github.com/pi-hole/FTL), the Web
Pi-hole being an **advertising-aware DNS/Web server**, makes use of the following technologies:
* [`dnsmasq`](http://www.thekelleys.org.uk/dnsmasq/doc.html) - a lightweight DNS and DHCP server
-* [`curl`](https://curl.haxx.se) - A command line tool for transferring data with URL syntax
-* [`lighttpd`](https://www.lighttpd.net) - web server designed and optimized for high performance
-* [`php`](https://secure.php.net) - a popular general-purpose web scripting language
-* [AdminLTE Dashboard](https://github.com/almasaeed2010/AdminLTE) - premium admin control panel based on Bootstrap 3.x
+* [`curl`](https://curl.haxx.se/) - A command line tool for transferring data with URL syntax
+* [`lighttpd`](https://www.lighttpd.net/) - web server designed and optimized for high performance
+* [`php`](https://www.php.net/) - a popular general-purpose web scripting language
+* [AdminLTE Dashboard](https://github.com/ColorlibHQ/AdminLTE) - premium admin control panel based on Bootstrap 3.x
While quite outdated at this point, [this original blog post about Pi-hole](https://jacobsalmela.com/2015/06/16/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0/) goes into **great detail** about how Pi-hole was originally set up and how it works. Syntactically, it's no longer accurate, but the same basic principles and logic still apply to Pi-hole's current state.
-----
-## Coverage
-- [Lifehacker: Turn A Raspberry Pi Into An Ad Blocker With A Single Command](https://www.lifehacker.com.au/2015/02/turn-a-raspberry-pi-into-an-ad-blocker-with-a-single-command/) (February, 2015)
-- [MakeUseOf: Adblock Everywhere: The Raspberry Pi-Hole Way](http://www.makeuseof.com/tag/adblock-everywhere-raspberry-pi-hole-way/) (March, 2015)
-- [Catchpoint: Ad-Blocking on Apple iOS9: Valuing the End User Experience](http://blog.catchpoint.com/2015/09/14/ad-blocking-apple/) (September, 2015)
-- [Security Now Netcast: Pi-hole](https://www.youtube.com/watch?v=p7-osq_y8i8&t=100m26s) (October, 2015)
-- [TekThing: Raspberry Pi-Hole Makes Ads Disappear!](https://youtu.be/8Co59HU2gY0?t=2m) (December, 2015)
-- [Foolish Tech Show](https://youtu.be/bYyena0I9yc?t=2m4s) (December, 2015)
-- [Block Ads on All Home Devices for $53.18](https://medium.com/@robleathern/block-ads-on-all-home-devices-for-53-18-a5f1ec139693#.gj1xpgr5d) (December, 2015)
-- [Pi-Hole for Ubuntu 14.04](http://www.boyter.org/2015/12/pi-hole-ubuntu-14-04/) (December, 2015)
-- [MacObserver Podcast 585](https://www.macobserver.com/tmo/podcast/macgeekgab-585) (December, 2015)
-- [The Defrag Show: Endoscope USB Camera, The Final [HoloLens] Vote, Adblock Pi and more](https://channel9.msdn.com/Shows/The-Defrag-Show/Defrag-Endoscope-USB-Camera-The-Final-HoloLens-Vote-Adblock-Pi-and-more?WT.mc_id=dlvr_twitter_ch9#time=20m39s) (January, 2016)
-- [Adafruit: Pi-hole is a black hole for internet ads](https://blog.adafruit.com/2016/03/04/pi-hole-is-a-black-hole-for-internet-ads-piday-raspberrypi-raspberry_pi/) (March, 2016)
-- [Digital Trends: 5 Fun, Easy Projects You Can Try With a $35 Raspberry Pi](https://youtu.be/QwrKlyC2kdM?t=1m42s) (March, 2016)
-- [Adafruit: Raspberry Pi Quick Look at Pi Hole ad blocking server with Tony D](https://www.youtube.com/watch?v=eg4u2j1HYlI) (June, 2016)
-- [Devacron: OrangePi Zero as an Ad-Block server with Pi-Hole](http://www.devacron.com/orangepi-zero-as-an-ad-block-server-with-pi-hole/) (December, 2016)
-- [Linux Pro: The Hole Truth](http://www.linuxpromagazine.com/Issues/2017/200/The-sysadmin-s-daily-grind-Pi-hole) (July, 2017)
-- [Adafruit: installing Pi-hole on a Pi Zero W](https://learn.adafruit.com/pi-hole-ad-blocker-with-pi-zero-w/install-pi-hole) (August, 2017)
-- [CryptoAUSTRALIA: How We Tried 5 Privacy Focused Raspberry Pi Projects](https://blog.cryptoaustralia.org.au/2017/10/05/5-privacy-focused-raspberry-pi-projects/) (October, 2017)
-- [CryptoAUSTRALIA: Pi-hole Workshop](https://blog.cryptoaustralia.org.au/2017/11/02/pi-hole-network-wide-ad-blocker/) (November, 2017)
-- [Know How 355: Killing ads with a Raspberry Pi-Hole!](https://www.twit.tv/shows/know-how/episodes/355) (November, 2017)
-- [Hobohouse: Block Advertising on your Network with Pi-hole and Raspberry Pi](https://hobo.house/2018/02/27/block-advertising-with-pi-hole-and-raspberry-pi/) (March, 2018)
-- [Scott Helme: Securing DNS across all of my devices with Pi-Hole + DNS-over-HTTPS + 1.1.1.1](https://scotthelme.co.uk/securing-dns-across-all-of-my-devices-with-pihole-dns-over-https-1-1-1-1/) (April, 2018)
-- [Scott Helme: Catching and dealing with naughty devices on my home network](https://scotthelme.co.uk/catching-naughty-devices-on-my-home-network/) (April, 2018)
-- [Bloomberg Business Week: Brotherhood of the Ad blockers](https://www.bloomberg.com/news/features/2018-05-10/inside-the-brotherhood-of-pi-hole-ad-blockers) (May, 2018)
-- [Software Engineering Daily: Interview with the creator of Pi-hole](https://softwareengineeringdaily.com/2018/05/29/pi-hole-ad-blocker-hardware-with-jacob-salmela/) (May, 2018)
-- [Raspberry Pi: Block ads at home using Pi-hole and a Raspberry Pi](https://www.raspberrypi.org/blog/pi-hole-raspberry-pi/) (July, 2018)
-- [Troy Hunt: Mmm... Pi-hole...](https://www.troyhunt.com/mmm-pi-hole/) (September, 2018)
-- [PEBKAK Podcast: Interview With Jacob Salmela](https://www.jerseystudios.net/2018/10/11/150-pi-hole/) (October, 2018)
+## [Coverage](https://docs.pi-hole.net/main/coverage/)
-----
## Pi-hole Projects
-- [The Big Blocklist Collection](https://wally3k.github.io)
+
+- [The Big Blocklist Collection](https://firebog.net/)
- [Pie in the Sky-Hole](https://dlaa.me/blog/post/skyhole)
- [Copernicus: Windows Tray Application](https://github.com/goldbattle/copernicus)
- [Magic Mirror with DNS Filtering](https://zonksec.com/blog/magic-mirror-dns-filtering/#dnssoftware)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index 757df9be..98f43c3f 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -13,7 +13,7 @@ LC_NUMERIC=C
# Retrieve stats from FTL engine
pihole-FTL() {
- ftl_port=$(cat /var/run/pihole-FTL.port 2> /dev/null)
+ ftl_port=$(cat /run/pihole-FTL.port 2> /dev/null)
if [[ -n "$ftl_port" ]]; then
# Open connection to FTL
exec 3<>"/dev/tcp/127.0.0.1/$ftl_port"
@@ -153,7 +153,7 @@ get_init_stats() {
sys_throttle_raw=$(vgt=$(sudo vcgencmd get_throttled); echo "${vgt##*x}")
- # Active Throttle Notice: http://bit.ly/2gnunOo
+ # Active Throttle Notice: https://bit.ly/2gnunOo
if [[ "$sys_throttle_raw" != "0" ]]; then
case "$sys_throttle_raw" in
*0001) thr_type="${COL_YELLOW}Under Voltage";;
diff --git a/advanced/Scripts/database_migration/gravity-db.sh b/advanced/Scripts/database_migration/gravity-db.sh
index 8a669429..70090a3b 100644
--- a/advanced/Scripts/database_migration/gravity-db.sh
+++ b/advanced/Scripts/database_migration/gravity-db.sh
@@ -104,4 +104,10 @@ upgrade_gravityDB(){
sqlite3 "${database}" < "${scriptPath}/10_to_11.sql"
version=11
fi
+ if [[ "$version" == "11" ]]; then
+ # Rename group 0 from "Unassociated" to "Default"
+ echo -e " ${INFO} Upgrading gravity database from version 11 to 12"
+ sqlite3 "${database}" < "${scriptPath}/11_to_12.sql"
+ version=12
+ fi
}
diff --git a/advanced/Scripts/database_migration/gravity/11_to_12.sql b/advanced/Scripts/database_migration/gravity/11_to_12.sql
new file mode 100644
index 00000000..45fbc845
--- /dev/null
+++ b/advanced/Scripts/database_migration/gravity/11_to_12.sql
@@ -0,0 +1,19 @@
+.timeout 30000
+
+PRAGMA FOREIGN_KEYS=OFF;
+
+BEGIN TRANSACTION;
+
+UPDATE "group" SET name = 'Default' WHERE id = 0;
+UPDATE "group" SET description = 'The default group' WHERE id = 0;
+
+DROP TRIGGER IF EXISTS tr_group_zero;
+
+CREATE TRIGGER tr_group_zero AFTER DELETE ON "group"
+ BEGIN
+ INSERT OR IGNORE INTO "group" (id,enabled,name,description) VALUES (0,1,'Default','The default group');
+ END;
+
+UPDATE info SET value = 12 WHERE property = 'version';
+
+COMMIT;
\ No newline at end of file
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 4f2e046f..77a5dece 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -22,6 +22,9 @@ web=false
domList=()
typeId=""
+comment=""
+declare -i domaincount
+domaincount=0
colfile="/opt/pihole/COL_TABLE"
source ${colfile}
@@ -97,10 +100,12 @@ ValidateDomain() {
fi
if [[ -n "${validDomain}" ]]; then
- domList=("${domList[@]}" ${validDomain})
+ domList=("${domList[@]}" "${validDomain}")
else
echo -e " ${CROSS} ${domain} is not a valid argument or domain name!"
fi
+
+ domaincount=$((domaincount+1))
}
ProcessDomainList() {
@@ -151,7 +156,12 @@ AddDomain() {
reload=true
# Insert only the domain here. The enabled and date_added fields will be filled
# with their default values (enabled = true, date_added = current timestamp)
- sqlite3 "${gravityDBfile}" "INSERT INTO domainlist (domain,type) VALUES ('${domain}',${typeId});"
+ if [[ -z "${comment}" ]]; then
+ sqlite3 "${gravityDBfile}" "INSERT INTO domainlist (domain,type) VALUES ('${domain}',${typeId});"
+ else
+ # also add comment when variable has been set through the "--comment" option
+ sqlite3 "${gravityDBfile}" "INSERT INTO domainlist (domain,type,comment) VALUES ('${domain}',${typeId},'${comment}');"
+ fi
}
RemoveDomain() {
@@ -224,8 +234,16 @@ NukeList() {
sqlite3 "${gravityDBfile}" "DELETE FROM domainlist WHERE type = ${typeId};"
}
-for var in "$@"; do
- case "${var}" in
+GetComment() {
+ comment="$1"
+ if [[ "${comment}" =~ [^a-zA-Z0-9_\#:/\.,\ -] ]]; then
+ echo " ${CROSS} Found invalid characters in domain comment!"
+ exit
+ fi
+}
+
+while (( "$#" )); do
+ case "${1}" in
"-w" | "whitelist" ) typeId=0;;
"-b" | "blacklist" ) typeId=1;;
"--white-regex" | "white-regex" ) typeId=2;;
@@ -239,13 +257,15 @@ for var in "$@"; do
"-l" | "--list" ) Displaylist;;
"--nuke" ) NukeList;;
"--web" ) web=true;;
- * ) ValidateDomain "${var}";;
+ "--comment" ) GetComment "${2}"; shift;;
+ * ) ValidateDomain "${1}";;
esac
+ shift
done
shift
-if [[ $# = 0 ]]; then
+if [[ ${domaincount} == 0 ]]; then
helpFunc
fi
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index 042a3c02..1c1b16a4 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -3,7 +3,7 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
#
-# Switch Pi-hole subsystems to a different Github branch.
+# Switch Pi-hole subsystems to a different GitHub branch.
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 4e137f8d..abf56153 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -87,7 +87,7 @@ PIHOLE_DHCP_CONFIG_FILE="${DNSMASQ_D_DIRECTORY}/02-pihole-dhcp.conf"
PIHOLE_WILDCARD_CONFIG_FILE="${DNSMASQ_D_DIRECTORY}/03-wildcard.conf"
WEB_SERVER_CONFIG_FILE="${WEB_SERVER_CONFIG_DIRECTORY}/lighttpd.conf"
-#WEB_SERVER_CUSTOM_CONFIG_FILE="${WEB_SERVER_CONFIG_DIRECTORY}/external.conf"
+WEB_SERVER_CUSTOM_CONFIG_FILE="${WEB_SERVER_CONFIG_DIRECTORY}/external.conf"
PIHOLE_INSTALL_LOG_FILE="${PIHOLE_DIRECTORY}/install.log"
PIHOLE_RAW_BLOCKLIST_FILES="${PIHOLE_DIRECTORY}/list.*"
@@ -166,11 +166,13 @@ REQUIRED_FILES=("${PIHOLE_CRON_FILE}"
"${PIHOLE_DHCP_CONFIG_FILE}"
"${PIHOLE_WILDCARD_CONFIG_FILE}"
"${WEB_SERVER_CONFIG_FILE}"
+"${WEB_SERVER_CUSTOM_CONFIG_FILE}"
"${PIHOLE_INSTALL_LOG_FILE}"
"${PIHOLE_RAW_BLOCKLIST_FILES}"
"${PIHOLE_LOCAL_HOSTS_FILE}"
"${PIHOLE_LOGROTATE_FILE}"
"${PIHOLE_SETUP_VARS_FILE}"
+"${PIHOLE_FTL_CONF_FILE}"
"${PIHOLE_COMMAND}"
"${PIHOLE_COLTABLE_FILE}"
"${FTL_PID}"
@@ -296,7 +298,11 @@ compare_local_version_to_git_version() {
log_write "${INFO} ${pihole_component}: ${COL_YELLOW}${remote_version:-Untagged}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
fi
- # If the repo is on the master branch, they are on the stable codebase
+ # Print the repo upstreams
+ remotes=$(git remote -v)
+ log_write "${INFO} Remotes: ${remotes//$'\n'/'\n '}"
+
+ # If the repo is on the master branchs, they are on the stable codebase
if [[ "${remote_branch}" == "master" ]]; then
# so the color of the text is green
log_write "${INFO} Branch: ${COL_GREEN}${remote_branch}${COL_NC}"
@@ -1107,22 +1113,19 @@ show_db_entries() {
}
show_groups() {
- show_db_entries "Groups" "SELECT id,name,enabled,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,description FROM \"group\"" "4 50 7 19 19 50"
+ 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"
}
show_adlists() {
- show_db_entries "Adlists" "SELECT id,address,enabled,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM adlist" "4 100 7 19 19 50"
- show_db_entries "Adlist groups" "SELECT * FROM adlist_by_group" "4 4"
+ show_db_entries "Adlists" "SELECT id,CASE enabled WHEN '0' THEN ' 0' WHEN '1' THEN ' 1' ELSE enabled END enabled,GROUP_CONCAT(adlist_by_group.group_id) group_ids,address,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM adlist LEFT JOIN adlist_by_group ON adlist.id = adlist_by_group.adlist_id GROUP BY id;" "4 7 12 100 19 19 50"
}
show_domainlist() {
- show_db_entries "Domainlist (0/1 = exact white-/blacklist, 2/3 = regex white-/blacklist)" "SELECT id,type,domain,enabled,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM domainlist" "4 4 100 7 19 19 50"
- show_db_entries "Domainlist groups" "SELECT * FROM domainlist_by_group" "10 10"
+ show_db_entries "Domainlist (0/1 = exact white-/blacklist, 2/3 = regex white-/blacklist)" "SELECT id,CASE type WHEN '0' THEN '0 ' WHEN '1' THEN ' 1 ' WHEN '2' THEN ' 2 ' WHEN '3' THEN ' 3' ELSE type END type,CASE enabled WHEN '0' THEN ' 0' WHEN '1' THEN ' 1' ELSE enabled END enabled,GROUP_CONCAT(domainlist_by_group.group_id) group_ids,domain,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM domainlist LEFT JOIN domainlist_by_group ON domainlist.id = domainlist_by_group.domainlist_id GROUP BY id;" "4 4 7 12 100 19 19 50"
}
show_clients() {
- show_db_entries "Clients" "SELECT id,ip,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM client" "4 100 19 19 50"
- show_db_entries "Client groups" "SELECT * FROM client_by_group" "10 10"
+ show_db_entries "Clients" "SELECT id,GROUP_CONCAT(client_by_group.group_id) group_ids,ip,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM client LEFT JOIN client_by_group ON client.id = client_by_group.client_id GROUP BY id;" "4 12 100 19 19 50"
}
analyze_gravity_list() {
diff --git a/advanced/Scripts/query.sh b/advanced/Scripts/query.sh
index 7518e6c4..fe9b8ebf 100755
--- a/advanced/Scripts/query.sh
+++ b/advanced/Scripts/query.sh
@@ -29,7 +29,7 @@ scanList(){
# Prevent grep from printing file path
cd "$piholeDir" || exit 1
- # Prevent grep -i matching slowly: http://bit.ly/2xFXtUX
+ # Prevent grep -i matching slowly: https://bit.ly/2xFXtUX
export LC_CTYPE=C
# /dev/null forces filename to be printed when only one list has been generated
diff --git a/advanced/Scripts/setupLCD.sh b/advanced/Scripts/setupLCD.sh
index e8f14f06..82523643 100755
--- a/advanced/Scripts/setupLCD.sh
+++ b/advanced/Scripts/setupLCD.sh
@@ -70,5 +70,5 @@ setupcon
reboot
# Start showing the stats on the screen by running the command on another tty:
-# http://unix.stackexchange.com/questions/170063/start-a-process-on-a-different-tty
+# https://unix.stackexchange.com/questions/170063/start-a-process-on-a-different-tty
#setsid sh -c 'exec /usr/local/bin/chronometer.sh <> /dev/tty1 >&0 2>&1'
diff --git a/advanced/Scripts/version.sh b/advanced/Scripts/version.sh
index f6d4d344..f77ee635 100755
--- a/advanced/Scripts/version.sh
+++ b/advanced/Scripts/version.sh
@@ -84,6 +84,21 @@ getRemoteVersion(){
# Get the version from the remote origin
local daemon="${1}"
local version
+ local cachedVersions
+ local arrCache
+ cachedVersions="/etc/pihole/GitHubVersions"
+
+ #If the above file exists, then we can read from that. Prevents overuse of GitHub API
+ if [[ -f "$cachedVersions" ]]; then
+ IFS=' ' read -r -a arrCache < "$cachedVersions"
+ case $daemon in
+ "pi-hole" ) echo "${arrCache[0]}";;
+ "AdminLTE" ) echo "${arrCache[1]}";;
+ "FTL" ) echo "${arrCache[2]}";;
+ esac
+
+ return 0
+ fi
version=$(curl --silent --fail "https://api.github.com/repos/pi-hole/${daemon}/releases/latest" | \
awk -F: '$1 ~/tag_name/ { print $2 }' | \
@@ -97,22 +112,48 @@ getRemoteVersion(){
return 0
}
+getLocalBranch(){
+ # Get the checked out branch of the local directory
+ local directory="${1}"
+ local branch
+
+ # Local FTL btranch is stored in /etc/pihole/ftlbranch
+ if [[ "$1" == "FTL" ]]; then
+ branch="$(pihole-FTL branch)"
+ else
+ cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
+ branch=$(git rev-parse --abbrev-ref HEAD || echo "$DEFAULT")
+ fi
+ if [[ ! "${branch}" =~ ^v ]]; then
+ if [[ "${branch}" == "master" ]]; then
+ echo ""
+ elif [[ "${branch}" == "HEAD" ]]; then
+ echo "in detached HEAD state at "
+ else
+ echo "${branch} "
+ fi
+ else
+ # Branch started in "v"
+ echo "release "
+ fi
+ return 0
+}
+
versionOutput() {
[[ "$1" == "pi-hole" ]] && GITDIR=$COREGITDIR
[[ "$1" == "AdminLTE" ]] && GITDIR=$WEBGITDIR
[[ "$1" == "FTL" ]] && GITDIR="FTL"
- [[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR)
+ [[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR) && branch=$(getLocalBranch $GITDIR)
[[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1")
if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then
- [[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR")
+ [[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR") && branch=$(getLocalBranch $GITDIR)
[[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)")
fi
-
if [[ -n "$current" ]] && [[ -n "$latest" ]]; then
- output="${1^} version is $current (Latest: $latest)"
+ output="${1^} version is $branch$current (Latest: $latest)"
elif [[ -n "$current" ]] && [[ -z "$latest" ]]; then
- output="Current ${1^} version is $current"
+ output="Current ${1^} version is $branch$current."
elif [[ -z "$current" ]] && [[ -n "$latest" ]]; then
output="Latest ${1^} version is $latest"
elif [[ "$curHash" == "N/A" ]] || [[ "$latHash" == "N/A" ]]; then
@@ -162,7 +203,7 @@ Repositories:
Options:
-c, --current Return the current version
-l, --latest Return the latest version
- --hash Return the Github hash from your local repositories
+ --hash Return the GitHub hash from your local repositories
-h, --help Show this help dialog"
exit 0
}
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index d5bf46a4..f53b58cc 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -18,6 +18,7 @@ readonly FTLconf="/etc/pihole/pihole-FTL.conf"
readonly dhcpstaticconfig="/etc/dnsmasq.d/04-pihole-static-dhcp.conf"
readonly PI_HOLE_BIN_DIR="/usr/local/bin"
readonly dnscustomfile="/etc/pihole/custom.list"
+readonly dnscustomcnamefile="/etc/dnsmasq.d/05-pihole-custom-cname.conf"
readonly gravityDBfile="/etc/pihole/gravity.db"
@@ -36,7 +37,6 @@ Options:
-c, celsius Set Celsius as preferred temperature unit
-f, fahrenheit Set Fahrenheit as preferred temperature unit
-k, kelvin Set Kelvin as preferred temperature unit
- -r, hostrecord Add a name to the DNS associated to an IPv4/IPv6 address
-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
@@ -432,6 +432,10 @@ SetWebUILayout() {
change_setting "WEBUIBOXEDLAYOUT" "${args[2]}"
}
+SetWebUITheme() {
+ change_setting "WEBTHEME" "${args[2]}"
+}
+
CheckUrl(){
local regex
# Check for characters NOT allowed in URLs
@@ -509,32 +513,6 @@ RemoveDHCPStaticAddress() {
sed -i "/dhcp-host=${mac}.*/d" "${dhcpstaticconfig}"
}
-SetHostRecord() {
- if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
- echo "Usage: pihole -a hostrecord [IPv4-address],[IPv6-address]
-Example: 'pihole -a hostrecord home.domain.com 192.168.1.1,2001:db8:a0b:12f0::1'
-Add a name to the DNS associated to an IPv4/IPv6 address
-
-Options:
- \"\" Empty: Remove host record
- -h, --help Show this help dialog"
- exit 0
- fi
-
- if [[ -n "${args[3]}" ]]; then
- change_setting "HOSTRECORD" "${args[2]},${args[3]}"
- echo -e " ${TICK} Setting host record for ${args[2]} to ${args[3]}"
- else
- change_setting "HOSTRECORD" ""
- echo -e " ${TICK} Removing host record"
- fi
-
- ProcessDNSSettings
-
- # Restart dnsmasq to load new configuration
- RestartDNS
-}
-
SetAdminEmail() {
if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
echo "Usage: pihole -a email
@@ -550,7 +528,10 @@ Options:
if [[ -n "${args[2]}" ]]; then
# Sanitize email address in case of security issues
- if [[ ! "${args[2]}" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$ ]]; then
+ # Regex from https://stackoverflow.com/a/2138832/4065967
+ local regex
+ regex="^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\$"
+ if [[ ! "${args[2]}" =~ ${regex} ]]; then
echo -e " ${CROSS} Invalid email address"
exit 0
fi
@@ -650,6 +631,7 @@ SetPrivacyLevel() {
# Set privacy level. Minimum is 0, maximum is 4
if [ "${args[2]}" -ge 0 ] && [ "${args[2]}" -le 4 ]; then
changeFTLsetting "PRIVACYLEVEL" "${args[2]}"
+ pihole restartdns reload-lists
fi
}
@@ -675,6 +657,28 @@ RemoveCustomDNSAddress() {
RestartDNS
}
+AddCustomCNAMERecord() {
+ echo -e " ${TICK} Adding custom CNAME record..."
+
+ domain="${args[2]}"
+ target="${args[3]}"
+ echo "cname=${domain},${target}" >> "${dnscustomcnamefile}"
+
+ # Restart dnsmasq to load new custom CNAME records
+ RestartDNS
+}
+
+RemoveCustomCNAMERecord() {
+ echo -e " ${TICK} Removing custom CNAME record..."
+
+ domain="${args[2]}"
+ target="${args[3]}"
+ sed -i "/cname=${domain},${target}/d" "${dnscustomcnamefile}"
+
+ # Restart dnsmasq to update removed custom CNAME records
+ RestartDNS
+}
+
main() {
args=("$@")
@@ -693,12 +697,12 @@ main() {
"enabledhcp" ) EnableDHCP;;
"disabledhcp" ) DisableDHCP;;
"layout" ) SetWebUILayout;;
+ "theme" ) SetWebUITheme;;
"-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;;
@@ -708,6 +712,8 @@ main() {
"-l" | "privacylevel" ) SetPrivacyLevel;;
"addcustomdns" ) AddCustomDNSAddress;;
"removecustomdns" ) RemoveCustomDNSAddress;;
+ "addcustomcname" ) AddCustomCNAMERecord;;
+ "removecustomcname" ) RemoveCustomCNAMERecord;;
* ) helpFunc;;
esac
diff --git a/advanced/Templates/gravity.db.sql b/advanced/Templates/gravity.db.sql
index e543bd19..fcf3489b 100644
--- a/advanced/Templates/gravity.db.sql
+++ b/advanced/Templates/gravity.db.sql
@@ -10,17 +10,18 @@ CREATE TABLE "group"
date_modified INTEGER NOT NULL DEFAULT (cast(strftime('%s', 'now') as int)),
description TEXT
);
-INSERT INTO "group" (id,enabled,name) VALUES (0,1,'Unassociated');
+INSERT INTO "group" (id,enabled,name,description) VALUES (0,1,'Default','The default group');
CREATE TABLE domainlist
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
type INTEGER NOT NULL DEFAULT 0,
- domain TEXT UNIQUE NOT NULL,
+ domain TEXT NOT NULL,
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,
+ UNIQUE(domain, type)
);
CREATE TABLE adlist
@@ -52,7 +53,7 @@ CREATE TABLE info
value TEXT NOT NULL
);
-INSERT INTO "info" VALUES('version','11');
+INSERT INTO "info" VALUES('version','12');
CREATE TABLE domain_audit
(
@@ -167,7 +168,7 @@ CREATE TRIGGER tr_group_update AFTER UPDATE ON "group"
CREATE TRIGGER tr_group_zero AFTER DELETE ON "group"
BEGIN
- INSERT OR IGNORE INTO "group" (id,enabled,name) VALUES (0,1,'Unassociated');
+ INSERT OR IGNORE INTO "group" (id,enabled,name) VALUES (0,1,'Default');
END;
CREATE TRIGGER tr_domainlist_delete AFTER DELETE ON domainlist
diff --git a/advanced/Templates/pihole-FTL.service b/advanced/Templates/pihole-FTL.service
index f32a5e89..6af449f3 100644
--- a/advanced/Templates/pihole-FTL.service
+++ b/advanced/Templates/pihole-FTL.service
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
### BEGIN INIT INFO
# Provides: pihole-FTL
-# Required-Start: $remote_fs $syslog
-# Required-Stop: $remote_fs $syslog
+# Required-Start: $remote_fs $syslog $network
+# Required-Stop: $remote_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: pihole-FTL daemon
@@ -10,7 +10,7 @@
### END INIT INFO
FTLUSER=pihole
-PIDFILE=/var/run/pihole-FTL.pid
+PIDFILE=/run/pihole-FTL.pid
get_pid() {
# First, try to obtain PID from PIDFILE
@@ -37,12 +37,12 @@ start() {
touch /var/log/pihole-FTL.log /var/log/pihole.log
touch /run/pihole-FTL.pid /run/pihole-FTL.port
touch /etc/pihole/dhcp.leases
- mkdir -p /var/run/pihole
+ mkdir -p /run/pihole
mkdir -p /var/log/pihole
- chown pihole:pihole /var/run/pihole /var/log/pihole
+ chown pihole:pihole /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
+ rm /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
chown pihole:pihole /etc/pihole /etc/pihole/dhcp.leases 2> /dev/null
@@ -50,7 +50,7 @@ start() {
chmod 0644 /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /var/log/pihole.log
# Chown database files to the user FTL runs as. We ignore errors as the files may not (yet) exist
chown pihole:pihole /etc/pihole/pihole-FTL.db /etc/pihole/gravity.db 2> /dev/null
- if setcap CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN+eip "$(which pihole-FTL)"; then
+ if setcap CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN,CAP_SYS_NICE+eip "$(which pihole-FTL)"; then
su -s /bin/sh -c "/usr/bin/pihole-FTL" "$FTLUSER"
else
echo "Warning: Starting pihole-FTL as root because setting capabilities is not supported on this system"
diff --git a/advanced/Templates/pihole.cron b/advanced/Templates/pihole.cron
index 8dc98721..ba89efdb 100644
--- a/advanced/Templates/pihole.cron
+++ b/advanced/Templates/pihole.cron
@@ -10,7 +10,7 @@
#
#
# This file is under source-control of the Pi-hole installation and update
-# scripts, any changes made to this file will be overwritten when the softare
+# scripts, any changes made to this file will be overwritten when the software
# is updated or re-installed. Please make any changes to the appropriate crontab
# or other cron file snippets.
diff --git a/advanced/bash-completion/pihole b/advanced/bash-completion/pihole
index cea36060..88282b02 100644
--- a/advanced/bash-completion/pihole
+++ b/advanced/bash-completion/pihole
@@ -15,7 +15,7 @@ _pihole() {
COMPREPLY=( $(compgen -W "${opts_lists}" -- ${cur}) )
;;
"admin")
- opts_admin="celsius email fahrenheit hostrecord interface kelvin password privacylevel"
+ opts_admin="celsius email fahrenheit interface kelvin password privacylevel"
COMPREPLY=( $(compgen -W "${opts_admin}" -- ${cur}) )
;;
"checkout")
diff --git a/advanced/index.php b/advanced/index.php
index 3b1de8d8..4f2a17f7 100644
--- a/advanced/index.php
+++ b/advanced/index.php
@@ -6,8 +6,8 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
-// Sanitize HTTP_HOST output
-$serverName = htmlspecialchars($_SERVER["HTTP_HOST"]);
+// Sanitize SERVER_NAME output
+$serverName = htmlspecialchars($_SERVER["SERVER_NAME"]);
// Remove external ipv6 brackets if any
$serverName = preg_replace('/^\[(.*)\]$/', '${1}', $serverName);
@@ -50,16 +50,24 @@ function setHeader($type = "x") {
}
// Determine block page type
-if ($serverName === "pi.hole") {
+if ($serverName === "pi.hole"
+ || (!empty($_SERVER["VIRTUAL_HOST"]) && $serverName === $_SERVER["VIRTUAL_HOST"])) {
// Redirect to Web Interface
exit(header("Location: /admin"));
} elseif (filter_var($serverName, FILTER_VALIDATE_IP) || in_array($serverName, $authorizedHosts)) {
// Set Splash Page output
$splashPage = "
-
+
+
$viewPort
-
- Pi-hole: Your black hole for Internet advertisements Did you mean to go to the admin panel?
+
+
+
+
+ Pi-hole: Your black hole for Internet advertisements
+ Did you mean to go to the admin panel?
+
+
";
// Set splash/landing page based off presence of $landPage
@@ -131,7 +139,12 @@ ini_set("default_socket_timeout", 3);
function queryAds($serverName) {
// Determine the time it takes while querying adlists
$preQueryTime = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"];
- $queryAds = file("http://127.0.0.1/admin/scripts/pi-hole/php/queryads.php?domain=$serverName&bp", FILE_IGNORE_NEW_LINES);
+ $queryAdsURL = sprintf(
+ "http://127.0.0.1:%s/admin/scripts/pi-hole/php/queryads.php?domain=%s&bp",
+ $_SERVER["SERVER_PORT"],
+ $serverName
+ );
+ $queryAds = file($queryAdsURL, FILE_IGNORE_NEW_LINES);
$queryAds = array_values(array_filter(preg_replace("/data:\s+/", "", $queryAds)));
$queryTime = sprintf("%.0f", (microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"]) - $preQueryTime);
@@ -226,10 +239,10 @@ setHeader();
=$viewPort ?>
-
-
+
+
● =$serverName ?>
-
+