diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 96ce4ba5..41564b65 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,32 +1,31 @@
-**By submitting this pull request, I confirm the following:** `{please fill any appropriate checkboxes, e.g: [X]}`
+**By submitting this pull request, I confirm the following:**
+*please fill any appropriate checkboxes, e.g: [X]*
-`{Please ensure that your pull request is for the 'development' branch!}`
+- [ ] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md), as well as this entire template.
+- [ ] I have made only one major change in my proposed changes.
+- [ ] I have commented my proposed changes within the code.
+- [ ] I have tested my proposed changes, and have included unit tests where possible.
+- [ ] I am willing to help maintain this change if there are issues with it later.
+- [ ] I give this submission freely and claim no ownership.
+- [ ] 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))
-- [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md), as well as this entire template.
-- [] I have made only one major change in my proposed changes.
-- [] I have commented my proposed changes within the code.
-- [] I have tested my proposed changes, and have included unit tests where possible.
-- [] I am willing to help maintain this change if there are issues with it later.
-- [] I give this submission freely and claim no ownership.
-- [] 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))
-- [] I have Signed Off all commits. ([`git commit --signoff`](https://git-scm.com/docs/git-commit#git-commit---signoff))
+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).
---
-
**What does this PR aim to accomplish?:**
+*A detailed description, screenshots (if necessary), as well as links to any relevant GitHub issues*
-`{A detailed description, screenshots (if necessary), as well as links to any relevant GitHub issues}`
**How does this PR accomplish the above?:**
+*A detailed description (such as a changelog) and screenshots (if necessary) of the implemented fix*
-`{A detailed description (such as a changelog) and screenshots (if necessary) of the implemented fix}`
**What documentation changes (if any) are needed to support this PR?:**
+*A detailed list of any necessary changes*
-`{A detailed list of any necessary changes}`
-> * `{Please delete this quoted section when opening your pull request}`
-> * You must follow the template instructions. Failure to do so will result in your issue being closed.
-> * Please respect that Pi-hole is developed by volunteers, who can only reply in their spare time.
-> * Detail helps us understand an issue quicker, but please ensure it's relevant.
+---
+* You must follow the template instructions. Failure to do so will result in your pull request being closed.
+* Please respect that Pi-hole is developed by volunteers, who can only reply in their spare time.
+
diff --git a/.gitignore b/.gitignore
index 91014dcd..73f14ae3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,69 @@
*.swp
__pycache__
.cache
-.pullapprove.yml
+
+# Created by https://www.gitignore.io/api/jetbrains+iml
+
+### JetBrains+iml ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# All idea files, with execptions
+.idea
+!.idea/codeStyles/*
+!.idea/codeStyleSettings.xml
+
+
+# Sensitive or high-churn files:
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.xml
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+
+# Gradle:
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# CMake
+cmake-build-debug/
+
+# Mongo Explorer plugin:
+.idea/**/mongoSettings.xml
+
+## File-based project format:
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Ruby plugin and RubyMine
+/.rakeTasks
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+### JetBrains+iml Patch ###
+# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
+
+*.iml
+.idea/misc.xml
+*.ipr
+
+# End of https://www.gitignore.io/api/jetbrains+iml
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 00000000..7704aeaa
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 00000000..79ee123c
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.stickler.yml b/.stickler.yml
new file mode 100644
index 00000000..b96fc2e7
--- /dev/null
+++ b/.stickler.yml
@@ -0,0 +1,3 @@
+linters:
+ shellcheck:
+ shell: bash
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8cb7ccb9..2b7fae5d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -28,6 +28,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.
## Technical Requirements
diff --git a/README.md b/README.md
index 97dde3c6..b7f4f249 100644
--- a/README.md
+++ b/README.md
@@ -1,95 +1,143 @@
-
-
-
+
+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.
-## Pi-hole®: The multi-platform, network-wide ad blocker
+- **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
+- **Responsive**: seamlessly speeds up the feel of everyday browsing by caching DNS queries
+- **Lightweight**: runs smoothly with [minimal hardware and software requirements](https://discourse.pi-hole.net/t/hardware-software-requirements/273)
+- **Robust**: a command line interface that is quality assured for interoperability
+- **Insightful**: a beautiful responsive Web Interface dashboard to view and control your Pi-hole
+- **Versatile**: can optionally function as a [DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026), ensuring *all* your devices are protected automatically
+- **Scalable**: [capable of handling hundreds of millions of queries](https://pi-hole.net/2017/05/24/how-much-traffic-can-pi-hole-handle/) when installed on server-grade hardware
+- **Modern**: blocks ads over both IPv4 and IPv6
+- **Free**: open source software which helps ensure _you_ are the sole person in control of your privacy
-Block ads for **all** your devices _without_ the need to install client-side software.
+-----
+
+
+
-## Executive Summary
-The Pi-hole blocks ads at the DNS-level, so all your devices are protected.
-
-- **Easy-to-install** - our intelligent installer walks you through the process with no additional software needed on client devices
-- **Universal** - ads are blocked in _non-browser locations_ such as ad-supported mobile apps and smart TVs
-- **Quick** - installation takes less than ten minutes and it [_really_ is _that easy_](https://discourse.pi-hole.net/t/new-pi-hole-questions/3971/5?u=jacob.salmela)
-- **Informative** - an administrative Web interface shows ad-blocking statistics
-- **Lightweight** - designed to run on [minimal resources](https://discourse.pi-hole.net/t/hardware-software-requirements/273)
-- **Scalable** - even in large environments, [Pi-hole can handle hundreds of millions of queries](https://pi-hole.net/2017/05/24/how-much-traffic-can-pi-hole-handle/) (with the right hardware specs)
-- **Powerful** - advertisements are blocked over IPv4 _and_ IPv6
-- **Fast** - it speeds up high-cost, high-latency networks by caching DNS queries and saves bandwidth by not downloading advertisement elements
-- **Versatile** - Pi-hole can function also function as a DHCP server
-
-# One-Step Automated Install
-1. Install a [supported operating system](https://discourse.pi-hole.net/t/hardware-software-requirements/273/1)
-2. Run the command below (it downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
+## One-Step Automated Install
+Those who want to get started quickly and conveniently, may install Pi-hole using the following command:
#### `curl -sSL https://install.pi-hole.net | bash`
-## Alternative Semi-Automated Install Methods
-_If you wish to read over the script before running it, run `nano basic-install.sh` to open the file in a text viewer._
-
-### Clone our repository and run the automated installer from your device.
+## 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:
+### Method 1: Clone our repository and run
```
git clone --depth 1 https://github.com/pi-hole/pi-hole.git Pi-hole
-cd Pi-hole/automated\ install/
-bash basic-install.sh
+cd "Pi-hole/automated install/"
+sudo bash basic-install.sh
```
-##### Or
-
-```bash
+### Method 2: Manually download the installer and run
+```
wget -O basic-install.sh https://install.pi-hole.net
-bash basic-install.sh
+sudo bash basic-install.sh
```
-Once installed, [configure your router to have **DHCP clients use the Pi-hole as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245) and then any device that connects to your network will have ads blocked without any further configuration.
+## Post-install: Make your network take advantage of Pi-hole
-If your router does not support setting the DNS server, you can [use Pi-hole's built in DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026); just be sure to disable DHCP on your router first.
+Once the installer has been run, you will need to [configure your router to have **DHCP clients use Pi-hole as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245) which ensures that all devices connecting to your network will have content blocked without any further intervention.
-Alternatively, you can manually set each device to use Pi-hole as their DNS server.
+If your router does not support setting the DNS server, you can [use Pi-hole's built in DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026); just be sure to disable DHCP on your router first (if it has that feature available).
-# What is Pi-hole and how do I install it?
-
-
-
+As a last resort, you can always manually set each device to use Pi-hole as their DNS server.
-# Pi-hole Is Free, But Powered By Your Donations
+-----
-All [our developers](https://github.com/orgs/pi-hole/people) are volunteers, so *your donations help keep us innovating*. Sending a donation using our links below helps us offset a portion of our monthly costs.
+## Pi-hole is free, but powered by your support
+There are many reoccurring costs involved with maintaining free, open source, and privacy respecting software; expenses which [our volunteer developers](https://github.com/orgs/pi-hole/people) pitch in to cover out-of-pocket. This is just one example of how strongly we feel about our software, as well as the importance of keeping it maintained.
--  [Donate via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
--  Bitcoin Address: 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
+Make no mistake: **your support is absolutely vital to help keep us innovating!**
-## Other Ways To Support Us
-### Affiliate Links
-If you'd rather not send money, there are [other ways to support us](https://pi-hole.net/donate): you can sign up for services through our affiliate links, which will also help us offset some of the costs associated with keeping Pi-hole operational; or you can support us in some non-tangible ways as listed below.
+### Donations
+Sending a donation using our links below is **extremely helpful** in offsetting a portion of our monthly expenses:
-### Contributing Code Via Pull Requests
+ Donate via PayPal
+ Bitcoin Address: 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
-We don't work on Pi-hole for monetary reasons; we work on it because we think it's fun and we think our software is important in today's world. To that end, we welcome all contributors--from novices to masters.
+### Alternative support
+If you'd rather not donate (_which is okay!_), there are other ways you can help support us:
-If you feel you have some code to contribute, we're happy to take a look. Just make sure to fill out our template when submitting a pull request. We're all volunteers on the project and without all the information in the template, it's very difficult for us to quickly get the code merged in.
+- [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/)
+- Spreading the word about our software, and how you have benefited from it
-You'll find that the [install script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) and the [debug script](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/piholeDebug.sh) have an abundance of comments. These are two important scripts but we think they can also be a valuable resource to those who want to learn how to write scripts or code a program, which is why they are fully commented. So we encourage anyone who likes to tinker to read through it and submit a PR for us to review.
+### Contributing via GitHub
+We welcome _everyone_ to contribute to issue reports, suggest new features, and create pull requests.
-### Presenting About Pi-hole
+If you have something to add - anything from a typo through to a whole new feature, we're happy to check it out! Just make sure to fill out our template when submitting your request; the questions that it asks will help the volunteers quickly understand what you're aiming to achieve.
-Word-of-mouth has immensely helped our project grow. If you are going to be presenting about Pi-hole at a conference, meetup, or even for a school project, [get a hold of us for some free swag](https://pi-hole.net/2017/05/17/giving-a-presentation-on-pi-hole-contact-us-first-for-some-goodies-and-support/) to hand out to your audience.
+You'll find that the [install script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) and the [debug script](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/piholeDebug.sh) have an abundance of comments, which will help you better understand how Pi-hole works. They're also a valuable resource to those who want to learn how to write scripts or code a program! We encourage anyone who likes to tinker to read through it, and submit a pull request for us to review.
-# Overview Of Features
+### Presentations about Pi-hole
+Word-of-mouth continues to help our project grow immensely, and so we are helping make this easier for people.
-## The Dashboard (Web Interface)
+If you are going to be presenting Pi-hole at a conference, meetup or even a school project, [get in touch with us](https://pi-hole.net/2017/05/17/giving-a-presentation-on-pi-hole-contact-us-first-for-some-goodies-and-support/) so we can hook you up with free swag to hand out to your audience!
-The [dashboard](https://github.com/pi-hole/AdminLTE#pi-hole-admin-dashboard) will (by default) be enabled during installation so you can view stats, change settings, and configure your Pi-hole.
+-----
-
+## Getting in touch with us
+While we are primarily reachable on our Discourse User Forum, we can also be found on a variety of social media outlets. **Please be sure to check the FAQ's** before starting a new discussion, as we do not have the spare time to reply to every request for assistance.
+
+
+
+-----
+
+## Breakdown of Features
+### The Command Line Interface
+The `pihole` command has all the functionality necessary to be able to fully administer the Pi-hole, without the need of the Web Interface. It's fast, user-friendly, and auditable by anyone with understanding of `bash`.
+
+
+
+Some notable features include:
+* [Whitelisting, Blacklisting and Wildcards](https://github.com/pi-hole/pi-hole/wiki/Core-Function-Breakdown#whitelisting-blacklisting-and-wildcards)
+* [Debugging utility](https://github.com/pi-hole/pi-hole/wiki/Core-Function-Breakdown#debugger)
+* [Viewing the live log file](https://github.com/pi-hole/pi-hole/wiki/Core-Function-Breakdown#tail)
+* [Real-time Statistics via `ssh`](https://github.com/pi-hole/pi-hole/wiki/Core-Function-Breakdown#chronometer) or [your TFT LCD screen](http://www.amazon.com/exec/obidos/ASIN/B00ID39LM4/pihole09-20)
+* [Updating Ad Lists](https://github.com/pi-hole/pi-hole/wiki/Core-Function-Breakdown#gravity)
+* [Querying Ad Lists for blocked domains](https://github.com/pi-hole/pi-hole/wiki/Core-Function-Breakdown#query)
+* [Enabling and Disabling Pi-hole](https://github.com/pi-hole/pi-hole/wiki/Core-Function-Breakdown#enable--disable)
+* ... and *many* more!
+
+You can read our [Core Feature Breakdown](https://github.com/pi-hole/pi-hole/wiki/Core-Function-Breakdown), as well as read up on [example usage](https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738) for more information.
+
+### 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!
+
+
+
+Some notable features include:
+* Mobile friendly interface
+* Password protection
+* Detailed graphs and doughnut charts
+* Top lists of domains and clients
+* A filterable and sortable query log
+* Long Term Statistics to view data over user defined time ranges
+* The ability to easily manage and configure Pi-hole features
+* ... and all the main features of the Command Line Interface!
There are several ways to [access the dashboard](https://discourse.pi-hole.net/t/how-do-i-access-pi-holes-dashboard-admin-interface/3168):
@@ -97,218 +145,73 @@ There are several ways to [access the dashboard](https://discourse.pi-hole.net/t
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 Query Log
+## 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*!
-If enabled, the query log will show all of the DNS queries requested by clients using Pi-hole as their DNS server. Forwarded domains will show in green, and blocked (_Pi-holed_) domains will show in red. You can also white or black list domains from within this section.
+Some of the statistics you can integrate include:
+* Total number of domains being blocked
+* Total number of DNS queries today
+* Total number of ads blocked today
+* Percentage of ads blocked
+* Unique domains
+* Queries forwarded (to your chosen upstream DNS server)
+* 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 query log and graphs are what have helped people [discover what sort of traffic is traversing their networks](https://pi-hole.net/2017/07/06/round-3-what-really-happens-on-your-network/).
+-----
-#### Long-term Statistics
-Using our Faster-Than-Light Engine ([FTL](https://github.com/pi-hole/FTL)), Pi-hole can store all of the domains queried in a database for retrieval or analysis later on. You can view this data as a graph, individual queries, or top clients/advertisers.
+## The Origin Of Pi-hole
+Pi-hole being a **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) - webserver 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
-### Whitelist And Blacklist
+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 setup 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.
-Domains can be [whitelisted](https://discourse.pi-hole.net/t/commonly-whitelisted-domains/212) and/or [blacklisted](https://discourse.pi-hole.net/t/commonly-blacklisted-domains/305) using either the dashboard or [the `pihole` command](https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738).
+-----
-
-
-
+## Pi-hole Projects
+- [The Big Blocklist Collection](https://wally3k.github.io)
+- [Docker Pi-hole container (x86 and ARM)](https://hub.docker.com/r/diginc/pi-hole/)
+- [Pi-Hole in the cloud](http://blog.codybunch.com/2015/07/28/Pi-Hole-in-the-cloud/)
+- [Pie in the Sky-Hole [A Pi-Hole in the cloud for ad-blocking via DNS]](https://dlaa.me/blog/post/skyhole)
+- [Pi-hole Enable/Disable Button](http://thetimmy.silvernight.org/pages/endisbutton/)
+- [Minibian Pi-hole](https://munkjensen.net/wiki/index.php/See_my_Pi-Hole#Minibian_Pi-hole)
+- [CHiP-hole: Network-wide Ad-blocker](https://www.hackster.io/jacobsalmela/chip-hole-network-wide-ad-blocker-98e037)
+- [Chrome Extension: Pi-Hole List Editor](https://chrome.google.com/webstore/detail/pi-hole-list-editor/hlnoeoejkllgkjbnnnhfolapllcnaglh) ([Source Code](https://github.com/packtloss/pihole-extension))
+- [Splunk: Pi-hole Visualiser](https://splunkbase.splunk.com/app/3023/)
+- [Adblocking with Pi-hole and Ubuntu 14.04 on VirtualBox](https://hbalagtas.blogspot.com.au/2016/02/adblocking-with-pi-hole-and-ubuntu-1404.html)
+- [Pi-hole stats in your Mac's menu bar](https://getbitbar.com/plugins/Network/pi-hole.1m.py)
+- [Pi-hole unRAID Template](https://forums.lime-technology.com/topic/36810-support-spants-nodered-mqtt-dashing-couchdb/)
+- [Copernicus: Windows Tray Application](https://github.com/goldbattle/copernicus)
+- [Let your blink1 device blink when Pi-hole filters ads](https://gist.github.com/elpatron68/ec0b4c582e5abf604885ac1e068d233f)
+- [Pi-hole metrics](https://github.com/nlamirault/pihole_exporter) exporter for [Prometheus](https://prometheus.io/)
+- [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)
+-----
-#### Additional Blocklists
-By default, Pi-hole blocks over 100,000 known ad-serving domains. You can expand the blocking power of your Pi-hole by [adding additional lists](https://discourse.pi-hole.net/t/how-do-i-add-additional-block-lists-to-pi-hole/259) such as the ones found on [The Big Blocklist Collection](https://wally3k.github.io/).
-
-
-
-
-
-### Enable And Disable Pi-hole
-Sometimes you may want to stop using Pi-hole or turn it back on. You can trigger this via the dashboard or command line.
-
-
-
-
-
-### Tools
-
-
-
-
-
-
-#### Update Ad Lists
-This runs `gravity` to download any newly-added domains from your source lists.
-
-#### Query Ad Lists
-You can find out what list a certain domain was on. This is useful for troubleshooting sites that may not work properly due to a blocked domain.
-
-#### `tail`ing Log Files
-You can [watch the log files](https://discourse.pi-hole.net/t/how-do-i-watch-and-interpret-the-pihole-log-file/276) in real time to help debug any issues, or just see what's happening with your Pi-hole.
-
-#### Pi-hole Debugger
-If you are having trouble with your Pi-hole, this is the place to go. You can run the debugger and it will attempt to diagnose any issues and then link to an FAQ with instructions on rectifying the problem.
-
-
-
-
-
-If run [via the command line](https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#debug), you will see red/yellow/green text, which makes it easy to identify any problems.
-
-
-
-
-
-
-After the debugger has finished, you have the option to upload it to our secure server for 48 hours. All you need to do then is provide one of our developers the unique token generated by the debugger (this is usually done via [our forums](https://discourse.pi-hole.net/c/bugs-problems-issues)).
-
-
-
-
-
-However, most of the time, you will be able to solve any issues without any intervention from us. But if you can't, we're always around to help out.
-
-### Settings
-
-The settings page lets you control and configure your Pi-hole. You can do things like:
-
-- view networking information
-- flush logs or disable the logging of queries
-- [enable Pi-hole's built-in DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026)
-- [manage block lists](https://discourse.pi-hole.net/t/how-do-i-add-additional-block-lists-to-pi-hole/259)
-- exclude domains from the graphs and enable privacy options
-- configure upstream DNS servers
-- restart Pi-hole's services
-- back up some of Pi-hole's important files
-- and more!
-
-
-
-
-
-
-## Built-in DHCP Server
-
-Pi-hole ships with a [built-in DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026). This allows you to let your network devices use Pi-hole as their DNS server if your router does not let you adjust the DHCP options.
-
-One nice feature of using Pi-hole's DHCP server if you can set hostnames and DHCP reservations so you'll [see hostnames in the query log instead of IP addresses](https://discourse.pi-hole.net/t/how-do-i-show-hostnames-instead-of-ip-addresses-in-the-dashboard/3530). You can still do this without using Pi-hole's DHCP server; it just takes a little more work. If you do plan to use Pi-hole's DHCP server, be sure to disable DHCP on your router first.
-
-
-
-
-
-## The FTL Engine: Our API
-
-A read-only API can be accessed at `admin/api.php` (the same output can be achieved on the CLI by running `pihole -c -j`).
-
-It returns the following JSON:
-``` json
-{
- "domains_being_blocked":111175,
- "dns_queries_today":15669,
- "ads_blocked_today":1752,
- "ads_percentage_today":11.181314,
- "unique_domains":1178,
- "queries_forwarded":9177,
- "queries_cached":4740,
- "unique_clients":18
- }
-```
-
-More details on the API can be found [here](https://discourse.pi-hole.net/t/pi-hole-api/1863) and on [the repo itself](https://github.com/pi-hole/FTL).
-
-### Real-time Statistics, Courtesy Of The Time Cops
-
-Using [chronometer2](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/chronometer.sh), you can view [real-time stats](https://discourse.pi-hole.net/t/how-do-i-view-my-pi-holes-stats-over-ssh-or-on-an-lcd-using-chronometer/240) via `ssh` or on an LCD screen such as the [2.8" LCD screen from Adafruit](http://amzn.to/1P0q1Fj).
-
-Simply run `pihole -c` for some detailed information.
-```
-|¯¯¯(¯)__|¯|_ ___|¯|___ Pi-hole: v3.2
-| ¯_/¯|__| ' \/ _ \ / -_) AdminLTE: v3.2
-|_| |_| |_||_\___/_\___| FTL: v2.10
- ——————————————————————————————————————————————————————————
- Hostname: pihole (Raspberry Pi 1, Model B)
- Uptime: 11 days, 12:55:01
- Task Load: 0.35 0.16 0.15 (Active: 5 of 33 tasks)
- CPU usage: 48% (1 core @ 700 MHz, 47c)
- RAM usage: 12% (Used: 54 MB of 434 MB)
- HDD usage: 20% (Used: 1 GB of 7 GB)
- LAN addr: 192.168.1.100 (Gateway: 192.168.1.1)
- Pi-hole: Active (Blocking: 111175 sites)
- Ads Today: 11% (1759 of 15812 queries)
- Fwd DNS: 208.67.222.222 (Alt DNS: 3 others)
- ——————————————————————————————————————————————————————————
- Recently blocked: www.google-analytics.com
- Top Advertiser: www.example.org
- Top Domain: www.example.org
- Top Client: somehost
-```
-
-
-
-
-
-
-
-
-
-# Get Help Or Connect With Us On The Web
-
-- [Users Forum](https://discourse.pi-hole.net/)
-- [FAQs](https://discourse.pi-hole.net/c/faqs)
-- [Feature requests](https://discourse.pi-hole.net/c/feature-requests?order=votes)
-- [Wiki](https://github.com/pi-hole/pi-hole/wiki)
-- [Facebook](https://www.facebook.com/ThePiHole/)
--  [Tweet @The_Pi_Hole](https://twitter.com/The_Pi_Hole)
--  [Reddit /r/pihole](https://www.reddit.com/r/pihole/)
--  [Pi-hole channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
-- [](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-# Technical Details
-
-To summarize into a short sentence, the Pi-hole is an **advertising-aware DNS/Web server**. And 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 it was setup 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.
-
-
-# Pi-hole Projects
-
-- [An ad blocking Magic Mirror](https://zonksec.com/blog/magic-mirror-dns-filtering/#dnssoftware)
-- [Pi-hole stats in your Mac's menu bar](https://getbitbar.com/plugins/Network/pi-hole.1m.py)
-- [Get LED alerts for each blocked ad](http://thetimmy.silvernight.org/pages/endisbutton/)
-- [Pi-hole on Ubuntu 14.04 on VirtualBox](http://hbalagtas.blogspot.com/2016/02/adblocking-with-pi-hole-and-ubuntu-1404.html)
-- [Docker Pi-hole container (x86 and ARM)](https://hub.docker.com/r/diginc/pi-hole/)
-- [Splunk: Pi-hole Visualiser](https://splunkbase.splunk.com/app/3023/)
-- [Pi-hole Chrome extension](https://chrome.google.com/webstore/detail/pi-hole-list-editor/hlnoeoejkllgkjbnnnhfolapllcnaglh) ([open source](https://github.com/packtloss/pihole-extension))
-- [Go Bananas for CHiP-hole ad blocking](https://www.hackster.io/jacobsalmela/chip-hole-network-wide-ad-blocker-98e037)
-- [Sky-Hole](http://dlaa.me/blog/post/skyhole)
-- [Pi-hole in the Cloud!](http://blog.codybunch.com/2015/07/28/Pi-Hole-in-the-cloud/)
-- [unRaid-hole](https://github.com/spants/unraidtemplates/blob/master/Spants/unRaid-hole.xml#L13)--[Repo and more info](http://lime-technology.com/forum/index.php?PHPSESSID=c0eae3e5ef7e521f7866034a3336489d&topic=38486.0)
-- [Pi-hole on/off button](http://thetimmy.silvernight.org/pages/endisbutton/)
-- [Minibian Pi-hole](http://munkjensen.net/wiki/index.php/See_my_Pi-Hole#Minibian_Pi-hole)
-- [Windows Tray Stat Application](https://github.com/goldbattle/copernicus)
-- [Let your blink1 device blink when Pi-hole filters ads](https://gist.github.com/elpatron68/ec0b4c582e5abf604885ac1e068d233f)
-- [Pi-hole Prometheus exporter](https://github.com/nlamirault/pihole_exporter): a [Prometheus](https://prometheus.io/) exporter for Pi-hole
-- [Pi-hole Droid - open source 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)
-
-# Coverage
-
-- [Adafruit livestream install](https://www.youtube.com/watch?v=eg4u2j1HYlI)
-- [TekThing: 5 fun, easy projects for a Raspberry Pi](https://youtu.be/QwrKlyC2kdM?t=1m42s)
-- [Pi-hole on Adafruit's blog](https://blog.adafruit.com/2016/03/04/pi-hole-is-a-black-hole-for-internet-ads-piday-raspberrypi-raspberry_pi/)
-- [The Defrag Show - MSDN/Channel 9](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)
-- [MacObserver Podcast 585](http://www.macobserver.com/tmo/podcast/macgeekgab-585)
-- [Medium: Block All Ads For $53](https://medium.com/@robleathern/block-ads-on-all-home-devices-for-53-18-a5f1ec139693#.gj1xpgr5d)
-- [MakeUseOf: Adblock Everywhere, The Pi-hole Way](http://www.makeuseof.com/tag/adblock-everywhere-raspberry-pi-hole-way/)
-- [Lifehacker: Turn Your Pi Into An Ad Blocker With A Single Command](http://lifehacker.com/turn-a-raspberry-pi-into-an-ad-blocker-with-a-single-co-1686093533)!
-- [Pi-hole on TekThing](https://youtu.be/8Co59HU2gY0?t=2m)
-- [Pi-hole on Security Now! Podcast](http://www.youtube.com/watch?v=p7-osq_y8i8&t=100m26s)
-- [Foolish Tech Show](https://youtu.be/bYyena0I9yc?t=2m4s)
-- [Pi-hole on Ubuntu](http://www.boyter.org/2015/12/pi-hole-ubuntu-14-04/)
-- [Catchpoint: iOS 9 Ad Blocking](http://blog.catchpoint.com/2015/09/14/ad-blocking-apple/)
-- [Build an Ad-Blocker for less than 10$ with Orange-Pi](http://www.devacron.com/orangepi-zero-as-an-ad-block-server-with-pi-hole/)
+## 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/)
+- [MakeUseOf: Adblock Everywhere: The Raspberry Pi-Hole Way](http://www.makeuseof.com/tag/adblock-everywhere-raspberry-pi-hole-way/)
+- [Catchpoint: Ad-Blocking on Apple iOS9: Valuing the End User Experience](http://blog.catchpoint.com/2015/09/14/ad-blocking-apple/)
+- [Security Now Netcast: Pi-hole](https://www.youtube.com/watch?v=p7-osq_y8i8&t=100m26s)
+- [TekThing: Raspberry Pi-Hole Makes Ads Disappear!](https://youtu.be/8Co59HU2gY0?t=2m)
+- [Foolish Tech Show](https://youtu.be/bYyena0I9yc?t=2m4s)
+- [Block Ads on All Home Devices for $53.18](https://medium.com/@robleathern/block-ads-on-all-home-devices-for-53-18-a5f1ec139693#.gj1xpgr5d)
+- [Pi-Hole for Ubuntu 14.04](http://www.boyter.org/2015/12/pi-hole-ubuntu-14-04/)
+- [MacObserver Podcast 585](https://www.macobserver.com/tmo/podcast/macgeekgab-585)
+- [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)
+- [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/)
+- [Digital Trends: 5 Fun, Easy Projects You Can Try With a $35 Raspberry Pi](https://youtu.be/QwrKlyC2kdM?t=1m42s)
+- [Adafruit: Raspberry Pi Quick Look at Pi Hole ad blocking server with Tony D](https://www.youtube.com/watch?v=eg4u2j1HYlI)
+- [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/)
+- [Linux Pro: The Hole Truth](http://www.linuxpromagazine.com/Issues/2017/200/The-sysadmin-s-daily-grind-Pi-hole)
+- [CryptoAUSTRALIA: How We Tried 5 Privacy Focused Raspberry Pi Projects](https://blog.cryptoaustralia.org.au/2017/10/05/5-privacy-focused-raspberry-pi-projects/)
+- [CryptoAUSTRALIA: Pi-hole Workshop](https://blog.cryptoaustralia.org.au/2017/11/02/pi-hole-network-wide-ad-blocker/)
+- [Know How 355: Killing ads with a Raspberry Pi-Hole!](https://www.twit.tv/shows/know-how/episodes/355)
diff --git a/advanced/01-pihole.conf b/advanced/01-pihole.conf
index f7b78ab0..85d260b2 100644
--- a/advanced/01-pihole.conf
+++ b/advanced/01-pihole.conf
@@ -39,7 +39,7 @@ interface=@INT@
cache-size=10000
-log-queries
+log-queries=extra
log-facility=/var/log/pihole.log
local-ttl=2
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index a9ccf900..13d743a8 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -15,7 +15,7 @@ pihole-FTL() {
ftl_port=$(cat /var/run/pihole-FTL.port 2> /dev/null)
if [[ -n "$ftl_port" ]]; then
# Open connection to FTL
- exec 3<>"/dev/tcp/localhost/$ftl_port"
+ exec 3<>"/dev/tcp/127.0.0.1/$ftl_port"
# Test if connection is open
if { "true" >&3; } 2> /dev/null; then
@@ -122,13 +122,13 @@ get_init_stats() {
}
# Convert seconds to human-readable format
- hrSecs() {
+ hrSecs() {
day=$(( $1/60/60/24 )); hrs=$(( $1/3600%24 ))
mins=$(( ($1%3600)/60 )); secs=$(( $1%60 ))
[[ "$day" -ge "2" ]] && plu="s"
[[ "$day" -ge "1" ]] && days="$day day${plu}, " || days=""
printf "%s%02d:%02d:%02d\\n" "$days" "$hrs" "$mins" "$secs"
- }
+ }
# Set Colour Codes
coltable="/opt/pihole/COL_TABLE"
@@ -199,7 +199,7 @@ get_init_stats() {
# Test existence of temperature file
if [[ -f "/sys/class/thermal/thermal_zone0/temp" ]]; then
temp_file="/sys/class/thermal/thermal_zone0/temp"
- elif [[ -f "/sys/class/hwmon/hwmon0/temp1_input" ]]; then
+ elif [[ -f "/sys/class/hwmon/hwmon0/temp1_input" ]]; then
temp_file="/sys/class/hwmon/hwmon0/temp1_input"
else
temp_file=""
@@ -302,7 +302,8 @@ get_sys_stats() {
# Determine whether to display CPU clock speed as MHz or GHz
if [[ -n "$cpu_mhz" ]]; then
- [[ "$cpu_mhz" -le "999" ]] && cpu_freq="$cpu_mhz MHz" || cpu_freq="$(calcFunc "$cpu_mhz"/1000) GHz"
+ [[ "$cpu_mhz" -le "999" ]] && cpu_freq="$cpu_mhz MHz" || cpu_freq="$(printf "%.1f" $(calcFunc "$cpu_mhz"/1000)) GHz"
+ [[ "${cpu_freq}" == *".0"* ]] && cpu_freq="${cpu_freq/.0/}"
fi
# Determine colour for temperature
@@ -380,7 +381,7 @@ get_ftl_stats() {
local top_domain_raw
local top_client_raw
- domains_being_blocked=$(printf "%.0f\\n" "${domains_being_blocked_raw}")
+ domains_being_blocked=$(printf "%.0f\\n" "${domains_being_blocked_raw}" 2> /dev/null)
dns_queries_today=$(printf "%.0f\\n" "${dns_queries_today_raw}")
ads_blocked_today=$(printf "%.0f\\n" "${ads_blocked_today_raw}")
ads_percentage_today=$(printf "%'.0f\\n" "${ads_percentage_today_raw}")
@@ -403,9 +404,9 @@ get_ftl_stats() {
get_strings() {
# Expand or contract strings depending on screen size
if [[ "$chrono_width" == "large" ]]; then
- phc_str=" ${COL_DARK_GRAY}Pi-hole"
- lte_str=" ${COL_DARK_GRAY}Admin"
- ftl_str=" ${COL_DARK_GRAY}FTL"
+ phc_str=" ${COL_DARK_GRAY}Core"
+ lte_str=" ${COL_DARK_GRAY}Web"
+ ftl_str=" ${COL_DARK_GRAY}FTL"
api_str="${COL_LIGHT_RED}API Offline"
host_info="$sys_type"
@@ -419,7 +420,7 @@ get_strings() {
ph_info="Blocking: $domains_being_blocked sites"
total_str="Total: "
else
- phc_str=" ${COL_DARK_GRAY}PH"
+ phc_str=" ${COL_DARK_GRAY}Core"
lte_str=" ${COL_DARK_GRAY}Web"
ftl_str=" ${COL_DARK_GRAY}FTL"
api_str="${COL_LIGHT_RED}API Down"
@@ -530,7 +531,7 @@ chronoFunc() {
sleep 5
fi
fi
-
+
done
}
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index a3f3261a..72250afd 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -19,7 +19,6 @@ addmode=true
verbose=true
domList=()
-domToRemoveList=()
listMain=""
listAlt=""
@@ -49,7 +48,8 @@ Options:
-nr, --noreload Update ${type}list without refreshing dnsmasq
-q, --quiet Make output less verbose
-h, --help Show this help dialog
- -l, --list Display all your ${type}listed domains"
+ -l, --list Display all your ${type}listed domains
+ --nuke Removes all entries in a list"
exit 0
}
@@ -70,7 +70,7 @@ HandleOther() {
validDomain=$(grep -P "^((-|_)*[a-z\d]((-|_)*[a-z\d])*(-|_)*)(\.(-|_)*([a-z\d]((-|_)*[a-z\d])*))*$" <<< "${domain}") # Valid chars check
validDomain=$(grep -P "^[^\.]{1,63}(\.[^\.]{1,63})*$" <<< "${validDomain}") # Length of each label
fi
-
+
if [[ -n "${validDomain}" ]]; then
domList=("${domList[@]}" ${validDomain})
else
@@ -223,6 +223,15 @@ Displaylist() {
exit 0;
}
+NukeList() {
+ if [[ -f "${listMain}" ]]; then
+ # Back up original list
+ cp "${listMain}" "${listMain}.bck~"
+ # Empty out file
+ echo "" > "${listMain}"
+ fi
+}
+
for var in "$@"; do
case "${var}" in
"-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";;
@@ -230,10 +239,10 @@ for var in "$@"; do
"-wild" | "wildcard" ) listMain="${wildcardlist}";;
"-nr"| "--noreload" ) reload=false;;
"-d" | "--delmode" ) addmode=false;;
- "-f" | "--force" ) force=true;;
"-q" | "--quiet" ) verbose=false;;
"-h" | "--help" ) helpFunc;;
"-l" | "--list" ) Displaylist;;
+ "--nuke" ) NukeList;;
* ) HandleOther "${var}";;
esac
done
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index ea387b5a..b668af94 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -29,13 +29,14 @@ if [[ -f ${PIHOLE_COLTABLE_FILE} ]]; then
source ${PIHOLE_COLTABLE_FILE}
else
COL_NC='\e[0m' # No Color
+ COL_RED='\e[1;91m'
+ COL_GREEN='\e[1;32m'
COL_YELLOW='\e[1;33m'
- COL_LIGHT_PURPLE='\e[1;35m'
+ COL_PURPLE='\e[1;35m'
COL_CYAN='\e[0;36m'
- TICK="[${COL_LIGHT_GREEN}✓${COL_NC}]"
- CROSS="[${COL_LIGHT_RED}✗${COL_NC}]"
+ TICK="[${COL_GREEN}✓${COL_NC}]"
+ CROSS="[${COL_RED}✗${COL_NC}]"
INFO="[i]"
- DONE="${COL_LIGHT_GREEN} done!${COL_NC}"
OVER="\r\033[K"
fi
@@ -175,7 +176,7 @@ show_disclaimer(){
source_setup_variables() {
# Display the current test that is running
- log_write "\n${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC} Sourcing setup variables"
+ log_write "\n${COL_PURPLE}*** [ INITIALIZING ]${COL_NC} Sourcing setup variables"
# If the variable file exists,
if ls "${PIHOLE_SETUP_VARS_FILE}" 1> /dev/null 2>&1; then
log_write "${INFO} Sourcing ${PIHOLE_SETUP_VARS_FILE}...";
@@ -183,7 +184,7 @@ source_setup_variables() {
source ${PIHOLE_SETUP_VARS_FILE}
else
# If it can't, show an error
- log_write "${PIHOLE_SETUP_VARS_FILE} ${COL_LIGHT_RED}does not exist or cannot be read.${COL_NC}"
+ log_write "${PIHOLE_SETUP_VARS_FILE} ${COL_RED}does not exist or cannot be read.${COL_NC}"
fi
}
@@ -214,14 +215,14 @@ copy_to_debug_log() {
sed 's/\[[0-9;]\{1,5\}m//g' > "${PIHOLE_DEBUG_LOG_SANITIZED}" <<< cat "${PIHOLE_DEBUG_LOG}"
}
-initiate_debug() {
+initialize_debug() {
# Clear the screen so the debug log is readable
clear
show_disclaimer
# Display that the debug process is beginning
- log_write "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}"
+ log_write "${COL_PURPLE}*** [ INITIALIZING ]${COL_NC}"
# Timestamp the start of the log
- log_write "${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated."
+ log_write "${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initialized."
}
# This is a function for visually displaying the curent test that is being run.
@@ -230,7 +231,7 @@ initiate_debug() {
echo_current_diagnostic() {
# Colors are used for visually distinguishing each test in the output
# These colors do not show in the GUI, but the formatting will
- log_write "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
+ log_write "\n${COL_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
}
compare_local_version_to_git_version() {
@@ -255,7 +256,7 @@ compare_local_version_to_git_version() {
# move into it
cd "${git_dir}" || \
# If not, show an error
- log_write "${COL_LIGHT_RED}Could not cd into ${git_dir}$COL_NC"
+ log_write "${COL_RED}Could not cd into ${git_dir}$COL_NC"
if git status &> /dev/null; then
# The current version the user is on
local remote_version
@@ -269,7 +270,7 @@ compare_local_version_to_git_version() {
# echo this information out to the user in a nice format
# If the current version matches what pihole -v produces, the user is up-to-date
if [[ "${remote_version}" == "$(pihole -v | awk '/${search_term}/ {print $6}' | cut -d ')' -f1)" ]]; then
- log_write "${TICK} ${pihole_component}: ${COL_LIGHT_GREEN}${remote_version}${COL_NC}"
+ log_write "${TICK} ${pihole_component}: ${COL_GREEN}${remote_version}${COL_NC}"
# If not,
else
# echo the current version in yellow, signifying it's something to take a look at, but not a critical error
@@ -280,7 +281,7 @@ compare_local_version_to_git_version() {
# If the repo is on the master branch, they are on the stable codebase
if [[ "${remote_branch}" == "master" ]]; then
# so the color of the text is green
- log_write "${INFO} Branch: ${COL_LIGHT_GREEN}${remote_branch}${COL_NC}"
+ log_write "${INFO} Branch: ${COL_GREEN}${remote_branch}${COL_NC}"
# If it is any other branch, they are in a developement branch
else
# So show that in yellow, signifying it's something to take a look at, but not a critical error
@@ -308,7 +309,7 @@ check_ftl_version() {
# Compare the current FTL version to the remote version
if [[ "${FTL_VERSION}" == "$(pihole -v | awk '/FTL/ {print $6}' | cut -d ')' -f1)" ]]; then
# If they are the same, FTL is up-to-date
- log_write "${TICK} ${ftl_name}: ${COL_LIGHT_GREEN}${FTL_VERSION}${COL_NC}"
+ log_write "${TICK} ${ftl_name}: ${COL_GREEN}${FTL_VERSION}${COL_NC}"
else
# If not, show it in yellow, signifying there is an update
log_write "${TICK} ${ftl_name}: ${COL_YELLOW}${FTL_VERSION}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
@@ -345,7 +346,7 @@ get_program_version() {
# If the program does not have a version (the variable is empty)
if [[ -z "${program_version}" ]]; then
# Display and error
- log_write "${CROSS} ${COL_LIGHT_RED}${program_name} version could not be detected.${COL_NC}"
+ log_write "${CROSS} ${COL_RED}${program_name} version could not be detected.${COL_NC}"
else
# Otherwise, display the version
log_write "${INFO} ${program_version}"
@@ -368,13 +369,13 @@ is_os_supported() {
# If the variable is one of our supported OSes,
case "${the_os}" in
# Print it in green
- "Raspbian") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
- "Ubuntu") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
- "Fedora") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
- "Debian") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
- "CentOS") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
+ "Raspbian") log_write "${TICK} ${COL_GREEN}${os_to_check}${COL_NC}";;
+ "Ubuntu") log_write "${TICK} ${COL_GREEN}${os_to_check}${COL_NC}";;
+ "Fedora") log_write "${TICK} ${COL_GREEN}${os_to_check}${COL_NC}";;
+ "Debian") log_write "${TICK} ${COL_GREEN}${os_to_check}${COL_NC}";;
+ "CentOS") log_write "${TICK} ${COL_GREEN}${os_to_check}${COL_NC}";;
# If not, show it in red and link to our software requirements page
- *) log_write "${CROSS} ${COL_LIGHT_RED}${os_to_check}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS})";
+ *) log_write "${CROSS} ${COL_RED}${os_to_check}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS})";
esac
}
@@ -418,7 +419,37 @@ diagnose_operating_system() {
get_distro_attributes
else
# If it doesn't exist, it's not a system we currently support and link to FAQ
- log_write "${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS})"
+ log_write "${CROSS} ${COL_RED}${error_msg}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS})"
+ fi
+}
+
+check_selinux() {
+ # SELinux is not supported by the Pi-hole
+ echo_current_diagnostic "SELinux"
+ # Check if a SELinux configuration file exists
+ if [[ -f /etc/selinux/config ]]; then
+ # If a SELinux configuration file was found, check the default SELinux mode.
+ DEFAULT_SELINUX=$(awk -F= '/^SELINUX=/ {print $2}' /etc/selinux/config)
+ case "${DEFAULT_SELINUX,,}" in
+ enforcing)
+ log_write "${CROSS} ${COL_RED}Default SELinux: $DEFAULT_SELINUX${COL_NC}"
+ ;;
+ *) # 'permissive' and 'disabled'
+ log_write "${TICK} ${COL_GREEN}Default SELinux: $DEFAULT_SELINUX${COL_NC}";
+ ;;
+ esac
+ # Check the current state of SELinux
+ CURRENT_SELINUX=$(getenforce)
+ case "${CURRENT_SELINUX,,}" in
+ enforcing)
+ log_write "${CROSS} ${COL_RED}Current SELinux: $CURRENT_SELINUX${COL_NC}"
+ ;;
+ *) # 'permissive' and 'disabled'
+ log_write "${TICK} ${COL_GREEN}Current SELinux: $CURRENT_SELINUX${COL_NC}";
+ ;;
+ esac
+ else
+ log_write "${INFO} ${COL_GREEN}SELinux not detected${COL_NC}";
fi
}
@@ -430,19 +461,19 @@ processor_check() {
if [[ -z "${PROCESSOR}" ]]; then
# we couldn't detect it, so show an error
PROCESSOR=$(lscpu | awk '/Architecture/ {print $2}')
- log_write "${CROSS} ${COL_LIGHT_RED}${PROCESSOR}${COL_NC} has not been tested with FTL, but may still work: (${FAQ_FTL_COMPATIBILITY})"
+ log_write "${CROSS} ${COL_RED}${PROCESSOR}${COL_NC} has not been tested with FTL, but may still work: (${FAQ_FTL_COMPATIBILITY})"
else
# Check if the architecture is currently supported for FTL
case "${PROCESSOR}" in
- "amd64") "${TICK} ${COL_LIGHT_GREEN}${PROCESSOR}${COL_NC}"
+ "amd64") "${TICK} ${COL_GREEN}${PROCESSOR}${COL_NC}"
;;
- "armv6l") "${TICK} ${COL_LIGHT_GREEN}${PROCESSOR}${COL_NC}"
+ "armv6l") "${TICK} ${COL_GREEN}${PROCESSOR}${COL_NC}"
;;
- "armv6") "${TICK} ${COL_LIGHT_GREEN}${PROCESSOR}${COL_NC}"
+ "armv6") "${TICK} ${COL_GREEN}${PROCESSOR}${COL_NC}"
;;
- "armv7l") "${TICK} ${COL_LIGHT_GREEN}${PROCESSOR}${COL_NC}"
+ "armv7l") "${TICK} ${COL_GREEN}${PROCESSOR}${COL_NC}"
;;
- "aarch64") "${TICK} ${COL_LIGHT_GREEN}${PROCESSOR}${COL_NC}"
+ "aarch64") "${TICK} ${COL_GREEN}${PROCESSOR}${COL_NC}"
;;
# Otherwise, show the processor type
*) log_write "${INFO} ${PROCESSOR}";
@@ -458,7 +489,7 @@ parse_setup_vars() {
parse_file "${PIHOLE_SETUP_VARS_FILE}"
else
# If not, show an error
- log_write "${CROSS} ${COL_LIGHT_RED}Could not read ${PIHOLE_SETUP_VARS_FILE}.${COL_NC}"
+ log_write "${CROSS} ${COL_RED}Could not read ${PIHOLE_SETUP_VARS_FILE}.${COL_NC}"
fi
}
@@ -468,16 +499,16 @@ does_ip_match_setup_vars() {
# IP address to check for
local ip_address="${2}"
# See what IP is in the setupVars.conf file
- local setup_vars_ip=$(cat ${PIHOLE_SETUP_VARS_FILE} | grep IPV${protocol}_ADDRESS | cut -d '=' -f2)
+ local setup_vars_ip=$(< ${PIHOLE_SETUP_VARS_FILE} grep IPV${protocol}_ADDRESS | cut -d '=' -f2)
# If it's an IPv6 address
if [[ "${protocol}" == "6" ]]; then
# Strip off the / (CIDR notation)
if [[ "${ip_address%/*}" == "${setup_vars_ip%/*}" ]]; then
# if it matches, show it in green
- log_write " ${COL_LIGHT_GREEN}${ip_address%/*}${COL_NC} matches the IP found in ${PIHOLE_SETUP_VARS_FILE}"
+ log_write " ${COL_GREEN}${ip_address%/*}${COL_NC} matches the IP found in ${PIHOLE_SETUP_VARS_FILE}"
else
# otherwise show it in red with an FAQ URL
- log_write " ${COL_LIGHT_RED}${ip_address%/*}${COL_NC} does not match the IP found in ${PIHOLE_SETUP_VARS_FILE} (${FAQ_ULA})"
+ log_write " ${COL_RED}${ip_address%/*}${COL_NC} does not match the IP found in ${PIHOLE_SETUP_VARS_FILE} (${FAQ_ULA})"
fi
else
@@ -485,10 +516,10 @@ does_ip_match_setup_vars() {
# since it exists in the setupVars.conf that way
if [[ "${ip_address}" == "${setup_vars_ip}" ]]; then
# show in green if it matches
- log_write " ${COL_LIGHT_GREEN}${ip_address}${COL_NC} matches the IP found in ${PIHOLE_SETUP_VARS_FILE}"
+ log_write " ${COL_GREEN}${ip_address}${COL_NC} matches the IP found in ${PIHOLE_SETUP_VARS_FILE}"
else
# otherwise show it in red
- log_write " ${COL_LIGHT_RED}${ip_address}${COL_NC} does not match the IP found in ${PIHOLE_SETUP_VARS_FILE} (${FAQ_ULA})"
+ log_write " ${COL_RED}${ip_address}${COL_NC} does not match the IP found in ${PIHOLE_SETUP_VARS_FILE} (${FAQ_ULA})"
fi
fi
}
@@ -516,7 +547,7 @@ detect_ip_addresses() {
log_write ""
else
# If there are no IPs detected, explain that the protocol is not configured
- log_write "${CROSS} ${COL_LIGHT_RED}No IPv${protocol} address(es) found on the ${PIHOLE_INTERFACE}${COL_NC} interace.\n"
+ log_write "${CROSS} ${COL_RED}No IPv${protocol} address(es) found on the ${PIHOLE_INTERFACE}${COL_NC} interface.\n"
return 1
fi
# If the protocol is v6
@@ -563,13 +594,13 @@ ping_gateway() {
# If pinging the gateway is not successful,
if ! ${cmd} -c 3 -W 2 -n ${gateway} -I ${PIHOLE_INTERFACE} >/dev/null; then
# let the user know
- log_write "${CROSS} ${COL_LIGHT_RED}Gateway did not respond.${COL_NC} ($FAQ_GATEWAY)\n"
+ log_write "${CROSS} ${COL_RED}Gateway did not respond.${COL_NC} ($FAQ_GATEWAY)\n"
# and return an error code
return 1
# Otherwise,
else
# show a success
- log_write "${TICK} ${COL_LIGHT_GREEN}Gateway responded.${COL_NC}"
+ log_write "${TICK} ${COL_GREEN}Gateway responded.${COL_NC}"
# and return a success code
return 0
fi
@@ -584,11 +615,11 @@ ping_internet() {
# Try to ping the address 3 times
if ! ${cmd} -W 2 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} >/dev/null; then
# if it's unsuccessful, show an error
- log_write "${CROSS} ${COL_LIGHT_RED}Cannot reach the Internet.${COL_NC}\n"
+ log_write "${CROSS} ${COL_RED}Cannot reach the Internet.${COL_NC}\n"
return 1
else
# Otherwise, show success
- log_write "${TICK} ${COL_LIGHT_GREEN}Query responded.${COL_NC}\n"
+ log_write "${TICK} ${COL_GREEN}Query responded.${COL_NC}\n"
return 0
fi
}
@@ -601,11 +632,11 @@ compare_port_to_service_assigned() {
local ftl="pihole-FTL"
if [[ "${service_name}" == "${resolver}" ]] || [[ "${service_name}" == "${web_server}" ]] || [[ "${service_name}" == "${ftl}" ]]; then
# if port 53 is dnsmasq, show it in green as it's standard
- log_write "[${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
+ log_write "[${COL_GREEN}${port_number}${COL_NC}] is in use by ${COL_GREEN}${service_name}${COL_NC}"
# Otherwise,
else
# Show the service name in red since it's non-standard
- log_write "[${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_PORTS})"
+ log_write "[${COL_RED}${port_number}${COL_NC}] is in use by ${COL_RED}${service_name}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_PORTS})"
fi
}
@@ -681,21 +712,21 @@ check_x_headers() {
# If the X-header found by curl matches what is should be,
if [[ $block_page == "$block_page_working" ]]; then
# display a success message
- log_write "$TICK ${COL_LIGHT_GREEN}${block_page}${COL_NC}"
+ log_write "$TICK ${COL_GREEN}${block_page}${COL_NC}"
else
# Otherwise, show an error
- log_write "$CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
- log_write "${COL_LIGHT_RED}${full_curl_output_block_page}${COL_NC}"
+ log_write "$CROSS ${COL_RED}X-Header does not match or could not be retrieved.${COL_NC}"
+ log_write "${COL_RED}${full_curl_output_block_page}${COL_NC}"
fi
# Same logic applies to the dashbord as above, if the X-Header matches what a working system shoud have,
if [[ $dashboard == "$dashboard_working" ]]; then
# then we can show a success
- log_write "$TICK ${COL_LIGHT_GREEN}${dashboard}${COL_NC}"
+ log_write "$TICK ${COL_GREEN}${dashboard}${COL_NC}"
else
# Othewise, it's a failure since the X-Headers either don't exist or have been modified in some way
- log_write "$CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
- log_write "${COL_LIGHT_RED}${full_curl_output_dashboard}${COL_NC}"
+ log_write "$CROSS ${COL_RED}X-Header does not match or could not be retrieved.${COL_NC}"
+ log_write "${COL_RED}${full_curl_output_dashboard}${COL_NC}"
fi
}
@@ -740,10 +771,10 @@ dig_at() {
# First, do a dig on localhost to see if Pi-hole can use itself to block a domain
if local_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
# If it can, show sucess
- log_write "${TICK} ${random_url} ${COL_LIGHT_GREEN}is ${local_dig}${COL_NC} via ${COL_CYAN}localhost$COL_NC (${local_address})"
+ log_write "${TICK} ${random_url} ${COL_GREEN}is ${local_dig}${COL_NC} via ${COL_CYAN}localhost$COL_NC (${local_address})"
else
# Otherwise, show a failure
- log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} via ${COL_LIGHT_RED}localhost${COL_NC} (${local_address})"
+ log_write "${CROSS} ${COL_RED}Failed to resolve${COL_NC} ${random_url} via ${COL_RED}localhost${COL_NC} (${local_address})"
fi
# Next we need to check if Pi-hole can resolve a domain when the query is sent to it's IP address
@@ -754,20 +785,20 @@ dig_at() {
# If Pi-hole can dig itself from it's IP (not the loopback address)
if pihole_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
# show a success
- log_write "${TICK} ${random_url} ${COL_LIGHT_GREEN}is ${pihole_dig}${COL_NC} via ${COL_CYAN}Pi-hole${COL_NC} (${pihole_address})"
+ log_write "${TICK} ${random_url} ${COL_GREEN}is ${pihole_dig}${COL_NC} via ${COL_CYAN}Pi-hole${COL_NC} (${pihole_address})"
else
# Othewise, show a failure
- log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} via ${COL_LIGHT_RED}Pi-hole${COL_NC} (${pihole_address})"
+ log_write "${CROSS} ${COL_RED}Failed to resolve${COL_NC} ${random_url} via ${COL_RED}Pi-hole${COL_NC} (${pihole_address})"
fi
# Finally, we need to make sure legitimate queries can out to the Internet using an external, public DNS server
# We are using the static remote_url here instead of a random one because we know it works with IPv4 and IPv6
if remote_dig=$(dig +tries=1 +time=2 -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
# If successful, the real IP of the domain will be returned instead of Pi-hole's IP
- log_write "${TICK} ${remote_url} ${COL_LIGHT_GREEN}is ${remote_dig}${COL_NC} via ${COL_CYAN}a remote, public DNS server${COL_NC} (${remote_address})"
+ log_write "${TICK} ${remote_url} ${COL_GREEN}is ${remote_dig}${COL_NC} via ${COL_CYAN}a remote, public DNS server${COL_NC} (${remote_address})"
else
# Otherwise, show an error
- log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${remote_url} via ${COL_LIGHT_RED}a remote, public DNS server${COL_NC} (${remote_address})"
+ log_write "${CROSS} ${COL_RED}Failed to resolve${COL_NC} ${remote_url} via ${COL_RED}a remote, public DNS server${COL_NC} (${remote_address})"
fi
}
@@ -778,15 +809,21 @@ process_status(){
local i
# For each process,
for i in "${PIHOLE_PROCESSES[@]}"; do
- # get its status via systemctl
- local status_of_process=$(systemctl is-active "${i}")
+ # If systemd
+ if command -v systemctl &> /dev/null; then
+ # get its status via systemctl
+ local status_of_process=$(systemctl is-active "${i}")
+ else
+ # Otherwise, use the service command
+ local status_of_process=$(service "${i}" status | awk '/Active:/ {print $2}') &> /dev/null
+ fi
# and print it out to the user
if [[ "${status_of_process}" == "active" ]]; then
# If it's active, show it in green
- log_write "${TICK} ${COL_LIGHT_GREEN}${i}${COL_NC} daemon is ${COL_LIGHT_GREEN}${status_of_process}${COL_NC}"
+ log_write "${TICK} ${COL_GREEN}${i}${COL_NC} daemon is ${COL_GREEN}${status_of_process}${COL_NC}"
else
# If it's not, show it in red
- log_write "${CROSS} ${COL_LIGHT_RED}${i}${COL_NC} daemon is ${COL_LIGHT_RED}${status_of_process}${COL_NC}"
+ log_write "${CROSS} ${COL_RED}${i}${COL_NC} daemon is ${COL_RED}${status_of_process}${COL_NC}"
fi
done
}
@@ -885,7 +922,7 @@ dir_check() {
:
else
# Otherwise, show an error
- log_write "${COL_LIGHT_RED}${directory} does not exist.${COL_NC}"
+ log_write "${COL_RED}${directory} does not exist.${COL_NC}"
fi
done
}
@@ -914,7 +951,7 @@ list_files_in_dir() {
for i in "${!REQUIRED_FILES[@]}"; do
if [[ "${dir_to_parse}/${each_file}" == ${REQUIRED_FILES[$i]} ]]; then
# display the filename
- log_write "\n${COL_LIGHT_GREEN}$(ls -ld ${dir_to_parse}/${each_file})${COL_NC}"
+ 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
@@ -963,7 +1000,7 @@ analyze_gravity_list() {
# Get the lines that are in the file(s) and store them in an array for parsing later
IFS=$'\r\n'
local gravity_permissions=$(ls -ld "${PIHOLE_BLOCKLIST_FILE}")
- log_write "${COL_LIGHT_GREEN}${gravity_permissions}${COL_NC}"
+ log_write "${COL_GREEN}${gravity_permissions}${COL_NC}"
local gravity_head=()
gravity_head=( $(head -n 4 ${PIHOLE_BLOCKLIST_FILE}) )
log_write " ${COL_CYAN}-----head of $(basename ${PIHOLE_BLOCKLIST_FILE})------${COL_NC}"
@@ -989,7 +1026,7 @@ analyze_pihole_log() {
# Get the lines that are in the file(s) and store them in an array for parsing later
IFS=$'\r\n'
local pihole_log_permissions=$(ls -ld "${PIHOLE_LOG}")
- log_write "${COL_LIGHT_GREEN}${pihole_log_permissions}${COL_NC}"
+ log_write "${COL_GREEN}${pihole_log_permissions}${COL_NC}"
local pihole_log_head=()
pihole_log_head=( $(head -n 20 ${PIHOLE_LOG}) )
log_write " ${COL_CYAN}-----head of $(basename ${PIHOLE_LOG})------${COL_NC}"
@@ -1008,7 +1045,7 @@ analyze_pihole_log() {
# If the variable contains a value, it found an error in the log
if [[ -n ${error_to_check_for} ]]; then
# So we can print it in red to make it visible to the user
- log_write " ${CROSS} ${COL_LIGHT_RED}${head_line}${COL_NC} (${FAQ_BAD_ADDRESS})"
+ log_write " ${CROSS} ${COL_RED}${head_line}${COL_NC} (${FAQ_BAD_ADDRESS})"
else
# If the variable does not a value (the current default behavior), so do not obfuscate anything
if [[ -z ${OBFUSCATE} ]]; then
@@ -1037,7 +1074,7 @@ tricorder_use_nc_or_ssl() {
# Check for openssl first since encryption is a good thing
if command -v openssl &> /dev/null; then
# If the command exists,
- log_write " * Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
+ log_write " * Using ${COL_GREEN}openssl${COL_NC} for transmission."
# encrypt and transmit the log and store the token returned in a variable
tricorder_token=$(< ${PIHOLE_DEBUG_LOG_SANITIZED} openssl s_client -quiet -connect tricorder.pi-hole.net:${TRICORDER_SSL_PORT_NUMBER} 2> /dev/null)
# Otherwise,
@@ -1058,9 +1095,9 @@ upload_to_tricorder() {
# Let the user know debugging is complete with something strikingly visual
log_write ""
- log_write "${COL_LIGHT_PURPLE}********************************************${COL_NC}"
- log_write "${COL_LIGHT_PURPLE}********************************************${COL_NC}"
- log_write "${TICK} ${COL_LIGHT_GREEN}** FINISHED DEBUGGING! **${COL_NC}\n"
+ log_write "${COL_PURPLE}********************************************${COL_NC}"
+ log_write "${COL_PURPLE}********************************************${COL_NC}"
+ log_write "${TICK} ${COL_GREEN}** FINISHED DEBUGGING! **${COL_NC}\n"
# Provide information on what they should do with their token
log_write " * The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
@@ -1082,7 +1119,7 @@ upload_to_tricorder() {
# If they say yes, run our function for uploading the log
[yY][eE][sS]|[yY]) tricorder_use_nc_or_ssl;;
# If they choose no, just exit out of the script
- *) log_write " * Log will ${COL_LIGHT_GREEN}NOT${COL_NC} be uploaded to tricorder.";exit;
+ *) log_write " * Log will ${COL_GREEN}NOT${COL_NC} be uploaded to tricorder.";exit;
esac
fi
# Check if tricorder.pi-hole.net is reachable and provide token
@@ -1091,19 +1128,19 @@ upload_to_tricorder() {
# Again, try to make this visually striking so the user realizes they need to do something with this information
# Namely, provide the Pi-hole devs with the token
log_write ""
- log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
- log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
- log_write "${TICK} Your debug token is: ${COL_LIGHT_GREEN}${tricorder_token}${COL_NC}"
- log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
- log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
+ log_write "${COL_PURPLE}***********************************${COL_NC}"
+ log_write "${COL_PURPLE}***********************************${COL_NC}"
+ log_write "${TICK} Your debug token is: ${COL_GREEN}${tricorder_token}${COL_NC}"
+ log_write "${COL_PURPLE}***********************************${COL_NC}"
+ log_write "${COL_PURPLE}***********************************${COL_NC}"
log_write ""
log_write " * Provide the token above to the Pi-hole team for assistance at"
log_write " * ${FORUMS_URL}"
- log_write " * Your log will self-destruct on our server after ${COL_LIGHT_RED}48 hours${COL_NC}."
+ log_write " * Your log will self-destruct on our server after ${COL_RED}48 hours${COL_NC}."
# If no token was generated
else
# Show an error and some help instructions
- log_write "${CROSS} ${COL_LIGHT_RED}There was an error uploading your debug log.${COL_NC}"
+ log_write "${CROSS} ${COL_RED}There was an error uploading your debug log.${COL_NC}"
log_write " * Please try again or contact the Pi-hole team for assistance."
fi
# Finally, show where the log file is no matter the outcome of the function so users can look at it
@@ -1112,13 +1149,14 @@ upload_to_tricorder() {
# Run through all the functions we made
make_temporary_log
-initiate_debug
+initialize_debug
# setupVars.conf needs to be sourced before the networking so the values are
# available to the other functions
source_setup_variables
check_component_versions
check_critical_program_versions
diagnose_operating_system
+check_selinux
processor_check
check_networking
check_name_resolution
diff --git a/advanced/Scripts/updatecheck.sh b/advanced/Scripts/updatecheck.sh
new file mode 100755
index 00000000..16938a3a
--- /dev/null
+++ b/advanced/Scripts/updatecheck.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+# Pi-hole: A black hole for Internet advertisements
+# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
+# Network-wide ad blocking via your own hardware.
+#
+# Checks for local or remote versions and branches
+#
+# This file is copyright under the latest version of the EUPL.
+# Please see LICENSE file for your rights under this license.
+
+# Credit: https://stackoverflow.com/a/46324904
+function json_extract() {
+ local key=$1
+ local json=$2
+
+ local string_regex='"([^"\]|\\.)*"'
+ local number_regex='-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?'
+ local value_regex="${string_regex}|${number_regex}|true|false|null"
+ local pair_regex="\"${key}\"[[:space:]]*:[[:space:]]*(${value_regex})"
+
+ if [[ ${json} =~ ${pair_regex} ]]; then
+ echo $(sed 's/^"\|"$//g' <<< "${BASH_REMATCH[1]}")
+ else
+ return 1
+ fi
+}
+
+function get_local_branch() {
+ # Return active branch
+ cd "${1}" 2> /dev/null || return 1
+ git rev-parse --abbrev-ref HEAD || return 1
+}
+
+function get_local_version() {
+# Return active branch
+cd "${1}" 2> /dev/null || return 1
+git describe --long --dirty --tags || return 1
+}
+
+if [[ "$2" == "remote" ]]; then
+
+ if [[ "$3" == "reboot" ]]; then
+ sleep 30
+ fi
+
+ GITHUB_CORE_VERSION="$(json_extract tag_name "$(curl -q 'https://api.github.com/repos/pi-hole/pi-hole/releases/latest' 2> /dev/null)")"
+ GITHUB_WEB_VERSION="$(json_extract tag_name "$(curl -q 'https://api.github.com/repos/pi-hole/AdminLTE/releases/latest' 2> /dev/null)")"
+ GITHUB_FTL_VERSION="$(json_extract tag_name "$(curl -q 'https://api.github.com/repos/pi-hole/FTL/releases/latest' 2> /dev/null)")"
+
+ echo -n "${GITHUB_CORE_VERSION} ${GITHUB_WEB_VERSION} ${GITHUB_FTL_VERSION}" > "/etc/pihole/GitHubVersions"
+
+else
+
+ CORE_BRANCH="$(get_local_branch /etc/.pihole)"
+ WEB_BRANCH="$(get_local_branch /var/www/html/admin)"
+ FTL_BRANCH="$(pihole-FTL branch)"
+
+ echo -n "${CORE_BRANCH} ${WEB_BRANCH} ${FTL_BRANCH}" > "/etc/pihole/localbranches"
+
+ CORE_VERSION="$(get_local_version /etc/.pihole)"
+ WEB_VERSION="$(get_local_version /var/www/html/admin)"
+ FTL_VERSION="$(pihole-FTL version)"
+
+ echo -n "${CORE_VERSION} ${WEB_VERSION} ${FTL_VERSION}" > "/etc/pihole/localversions"
+
+fi
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index b0957ab4..27b3de5d 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -110,7 +110,7 @@ SetWebPassword() {
fi
if [ "${PASSWORD}" == "${CONFIRM}" ] ; then
- hash=$(HashPassword ${PASSWORD})
+ hash=$(HashPassword "${PASSWORD}")
# Save hash to file
change_setting "WEBPASSWORD" "${hash}"
echo -e " ${TICK} New password set"
@@ -153,6 +153,7 @@ ProcessDNSSettings() {
if [[ "${DNSSEC}" == true ]]; then
echo "dnssec
trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
+trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
" >> "${dnsmasqconfig}"
fi
@@ -174,6 +175,11 @@ trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE3
add_dnsmasq_setting "local-service"
else
# Listen only on one interface
+ # Use eth0 as fallback interface if interface is missing in setupVars.conf
+ if [ -z "${PIHOLE_INTERFACE}" ]; then
+ PIHOLE_INTERFACE="eth0"
+ fi
+
add_dnsmasq_setting "interface" "${PIHOLE_INTERFACE}"
fi
@@ -240,7 +246,7 @@ ProcessDHCPSettings() {
source "${setupVars}"
if [[ "${DHCP_ACTIVE}" == "true" ]]; then
- interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//")
+ interface="${PIHOLE_INTERFACE}"
# Use eth0 as fallback interface
if [ -z ${interface} ]; then
@@ -248,7 +254,7 @@ ProcessDHCPSettings() {
fi
if [[ "${PIHOLE_DOMAIN}" == "" ]]; then
- PIHOLE_DOMAIN="local"
+ PIHOLE_DOMAIN="lan"
change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}"
fi
@@ -418,7 +424,7 @@ Options:
}
SetAdminEmail() {
- if [[ "${1}" == *"-h"* ]]; then
+ if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
echo "Usage: pihole -a email
Example: 'pihole -a email admin@address.com'
Set an administrative contact address for the Block Page
diff --git a/advanced/index.php b/advanced/index.php
index 923aa7ce..d3e2f768 100644
--- a/advanced/index.php
+++ b/advanced/index.php
@@ -9,37 +9,42 @@
// Sanitise HTTP_HOST output
$serverName = htmlspecialchars($_SERVER["HTTP_HOST"]);
+if (!is_file("/etc/pihole/setupVars.conf"))
+ die("[ERROR] File not found: /etc/pihole/setupVars.conf");
+
// Get values from setupVars.conf
-if (is_file("/etc/pihole/setupVars.conf")) {
- $setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
- $svFQDN = $setupVars["FQDN"];
- $svPasswd = !empty($setupVars["WEBPASSWORD"]);
- $svEmail = (!empty($setupVars["ADMIN_EMAIL"]) && filter_var($setupVars["ADMIN_EMAIL"], FILTER_VALIDATE_EMAIL)) ? $setupVars["ADMIN_EMAIL"] : "";
- unset($setupVars);
-} else {
- die("[ERROR] File not found: /etc/pihole/setupVars.conf");
-}
+$setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
+$svPasswd = !empty($setupVars["WEBPASSWORD"]);
+$svEmail = (!empty($setupVars["ADMIN_EMAIL"]) && filter_var($setupVars["ADMIN_EMAIL"], FILTER_VALIDATE_EMAIL)) ? $setupVars["ADMIN_EMAIL"] : "";
+unset($setupVars);
// Set landing page location, found within /var/www/html/
$landPage = "../landing.php";
-// Set empty array for hostnames to be accepted as self address for splash page
+// Define array for hostnames to be accepted as self address for splash page
$authorizedHosts = [];
-
-// Append FQDN to $authorizedHosts
-if (!empty($svFQDN)) array_push($authorizedHosts, $svFQDN);
-
-// Append virtual hostname to $authorizedHosts
-if (!empty($_SERVER["VIRTUAL_HOST"])) {
+if (!empty($_SERVER["FQDN"])) {
+ // If setenv.add-environment = ("fqdn" => "true") is configured in lighttpd,
+ // append $serverName to $authorizedHosts
+ array_push($authorizedHosts, $serverName);
+} else if (!empty($_SERVER["VIRTUAL_HOST"])) {
+ // Append virtual hostname to $authorizedHosts
array_push($authorizedHosts, $_SERVER["VIRTUAL_HOST"]);
}
-// Set which extension types render as Block Page (Including "" for index.wxyz)
+// Set which extension types render as Block Page (Including "" for index.ext)
$validExtTypes = array("asp", "htm", "html", "php", "rss", "xml", "");
// Get extension of current URL
$currentUrlExt = pathinfo($_SERVER["REQUEST_URI"], PATHINFO_EXTENSION);
+// Check if this is served over HTTP or HTTPS
+if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") {
+ $proto = "https";
+} else {
+ $proto = "http";
+}
+
// Set mobile friendly viewport
$viewPort = '';
@@ -49,8 +54,9 @@ function setHeader($type = "x") {
if (isset($type) && $type === "js") header("Content-Type: application/javascript");
}
-// Determine block page redirect type
+// Determine block page type
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
@@ -60,22 +66,29 @@ if ($serverName === "pi.hole") {
Pi-hole: Your black hole for Internet advertisements