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 @@
+
-
-
-
+
+Network-wide ad blocking via your own Linux hardware
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.
+-----
-![Pi-hole Dashboard](https://assets.pi-hole.net/static/dashboard.png)
+## 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.
+
+
+- -
+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/) -- ![Twitter](https://assets.pi-hole.net/static/twitter.png) [Tweet @The_Pi_Hole](https://twitter.com/The_Pi_Hole) -- ![Reddit](https://assets.pi-hole.net/static/reddit.png) [Reddit /r/pihole](https://www.reddit.com/r/pihole/) -- ![YouTube](https://assets.pi-hole.net/static/youtube.png) [Pi-hole channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w) -- [![Join the chat at https://gitter.im/pi-hole/pi-hole](https://badges.gitter.im/pi-hole/pi-hole.svg)](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") {