mirror of
https://github.com/pi-hole/pi-hole
synced 2025-01-03 12:40:56 +00:00
Merge remote-tracking branch 'origin/development' into tweak/block-page-no-password
This commit is contained in:
commit
c7219fbdff
37
.github/PULL_REQUEST_TEMPLATE.md
vendored
37
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -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.
|
||||
|
||||
|
67
.gitignore
vendored
67
.gitignore
vendored
@ -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
|
||||
|
13
.idea/codeStyles/Project.xml
Normal file
13
.idea/codeStyles/Project.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<option name="OTHER_INDENT_OPTIONS">
|
||||
<value>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</value>
|
||||
</option>
|
||||
<MarkdownNavigatorCodeStyleSettings>
|
||||
<option name="RIGHT_MARGIN" value="72" />
|
||||
</MarkdownNavigatorCodeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
3
.stickler.yml
Normal file
3
.stickler.yml
Normal file
@ -0,0 +1,3 @@
|
||||
linters:
|
||||
shellcheck:
|
||||
shell: bash
|
@ -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
|
||||
|
||||
|
431
README.md
431
README.md
@ -1,95 +1,143 @@
|
||||
<p align="center">
|
||||
<a href=https://www.bountysource.com/trackers/3011939-pi-hole-pi-hole?utm_source=3011939&utm_medium=shield&utm_campaign=TRACKER_BADGE><img src="https://www.bountysource.com/badge/tracker?tracker_id=3011939"></a>
|
||||
<a href="https://www.codacy.com/app/Pi-hole/pi-hole?utm_source=github.com&utm_medium=referral&utm_content=pi-hole/pi-hole&utm_campaign=Badge_Grade"><img src="https://api.codacy.com/project/badge/Grade/c558a0f8d7124c99b02b84f0f5564238"/></a>
|
||||
<a href=https://travis-ci.org/pi-hole/pi-hole><img src="https://travis-ci.org/pi-hole/pi-hole.svg?branch=development"></a>
|
||||
<a href="https://pi-hole.net"><img src="https://pi-hole.github.io/graphics/Vortex/Vortex_with_text.png" width="150" height="255" alt="Pi-hole"></a><br/>
|
||||
<b>Network-wide ad blocking via your own Linux hardware</b><br/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href=https://discourse.pi-hole.net><img src="https://assets.pi-hole.net/static/Vortex_with_text_and_TM.png" width=210></a>
|
||||
</p>
|
||||
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.
|
||||
-----
|
||||
<a href="https://www.codacy.com/app/Pi-hole/pi-hole?utm_source=github.com&utm_medium=referral&utm_content=pi-hole/pi-hole&utm_campaign=Badge_Grade"><img src="https://api.codacy.com/project/badge/Grade/c558a0f8d7124c99b02b84f0f5564238" alt="Codacy Grade"/></a>
|
||||
<a href="https://travis-ci.org/pi-hole/pi-hole"><img src="https://travis-ci.org/pi-hole/pi-hole.svg?branch=development" alt="Travis Build Status"/></a>
|
||||
<a href="https://www.bountysource.com/trackers/3011939-pi-hole-pi-hole?utm_source=3011939&utm_medium=shield&utm_campaign=TRACKER_BADGE"><img src="https://www.bountysource.com/badge/tracker?tracker_id=3011939" alt="BountySource"/></a>
|
||||
|
||||
## 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?
|
||||
<p align="center">
|
||||
<a href=https://www.youtube.com/watch?v=vKWjx1AQYgs><img src="https://assets.pi-hole.net/static/video-explainer.png"></a>
|
||||
</p>
|
||||
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.
|
||||
|
||||
- ![Paypal](https://assets.pi-hole.net/static/paypal.png) [Donate via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
|
||||
- ![Bitcoin](https://assets.pi-hole.net/static/Bitcoin.png) 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
|
||||
<img src="https://pi-hole.github.io/graphics/Badges/paypal-badge-black.svg" width="24" height="24" alt="PP"/> <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY">Donate via PayPal</a><br/>
|
||||
<img src="https://pi-hole.github.io/graphics/Badges/bitcoin-badge-black.svg" width="24" height="24" alt="BTC"/> Bitcoin Address: <code>1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL</code>
|
||||
|
||||
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 <a href="https://discourse.pi-hole.net/">Discourse User Forum</a>, 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.
|
||||
|
||||
<ul>
|
||||
<li><a href="https://discourse.pi-hole.net/c/faqs">Frequently Asked Questions</a></li>
|
||||
<li><a href="https://github.com/pi-hole/pi-hole/wiki">Pi-hole Wiki</a></li>
|
||||
<li><a href="https://discourse.pi-hole.net/c/feature-requests?order=votes">Feature Requests</a></li>
|
||||
</ul>
|
||||
<br/>
|
||||
<ul>
|
||||
<li><a href="https://discourse.pi-hole.net/">Discourse User Forum</a></li>
|
||||
<li><a href="https://www.reddit.com/r/pihole/">Reddit</a></li>
|
||||
<li><a href="https://gitter.im/pi-hole/pi-hole">Gitter</a> (Real-time chat)</li>
|
||||
<li><a href="https://twitter.com/The_Pi_Hole">Twitter</a></li>
|
||||
<li><a href="https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w">YouTube</a></li>
|
||||
<li><a href="https://www.facebook.com/ThePiHole/">Facebook</a></li>
|
||||
</ul>
|
||||
|
||||
-----
|
||||
|
||||
## 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`.
|
||||
|
||||
<a href="https://pi-hole.github.io/graphics/Screenshots/blacklist-cli.gif"><img src="https://pi-hole.github.io/graphics/Screenshots/blacklist-cli.gif" alt="Pi-hole Blacklist Demo"/></a>
|
||||
|
||||
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!
|
||||
|
||||
<a href="https://pi-hole.github.io/graphics/Screenshots/dashboard.png"><img src="https://pi-hole.github.io/graphics/Screenshots/dashboard.png" width="888" height="522" alt="Pi-hole Dashboard"/></a>
|
||||
|
||||
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
|
||||
|
||||
<p align="center">
|
||||
<img src="https://assets.pi-hole.net/static/query_log.png">
|
||||
</p>
|
||||
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:
|
||||
|
||||
<p align="center">
|
||||
<img src="https://assets.pi-hole.net/static/long-term-stats.png">
|
||||
</p>
|
||||
* [`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).
|
||||
-----
|
||||
|
||||
<p align="center">
|
||||
<a href=https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting><img src="https://assets.pi-hole.net/static/whitelist.png"></a>
|
||||
</p>
|
||||
## 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/).
|
||||
|
||||
<p align="center">
|
||||
<a href=https://discourse.pi-hole.net/t/how-do-i-add-additional-block-lists-to-pi-hole/259><img src="https://assets.pi-hole.net/static/manage-ad-lists.png"></a>
|
||||
</p>
|
||||
|
||||
### 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.
|
||||
|
||||
<p align="center">
|
||||
<img src="https://assets.pi-hole.net/static/enable-disable.png">
|
||||
</p>
|
||||
|
||||
### Tools
|
||||
|
||||
<p align="center">
|
||||
<img src="https://assets.pi-hole.net/static/tools.png">
|
||||
</p>
|
||||
|
||||
|
||||
#### 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.
|
||||
|
||||
<p align="center">
|
||||
<img src="https://assets.pi-hole.net/static/debug-gui.png">
|
||||
</p>
|
||||
|
||||
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.
|
||||
|
||||
<p align="center">
|
||||
<a href=https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#debugs><img src="https://assets.pi-hole.net/static/debug-cli.png"></a>
|
||||
</p>
|
||||
|
||||
|
||||
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)).
|
||||
|
||||
<p align="center">
|
||||
<a href=https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#debugs><img src="https://assets.pi-hole.net/static/debug-token.png"></a>
|
||||
</p>
|
||||
|
||||
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!
|
||||
|
||||
<p align="center">
|
||||
<img src="https://assets.pi-hole.net/static/settings-page.png">
|
||||
</p>
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
<p align="center">
|
||||
<a href=https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026><img src="https://assets.pi-hole.net/static/piholedhcpserver.png"></a>
|
||||
</p>
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<img src="https://assets.pi-hole.net/static/chrono1.jpg">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://assets.pi-hole.net/static/chrono2.jpg">
|
||||
</p>
|
||||
|
||||
# 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)
|
||||
|
@ -39,7 +39,7 @@ interface=@INT@
|
||||
|
||||
cache-size=10000
|
||||
|
||||
log-queries
|
||||
log-queries=extra
|
||||
log-facility=/var/log/pihole.log
|
||||
|
||||
local-ttl=2
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
66
advanced/Scripts/updatecheck.sh
Executable file
66
advanced/Scripts/updatecheck.sh
Executable file
@ -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
|
@ -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 <address>
|
||||
Example: 'pihole -a email admin@address.com'
|
||||
Set an administrative contact address for the Block Page
|
||||
|
@ -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: <code>/etc/pihole/setupVars.conf</code>");
|
||||
|
||||
// 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: <code>/etc/pihole/setupVars.conf</code>");
|
||||
}
|
||||
$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 = '<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>';
|
||||
|
||||
@ -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") {
|
||||
<link rel='stylesheet' href='/pihole/blockingpage.css' type='text/css'/>
|
||||
</head><body id='splashpage'><img src='/admin/img/logo.svg'/><br/>Pi-<b>hole</b>: Your black hole for Internet advertisements</body></html>
|
||||
";
|
||||
|
||||
// Render splash page or landing page when directly browsing via IP or auth'd hostname
|
||||
|
||||
// Set splash/landing page based off presence of $landPage
|
||||
$renderPage = is_file(getcwd()."/$landPage") ? include $landPage : "$splashPage";
|
||||
unset($serverName, $svFQDN, $svPasswd, $svEmail, $authorizedHosts, $validExtTypes, $currentUrlExt, $viewPort);
|
||||
|
||||
// Unset variables so as to not be included in $landPage
|
||||
unset($serverName, $svPasswd, $svEmail, $authorizedHosts, $validExtTypes, $currentUrlExt, $viewPort);
|
||||
|
||||
// Render splash/landing page when directly browsing via IP or authorised hostname
|
||||
exit($renderPage);
|
||||
} elseif ($currentUrlExt === "js") {
|
||||
// Serve dummy Javascript for blocked domains
|
||||
// Serve Pi-hole Javascript for blocked domains requesting JS
|
||||
exit(setHeader("js").'var x = "Pi-hole: A black hole for Internet advertisements."');
|
||||
} elseif (strpos($_SERVER["REQUEST_URI"], "?") !== FALSE && isset($_SERVER["HTTP_REFERER"])) {
|
||||
// Serve blank image upon receiving REQUEST_URI w/ query string & HTTP_REFERRER (e.g: an iframe of a blocked domain)
|
||||
// Serve blank image upon receiving REQUEST_URI w/ query string & HTTP_REFERRER
|
||||
// e.g: An iframe of a blocked domain
|
||||
exit(setHeader().'<html>
|
||||
<head><script>window.close();</script></head>
|
||||
<body><img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs="></body>
|
||||
</html>');
|
||||
} elseif (!in_array($currentUrlExt, $validExtTypes) || substr_count($_SERVER["REQUEST_URI"], "?")) {
|
||||
// Serve SVG upon receiving non $validExtTypes URL extension or query string (e.g: not an iframe of a blocked domain)
|
||||
// Serve SVG upon receiving non $validExtTypes URL extension or query string
|
||||
// e.g: Not an iframe of a blocked domain, such as when browsing to a file/query directly
|
||||
// QoL addition: Allow the SVG to be clicked on in order to quickly show the full Block Page
|
||||
$blockImg = '<a href="/"><svg xmlns="http://www.w3.org/2000/svg" width="110" height="16"><defs><style>a {text-decoration: none;} circle {stroke: rgba(152,2,2,0.5); fill: none; stroke-width: 2;} rect {fill: rgba(152,2,2,0.5);} text {opacity: 0.3; font: 11px Arial;}</style></defs><circle cx="8" cy="8" r="7"/><rect x="10.3" y="-6" width="2" height="12" transform="rotate(45)"/><text x="19.3" y="12">Blocked by Pi-hole</text></svg></a>';
|
||||
exit(setHeader()."<html>
|
||||
<head>$viewPort</head>
|
||||
@ -88,7 +101,7 @@ if ($serverName === "pi.hole") {
|
||||
// Determine placeholder text based off $svPasswd presence
|
||||
$wlPlaceHolder = empty($svPasswd) ? "No admin password set" : "Javascript disabled";
|
||||
|
||||
// Define admin email address text
|
||||
// Define admin email address text based off $svEmail presence
|
||||
$bpAskAdmin = !empty($svEmail) ? '<a href="mailto:'.$svEmail.'?subject=Site Blocked: '.$serverName.'"></a>' : "<span/>";
|
||||
|
||||
// Determine if at least one block list has been generated
|
||||
@ -113,8 +126,10 @@ if (empty($adlistsUrls))
|
||||
// Get total number of blocklists (Including Whitelist, Blacklist & Wildcard lists)
|
||||
$adlistsCount = count($adlistsUrls) + 3;
|
||||
|
||||
// Get results of queryads.php exact search
|
||||
// Set query timeout
|
||||
ini_set("default_socket_timeout", 3);
|
||||
|
||||
// Logic for querying blocklists
|
||||
function queryAds($serverName) {
|
||||
// Determine the time it takes while querying adlists
|
||||
$preQueryTime = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"];
|
||||
@ -124,32 +139,39 @@ function queryAds($serverName) {
|
||||
|
||||
// Exception Handling
|
||||
try {
|
||||
if ($queryTime >= ini_get("default_socket_timeout")) {
|
||||
// Define Exceptions
|
||||
if (strpos($queryAds[0], "No exact results") !== FALSE) {
|
||||
// Return "none" into $queryAds array
|
||||
return array("0" => "none");
|
||||
} else if ($queryTime >= ini_get("default_socket_timeout")) {
|
||||
// Connection Timeout
|
||||
throw new Exception ("Connection timeout (".ini_get("default_socket_timeout")."s)");
|
||||
} elseif (!strpos($queryAds[0], ".") !== false) {
|
||||
if (strpos($queryAds[0], "No exact results") !== FALSE) return array("0" => "none");
|
||||
// Unknown $queryAds output
|
||||
throw new Exception ("Unhandled error message (<code>$queryAds[0]</code>)");
|
||||
}
|
||||
return $queryAds;
|
||||
} catch (Exception $e) {
|
||||
// Return exception as array
|
||||
return array("0" => "error", "1" => $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Get results of queryads.php exact search
|
||||
$queryAds = queryAds($serverName);
|
||||
|
||||
if ($queryAds[0] === "error") {
|
||||
// Pass error through to Block Page
|
||||
if ($queryAds[0] === "error")
|
||||
die("[ERROR]: Unable to parse results from <i>queryads.php</i>: <code>".$queryAds[1]."</code>");
|
||||
} else {
|
||||
$featuredTotal = count($queryAds);
|
||||
|
||||
// Place results into key => value array
|
||||
$queryResults = null;
|
||||
foreach ($queryAds as $str) {
|
||||
$value = explode(" ", $str);
|
||||
@$queryResults[$value[0]] .= "$value[1]";
|
||||
}
|
||||
// Count total number of matching blocklists
|
||||
$featuredTotal = count($queryAds);
|
||||
|
||||
// Place results into key => value array
|
||||
$queryResults = null;
|
||||
foreach ($queryAds as $str) {
|
||||
$value = explode(" ", $str);
|
||||
@$queryResults[$value[0]] .= "$value[1]";
|
||||
}
|
||||
|
||||
// Determine if domain has been blacklisted, whitelisted, wildcarded or CNAME blocked
|
||||
@ -167,7 +189,8 @@ if (strpos($queryAds[0], "blacklist") !== FALSE) {
|
||||
$featuredTotal = "0";
|
||||
$notableFlagClass = "noblock";
|
||||
|
||||
// Determine appropriate info message if CNAME exists
|
||||
// QoL addition: Determine appropriate info message if CNAME exists
|
||||
// Suggests to the user that $serverName has a CNAME (alias) that may be blocked
|
||||
$dnsRecord = dns_get_record("$serverName")[0];
|
||||
if (array_key_exists("target", $dnsRecord)) {
|
||||
$wlInfo = $dnsRecord['target'];
|
||||
@ -184,9 +207,14 @@ $wlOutput = (isset($wlInfo) && $wlInfo !== "recentwl") ? "<a href='http://$wlInf
|
||||
$phVersion = exec("cd /etc/.pihole/ && git describe --long --tags");
|
||||
|
||||
// Print $execTime on development branches
|
||||
// Marginally faster than "git rev-parse --abbrev-ref HEAD"
|
||||
// Testing for - is marginally faster than "git rev-parse --abbrev-ref HEAD"
|
||||
if (explode("-", $phVersion)[1] != "0")
|
||||
$execTime = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"];
|
||||
|
||||
// Please Note: Text is added via CSS to allow an admin to provide a localised
|
||||
// language without the need to edit this file
|
||||
|
||||
setHeader();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<!-- Pi-hole: A black hole for Internet advertisements
|
||||
@ -198,13 +226,12 @@ if (explode("-", $phVersion)[1] != "0")
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<?=$viewPort ?>
|
||||
<?=setHeader() ?>
|
||||
<meta name="robots" content="noindex,nofollow"/>
|
||||
<meta http-equiv="x-dns-prefetch-control" content="off">
|
||||
<link rel="shortcut icon" href="http://pi.hole/admin/img/favicon.png" type="image/x-icon"/>
|
||||
<link rel="stylesheet" href="http://pi.hole/pihole/blockingpage.css" type="text/css"/>
|
||||
<link rel="shortcut icon" href="<?=$proto ?>://pi.hole/admin/img/favicon.png" type="image/x-icon"/>
|
||||
<link rel="stylesheet" href="<?=$proto ?>://pi.hole/pihole/blockingpage.css" type="text/css"/>
|
||||
<title>● <?=$serverName ?></title>
|
||||
<script src="http://pi.hole/admin/scripts/vendor/jquery.min.js"></script>
|
||||
<script src="<?=$proto ?>://pi.hole/admin/scripts/vendor/jquery.min.js"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
<?php
|
||||
@ -271,7 +298,7 @@ if (explode("-", $phVersion)[1] != "0")
|
||||
<div id="bpMoreInfo">
|
||||
<span id="bpFoundIn"><span><?=$featuredTotal ?></span><?=$adlistsCount ?></span>
|
||||
<pre id='bpQueryOutput'><?php if ($featuredTotal > 0) foreach ($queryResults as $num => $value) { echo "<span>[$num]:</span>$adlistsUrls[$num]\n"; } ?></pre>
|
||||
|
||||
|
||||
<form id="bpWLButtons" class="buttons">
|
||||
<input id="bpWLDomain" type="text" value="<?=$serverName ?>" disabled/>
|
||||
<input id="bpWLPassword" type="password" placeholder="<?=$wlPlaceHolder ?>" disabled style="display: none"/><button id="bpWhitelist" type="button" disabled></button>
|
||||
|
@ -2,18 +2,16 @@
|
||||
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
||||
# Network-wide ad blocking via your own hardware.
|
||||
#
|
||||
# lighttpd config for Pi-hole
|
||||
# Lighttpd config for Pi-hole
|
||||
#
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# FILE AUTOMATICALLY OVERWRITTEN BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||
# #
|
||||
# CHANGES SHOULD BE MADE IN A SEPERATE CONFIG FILE: #
|
||||
# CHANGES SHOULD BE MADE IN A SEPARATE CONFIG FILE: #
|
||||
# /etc/lighttpd/external.conf #
|
||||
###############################################################################
|
||||
|
||||
@ -39,7 +37,6 @@ server.port = 80
|
||||
accesslog.filename = "/var/log/lighttpd/access.log"
|
||||
accesslog.format = "%{%s}t|%V|%r|%s|%b"
|
||||
|
||||
|
||||
index-file.names = ( "index.php", "index.html", "index.lighttpd.html" )
|
||||
url.access-deny = ( "~", ".inc", ".md", ".yml", ".ini" )
|
||||
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
|
||||
@ -50,16 +47,19 @@ compress.filetype = ( "application/javascript", "text/css", "text/html
|
||||
# default listening port for IPv6 falls back to the IPv4 port
|
||||
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
|
||||
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
|
||||
|
||||
# Prevent Lighttpd from enabling Let's Encrypt SSL for every blocked domain
|
||||
#include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
|
||||
include_shell "find /etc/lighttpd/conf-enabled -name '*.conf' -a ! -name 'letsencrypt.conf' -printf 'include \"%p\"\n' 2>/dev/null"
|
||||
|
||||
# If the URL starts with /admin, it is the Web interface
|
||||
$HTTP["url"] =~ "^/admin/" {
|
||||
# Create a response header for debugging using curl -I
|
||||
# Create a response header for debugging using curl -I
|
||||
setenv.add-response-header = (
|
||||
"X-Pi-hole" => "The Pi-hole Web interface is working!",
|
||||
"X-Frame-Options" => "DENY"
|
||||
)
|
||||
|
||||
$HTTP["url"] =~ ".ttf$" {
|
||||
# Allow Block Page access to local fonts
|
||||
setenv.add-response-header = ( "Access-Control-Allow-Origin" => "*" )
|
||||
|
@ -7,13 +7,11 @@
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# FILE AUTOMATICALLY OVERWRITTEN BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||
# #
|
||||
# CHANGES SHOULD BE MADE IN A SEPERATE CONFIG FILE: #
|
||||
# CHANGES SHOULD BE MADE IN A SEPARATE CONFIG FILE: #
|
||||
# /etc/lighttpd/external.conf #
|
||||
###############################################################################
|
||||
|
||||
@ -74,11 +72,12 @@ fastcgi.server = ( ".php" =>
|
||||
|
||||
# If the URL starts with /admin, it is the Web interface
|
||||
$HTTP["url"] =~ "^/admin/" {
|
||||
# Create a response header for debugging using curl -I
|
||||
# Create a response header for debugging using curl -I
|
||||
setenv.add-response-header = (
|
||||
"X-Pi-hole" => "The Pi-hole Web interface is working!",
|
||||
"X-Frame-Options" => "DENY"
|
||||
)
|
||||
|
||||
$HTTP["url"] =~ ".ttf$" {
|
||||
# Allow Block Page access to local fonts
|
||||
setenv.add-response-header = ( "Access-Control-Allow-Origin" => "*" )
|
||||
|
@ -25,9 +25,13 @@ start() {
|
||||
if is_running; then
|
||||
echo "pihole-FTL is already running"
|
||||
else
|
||||
touch /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port
|
||||
touch /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /var/log/pihole.log
|
||||
mkdir -p /var/run/pihole
|
||||
mkdir -p /var/log/pihole
|
||||
chown pihole:pihole /var/run/pihole /var/log/pihole
|
||||
rm /var/run/pihole/FTL.sock
|
||||
chown pihole:pihole /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /etc/pihole
|
||||
chmod 0644 /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port
|
||||
chmod 0644 /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /var/log/pihole.log
|
||||
su -s /bin/sh -c "/usr/bin/pihole-FTL" "$FTLUSER"
|
||||
echo
|
||||
fi
|
||||
|
@ -14,13 +14,10 @@
|
||||
# is updated or re-installed. Please make any changes to the appropriate crontab
|
||||
# or other cron file snippets.
|
||||
|
||||
# Pi-hole: Update the ad sources once a week on Sunday at 01:59
|
||||
# Download any updates from the adlists
|
||||
# Pi-hole: Update the ad sources once a week on Sunday at a random time in the
|
||||
# early morning. Download any updates from the adlists
|
||||
59 1 * * 7 root PATH="$PATH:/usr/local/bin/" pihole updateGravity
|
||||
|
||||
# Pi-hole: Update Pi-hole! Uncomment to enable auto update
|
||||
#30 2 * * 7 root PATH="$PATH:/usr/local/bin/" pihole updatePihole
|
||||
|
||||
# Pi-hole: Flush the log daily at 00:00
|
||||
# The flush script will use logrotate if available
|
||||
# parameter "once": logrotate only once (default is twice)
|
||||
@ -28,3 +25,10 @@
|
||||
00 00 * * * root PATH="$PATH:/usr/local/bin/" pihole flush once quiet
|
||||
|
||||
@reboot root /usr/sbin/logrotate /etc/pihole/logrotate
|
||||
|
||||
# Pi-hole: Grab local version and branch every 10 minutes
|
||||
*/10 * * * * root PATH="$PATH:/usr/local/bin/" pihole updatechecker local
|
||||
|
||||
# Pi-hole: Grab remote version every 24 hours
|
||||
59 17 * * * root PATH="$PATH:/usr/local/bin/" pihole updatechecker remote
|
||||
@reboot root PATH="$PATH:/usr/local/bin/" pihole updatechecker remote reboot
|
||||
|
@ -2,7 +2,7 @@
|
||||
# shellcheck disable=SC1090
|
||||
|
||||
# Pi-hole: A black hole for Internet advertisements
|
||||
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
||||
# (c) 2017-2018 Pi-hole, LLC (https://pi-hole.net)
|
||||
# Network-wide ad blocking via your own hardware.
|
||||
#
|
||||
# Installs and Updates Pi-hole
|
||||
@ -14,7 +14,7 @@
|
||||
#
|
||||
# Install with this command (from your Linux machine):
|
||||
#
|
||||
# curl -L install.pi-hole.net | bash
|
||||
# curl -sSL https://install.pi-hole.net | bash
|
||||
|
||||
# -e option instructs bash to immediately exit if any command [1] has a non-zero exit status
|
||||
# We do not want users to end up with a partially working install, so we exit the script
|
||||
@ -28,9 +28,8 @@ set -e
|
||||
# Local variables will be in lowercase and will exist only within functions
|
||||
# It's still a work in progress, so you may see some variance in this guideline until it is complete
|
||||
|
||||
# We write to a temporary file before moving the log to the pihole folder
|
||||
tmpLog=/tmp/pihole-install.log
|
||||
instalLogLoc=/etc/pihole/install.log
|
||||
# Location for final installation log storage
|
||||
installLogLoc=/etc/pihole/install.log
|
||||
# This is an important file as it contains information specific to the machine it's being installed on
|
||||
setupVars=/etc/pihole/setupVars.conf
|
||||
# Pi-hole uses lighttpd as a Web server, and this is the config file for it
|
||||
@ -208,9 +207,10 @@ elif command -v rpm &> /dev/null; then
|
||||
PKG_INSTALL=(${PKG_MANAGER} install -y)
|
||||
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
|
||||
INSTALLER_DEPS=(dialog git iproute net-tools newt procps-ng)
|
||||
PIHOLE_DEPS=(bc bind-utils cronie curl dnsmasq findutils nmap-ncat sudo unzip wget idn2)
|
||||
PIHOLE_DEPS=(bc bind-utils cronie curl dnsmasq findutils nmap-ncat sudo unzip wget libidn2 psmisc)
|
||||
PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php php-common php-cli php-pdo)
|
||||
if ! grep -q 'Fedora' /etc/redhat-release; then
|
||||
# EPEL (https://fedoraproject.org/wiki/EPEL) is required for lighttpd on CentOS
|
||||
if grep -qi 'centos' /etc/redhat-release; then
|
||||
INSTALLER_DEPS=("${INSTALLER_DEPS[@]}" "epel-release");
|
||||
fi
|
||||
LIGHTTPD_USER="lighttpd"
|
||||
@ -218,7 +218,7 @@ elif command -v rpm &> /dev/null; then
|
||||
LIGHTTPD_CFG="lighttpd.conf.fedora"
|
||||
DNSMASQ_USER="nobody"
|
||||
|
||||
# If neither apt-get or rmp/dnf are not found
|
||||
# If neither apt-get or rmp/dnf are found
|
||||
else
|
||||
# it's not an OS we can support,
|
||||
echo -e " ${CROSS} OS distribution not supported"
|
||||
@ -503,15 +503,21 @@ testIPv6() {
|
||||
# first will contain fda2 (ULA)
|
||||
first="$(cut -f1 -d":" <<< "$1")"
|
||||
# value1 will contain 253 which is the decimal value corresponding to 0xfd
|
||||
value1=$(((0x$first)/256))
|
||||
value1=$(( (0x$first)/256 ))
|
||||
# will contain 162 which is the decimal value corresponding to 0xa2
|
||||
value2=$(((0x$first)%256))
|
||||
value2=$(( (0x$first)%256 ))
|
||||
# the ULA test is testing for fc00::/7 according to RFC 4193
|
||||
(((value1&254)==252)) && echo "ULA" || true
|
||||
if (( (value1&254)==252 )); then
|
||||
echo "ULA"
|
||||
fi
|
||||
# the GUA test is testing for 2000::/3 according to RFC 4291
|
||||
(((value1&112)==32)) && echo "GUA" || true
|
||||
if (( (value1&112)==32 )); then
|
||||
echo "GUA"
|
||||
fi
|
||||
# the LL test is testing for fe80::/10 according to RFC 4193
|
||||
(((value1==254) && ((value2&192)==128))) && echo "Link-local" || true
|
||||
if (( (value1)==254 )) && (( (value2&192)==128 )); then
|
||||
echo "Link-local"
|
||||
fi
|
||||
}
|
||||
|
||||
# A dialog for showing the user about IPv6 blocking
|
||||
@ -709,8 +715,8 @@ setStaticIPv4() {
|
||||
}> "${IFCFG_FILE}"
|
||||
# Use ip to immediately set the new address
|
||||
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
|
||||
# If NetworkMangler command line interface exists,
|
||||
if command -v nmcli &> /dev/null;then
|
||||
# If NetworkMangler command line interface exists and ready to mangle,
|
||||
if command -v nmcli &> /dev/null && nmcli general status &> /dev/null; then
|
||||
# Tell NetworkManagler to read our new sysconfig file
|
||||
nmcli con load "${IFCFG_FILE}" > /dev/null
|
||||
fi
|
||||
@ -764,9 +770,10 @@ setDNS() {
|
||||
Norton ""
|
||||
Comodo ""
|
||||
DNSWatch ""
|
||||
Quad9 ""
|
||||
Custom "")
|
||||
# In a whiptail dialog, show the options
|
||||
DNSchoices=$(whiptail --separate-output --menu "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6 \
|
||||
DNSchoices=$(whiptail --separate-output --menu "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 7 \
|
||||
"${DNSChooseOptions[@]}" 2>&1 >/dev/tty) || \
|
||||
# exit if Cancel is selected
|
||||
{ echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
|
||||
@ -805,6 +812,11 @@ setDNS() {
|
||||
PIHOLE_DNS_1="84.200.69.80"
|
||||
PIHOLE_DNS_2="84.200.70.40"
|
||||
;;
|
||||
Quad9)
|
||||
echo "Quad9 servers"
|
||||
PIHOLE_DNS_1="9.9.9.9"
|
||||
PIHOLE_DNS_2="149.112.112.112"
|
||||
;;
|
||||
Custom)
|
||||
# Until the DNS settings are selected,
|
||||
until [[ "${DNSSettingsCorrect}" = True ]]; do
|
||||
@ -1232,7 +1244,7 @@ install_dependent_packages() {
|
||||
echo -e "${OVER} ${TICK} Checking for $i"
|
||||
else
|
||||
#
|
||||
echo -e "${OVER} ${CROSS} Checking for $i (will be installed)"
|
||||
echo -e "${OVER} ${INFO} Checking for $i (will be installed)"
|
||||
#
|
||||
installArray+=("${i}")
|
||||
fi
|
||||
@ -1257,19 +1269,19 @@ install_dependent_packages() {
|
||||
if ${PKG_MANAGER} -q list installed "${i}" &> /dev/null; then
|
||||
echo -e "${OVER} ${TICK} Checking for $i"
|
||||
else
|
||||
echo -e "${OVER} ${CROSS} Checking for $i (will be installed)"
|
||||
echo -e "${OVER} ${INFO} Checking for $i (will be installed)"
|
||||
#
|
||||
installArray+=("${i}")
|
||||
fi
|
||||
done
|
||||
#
|
||||
if [[ "${#installArray[@]}" -gt 0 ]]; then
|
||||
#
|
||||
if [[ "${#installArray[@]}" -gt 0 ]]; then
|
||||
#
|
||||
"${PKG_INSTALL[@]}" "${installArray[@]}" &> /dev/null
|
||||
return
|
||||
fi
|
||||
echo ""
|
||||
return 0
|
||||
"${PKG_INSTALL[@]}" "${installArray[@]}" &> /dev/null
|
||||
return
|
||||
fi
|
||||
echo ""
|
||||
return 0
|
||||
}
|
||||
|
||||
# Create logfiles if necessary
|
||||
@ -1323,7 +1335,7 @@ installPiholeWeb() {
|
||||
else
|
||||
# don't do anything
|
||||
echo -e "${OVER} ${CROSS} ${str}
|
||||
No default index.lighttpd.html file found... not backing up"
|
||||
No default index.lighttpd.html file found... not backing up"
|
||||
fi
|
||||
|
||||
# Install Sudoers file
|
||||
@ -1356,6 +1368,10 @@ installCron() {
|
||||
echo -ne " ${INFO} ${str}..."
|
||||
# Copy the cron file over from the local repo
|
||||
cp ${PI_HOLE_LOCAL_REPO}/advanced/pihole.cron /etc/cron.d/pihole
|
||||
# Randomize gravity update time
|
||||
sed -i "s/59 1 /$((1 + RANDOM % 58)) $((3 + RANDOM % 2))/" /etc/cron.d/pihole
|
||||
# Randomize update checker time
|
||||
sed -i "s/59 17/$((1 + RANDOM % 58)) $((12 + RANDOM % 8))/" /etc/cron.d/pihole
|
||||
echo -e "${OVER} ${TICK} ${str}"
|
||||
}
|
||||
|
||||
@ -1668,14 +1684,14 @@ update_dialogs() {
|
||||
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3) || \
|
||||
{ echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
|
||||
|
||||
# Set the variable based on if the user user chooses
|
||||
# Set the variable based on if the user chooses
|
||||
case ${UpdateCmd} in
|
||||
# repair, or
|
||||
${opt1a})
|
||||
echo -e " ${INFO} ${opt1a} option selected"
|
||||
useUpdateVars=true
|
||||
;;
|
||||
# recongigure,
|
||||
# reconfigure,
|
||||
${opt2a})
|
||||
echo -e " ${INFO} ${opt2a} option selected"
|
||||
useUpdateVars=false
|
||||
@ -1849,7 +1865,7 @@ FTLdetect() {
|
||||
#If the installed version matches the latest version, then check the installed sha1sum of the binary vs the remote sha1sum. If they do not match, then download
|
||||
echo -e " ${INFO} Checking for existing FTL binary..."
|
||||
|
||||
local ftlLoc=$(which pihole-FTL)
|
||||
local ftlLoc=$(which pihole-FTL 2>/dev/null)
|
||||
|
||||
if [[ ${ftlLoc} ]]; then
|
||||
local FTLversion=$(/usr/bin/pihole-FTL tag)
|
||||
@ -1875,14 +1891,28 @@ FTLdetect() {
|
||||
# Install FTL
|
||||
FTLinstall "${binary}" || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
make_temporary_log() {
|
||||
# Create a random temporary file for the log
|
||||
TEMPLOG=$(mktemp /tmp/pihole_temp.XXXXXX)
|
||||
# Open handle 3 for templog
|
||||
# https://stackoverflow.com/questions/18460186/writing-outputs-to-log-file-and-console
|
||||
exec 3>"$TEMPLOG"
|
||||
# Delete templog, but allow for addressing via file handle
|
||||
# This lets us write to the log without having a temporary file on the drive, which
|
||||
# is meant to be a security measure so there is not a lingering file on the drive during the install process
|
||||
rm "$TEMPLOG"
|
||||
}
|
||||
|
||||
copy_to_install_log() {
|
||||
# Copy the contents of file descriptor 3 into the install log
|
||||
# Since we use color codes such as '\e[1;33m', they should be removed
|
||||
sed 's/\[[0-9;]\{1,5\}m//g' < /proc/$$/fd/3 > "${installLogLoc}"
|
||||
}
|
||||
|
||||
main() {
|
||||
######## FIRST CHECK ########
|
||||
# Show the Pi-hole logo so people know it's genuine since the logo and name are trademarked
|
||||
show_ascii_berry
|
||||
# Must be root to install
|
||||
local str="Root user check"
|
||||
echo ""
|
||||
@ -1891,6 +1921,9 @@ main() {
|
||||
if [[ "${EUID}" -eq 0 ]]; then
|
||||
# they are root and all is good
|
||||
echo -e " ${TICK} ${str}"
|
||||
# Show the Pi-hole logo so people know it's genuine since the logo and name are trademarked
|
||||
show_ascii_berry
|
||||
make_temporary_log
|
||||
# Otherwise,
|
||||
else
|
||||
# They do not have enough privileges, so let the user know
|
||||
@ -1997,8 +2030,15 @@ main() {
|
||||
# just install the Core dependencies
|
||||
DEPS=("${PIHOLE_DEPS[@]}")
|
||||
fi
|
||||
|
||||
install_dependent_packages DEPS[@]
|
||||
|
||||
# On some systems, lighttpd is not enabled on first install. We need to enable it here if the user
|
||||
# has chosen to install the web interface, else the `LIGHTTPD_ENABLED` check will fail
|
||||
if [[ "${INSTALL_WEB}" == true ]]; then
|
||||
enable_service lighttpd
|
||||
fi
|
||||
|
||||
if [[ -x "$(command -v systemctl)" ]]; then
|
||||
# Value will either be 1, if true, or 0
|
||||
LIGHTTPD_ENABLED=$(systemctl is-enabled lighttpd | grep -c 'enabled' || true)
|
||||
@ -2008,14 +2048,14 @@ main() {
|
||||
fi
|
||||
|
||||
# Install and log everything to a file
|
||||
installPihole | tee ${tmpLog}
|
||||
installPihole | tee -a /proc/$$/fd/3
|
||||
else
|
||||
# Source ${setupVars} to use predefined user variables in the functions
|
||||
source ${setupVars}
|
||||
|
||||
# Clone/Update the repos
|
||||
clone_or_update_repos
|
||||
|
||||
# Source ${setupVars} for use in the rest of the functions
|
||||
source ${setupVars}
|
||||
|
||||
# Install packages used by the Pi-hole
|
||||
if [[ "${INSTALL_WEB}" == true ]]; then
|
||||
# Install the Web dependencies
|
||||
@ -2034,12 +2074,11 @@ main() {
|
||||
# Value will either be 1, if true, or 0
|
||||
LIGHTTPD_ENABLED=$(service lighttpd status | awk '/Loaded:/ {print $0}' | grep -c 'enabled' || true)
|
||||
fi
|
||||
|
||||
updatePihole | tee ${tmpLog}
|
||||
updatePihole | tee -a /proc/$$/fd/3
|
||||
fi
|
||||
|
||||
# Move the log file into /etc/pihole for storage
|
||||
mv ${tmpLog} ${instalLogLoc}
|
||||
# Copy the temp log file into final log location for storage
|
||||
copy_to_install_log
|
||||
|
||||
if [[ "${INSTALL_WEB}" == true ]]; then
|
||||
# Add password to web UI if there is none
|
||||
@ -2077,6 +2116,10 @@ main() {
|
||||
# Download and compile the aggregated block list
|
||||
runGravity
|
||||
|
||||
# Force an update of the updatechecker
|
||||
. /opt/pihole/updatecheck.sh
|
||||
. /opt/pihole/updatecheck.sh x remote
|
||||
|
||||
#
|
||||
if [[ "${useUpdateVars}" == false ]]; then
|
||||
displayFinalMessage "${pw}"
|
||||
@ -2112,7 +2155,7 @@ main() {
|
||||
fi
|
||||
|
||||
# Display where the log file is
|
||||
echo -e "\\n ${INFO} The install log is located at: /etc/pihole/install.log
|
||||
echo -e "\\n ${INFO} The install log is located at: ${installLogLoc}
|
||||
${COL_LIGHT_GREEN}${INSTALL_TYPE} Complete! ${COL_NC}"
|
||||
|
||||
}
|
||||
|
164
gravity.sh
164
gravity.sh
@ -68,8 +68,8 @@ if [[ -r "${piholeDir}/pihole.conf" ]]; then
|
||||
fi
|
||||
|
||||
# Determine if DNS resolution is available before proceeding
|
||||
gravity_DNSLookup() {
|
||||
local lookupDomain="pi.hole" plural=""
|
||||
gravity_CheckDNSResolutionAvailable() {
|
||||
local lookupDomain="pi.hole"
|
||||
|
||||
# Determine if $localList does not exist
|
||||
if [[ ! -e "${localList}" ]]; then
|
||||
@ -88,6 +88,19 @@ gravity_DNSLookup() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If the /etc/resolv.conf contains resolvers other than 127.0.0.1 then the local dnsmasq will not be queried and pi.hole is NXDOMAIN.
|
||||
# This means that even though name resolution is working, the getent hosts check fails and the holddown timer keeps ticking and eventualy fails
|
||||
# So we check the output of the last command and if it failed, attempt to use dig +short as a fallback
|
||||
if timeout 1 dig +short "${lookupDomain}" &> /dev/null; then
|
||||
if [[ -n "${secs:-}" ]]; then
|
||||
echo -e "${OVER} ${TICK} DNS resolution is now available\\n"
|
||||
fi
|
||||
return 0
|
||||
elif [[ -n "${secs:-}" ]]; then
|
||||
echo -e "${OVER} ${CROSS} DNS resolution is not available"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Determine error output message
|
||||
if pidof dnsmasq &> /dev/null; then
|
||||
echo -e " ${CROSS} DNS resolution is currently unavailable"
|
||||
@ -98,21 +111,20 @@ gravity_DNSLookup() {
|
||||
|
||||
# Ensure DNS server is given time to be resolvable
|
||||
secs="120"
|
||||
echo -ne " ${INFO} Waiting up to ${secs} seconds before continuing..."
|
||||
echo -ne " ${INFO} Time until retry: ${secs}"
|
||||
until timeout 1 getent hosts "${lookupDomain}" &> /dev/null; do
|
||||
[[ "${secs:-}" -eq 0 ]] && break
|
||||
[[ "${secs:-}" -ne 1 ]] && plural="s"
|
||||
echo -ne "${OVER} ${INFO} Waiting up to ${secs} second${plural} before continuing..."
|
||||
echo -ne "${OVER} ${INFO} Time until retry: ${secs}"
|
||||
: $((secs--))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Try again
|
||||
gravity_DNSLookup
|
||||
gravity_CheckDNSResolutionAvailable
|
||||
}
|
||||
|
||||
# Retrieve blocklist URLs and parse domains from adlists.list
|
||||
gravity_Collapse() {
|
||||
gravity_GetBlocklistUrls() {
|
||||
echo -e " ${INFO} ${COL_BOLD}Neutrino emissions detected${COL_NC}..."
|
||||
|
||||
# Determine if adlists file needs handling
|
||||
@ -139,7 +151,8 @@ gravity_Collapse() {
|
||||
awk -F '[/:]' '{
|
||||
# Remove URL protocol & optional username:password@
|
||||
gsub(/(.*:\/\/|.*:.*@)/, "", $0)
|
||||
print $1
|
||||
if(length($1)>0){print $1}
|
||||
else {print "local"}
|
||||
}' <<< "$(printf '%s\n' "${sources[@]}")" 2> /dev/null
|
||||
)"
|
||||
|
||||
@ -152,7 +165,7 @@ gravity_Collapse() {
|
||||
}
|
||||
|
||||
# Define options for when retrieving blocklists
|
||||
gravity_Supernova() {
|
||||
gravity_SetDownloadOptions() {
|
||||
local url domain agent cmd_ext str
|
||||
|
||||
echo ""
|
||||
@ -177,7 +190,7 @@ gravity_Supernova() {
|
||||
|
||||
if [[ "${skipDownload}" == false ]]; then
|
||||
echo -e " ${INFO} Target: ${domain} (${url##*/})"
|
||||
gravity_Pull "${url}" "${cmd_ext}" "${agent}"
|
||||
gravity_DownloadBlocklistFromUrl "${url}" "${cmd_ext}" "${agent}"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
@ -185,16 +198,17 @@ gravity_Supernova() {
|
||||
}
|
||||
|
||||
# Download specified URL and perform checks on HTTP status and file content
|
||||
gravity_Pull() {
|
||||
gravity_DownloadBlocklistFromUrl() {
|
||||
local url="${1}" cmd_ext="${2}" agent="${3}" heisenbergCompensator="" patternBuffer str httpCode success=""
|
||||
|
||||
# Create temp file to store content on disk instead of RAM
|
||||
patternBuffer=$(mktemp -p "/tmp" --suffix=".phgpb")
|
||||
|
||||
# Determine if $saveLocation has read permission
|
||||
if [[ -r "${saveLocation}" ]]; then
|
||||
if [[ -r "${saveLocation}" && $url != "file"* ]]; then
|
||||
# Have curl determine if a remote file has been modified since last retrieval
|
||||
# Uses "Last-Modified" header, which certain web servers do not provide (e.g: raw github urls)
|
||||
# Note: Don't do this for local files, always download them
|
||||
heisenbergCompensator="-z ${saveLocation}"
|
||||
fi
|
||||
|
||||
@ -203,20 +217,32 @@ gravity_Pull() {
|
||||
# shellcheck disable=SC2086
|
||||
httpCode=$(curl -s -L ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" -A "${agent}" "${url}" -o "${patternBuffer}" 2> /dev/null)
|
||||
|
||||
# Determine "Status:" output based on HTTP response
|
||||
case "${httpCode}" in
|
||||
"200") echo -e "${OVER} ${TICK} ${str} Retrieval successful"; success=true;;
|
||||
"304") echo -e "${OVER} ${TICK} ${str} No changes detected"; success=true;;
|
||||
"000") echo -e "${OVER} ${CROSS} ${str} Connection Refused";;
|
||||
"403") echo -e "${OVER} ${CROSS} ${str} Forbidden";;
|
||||
"404") echo -e "${OVER} ${CROSS} ${str} Not found";;
|
||||
"408") echo -e "${OVER} ${CROSS} ${str} Time-out";;
|
||||
"451") echo -e "${OVER} ${CROSS} ${str} Unavailable For Legal Reasons";;
|
||||
"500") echo -e "${OVER} ${CROSS} ${str} Internal Server Error";;
|
||||
"504") echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Gateway)";;
|
||||
"521") echo -e "${OVER} ${CROSS} ${str} Web Server Is Down (Cloudflare)";;
|
||||
"522") echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Cloudflare)";;
|
||||
* ) echo -e "${OVER} ${CROSS} ${str} ${httpCode}";;
|
||||
case $url in
|
||||
# Did we "download" a remote file?
|
||||
"http"*)
|
||||
# Determine "Status:" output based on HTTP response
|
||||
case "${httpCode}" in
|
||||
"200") echo -e "${OVER} ${TICK} ${str} Retrieval successful"; success=true;;
|
||||
"304") echo -e "${OVER} ${TICK} ${str} No changes detected"; success=true;;
|
||||
"000") echo -e "${OVER} ${CROSS} ${str} Connection Refused";;
|
||||
"403") echo -e "${OVER} ${CROSS} ${str} Forbidden";;
|
||||
"404") echo -e "${OVER} ${CROSS} ${str} Not found";;
|
||||
"408") echo -e "${OVER} ${CROSS} ${str} Time-out";;
|
||||
"451") echo -e "${OVER} ${CROSS} ${str} Unavailable For Legal Reasons";;
|
||||
"500") echo -e "${OVER} ${CROSS} ${str} Internal Server Error";;
|
||||
"504") echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Gateway)";;
|
||||
"521") echo -e "${OVER} ${CROSS} ${str} Web Server Is Down (Cloudflare)";;
|
||||
"522") echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Cloudflare)";;
|
||||
* ) echo -e "${OVER} ${CROSS} ${str} ${httpCode}";;
|
||||
esac;;
|
||||
# Did we "download" a local file?
|
||||
"file"*)
|
||||
if [[ -s "${patternBuffer}" ]]; then
|
||||
echo -e "${OVER} ${TICK} ${str} Retrieval successful"; success=true
|
||||
else
|
||||
echo -e "${OVER} ${CROSS} ${str} Not found / empty list"
|
||||
fi;;
|
||||
*) echo -e "${OVER} ${CROSS} ${str} ${url} ${httpCode}";;
|
||||
esac
|
||||
|
||||
# Determine if the blocklist was downloaded and saved correctly
|
||||
@ -243,36 +269,22 @@ gravity_Pull() {
|
||||
|
||||
# Parse source files into domains format
|
||||
gravity_ParseFileIntoDomains() {
|
||||
local source="${1}" destination="${2}" commentPattern firstLine abpFilter
|
||||
local source="${1}" destination="${2}" firstLine abpFilter
|
||||
|
||||
# Determine if we are parsing a consolidated list
|
||||
if [[ "${source}" == "${piholeDir}/${matterAndLight}" ]]; then
|
||||
# Define symbols used as comments: #;@![/
|
||||
commentPattern="[#;@![\\/]"
|
||||
# Remove comments and print only the domain name
|
||||
# Most of the lists downloaded are already in hosts file format but the spacing/formating is not contigious
|
||||
# This helps with that and makes it easier to read
|
||||
# It also helps with debugging so each stage of the script can be researched more in depth
|
||||
#Awk -F splits on given IFS, we grab the right hand side (chops trailing #coments and /'s to grab the domain only.
|
||||
#Last awk command takes non-commented lines and if they have 2 fields, take the left field (the domain) and leave
|
||||
#+ the right (IP address), otherwise grab the single field.
|
||||
|
||||
# Parse Domains/Hosts files by removing comments & host IPs
|
||||
# Logic: Ignore lines which begin with comments
|
||||
awk '!/^'"${commentPattern}"'/ {
|
||||
# Determine if there are multiple words seperated by a space
|
||||
if(NF>1) {
|
||||
# Remove comments (including prefixed spaces/tabs)
|
||||
if($0 ~ /'"${commentPattern}"'/) { gsub("( |\t)'"${commentPattern}"'.*", "", $0) }
|
||||
# Determine if there are aliased domains
|
||||
if($3) {
|
||||
# Remove IP address
|
||||
$1=""
|
||||
# Remove space which is left in $0 when removing $1
|
||||
gsub("^ ", "", $0)
|
||||
print $0
|
||||
} else if($2) {
|
||||
# Print single domain without IP
|
||||
print $2
|
||||
}
|
||||
# If there are no words seperated by space
|
||||
} else if($1) {
|
||||
print $1
|
||||
}
|
||||
}' "${source}" 2> /dev/null > "${destination}"
|
||||
< ${source} awk -F '#' '{print $1}' | \
|
||||
awk -F '/' '{print $1}' | \
|
||||
awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' | \
|
||||
sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${destination}
|
||||
return 0
|
||||
fi
|
||||
|
||||
@ -353,7 +365,7 @@ gravity_ParseFileIntoDomains() {
|
||||
}
|
||||
|
||||
# Create (unfiltered) "Matter and Light" consolidated list
|
||||
gravity_Schwarzschild() {
|
||||
gravity_ConsolidateDownloadedBlocklists() {
|
||||
local str lastLine
|
||||
|
||||
str="Consolidating blocklists"
|
||||
@ -381,7 +393,7 @@ gravity_Schwarzschild() {
|
||||
}
|
||||
|
||||
# Parse consolidated list into (filtered, unique) domains-only format
|
||||
gravity_Filter() {
|
||||
gravity_SortAndFilterConsolidatedList() {
|
||||
local str num
|
||||
|
||||
str="Extracting domains from blocklists"
|
||||
@ -393,7 +405,7 @@ gravity_Filter() {
|
||||
# Format $parsedMatter line total as currency
|
||||
num=$(printf "%'.0f" "$(wc -l < "${piholeDir}/${parsedMatter}")")
|
||||
echo -e "${OVER} ${TICK} ${str}
|
||||
${INFO} ${COL_BLUE}${num}${COL_NC} domains being pulled in by gravity"
|
||||
${INFO} Number of domains being pulled in by gravity: ${COL_BLUE}${num}${COL_NC}"
|
||||
|
||||
str="Removing duplicate domains"
|
||||
echo -ne " ${INFO} ${str}..."
|
||||
@ -402,31 +414,30 @@ gravity_Filter() {
|
||||
|
||||
# Format $preEventHorizon line total as currency
|
||||
num=$(printf "%'.0f" "$(wc -l < "${piholeDir}/${preEventHorizon}")")
|
||||
echo -e " ${INFO} ${COL_BLUE}${num}${COL_NC} unique domains trapped in the Event Horizon"
|
||||
echo -e " ${INFO} Number of unique domains trapped in the Event Horizon: ${COL_BLUE}${num}${COL_NC}"
|
||||
}
|
||||
|
||||
# Whitelist unique blocklist domain sources
|
||||
gravity_WhitelistBLD() {
|
||||
local uniqDomains plural="" str
|
||||
gravity_WhitelistBlocklistSourceUrls() {
|
||||
local uniqDomains str
|
||||
|
||||
echo ""
|
||||
|
||||
# Create array of unique $sourceDomains
|
||||
mapfile -t uniqDomains <<< "$(awk '{ if(!a[$1]++) { print $1 } }' <<< "$(printf '%s\n' "${sourceDomains[@]}")")"
|
||||
[[ "${#uniqDomains[@]}" -ne 1 ]] && plural="s"
|
||||
|
||||
str="Adding ${#uniqDomains[@]} blocklist source domain${plural} to the whitelist"
|
||||
str="Number of blocklist source domains being added to the whitelist: ${#uniqDomains[@]}"
|
||||
echo -ne " ${INFO} ${str}..."
|
||||
|
||||
# Whitelist $uniqDomains
|
||||
"${PIHOLE_COMMAND}" -w -nr -q "${uniqDomains[*]}" &> /dev/null
|
||||
"${PIHOLE_COMMAND}" -w -nr -q ${uniqDomains[*]} &> /dev/null
|
||||
|
||||
echo -e "${OVER} ${TICK} ${str}"
|
||||
echo -e "${OVER} ${INFO} ${str}"
|
||||
}
|
||||
|
||||
# Whitelist user-defined domains
|
||||
gravity_Whitelist() {
|
||||
local num plural="" str
|
||||
local num str
|
||||
|
||||
if [[ ! -f "${whitelistFile}" ]]; then
|
||||
echo -e " ${INFO} Nothing to whitelist!"
|
||||
@ -434,24 +445,22 @@ gravity_Whitelist() {
|
||||
fi
|
||||
|
||||
num=$(wc -l < "${whitelistFile}")
|
||||
[[ "${num}" -ne 1 ]] && plural="s"
|
||||
str="Whitelisting ${num} domain${plural}"
|
||||
str="Number of whitelisted domains: ${num}"
|
||||
echo -ne " ${INFO} ${str}..."
|
||||
|
||||
# Print everything from preEventHorizon into whitelistMatter EXCEPT domains in $whitelistFile
|
||||
grep -F -x -v -f "${whitelistFile}" "${piholeDir}/${preEventHorizon}" > "${piholeDir}/${whitelistMatter}"
|
||||
|
||||
echo -e "${OVER} ${TICK} ${str}"
|
||||
echo -e "${OVER} ${INFO} ${str}"
|
||||
}
|
||||
|
||||
# Output count of blacklisted domains and wildcards
|
||||
gravity_ShowBlockCount() {
|
||||
local num plural
|
||||
local num
|
||||
|
||||
if [[ -f "${blacklistFile}" ]]; then
|
||||
num=$(printf "%'.0f" "$(wc -l < "${blacklistFile}")")
|
||||
plural=; [[ "${num}" -ne 1 ]] && plural="s"
|
||||
echo -e " ${INFO} Blacklisted ${num} domain${plural}"
|
||||
echo -e " ${INFO} Number of blacklisted domains: ${num}"
|
||||
fi
|
||||
|
||||
if [[ -f "${wildcardFile}" ]]; then
|
||||
@ -460,8 +469,7 @@ gravity_ShowBlockCount() {
|
||||
if [[ -n "${IPV4_ADDRESS}" ]] && [[ -n "${IPV6_ADDRESS}" ]];then
|
||||
num=$(( num/2 ))
|
||||
fi
|
||||
plural=; [[ "${num}" -ne 1 ]] && plural="s"
|
||||
echo -e " ${INFO} Wildcard blocked ${num} domain${plural}"
|
||||
echo -e " ${INFO} Number of wildcard blocked domains: ${num}"
|
||||
fi
|
||||
}
|
||||
|
||||
@ -555,7 +563,7 @@ gravity_Cleanup() {
|
||||
rm ${piholeDir}/*.tmp 2> /dev/null
|
||||
rm /tmp/*.phgpb 2> /dev/null
|
||||
|
||||
# Ensure this function only runs when gravity_Supernova() has completed
|
||||
# Ensure this function only runs when gravity_SetDownloadOptions() has completed
|
||||
if [[ "${gravity_Blackbody:-}" == true ]]; then
|
||||
# Remove any unused .domains files
|
||||
for file in ${piholeDir}/*.${domainsExtension}; do
|
||||
@ -617,12 +625,12 @@ fi
|
||||
# Determine which functions to run
|
||||
if [[ "${skipDownload}" == false ]]; then
|
||||
# Gravity needs to download blocklists
|
||||
gravity_DNSLookup
|
||||
gravity_Collapse
|
||||
gravity_Supernova
|
||||
gravity_Schwarzschild
|
||||
gravity_Filter
|
||||
gravity_WhitelistBLD
|
||||
gravity_CheckDNSResolutionAvailable
|
||||
gravity_GetBlocklistUrls
|
||||
gravity_SetDownloadOptions
|
||||
gravity_ConsolidateDownloadedBlocklists
|
||||
gravity_SortAndFilterConsolidatedList
|
||||
gravity_WhitelistBlocklistSourceUrls
|
||||
else
|
||||
# Gravity needs to modify Blacklist/Whitelist/Wildcards
|
||||
echo -e " ${INFO} Using cached Event Horizon list..."
|
||||
|
28
pihole
28
pihole
@ -85,7 +85,8 @@ updateGravityFunc() {
|
||||
|
||||
# Scan an array of files for matching strings
|
||||
scanList(){
|
||||
local domain="${1}" lists="${2}" type="${3:-}"
|
||||
# Escape full stops
|
||||
local domain="${1//./\\.}" lists="${2}" type="${3:-}"
|
||||
|
||||
# Prevent grep from printing file path
|
||||
cd "/etc/pihole" || exit 1
|
||||
@ -154,7 +155,7 @@ Options:
|
||||
|
||||
# Strip valid options, leaving only the domain and invalid options
|
||||
# This allows users to place the options before or after the domain
|
||||
options=$(sed -E 's/ ?-(bp|adlists?|all|exact)//g' <<< "${options}")
|
||||
options=$(sed -E 's/ ?-(bp|adlists?|all|exact) ?//g' <<< "${options}")
|
||||
|
||||
# Handle remaining options
|
||||
# If $options contain non ASCII characters, convert to punycode
|
||||
@ -199,7 +200,7 @@ Options:
|
||||
|
||||
# Scan Wildcards
|
||||
if [[ -e "${wildcardlist}" ]]; then
|
||||
# Determine all subdomains, domain and TLDs
|
||||
# Determine all subdomains, domain and TLDs
|
||||
mapfile -t wildcards <<< "$(processWildcards "${domainQuery}")"
|
||||
|
||||
for match in "${wildcards[@]}"; do
|
||||
@ -335,7 +336,7 @@ restartDNS() {
|
||||
if [[ "${svcOption}" =~ "reload" ]]; then
|
||||
# Using SIGHUP will NOT re-read any *.conf files
|
||||
svc="killall -s SIGHUP dnsmasq"
|
||||
elif [[ -z "${svcOption}" ]]; then
|
||||
else
|
||||
# Get PID of dnsmasq to determine if it needs to start or restart
|
||||
if pidof dnsmasq &> /dev/null; then
|
||||
svcOption="restart"
|
||||
@ -358,6 +359,9 @@ restartDNS() {
|
||||
[[ ! -t 1 ]] && local OVER=""
|
||||
echo -e "${OVER} ${CROSS} ${output}"
|
||||
fi
|
||||
|
||||
# Send signal to FTL to have it re-parse the gravity files
|
||||
killall -s SIGHUP pihole-FTL
|
||||
}
|
||||
|
||||
piholeEnable() {
|
||||
@ -440,13 +444,17 @@ Specify whether the Pi-hole log should be used
|
||||
|
||||
Options:
|
||||
on Enable the Pi-hole log at /var/log/pihole.log
|
||||
off Disable the Pi-hole log at /var/log/pihole.log"
|
||||
off Disable and flush the Pi-hole log at /var/log/pihole.log
|
||||
off noflush Disable the Pi-hole log at /var/log/pihole.log"
|
||||
exit 0
|
||||
elif [[ "${1}" == "off" ]]; then
|
||||
# Disable logging
|
||||
sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
|
||||
sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
|
||||
pihole -f
|
||||
if [[ "${2}" != "noflush" ]]; then
|
||||
# Flush logs
|
||||
pihole -f
|
||||
fi
|
||||
echo -e " ${INFO} Disabling logging..."
|
||||
local str="Logging has been disabled!"
|
||||
elif [[ "${1}" == "on" ]]; then
|
||||
@ -482,7 +490,7 @@ statusFunc() {
|
||||
|
||||
# Determine if Pi-hole's addn-hosts configs are commented out
|
||||
addnConfigs=$(grep -i "addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)
|
||||
|
||||
|
||||
if [[ "${addnConfigs}" =~ "#" ]]; then
|
||||
# A config is commented out
|
||||
case "${1}" in
|
||||
@ -578,6 +586,11 @@ tricorderFunc() {
|
||||
fi
|
||||
}
|
||||
|
||||
updateCheckFunc() {
|
||||
"${PI_HOLE_SCRIPT_DIR}"/updatecheck.sh "$@"
|
||||
exit 0
|
||||
}
|
||||
|
||||
helpFunc() {
|
||||
echo "Usage: pihole [options]
|
||||
Example: 'pihole -w -h'
|
||||
@ -649,5 +662,6 @@ case "${1}" in
|
||||
"-t" | "tail" ) tailFunc;;
|
||||
"checkout" ) piholeCheckoutFunc "$@";;
|
||||
"tricorder" ) tricorderFunc;;
|
||||
"updatechecker" ) updateCheckFunc "$@";;
|
||||
* ) helpFunc;;
|
||||
esac
|
||||
|
Loading…
Reference in New Issue
Block a user