mirror of
https://github.com/pi-hole/pi-hole
synced 2025-01-03 12:40:56 +00:00
Release 5.12 (#4889)
This commit is contained in:
commit
f998eee467
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout repository
|
name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3.0.2
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
-
|
-
|
||||||
name: Initialize CodeQL
|
name: Initialize CodeQL
|
||||||
|
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v5
|
- uses: actions/stale@v5.1.1
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
days-before-stale: 30
|
days-before-stale: 30
|
||||||
|
4
.github/workflows/sync-back-to-dev.yml
vendored
4
.github/workflows/sync-back-to-dev.yml
vendored
@ -11,7 +11,7 @@ jobs:
|
|||||||
name: Syncing branches
|
name: Syncing branches
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3.0.2
|
||||||
- name: Opening pull request
|
- name: Opening pull request
|
||||||
id: pull
|
id: pull
|
||||||
uses: tretuna/sync-branches@1.4.0
|
uses: tretuna/sync-branches@1.4.0
|
||||||
@ -20,7 +20,7 @@ jobs:
|
|||||||
FROM_BRANCH: 'master'
|
FROM_BRANCH: 'master'
|
||||||
TO_BRANCH: 'development'
|
TO_BRANCH: 'development'
|
||||||
- name: Label the pull request to ignore for release note generation
|
- name: Label the pull request to ignore for release note generation
|
||||||
uses: actions-ecosystem/action-add-labels@v1
|
uses: actions-ecosystem/action-add-labels@v1.1.3
|
||||||
with:
|
with:
|
||||||
labels: internal
|
labels: internal
|
||||||
repo: ${{ github.repository }}
|
repo: ${{ github.repository }}
|
||||||
|
11
.github/workflows/test.yml
vendored
11
.github/workflows/test.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout repository
|
name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3.0.2
|
||||||
-
|
-
|
||||||
name: Check scripts in repository are executable
|
name: Check scripts in repository are executable
|
||||||
run: |
|
run: |
|
||||||
@ -30,7 +30,7 @@ jobs:
|
|||||||
ignore_words_file: .codespellignore
|
ignore_words_file: .codespellignore
|
||||||
-
|
-
|
||||||
name: Get editorconfig-checker
|
name: Get editorconfig-checker
|
||||||
uses: editorconfig-checker/action-editorconfig-checker@main
|
uses: editorconfig-checker/action-editorconfig-checker@main # tag v1.0.0 is really out of date
|
||||||
-
|
-
|
||||||
name: Run editorconfig-checker
|
name: Run editorconfig-checker
|
||||||
run: editorconfig-checker
|
run: editorconfig-checker
|
||||||
@ -41,17 +41,18 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: smoke-tests
|
needs: smoke-tests
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
distro: [debian_10, debian_11, ubuntu_18, ubuntu_20, ubuntu_21, ubuntu_22, centos_7, centos_8, fedora_34]
|
distro: [debian_10, debian_11, ubuntu_18, ubuntu_20, ubuntu_22, centos_8, fedora_34]
|
||||||
env:
|
env:
|
||||||
DISTRO: ${{matrix.distro}}
|
DISTRO: ${{matrix.distro}}
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout repository
|
name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3.0.2
|
||||||
-
|
-
|
||||||
name: Set up Python 3.8
|
name: Set up Python 3.8
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4.2.0
|
||||||
with:
|
with:
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
-
|
-
|
||||||
|
20
README.md
20
README.md
@ -3,15 +3,15 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://pi-hole.net/#gh-light-mode-only">
|
<picture>
|
||||||
<img src="https://github.com/pi-hole/graphics/blob/master/Vortex/Vortex_Vertical_wordmark_lightmode.png?raw=true)" alt="Pi-hole">
|
<source media="(prefers-color-scheme: dark)" srcset="https://pi-hole.github.io/graphics/Vortex/Vortex_Vertical_wordmark_darkmode.png">
|
||||||
</a>
|
<source media="(prefers-color-scheme: light)" srcset="https://pi-hole.github.io/graphics/Vortex/Vortex_Vertical_wordmark_lightmode.png">
|
||||||
<a href="https://pi-hole.net/#gh-dark-mode-only">
|
<img src="https://pi-hole.github.io/graphics/Vortex/Vortex_Vertical_wordmark_lightmode.png" width="168" height="270" alt="Pi-hole website">
|
||||||
<img src="https://github.com/pi-hole/graphics/blob/master/Vortex/Vortex_Vertical_wordmark_darkmode.png?raw=true" alt="Pi-hole">
|
</picture>
|
||||||
</a>
|
|
||||||
<br>
|
<br>
|
||||||
<strong>Network-wide ad blocking via your own Linux hardware</strong>
|
<strong>Network-wide ad blocking via your own Linux hardware</strong>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- markdownlint-enable MD033 -->
|
<!-- markdownlint-enable MD033 -->
|
||||||
|
|
||||||
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.
|
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.
|
||||||
@ -22,7 +22,7 @@ The Pi-hole® is a [DNS sinkhole](https://en.wikipedia.org/wiki/DNS_Sinkhole) th
|
|||||||
- **Lightweight**: runs smoothly with [minimal hardware and software requirements](https://docs.pi-hole.net/main/prerequisites/)
|
- **Lightweight**: runs smoothly with [minimal hardware and software requirements](https://docs.pi-hole.net/main/prerequisites/)
|
||||||
- **Robust**: a command line interface that is quality assured for interoperability
|
- **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
|
- **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
|
- **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
|
- **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
|
- **Modern**: blocks ads over both IPv4 and IPv6
|
||||||
- **Free**: open source software that helps ensure _you_ are the sole person in control of your privacy
|
- **Free**: open source software that helps ensure _you_ are the sole person in control of your privacy
|
||||||
@ -53,7 +53,9 @@ sudo bash basic-install.sh
|
|||||||
wget -O basic-install.sh https://install.pi-hole.net
|
wget -O basic-install.sh https://install.pi-hole.net
|
||||||
sudo bash basic-install.sh
|
sudo bash basic-install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### Method 3: Using Docker to deploy Pi-hole
|
### Method 3: Using Docker to deploy Pi-hole
|
||||||
|
|
||||||
Please refer to the [Pi-hole docker repo](https://github.com/pi-hole/docker-pi-hole) to use the Official Docker Images.
|
Please refer to the [Pi-hole docker repo](https://github.com/pi-hole/docker-pi-hole) to use the Official Docker Images.
|
||||||
|
|
||||||
## [Post-install: Make your network take advantage of Pi-hole](https://docs.pi-hole.net/main/post-install/)
|
## [Post-install: Make your network take advantage of Pi-hole](https://docs.pi-hole.net/main/post-install/)
|
||||||
@ -115,7 +117,7 @@ While we are primarily reachable on our [Discourse User Forum](https://discourse
|
|||||||
|
|
||||||
### [Faster-than-light Engine](https://github.com/pi-hole/ftl)
|
### [Faster-than-light Engine](https://github.com/pi-hole/ftl)
|
||||||
|
|
||||||
[FTLDNS](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, FTLDNS does this all *very quickly*!
|
[FTLDNS](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, FTLDNS does this all _very quickly_!
|
||||||
|
|
||||||
Some of the statistics you can integrate include:
|
Some of the statistics you can integrate include:
|
||||||
|
|
||||||
@ -142,7 +144,7 @@ Some notable features include:
|
|||||||
- [Updating Ad Lists](https://docs.pi-hole.net/core/pihole-command/#gravity)
|
- [Updating Ad Lists](https://docs.pi-hole.net/core/pihole-command/#gravity)
|
||||||
- [Querying Ad Lists for blocked domains](https://docs.pi-hole.net/core/pihole-command/#query)
|
- [Querying Ad Lists for blocked domains](https://docs.pi-hole.net/core/pihole-command/#query)
|
||||||
- [Enabling and Disabling Pi-hole](https://docs.pi-hole.net/core/pihole-command/#enable-disable)
|
- [Enabling and Disabling Pi-hole](https://docs.pi-hole.net/core/pihole-command/#enable-disable)
|
||||||
- ... and *many* more!
|
- ... and _many_ more!
|
||||||
|
|
||||||
You can read our [Core Feature Breakdown](https://docs.pi-hole.net/core/pihole-command/#pi-hole-core) for more information.
|
You can read our [Core Feature Breakdown](https://docs.pi-hole.net/core/pihole-command/#pi-hole-core) for more information.
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 35 B |
Binary file not shown.
Before Width: | Height: | Size: 26 B |
Binary file not shown.
Before Width: | Height: | Size: 37 B |
Binary file not shown.
Before Width: | Height: | Size: 43 B |
@ -332,17 +332,34 @@ compare_local_version_to_git_version() {
|
|||||||
|
|
||||||
check_ftl_version() {
|
check_ftl_version() {
|
||||||
local ftl_name="FTL"
|
local ftl_name="FTL"
|
||||||
|
local FTL_VERSION FTL_COMMIT FTL_BRANCH
|
||||||
echo_current_diagnostic "${ftl_name} version"
|
echo_current_diagnostic "${ftl_name} version"
|
||||||
# Use the built in command to check FTL's version
|
# Use the built in command to check FTL's version
|
||||||
FTL_VERSION=$(pihole-FTL version)
|
FTL_VERSION=$(pihole-FTL -vv | grep -m 1 Version | awk '{printf $2}')
|
||||||
|
FTL_BRANCH=$(pihole-FTL -vv | grep -m 1 Branch | awk '{printf $2}')
|
||||||
|
FTL_COMMIT=$(pihole-FTL -vv | grep -m 1 Commit | awk '{printf $2}')
|
||||||
|
|
||||||
# Compare the current FTL version to the remote version
|
# Compare the current FTL version to the remote version
|
||||||
if [[ "${FTL_VERSION}" == "$(pihole -v | awk '/FTL/ {print $6}' | cut -d ')' -f1)" ]]; then
|
if [[ "${FTL_VERSION}" == "$(pihole -v | awk '/FTL/ {print $6}' | cut -d ')' -f1)" ]]; then
|
||||||
# If they are the same, FTL is up-to-date
|
# If they are the same, FTL is up-to-date
|
||||||
log_write "${TICK} ${ftl_name}: ${COL_GREEN}${FTL_VERSION}${COL_NC}"
|
log_write "${TICK} ${ftl_name}: ${COL_GREEN}${FTL_VERSION}${COL_NC}"
|
||||||
else
|
else
|
||||||
# If not, show it in yellow, signifying there is an update
|
# 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})"
|
log_write "${INFO} ${ftl_name}: ${COL_YELLOW}${FTL_VERSION}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# If they use the master branch, they are on the stable codebase
|
||||||
|
if [[ "${FTL_BRANCH}" == "master" ]]; then
|
||||||
|
# so the color of the text is green
|
||||||
|
log_write "${INFO} Branch: ${COL_GREEN}${FTL_BRANCH}${COL_NC}"
|
||||||
|
# If it is any other branch, they are in a development branch
|
||||||
|
else
|
||||||
|
# So show that in yellow, signifying it's something to take a look at, but not a critical error
|
||||||
|
log_write "${INFO} Branch: ${COL_YELLOW}${FTL_BRANCH}${COL_NC} (${FAQ_CHECKOUT_COMMAND})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# echo the current commit
|
||||||
|
log_write "${INFO} Commit: ${FTL_COMMIT}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Checks the core version of the Pi-hole codebase
|
# Checks the core version of the Pi-hole codebase
|
||||||
@ -797,29 +814,13 @@ check_x_headers() {
|
|||||||
# server is operating correctly
|
# server is operating correctly
|
||||||
echo_current_diagnostic "Dashboard and block page"
|
echo_current_diagnostic "Dashboard and block page"
|
||||||
# Use curl -I to get the header and parse out just the X-Pi-hole one
|
# Use curl -I to get the header and parse out just the X-Pi-hole one
|
||||||
local block_page
|
local full_curl_output_dashboard
|
||||||
block_page=$(curl -Is localhost | awk '/X-Pi-hole/' | tr -d '\r')
|
|
||||||
# Do it for the dashboard as well, as the header is different than above
|
|
||||||
local dashboard
|
local dashboard
|
||||||
dashboard=$(curl -Is localhost/admin/ | awk '/X-Pi-hole/' | tr -d '\r')
|
full_curl_output_dashboard="$(curl -Is localhost/admin/)"
|
||||||
|
dashboard=$(echo "${full_curl_output_dashboard}" | awk '/X-Pi-hole/' | tr -d '\r')
|
||||||
# Store what the X-Header should be in variables for comparison later
|
# Store what the X-Header should be in variables for comparison later
|
||||||
local block_page_working
|
|
||||||
block_page_working="X-Pi-hole: A black hole for Internet advertisements."
|
|
||||||
local dashboard_working
|
local dashboard_working
|
||||||
dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!"
|
dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!"
|
||||||
local full_curl_output_block_page
|
|
||||||
full_curl_output_block_page="$(curl -Is localhost)"
|
|
||||||
local full_curl_output_dashboard
|
|
||||||
full_curl_output_dashboard="$(curl -Is localhost/admin/)"
|
|
||||||
# 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 Block page X-Header: ${COL_GREEN}${block_page}${COL_NC}"
|
|
||||||
else
|
|
||||||
# Otherwise, show an error
|
|
||||||
log_write "$CROSS Block page X-Header: ${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 dashboard as above, if the X-Header matches what a working system should have,
|
# Same logic applies to the dashboard as above, if the X-Header matches what a working system should have,
|
||||||
if [[ $dashboard == "$dashboard_working" ]]; then
|
if [[ $dashboard == "$dashboard_working" ]]; then
|
||||||
@ -828,6 +829,7 @@ check_x_headers() {
|
|||||||
else
|
else
|
||||||
# Otherwise, it's a failure since the X-Headers either don't exist or have been modified in some way
|
# Otherwise, it's a failure since the X-Headers either don't exist or have been modified in some way
|
||||||
log_write "$CROSS Web interface X-Header: ${COL_RED}X-Header does not match or could not be retrieved.${COL_NC}"
|
log_write "$CROSS Web interface X-Header: ${COL_RED}X-Header does not match or could not be retrieved.${COL_NC}"
|
||||||
|
|
||||||
log_write "${COL_RED}${full_curl_output_dashboard}${COL_NC}"
|
log_write "${COL_RED}${full_curl_output_dashboard}${COL_NC}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -1230,7 +1232,7 @@ check_dhcp_servers() {
|
|||||||
OLD_IFS="$IFS"
|
OLD_IFS="$IFS"
|
||||||
IFS=$'\n'
|
IFS=$'\n'
|
||||||
local entries=()
|
local entries=()
|
||||||
mapfile -t entries < <(pihole-FTL dhcp-discover)
|
mapfile -t entries < <(pihole-FTL dhcp-discover & spinner)
|
||||||
|
|
||||||
for line in "${entries[@]}"; do
|
for line in "${entries[@]}"; do
|
||||||
log_write " ${line}"
|
log_write " ${line}"
|
||||||
@ -1259,12 +1261,21 @@ show_messages() {
|
|||||||
show_FTL_db_entries "Pi-hole diagnosis messages" "SELECT count (message) as count, datetime(max(timestamp),'unixepoch','localtime') as 'last timestamp', type, message, blob1, blob2, blob3, blob4, blob5 FROM message GROUP BY type, message, blob1, blob2, blob3, blob4, blob5;" "6 19 20 60 20 20 20 20 20"
|
show_FTL_db_entries "Pi-hole diagnosis messages" "SELECT count (message) as count, datetime(max(timestamp),'unixepoch','localtime') as 'last timestamp', type, message, blob1, blob2, blob3, blob4, blob5 FROM message GROUP BY type, message, blob1, blob2, blob3, blob4, blob5;" "6 19 20 60 20 20 20 20 20"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
database_permissions() {
|
||||||
|
local permissions
|
||||||
|
permissions=$(ls -lhd "${1}")
|
||||||
|
log_write "${COL_GREEN}${permissions}${COL_NC}"
|
||||||
|
}
|
||||||
|
|
||||||
analyze_gravity_list() {
|
analyze_gravity_list() {
|
||||||
echo_current_diagnostic "Gravity Database"
|
echo_current_diagnostic "Gravity Database"
|
||||||
|
|
||||||
local gravity_permissions
|
database_permissions "${PIHOLE_GRAVITY_DB_FILE}"
|
||||||
gravity_permissions=$(ls -lhd "${PIHOLE_GRAVITY_DB_FILE}")
|
|
||||||
log_write "${COL_GREEN}${gravity_permissions}${COL_NC}"
|
# if users want to check database integrity
|
||||||
|
if [[ "${CHECK_DATABASE}" = true ]]; then
|
||||||
|
database_integrity_check "${PIHOLE_FTL_DB_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
show_db_entries "Info table" "SELECT property,value FROM info" "20 40"
|
show_db_entries "Info table" "SELECT property,value FROM info" "20 40"
|
||||||
gravity_updated_raw="$(pihole-FTL sqlite3 "${PIHOLE_GRAVITY_DB_FILE}" "SELECT value FROM info where property = 'updated'")"
|
gravity_updated_raw="$(pihole-FTL sqlite3 "${PIHOLE_GRAVITY_DB_FILE}" "SELECT value FROM info where property = 'updated'")"
|
||||||
@ -1286,6 +1297,95 @@ analyze_gravity_list() {
|
|||||||
IFS="$OLD_IFS"
|
IFS="$OLD_IFS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
analyze_ftl_db() {
|
||||||
|
echo_current_diagnostic "Pi-hole FTL Query Database"
|
||||||
|
database_permissions "${PIHOLE_FTL_DB_FILE}"
|
||||||
|
# if users want to check database integrity
|
||||||
|
if [[ "${CHECK_DATABASE}" = true ]]; then
|
||||||
|
database_integrity_check "${PIHOLE_FTL_DB_FILE}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
database_integrity_check(){
|
||||||
|
local result
|
||||||
|
local database="${1}"
|
||||||
|
|
||||||
|
log_write "${INFO} Checking integrity of ${database} ... (this can take several minutes)"
|
||||||
|
result="$(pihole-FTL "${database}" "PRAGMA integrity_check" 2>&1 & spinner)"
|
||||||
|
if [[ ${result} = "ok" ]]; then
|
||||||
|
log_write "${TICK} Integrity of ${database} intact"
|
||||||
|
|
||||||
|
|
||||||
|
log_write "${INFO} Checking foreign key constraints of ${database} ... (this can take several minutes)"
|
||||||
|
unset result
|
||||||
|
result="$(pihole-FTL sqlite3 "${database}" -cmd ".headers on" -cmd ".mode column" "PRAGMA foreign_key_check" 2>&1 & spinner)"
|
||||||
|
if [[ -z ${result} ]]; then
|
||||||
|
log_write "${TICK} No foreign key errors in ${database}"
|
||||||
|
else
|
||||||
|
log_write "${CROSS} ${COL_RED}Foreign key errors in ${database} found.${COL_NC}"
|
||||||
|
while IFS= read -r line ; do
|
||||||
|
log_write " $line"
|
||||||
|
done <<< "$result"
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
log_write "${CROSS} ${COL_RED}Integrity errors in ${database} found.\n${COL_NC}"
|
||||||
|
while IFS= read -r line ; do
|
||||||
|
log_write " $line"
|
||||||
|
done <<< "$result"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
check_database_integrity() {
|
||||||
|
echo_current_diagnostic "Gravity Database"
|
||||||
|
database_permissions "${PIHOLE_GRAVITY_DB_FILE}"
|
||||||
|
database_integrity_check "${PIHOLE_GRAVITY_DB_FILE}"
|
||||||
|
|
||||||
|
echo_current_diagnostic "Pi-hole FTL Query Database"
|
||||||
|
database_permissions "${PIHOLE_FTL_DB_FILE}"
|
||||||
|
database_integrity_check "${PIHOLE_FTL_DB_FILE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show a text spinner during a long process run
|
||||||
|
spinner(){
|
||||||
|
# Show the spinner only if there is a tty
|
||||||
|
if tty -s; then
|
||||||
|
# PID of the most recent background process
|
||||||
|
_PID=$!
|
||||||
|
_spin="/-\|"
|
||||||
|
_start=0
|
||||||
|
_elapsed=0
|
||||||
|
_i=1
|
||||||
|
|
||||||
|
# Start the counter
|
||||||
|
_start=$(date +%s)
|
||||||
|
|
||||||
|
# Hide the cursor
|
||||||
|
tput civis > /dev/tty
|
||||||
|
|
||||||
|
# ensures cursor is visible again, in case of premature exit
|
||||||
|
trap 'tput cnorm > /dev/tty' EXIT
|
||||||
|
|
||||||
|
while [ -d /proc/$_PID ]; do
|
||||||
|
_elapsed=$(( $(date +%s) - _start ))
|
||||||
|
# use hours only if needed
|
||||||
|
if [ "$_elapsed" -lt 3600 ]; then
|
||||||
|
printf "\r${_spin:_i++%${#_spin}:1} %02d:%02d" $((_elapsed/60)) $((_elapsed%60)) >"$(tty)"
|
||||||
|
else
|
||||||
|
printf "\r${_spin:_i++%${#_spin}:1} %02d:%02d:%02d" $((_elapsed/3600)) $(((_elapsed/60)%60)) $((_elapsed%60)) >"$(tty)"
|
||||||
|
fi
|
||||||
|
sleep 0.25
|
||||||
|
done
|
||||||
|
|
||||||
|
# Return to the begin of the line after completion (the spinner will be overwritten)
|
||||||
|
printf "\r" >"$(tty)"
|
||||||
|
|
||||||
|
# Restore cursor visibility
|
||||||
|
tput cnorm > /dev/tty
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
obfuscated_pihole_log() {
|
obfuscated_pihole_log() {
|
||||||
local pihole_log=("$@")
|
local pihole_log=("$@")
|
||||||
local line
|
local line
|
||||||
@ -1431,7 +1531,7 @@ upload_to_tricorder() {
|
|||||||
if [[ "${WEBCALL}" ]] && [[ ! "${AUTOMATED}" ]]; then
|
if [[ "${WEBCALL}" ]] && [[ ! "${AUTOMATED}" ]]; then
|
||||||
:
|
:
|
||||||
else
|
else
|
||||||
log_write "${CROSS} ${COL_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."
|
log_write " * Please try again or contact the Pi-hole team for assistance."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -1460,6 +1560,7 @@ process_status
|
|||||||
ftl_full_status
|
ftl_full_status
|
||||||
parse_setup_vars
|
parse_setup_vars
|
||||||
check_x_headers
|
check_x_headers
|
||||||
|
analyze_ftl_db
|
||||||
analyze_gravity_list
|
analyze_gravity_list
|
||||||
show_groups
|
show_groups
|
||||||
show_domainlist
|
show_domainlist
|
||||||
|
@ -16,7 +16,6 @@ GRAVITYDB="${piholeDir}/gravity.db"
|
|||||||
options="$*"
|
options="$*"
|
||||||
all=""
|
all=""
|
||||||
exact=""
|
exact=""
|
||||||
blockpage=""
|
|
||||||
matchType="match"
|
matchType="match"
|
||||||
# Source pihole-FTL from install script
|
# Source pihole-FTL from install script
|
||||||
pihole_FTL="${piholeDir}/pihole-FTL.conf"
|
pihole_FTL="${piholeDir}/pihole-FTL.conf"
|
||||||
@ -34,7 +33,7 @@ source "${colfile}"
|
|||||||
# Scan an array of files for matching strings
|
# Scan an array of files for matching strings
|
||||||
scanList(){
|
scanList(){
|
||||||
# Escape full stops
|
# Escape full stops
|
||||||
local domain="${1}" esc_domain="${1//./\\.}" lists="${2}" type="${3:-}"
|
local domain="${1}" esc_domain="${1//./\\.}" lists="${2}" list_type="${3:-}"
|
||||||
|
|
||||||
# Prevent grep from printing file path
|
# Prevent grep from printing file path
|
||||||
cd "$piholeDir" || exit 1
|
cd "$piholeDir" || exit 1
|
||||||
@ -43,7 +42,7 @@ scanList(){
|
|||||||
export LC_CTYPE=C
|
export LC_CTYPE=C
|
||||||
|
|
||||||
# /dev/null forces filename to be printed when only one list has been generated
|
# /dev/null forces filename to be printed when only one list has been generated
|
||||||
case "${type}" in
|
case "${list_type}" in
|
||||||
"exact" ) grep -i -E -l "(^|(?<!#)\\s)${esc_domain}($|\\s|#)" ${lists} /dev/null 2>/dev/null;;
|
"exact" ) grep -i -E -l "(^|(?<!#)\\s)${esc_domain}($|\\s|#)" ${lists} /dev/null 2>/dev/null;;
|
||||||
# Iterate through each regexp and check whether it matches the domainQuery
|
# Iterate through each regexp and check whether it matches the domainQuery
|
||||||
# If it does, print the matching regexp and continue looping
|
# If it does, print the matching regexp and continue looping
|
||||||
@ -71,18 +70,14 @@ Options:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Handle valid options
|
# Handle valid options
|
||||||
if [[ "${options}" == *"-bp"* ]]; then
|
[[ "${options}" == *"-all"* ]] && all=true
|
||||||
exact="exact"; blockpage=true
|
if [[ "${options}" == *"-exact"* ]]; then
|
||||||
else
|
exact="exact"; matchType="exact ${matchType}"
|
||||||
[[ "${options}" == *"-all"* ]] && all=true
|
|
||||||
if [[ "${options}" == *"-exact"* ]]; then
|
|
||||||
exact="exact"; matchType="exact ${matchType}"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Strip valid options, leaving only the domain and invalid options
|
# Strip valid options, leaving only the domain and invalid options
|
||||||
# This allows users to place the options before or after the domain
|
# 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/ ?-(adlists?|all|exact) ?//g' <<< "${options}")
|
||||||
|
|
||||||
# Handle remaining options
|
# Handle remaining options
|
||||||
# If $options contain non ASCII characters, convert to punycode
|
# If $options contain non ASCII characters, convert to punycode
|
||||||
@ -99,10 +94,10 @@ if [[ -n "${str:-}" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
scanDatabaseTable() {
|
scanDatabaseTable() {
|
||||||
local domain table type querystr result extra
|
local domain table list_type querystr result extra
|
||||||
domain="$(printf "%q" "${1}")"
|
domain="$(printf "%q" "${1}")"
|
||||||
table="${2}"
|
table="${2}"
|
||||||
type="${3:-}"
|
list_type="${3:-}"
|
||||||
|
|
||||||
# As underscores are legitimate parts of domains, we escape them when using the LIKE operator.
|
# As underscores are legitimate parts of domains, we escape them when using the LIKE operator.
|
||||||
# Underscores are SQLite wildcards matching exactly one character. We obviously want to suppress this
|
# Underscores are SQLite wildcards matching exactly one character. We obviously want to suppress this
|
||||||
@ -115,8 +110,8 @@ scanDatabaseTable() {
|
|||||||
esac
|
esac
|
||||||
else
|
else
|
||||||
case "${exact}" in
|
case "${exact}" in
|
||||||
"exact" ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${type}' AND domain = '${domain}'";;
|
"exact" ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${list_type}' AND domain = '${domain}'";;
|
||||||
* ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${type}' AND domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
|
* ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${list_type}' AND domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -136,17 +131,11 @@ scanDatabaseTable() {
|
|||||||
wbMatch=true
|
wbMatch=true
|
||||||
|
|
||||||
# Print table name
|
# Print table name
|
||||||
if [[ -z "${blockpage}" ]]; then
|
echo " ${matchType^} found in ${COL_BOLD}exact ${table}${COL_NC}"
|
||||||
echo " ${matchType^} found in ${COL_BOLD}exact ${table}${COL_NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Loop over results and print them
|
# Loop over results and print them
|
||||||
mapfile -t results <<< "${result}"
|
mapfile -t results <<< "${result}"
|
||||||
for result in "${results[@]}"; do
|
for result in "${results[@]}"; do
|
||||||
if [[ -n "${blockpage}" ]]; then
|
|
||||||
echo "π ${result}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
domain="${result/|*}"
|
domain="${result/|*}"
|
||||||
if [[ "${result#*|}" == "0" ]]; then
|
if [[ "${result#*|}" == "0" ]]; then
|
||||||
extra=" (disabled)"
|
extra=" (disabled)"
|
||||||
@ -158,13 +147,13 @@ scanDatabaseTable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scanRegexDatabaseTable() {
|
scanRegexDatabaseTable() {
|
||||||
local domain list
|
local domain list list_type
|
||||||
domain="${1}"
|
domain="${1}"
|
||||||
list="${2}"
|
list="${2}"
|
||||||
type="${3:-}"
|
list_type="${3:-}"
|
||||||
|
|
||||||
# Query all regex from the corresponding database tables
|
# Query all regex from the corresponding database tables
|
||||||
mapfile -t regexList < <(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT domain FROM domainlist WHERE type = ${type}" 2> /dev/null)
|
mapfile -t regexList < <(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT domain FROM domainlist WHERE type = ${list_type}" 2> /dev/null)
|
||||||
|
|
||||||
# If we have regexps to process
|
# If we have regexps to process
|
||||||
if [[ "${#regexList[@]}" -ne 0 ]]; then
|
if [[ "${#regexList[@]}" -ne 0 ]]; then
|
||||||
@ -181,18 +170,13 @@ scanRegexDatabaseTable() {
|
|||||||
# Form a "results" message
|
# Form a "results" message
|
||||||
str_result="${COL_BOLD}${str_regexMatches}${COL_NC}"
|
str_result="${COL_BOLD}${str_regexMatches}${COL_NC}"
|
||||||
# If we are displaying more than just the source of the block
|
# If we are displaying more than just the source of the block
|
||||||
if [[ -z "${blockpage}" ]]; then
|
# Set the wildcard match flag
|
||||||
# Set the wildcard match flag
|
wcMatch=true
|
||||||
wcMatch=true
|
# Echo the "matched" message, indented by one space
|
||||||
# Echo the "matched" message, indented by one space
|
echo " ${str_message}"
|
||||||
echo " ${str_message}"
|
# Echo the "results" message, each line indented by three spaces
|
||||||
# Echo the "results" message, each line indented by three spaces
|
# shellcheck disable=SC2001
|
||||||
# shellcheck disable=SC2001
|
echo "${str_result}" | sed 's/^/ /'
|
||||||
echo "${str_result}" | sed 's/^/ /'
|
|
||||||
else
|
|
||||||
echo "π .wildcard"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -222,7 +206,7 @@ elif [[ -z "${all}" ]] && [[ "${#results[*]}" -ge 100 ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Print "Exact matches for" title
|
# Print "Exact matches for" title
|
||||||
if [[ -n "${exact}" ]] && [[ -z "${blockpage}" ]]; then
|
if [[ -n "${exact}" ]]; then
|
||||||
plural=""; [[ "${#results[*]}" -gt 1 ]] && plural="es"
|
plural=""; [[ "${#results[*]}" -gt 1 ]] && plural="es"
|
||||||
echo " ${matchType^}${plural} for ${COL_BOLD}${domainQuery}${COL_NC} found in:"
|
echo " ${matchType^}${plural} for ${COL_BOLD}${domainQuery}${COL_NC} found in:"
|
||||||
fi
|
fi
|
||||||
@ -238,9 +222,7 @@ for result in "${results[@]}"; do
|
|||||||
extra=""
|
extra=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "${blockpage}" ]]; then
|
if [[ -n "${exact}" ]]; then
|
||||||
echo "0 ${adlistAddress}"
|
|
||||||
elif [[ -n "${exact}" ]]; then
|
|
||||||
echo " - ${adlistAddress}${extra}"
|
echo " - ${adlistAddress}${extra}"
|
||||||
else
|
else
|
||||||
if [[ ! "${adlistAddress}" == "${adlistAddress_prev:-}" ]]; then
|
if [[ ! "${adlistAddress}" == "${adlistAddress_prev:-}" ]]; then
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
#!/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.
|
|
||||||
#
|
|
||||||
# Automatically configures the Pi to use the 2.8 LCD screen to display stats on it (also works over ssh)
|
|
||||||
#
|
|
||||||
# This file is copyright under the latest version of the EUPL.
|
|
||||||
# Please see LICENSE file for your rights under this license.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
############ FUNCTIONS ###########
|
|
||||||
|
|
||||||
# Borrowed from adafruit-pitft-helper < borrowed from raspi-config
|
|
||||||
# https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L324-L334
|
|
||||||
getInitSys() {
|
|
||||||
if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
|
|
||||||
SYSTEMD=1
|
|
||||||
elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
|
|
||||||
SYSTEMD=0
|
|
||||||
else
|
|
||||||
echo "Unrecognized init system"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Borrowed from adafruit-pitft-helper:
|
|
||||||
# https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L274-L285
|
|
||||||
autoLoginPiToConsole() {
|
|
||||||
if [ -e /etc/init.d/lightdm ]; then
|
|
||||||
if [ ${SYSTEMD} -eq 1 ]; then
|
|
||||||
systemctl set-default multi-user.target
|
|
||||||
ln -fs /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/getty@tty1.service
|
|
||||||
else
|
|
||||||
update-rc.d lightdm disable 2
|
|
||||||
sed /etc/inittab -i -e "s/1:2345:respawn:\/sbin\/getty --noclear 38400 tty1/1:2345:respawn:\/bin\/login -f pi tty1 <\/dev\/tty1 >\/dev\/tty1 2>&1/"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
######### SCRIPT ###########
|
|
||||||
# Set pi to log in automatically
|
|
||||||
getInitSys
|
|
||||||
autoLoginPiToConsole
|
|
||||||
|
|
||||||
# Set chronomter to run automatically when pi logs in
|
|
||||||
echo /usr/local/bin/chronometer.sh >> /home/pi/.bashrc
|
|
||||||
# OR
|
|
||||||
#$SUDO echo /usr/local/bin/chronometer.sh >> /etc/profile
|
|
||||||
|
|
||||||
# Set up the LCD screen based on Adafruits instructions:
|
|
||||||
# https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi/easy-install
|
|
||||||
curl -SLs https://apt.adafruit.com/add-pin | bash
|
|
||||||
apt-get -y install raspberrypi-bootloader
|
|
||||||
apt-get -y install adafruit-pitft-helper
|
|
||||||
adafruit-pitft-helper -t 28r
|
|
||||||
|
|
||||||
# Download the cmdline.txt file that prevents the screen from going blank after a period of time
|
|
||||||
mv /boot/cmdline.txt /boot/cmdline.orig
|
|
||||||
curl -o /boot/cmdline.txt https://raw.githubusercontent.com/pi-hole/pi-hole/master/advanced/cmdline.txt
|
|
||||||
|
|
||||||
# Back up the original file and download the new one
|
|
||||||
mv /etc/default/console-setup /etc/default/console-setup.orig
|
|
||||||
curl -o /etc/default/console-setup https://raw.githubusercontent.com/pi-hole/pi-hole/master/advanced/console-setup
|
|
||||||
|
|
||||||
# Instantly apply the font change to the LCD screen
|
|
||||||
setupcon
|
|
||||||
|
|
||||||
reboot
|
|
||||||
|
|
||||||
# Start showing the stats on the screen by running the command on another tty:
|
|
||||||
# https://unix.stackexchange.com/questions/170063/start-a-process-on-a-different-tty
|
|
||||||
#setsid sh -c 'exec /usr/local/bin/chronometer.sh <> /dev/tty1 >&0 2>&1'
|
|
@ -8,23 +8,6 @@
|
|||||||
# This file is copyright under the latest version of the EUPL.
|
# This file is copyright under the latest version of the EUPL.
|
||||||
# Please see LICENSE file for your rights under this license.
|
# 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() {
|
function get_local_branch() {
|
||||||
# Return active branch
|
# Return active branch
|
||||||
cd "${1}" 2> /dev/null || return 1
|
cd "${1}" 2> /dev/null || return 1
|
||||||
@ -41,54 +24,64 @@ function get_local_version() {
|
|||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
. /etc/pihole/setupVars.conf
|
. /etc/pihole/setupVars.conf
|
||||||
|
|
||||||
|
# Source the utils file
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. /opt/pihole/utils.sh
|
||||||
|
|
||||||
|
# Remove the below three legacy files if they exist
|
||||||
|
rm -f "/etc/pihole/GitHubVersions"
|
||||||
|
rm -f "/etc/pihole/localbranches"
|
||||||
|
rm -f "/etc/pihole/localversions"
|
||||||
|
|
||||||
|
# Create new versions file if it does not exist
|
||||||
|
VERSION_FILE="/etc/pihole/versions"
|
||||||
|
touch "${VERSION_FILE}"
|
||||||
|
chmod 644 "${VERSION_FILE}"
|
||||||
|
|
||||||
if [[ "$2" == "remote" ]]; then
|
if [[ "$2" == "remote" ]]; then
|
||||||
|
|
||||||
if [[ "$3" == "reboot" ]]; then
|
if [[ "$3" == "reboot" ]]; then
|
||||||
sleep 30
|
sleep 30
|
||||||
fi
|
fi
|
||||||
|
|
||||||
GITHUB_VERSION_FILE="/etc/pihole/GitHubVersions"
|
GITHUB_CORE_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/pi-hole/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||||
|
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_VERSION" "${GITHUB_CORE_VERSION}"
|
||||||
GITHUB_CORE_VERSION="$(json_extract tag_name "$(curl -s 'https://api.github.com/repos/pi-hole/pi-hole/releases/latest' 2> /dev/null)")"
|
|
||||||
echo -n "${GITHUB_CORE_VERSION}" > "${GITHUB_VERSION_FILE}"
|
|
||||||
chmod 644 "${GITHUB_VERSION_FILE}"
|
|
||||||
|
|
||||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||||
GITHUB_WEB_VERSION="$(json_extract tag_name "$(curl -s 'https://api.github.com/repos/pi-hole/AdminLTE/releases/latest' 2> /dev/null)")"
|
GITHUB_WEB_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/AdminLTE/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||||
echo -n " ${GITHUB_WEB_VERSION}" >> "${GITHUB_VERSION_FILE}"
|
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_VERSION" "${GITHUB_WEB_VERSION}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
GITHUB_FTL_VERSION="$(json_extract tag_name "$(curl -s 'https://api.github.com/repos/pi-hole/FTL/releases/latest' 2> /dev/null)")"
|
GITHUB_FTL_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/FTL/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||||
echo -n " ${GITHUB_FTL_VERSION}" >> "${GITHUB_VERSION_FILE}"
|
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_VERSION" "${GITHUB_FTL_VERSION}"
|
||||||
|
|
||||||
|
if [[ "${PIHOLE_DOCKER_TAG}" ]]; then
|
||||||
|
GITHUB_DOCKER_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/docker-pi-hole/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||||
|
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_DOCKER_VERSION" "${GITHUB_DOCKER_VERSION}"
|
||||||
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
LOCAL_BRANCH_FILE="/etc/pihole/localbranches"
|
|
||||||
|
|
||||||
CORE_BRANCH="$(get_local_branch /etc/.pihole)"
|
CORE_BRANCH="$(get_local_branch /etc/.pihole)"
|
||||||
echo -n "${CORE_BRANCH}" > "${LOCAL_BRANCH_FILE}"
|
addOrEditKeyValPair "${VERSION_FILE}" "CORE_BRANCH" "${CORE_BRANCH}"
|
||||||
chmod 644 "${LOCAL_BRANCH_FILE}"
|
|
||||||
|
|
||||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||||
WEB_BRANCH="$(get_local_branch /var/www/html/admin)"
|
WEB_BRANCH="$(get_local_branch /var/www/html/admin)"
|
||||||
echo -n " ${WEB_BRANCH}" >> "${LOCAL_BRANCH_FILE}"
|
addOrEditKeyValPair "${VERSION_FILE}" "WEB_BRANCH" "${WEB_BRANCH}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
FTL_BRANCH="$(pihole-FTL branch)"
|
FTL_BRANCH="$(pihole-FTL branch)"
|
||||||
echo -n " ${FTL_BRANCH}" >> "${LOCAL_BRANCH_FILE}"
|
addOrEditKeyValPair "${VERSION_FILE}" "FTL_BRANCH" "${FTL_BRANCH}"
|
||||||
|
|
||||||
LOCAL_VERSION_FILE="/etc/pihole/localversions"
|
|
||||||
|
|
||||||
CORE_VERSION="$(get_local_version /etc/.pihole)"
|
CORE_VERSION="$(get_local_version /etc/.pihole)"
|
||||||
echo -n "${CORE_VERSION}" > "${LOCAL_VERSION_FILE}"
|
addOrEditKeyValPair "${VERSION_FILE}" "CORE_VERSION" "${CORE_VERSION}"
|
||||||
chmod 644 "${LOCAL_VERSION_FILE}"
|
|
||||||
|
|
||||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||||
WEB_VERSION="$(get_local_version /var/www/html/admin)"
|
WEB_VERSION="$(get_local_version /var/www/html/admin)"
|
||||||
echo -n " ${WEB_VERSION}" >> "${LOCAL_VERSION_FILE}"
|
addOrEditKeyValPair "${VERSION_FILE}" "WEB_VERSION" "${WEB_VERSION}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
FTL_VERSION="$(pihole-FTL version)"
|
FTL_VERSION="$(pihole-FTL version)"
|
||||||
echo -n " ${FTL_VERSION}" >> "${LOCAL_VERSION_FILE}"
|
addOrEditKeyValPair "${VERSION_FILE}" "FTL_VERSION" "${FTL_VERSION}"
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
@ -71,28 +71,87 @@ removeKey() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
# returns FTL's current telnet API port
|
# returns path of FTL's port file
|
||||||
|
#######################
|
||||||
|
getFTLAPIPortFile() {
|
||||||
|
local FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
|
||||||
|
local DEFAULT_PORT_FILE="/run/pihole-FTL.port"
|
||||||
|
local FTL_APIPORT_FILE
|
||||||
|
|
||||||
|
if [ -s "${FTLCONFFILE}" ]; then
|
||||||
|
# if PORTFILE is not set in pihole-FTL.conf, use the default path
|
||||||
|
FTL_APIPORT_FILE="$({ grep '^PORTFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PORT_FILE}"; } | cut -d'=' -f2-)"
|
||||||
|
else
|
||||||
|
# if there is no pihole-FTL.conf, use the default path
|
||||||
|
FTL_APIPORT_FILE="${DEFAULT_PORT_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${FTL_APIPORT_FILE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#######################
|
||||||
|
# returns FTL's current telnet API port based on the content of the pihole-FTL.port file
|
||||||
|
#
|
||||||
|
# Takes one argument: path to pihole-FTL.port
|
||||||
|
# Example getFTLAPIPort "/run/pihole-FTL.port"
|
||||||
#######################
|
#######################
|
||||||
getFTLAPIPort(){
|
getFTLAPIPort(){
|
||||||
local FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
|
local PORTFILE="${1}"
|
||||||
local DEFAULT_PORT_FILE="/run/pihole-FTL.port"
|
local DEFAULT_FTL_PORT=4711
|
||||||
local DEFAULT_FTL_PORT=4711
|
local ftl_api_port
|
||||||
local PORTFILE
|
|
||||||
local ftl_api_port
|
|
||||||
|
|
||||||
if [ -f "$FTLCONFFILE" ]; then
|
if [ -s "$PORTFILE" ]; then
|
||||||
# if PORTFILE is not set in pihole-FTL.conf, use the default path
|
# -s: FILE exists and has a size greater than zero
|
||||||
PORTFILE="$( (grep "^PORTFILE=" $FTLCONFFILE || echo "$DEFAULT_PORT_FILE") | cut -d"=" -f2-)"
|
ftl_api_port=$(cat "${PORTFILE}")
|
||||||
fi
|
# Exploit prevention: unset the variable if there is malicious content
|
||||||
|
# Verify that the value read from the file is numeric
|
||||||
|
expr "$ftl_api_port" : "[^[:digit:]]" > /dev/null && unset ftl_api_port
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -s "$PORTFILE" ]; then
|
# echo the port found in the portfile or default to the default port
|
||||||
# -s: FILE exists and has a size greater than zero
|
echo "${ftl_api_port:=$DEFAULT_FTL_PORT}"
|
||||||
ftl_api_port=$(cat "${PORTFILE}")
|
}
|
||||||
# Exploit prevention: unset the variable if there is malicious content
|
|
||||||
# Verify that the value read from the file is numeric
|
#######################
|
||||||
expr "$ftl_api_port" : "[^[:digit:]]" > /dev/null && unset ftl_api_port
|
# returns path of FTL's PID file
|
||||||
fi
|
#######################
|
||||||
|
getFTLPIDFile() {
|
||||||
# echo the port found in the portfile or default to the default port
|
local FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
|
||||||
echo "${ftl_api_port:=$DEFAULT_FTL_PORT}"
|
local DEFAULT_PID_FILE="/run/pihole-FTL.pid"
|
||||||
|
local FTL_PID_FILE
|
||||||
|
|
||||||
|
if [ -s "${FTLCONFFILE}" ]; then
|
||||||
|
# if PIDFILE is not set in pihole-FTL.conf, use the default path
|
||||||
|
FTL_PID_FILE="$({ grep '^PIDFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PID_FILE}"; } | cut -d'=' -f2-)"
|
||||||
|
else
|
||||||
|
# if there is no pihole-FTL.conf, use the default path
|
||||||
|
FTL_PID_FILE="${DEFAULT_PID_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${FTL_PID_FILE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
#######################
|
||||||
|
# returns FTL's PID based on the content of the pihole-FTL.pid file
|
||||||
|
#
|
||||||
|
# Takes one argument: path to pihole-FTL.pid
|
||||||
|
# Example getFTLPID "/run/pihole-FTL.pid"
|
||||||
|
#######################
|
||||||
|
getFTLPID() {
|
||||||
|
local FTL_PID_FILE="${1}"
|
||||||
|
local FTL_PID
|
||||||
|
|
||||||
|
if [ -s "${FTL_PID_FILE}" ]; then
|
||||||
|
# -s: FILE exists and has a size greater than zero
|
||||||
|
FTL_PID="$(cat "${FTL_PID_FILE}")"
|
||||||
|
# Exploit prevention: unset the variable if there is malicious content
|
||||||
|
# Verify that the value read from the file is numeric
|
||||||
|
expr "${FTL_PID}" : "[^[:digit:]]" > /dev/null && unset FTL_PID
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If FTL is not running, or the PID file contains malicious stuff, substitute
|
||||||
|
# negative PID to signal this
|
||||||
|
FTL_PID=${FTL_PID:=-1}
|
||||||
|
echo "${FTL_PID}"
|
||||||
}
|
}
|
||||||
|
@ -89,17 +89,18 @@ getRemoteVersion(){
|
|||||||
local daemon="${1}"
|
local daemon="${1}"
|
||||||
local version
|
local version
|
||||||
local cachedVersions
|
local cachedVersions
|
||||||
local arrCache
|
cachedVersions="/etc/pihole/versions"
|
||||||
cachedVersions="/etc/pihole/GitHubVersions"
|
|
||||||
|
|
||||||
#If the above file exists, then we can read from that. Prevents overuse of GitHub API
|
#If the above file exists, then we can read from that. Prevents overuse of GitHub API
|
||||||
if [[ -f "$cachedVersions" ]]; then
|
if [[ -f "$cachedVersions" ]]; then
|
||||||
IFS=' ' read -r -a arrCache < "$cachedVersions"
|
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
. "$cachedVersions"
|
||||||
|
|
||||||
case $daemon in
|
case $daemon in
|
||||||
"pi-hole" ) echo "${arrCache[0]}";;
|
"pi-hole" ) echo "${GITHUB_CORE_VERSION}";;
|
||||||
"AdminLTE" ) [[ "${INSTALL_WEB_INTERFACE}" == true ]] && echo "${arrCache[1]}";;
|
"AdminLTE" ) [[ "${INSTALL_WEB_INTERFACE}" == true ]] && echo "${GITHUB_WEB_VERSION}";;
|
||||||
"FTL" ) [[ "${INSTALL_WEB_INTERFACE}" == true ]] && echo "${arrCache[2]}" || echo "${arrCache[1]}";;
|
"FTL" ) echo "${GITHUB_FTL_VERSION}";;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -46,7 +46,6 @@ Options:
|
|||||||
-c, celsius Set Celsius as preferred temperature unit
|
-c, celsius Set Celsius as preferred temperature unit
|
||||||
-f, fahrenheit Set Fahrenheit as preferred temperature unit
|
-f, fahrenheit Set Fahrenheit as preferred temperature unit
|
||||||
-k, kelvin Set Kelvin as preferred temperature unit
|
-k, kelvin Set Kelvin as preferred temperature unit
|
||||||
-e, email Set an administrative contact address for the Block Page
|
|
||||||
-h, --help Show this help dialog
|
-h, --help Show this help dialog
|
||||||
-i, interface Specify dnsmasq's interface listening behavior
|
-i, interface Specify dnsmasq's interface listening behavior
|
||||||
-l, privacylevel Set privacy level (0 = lowest, 3 = highest)
|
-l, privacylevel Set privacy level (0 = lowest, 3 = highest)
|
||||||
@ -568,37 +567,6 @@ RemoveDHCPStaticAddress() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetAdminEmail() {
|
|
||||||
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
|
|
||||||
|
|
||||||
Options:
|
|
||||||
\"\" Empty: Remove admin contact
|
|
||||||
-h, --help Show this help dialog"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "${args[2]}" ]]; then
|
|
||||||
|
|
||||||
# Sanitize email address in case of security issues
|
|
||||||
# Regex from https://stackoverflow.com/a/2138832/4065967
|
|
||||||
local regex
|
|
||||||
regex="^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\$"
|
|
||||||
if [[ ! "${args[2]}" =~ ${regex} ]]; then
|
|
||||||
echo -e " ${CROSS} Invalid email address"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
addOrEditKeyValPair "${setupVars}" "ADMIN_EMAIL" "${args[2]}"
|
|
||||||
echo -e " ${TICK} Setting admin contact to ${args[2]}"
|
|
||||||
else
|
|
||||||
addOrEditKeyValPair "${setupVars}" "ADMIN_EMAIL" ""
|
|
||||||
echo -e " ${TICK} Removing admin contact"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
SetListeningMode() {
|
SetListeningMode() {
|
||||||
source "${setupVars}"
|
source "${setupVars}"
|
||||||
|
|
||||||
@ -847,7 +815,6 @@ main() {
|
|||||||
"-h" | "--help" ) helpFunc;;
|
"-h" | "--help" ) helpFunc;;
|
||||||
"addstaticdhcp" ) AddDHCPStaticAddress;;
|
"addstaticdhcp" ) AddDHCPStaticAddress;;
|
||||||
"removestaticdhcp" ) RemoveDHCPStaticAddress;;
|
"removestaticdhcp" ) RemoveDHCPStaticAddress;;
|
||||||
"-e" | "email" ) SetAdminEmail "$3";;
|
|
||||||
"-i" | "interface" ) SetListeningMode "$@";;
|
"-i" | "interface" ) SetListeningMode "$@";;
|
||||||
"-t" | "teleporter" ) Teleporter;;
|
"-t" | "teleporter" ) Teleporter;;
|
||||||
"adlist" ) CustomizeAdLists;;
|
"adlist" ) CustomizeAdLists;;
|
||||||
|
@ -9,48 +9,10 @@
|
|||||||
# Description: Enable service provided by pihole-FTL daemon
|
# Description: Enable service provided by pihole-FTL daemon
|
||||||
### END INIT INFO
|
### END INIT INFO
|
||||||
|
|
||||||
# Global variables
|
#source utils.sh for getFTLPIDFile(), getFTLPID (), getFTLAPIPortFile()
|
||||||
FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
|
PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
||||||
DEFAULT_PID_FILE="/run/pihole-FTL.pid"
|
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||||
DEFAULT_PORT_FILE="/run/pihole-FTL.port"
|
. "${utilsfile}"
|
||||||
FTL_PID=''
|
|
||||||
|
|
||||||
# Get the file path of the pihole-FTL.pid file
|
|
||||||
getFTLPIDFile() {
|
|
||||||
if [ -s "${FTLCONFFILE}" ]; then
|
|
||||||
# if PIDFILE is not set in pihole-FTL.conf, use the default path
|
|
||||||
FTL_PID_FILE="$({ grep '^PIDFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PID_FILE}"; } | cut -d'=' -f2-)"
|
|
||||||
else
|
|
||||||
# if there is no pihole-FTL.conf, use the default path
|
|
||||||
FTL_PID_FILE="${DEFAULT_PID_FILE}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the PID of the FTL process based on the content of the pihole-FTL.pid file
|
|
||||||
getFTLPID() {
|
|
||||||
if [ -s "${FTL_PID_FILE}" ]; then
|
|
||||||
# -s: FILE exists and has a size greater than zero
|
|
||||||
FTL_PID="$(cat "${FTL_PID_FILE}")"
|
|
||||||
# Exploit prevention: unset the variable if there is malicious content
|
|
||||||
# Verify that the value read from the file is numeric
|
|
||||||
expr "${FTL_PID}" : "[^[:digit:]]" > /dev/null && unset FTL_PID
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If FTL is not running, or the PID file contains malicious stuff, substitute
|
|
||||||
# negative PID to signal this
|
|
||||||
FTL_PID=${FTL_PID:=-1}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the file path of the pihole-FTL.port file
|
|
||||||
getFTLPortFile() {
|
|
||||||
if [ -s "${FTLCONFFILE}" ]; then
|
|
||||||
# if PORTFILE is not set in pihole-FTL.conf, use the default path
|
|
||||||
FTL_PORT_FILE="$({ grep '^PORTFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PORT_FILE}"; } | cut -d'=' -f2-)"
|
|
||||||
else
|
|
||||||
# if there is no pihole-FTL.conf, use the default path
|
|
||||||
FTL_PORT_FILE="${DEFAULT_PORT_FILE}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
is_running() {
|
is_running() {
|
||||||
@ -68,8 +30,8 @@ start() {
|
|||||||
else
|
else
|
||||||
# Touch files to ensure they exist (create if non-existing, preserve if existing)
|
# Touch files to ensure they exist (create if non-existing, preserve if existing)
|
||||||
mkdir -pm 0755 /run/pihole /var/log/pihole
|
mkdir -pm 0755 /run/pihole /var/log/pihole
|
||||||
[ ! -f "${FTL_PID_FILE}" ] && install -m 644 -o pihole -g pihole /dev/null "${FTL_PID_FILE}"
|
[ ! -f "${FTL_PID_FILE}" ] && install -D -m 644 -o pihole -g pihole /dev/null "${FTL_PID_FILE}"
|
||||||
[ ! -f "${FTL_PORT_FILE}" ] && install -m 644 -o pihole -g pihole /dev/null "${FTL_PORT_FILE}"
|
[ ! -f "${FTL_PORT_FILE}" ] && install -D -m 644 -o pihole -g pihole /dev/null "${FTL_PORT_FILE}"
|
||||||
[ ! -f /var/log/pihole/FTL.log ] && install -m 644 -o pihole -g pihole /dev/null /var/log/pihole/FTL.log
|
[ ! -f /var/log/pihole/FTL.log ] && install -m 644 -o pihole -g pihole /dev/null /var/log/pihole/FTL.log
|
||||||
[ ! -f /var/log/pihole/pihole.log ] && install -m 640 -o pihole -g pihole /dev/null /var/log/pihole/pihole.log
|
[ ! -f /var/log/pihole/pihole.log ] && install -m 640 -o pihole -g pihole /dev/null /var/log/pihole/pihole.log
|
||||||
[ ! -f /etc/pihole/dhcp.leases ] && install -m 644 -o pihole -g pihole /dev/null /etc/pihole/dhcp.leases
|
[ ! -f /etc/pihole/dhcp.leases ] && install -m 644 -o pihole -g pihole /dev/null /etc/pihole/dhcp.leases
|
||||||
@ -96,10 +58,10 @@ start() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if setcap CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN,CAP_SYS_NICE,CAP_IPC_LOCK,CAP_CHOWN+eip "/usr/bin/pihole-FTL"; then
|
if setcap CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN,CAP_SYS_NICE,CAP_IPC_LOCK,CAP_CHOWN+eip "/usr/bin/pihole-FTL"; then
|
||||||
su -s /bin/sh -c "/usr/bin/pihole-FTL" pihole
|
su -s /bin/sh -c "/usr/bin/pihole-FTL" pihole || exit $?
|
||||||
else
|
else
|
||||||
echo "Warning: Starting pihole-FTL as root because setting capabilities is not supported on this system"
|
echo "Warning: Starting pihole-FTL as root because setting capabilities is not supported on this system"
|
||||||
/usr/bin/pihole-FTL
|
/usr/bin/pihole-FTL || exit $?
|
||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
@ -148,11 +110,11 @@ status() {
|
|||||||
### main logic ###
|
### main logic ###
|
||||||
|
|
||||||
# Get file paths
|
# Get file paths
|
||||||
getFTLPIDFile
|
FTL_PID_FILE="$(getFTLPIDFile)"
|
||||||
getFTLPortFile
|
FTL_PORT_FILE="$(getFTLAPIPortFile)"
|
||||||
|
|
||||||
# Get FTL's current PID
|
# Get FTL's current PID
|
||||||
getFTLPID
|
FTL_PID="$(getFTLPID ${FTL_PID_FILE})"
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
stop)
|
stop)
|
||||||
|
@ -15,7 +15,7 @@ _pihole() {
|
|||||||
COMPREPLY=( $(compgen -W "${opts_lists}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts_lists}" -- ${cur}) )
|
||||||
;;
|
;;
|
||||||
"admin")
|
"admin")
|
||||||
opts_admin="celsius email fahrenheit interface kelvin password privacylevel"
|
opts_admin="celsius fahrenheit interface kelvin password privacylevel"
|
||||||
COMPREPLY=( $(compgen -W "${opts_admin}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts_admin}" -- ${cur}) )
|
||||||
;;
|
;;
|
||||||
"checkout")
|
"checkout")
|
||||||
|
@ -1,455 +0,0 @@
|
|||||||
/* 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.
|
|
||||||
*
|
|
||||||
* This file is copyright under the latest version of the EUPL.
|
|
||||||
* Please see LICENSE file for your rights under this license. */
|
|
||||||
|
|
||||||
/* Text Customisation Options ======> */
|
|
||||||
.title::before { content: "Website Blocked"; }
|
|
||||||
.altBtn::before { content: "Why am I here?"; }
|
|
||||||
.linkPH::before { content: "About Pi-hole"; }
|
|
||||||
.linkEmail::before { content: "Contact Admin"; }
|
|
||||||
|
|
||||||
#bpOutput.add::before { content: "Info"; }
|
|
||||||
#bpOutput.add::after { content: "The domain is being whitelisted..."; }
|
|
||||||
#bpOutput.error::before, .unhandled::before { content: "Error"; }
|
|
||||||
#bpOutput.unhandled::after { content: "An unhandled exception occurred. This may happen when your browser is unable to load jQuery, or when the webserver is denying access to the Pi-hole API."; }
|
|
||||||
#bpOutput.success::before { content: "Success"; }
|
|
||||||
#bpOutput.success::after { content: "Website has been whitelisted! You may need to flush your DNS cache"; }
|
|
||||||
|
|
||||||
.recentwl::before { content: "This site has been whitelisted. Please flush your DNS cache and/or restart your browser."; }
|
|
||||||
.unknown::before { content: "This website is not found in any of Pi-hole's blacklists. The reason you have arrived here is unknown."; }
|
|
||||||
.cname::before { content: "This site is an alias for "; } /* <a href="http://cname.com">cname.com</a> */
|
|
||||||
.cname::after { content: ", which may be blocked by Pi-hole."; }
|
|
||||||
|
|
||||||
.blacklist::before { content: "Manually Blacklisted"; }
|
|
||||||
.wildcard::before { content: "Manually Blacklisted by Wildcard"; }
|
|
||||||
.noblock::before { content: "Not found on any Blacklist"; }
|
|
||||||
|
|
||||||
#bpBlock::before { content: "Access to the following website has been denied:"; }
|
|
||||||
#bpFlag::before { content: "This is primarily due to being flagged as:"; }
|
|
||||||
|
|
||||||
#bpHelpTxt::before { content: "If you have an ongoing use for this website, please "; }
|
|
||||||
#bpHelpTxt a::before, #bpHelpTxt span::before { content: "ask the administrator"; }
|
|
||||||
#bpHelpTxt::after{ content: " of the Pi-hole on this network to have it whitelisted"; }
|
|
||||||
|
|
||||||
#bpBack::before { content: "Back to safety"; }
|
|
||||||
#bpInfo::before { content: "Technical Info"; }
|
|
||||||
#bpFoundIn::before { content: "This site is found in "; }
|
|
||||||
#bpFoundIn span::after { content: " of "; }
|
|
||||||
#bpFoundIn::after { content: " lists:"; }
|
|
||||||
#bpWhitelist::before { content: "Whitelist"; }
|
|
||||||
|
|
||||||
footer span::before { content: "Page generated on "; }
|
|
||||||
|
|
||||||
/* Hide whitelisting form entirely */
|
|
||||||
/* #bpWLButtons { display: none; } */
|
|
||||||
|
|
||||||
/* Text Customisation Options <=============================== */
|
|
||||||
|
|
||||||
/* http://necolas.github.io/normalize.css ======> */
|
|
||||||
html { font-family: sans-serif; line-height: 1.15; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; }
|
|
||||||
body { margin: 0; }
|
|
||||||
article, aside, footer, header, nav, section { display: block; }
|
|
||||||
h1 { font-size: 2em; margin: 0.67em 0; }
|
|
||||||
figcaption, figure, main { display: block; }
|
|
||||||
figure { margin: 1em 40px; }
|
|
||||||
hr { box-sizing: content-box; height: 0; overflow: visible; }
|
|
||||||
pre { font-family: monospace, monospace; font-size: 1em; }
|
|
||||||
a { background-color: transparent; -webkit-text-decoration-skip: objects; }
|
|
||||||
a:active, a:hover { outline-width: 0; }
|
|
||||||
abbr[title] { border-bottom: none; text-decoration: underline; text-decoration: underline dotted; }
|
|
||||||
b, strong { font-weight: inherit; }
|
|
||||||
b, strong { font-weight: bolder; }
|
|
||||||
code, kbd, samp { font-family: monospace, monospace; font-size: 1em; }
|
|
||||||
dfn { font-style: italic; }
|
|
||||||
mark { background-color: #ff0; color: #000; }
|
|
||||||
small { font-size: 80%; }
|
|
||||||
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
|
|
||||||
sub { bottom: -0.25em; }
|
|
||||||
sup { top: -0.5em; }
|
|
||||||
audio, video { display: inline-block; }
|
|
||||||
audio:not([controls]) { display: none; height: 0; }
|
|
||||||
img { border-style: none; }
|
|
||||||
svg:not(:root) { overflow: hidden; }
|
|
||||||
button, input, optgroup, select, textarea { font-family: sans-serif; font-size: 100%; line-height: 1.15; margin: 0; }
|
|
||||||
button, input { overflow: visible; }
|
|
||||||
button, select { text-transform: none; }
|
|
||||||
button, html [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; }
|
|
||||||
button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { border-style: none; padding: 0; }
|
|
||||||
button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; }
|
|
||||||
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
|
|
||||||
legend { box-sizing: border-box; color: inherit; display: table; max-width: 100%; padding: 0; white-space: normal; }
|
|
||||||
progress { display: inline-block; vertical-align: baseline; }
|
|
||||||
textarea { overflow: auto; }
|
|
||||||
[type="checkbox"], [type="radio"] { box-sizing: border-box; padding: 0; }
|
|
||||||
[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; }
|
|
||||||
[type="search"] { -webkit-appearance: textfield; outline-offset: -2px; }
|
|
||||||
[type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
|
|
||||||
::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; }
|
|
||||||
details, menu { display: block; }
|
|
||||||
summary { display: list-item; }
|
|
||||||
canvas { display: inline-block; }
|
|
||||||
template { display: none; }
|
|
||||||
[hidden] { display: none; }
|
|
||||||
/* Normalize.css <=============================== */
|
|
||||||
|
|
||||||
html { font-size: 62.5%; }
|
|
||||||
|
|
||||||
a { color: #3c8dbc; text-decoration: none; }
|
|
||||||
a:hover { color: #72afda; text-decoration: underline; }
|
|
||||||
b { color: rgb(68, 68, 68); }
|
|
||||||
p { margin: 0; }
|
|
||||||
|
|
||||||
label, .buttons a {
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
label, .buttons *:not([disabled]) { cursor: pointer; }
|
|
||||||
|
|
||||||
/* Touch device dark tap highlight */
|
|
||||||
header h1 a, label, .buttons * { -webkit-tap-highlight-color: transparent; }
|
|
||||||
|
|
||||||
/* Webkit Focus Glow */
|
|
||||||
textarea, input, button { outline: none; }
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Source Sans Pro";
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
font-display: swap;
|
|
||||||
src: local("Source Sans Pro Regular"), local("SourceSansPro-Regular"),
|
|
||||||
url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-regular.woff2") format("woff2"),
|
|
||||||
url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-regular.woff") format("woff");
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Source Sans Pro";
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 700;
|
|
||||||
font-display: swap;
|
|
||||||
src: local("Source Sans Pro Bold"), local("SourceSansPro-Bold"),
|
|
||||||
url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-700.woff2") format("woff2"),
|
|
||||||
url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-700.woff") format("woff");
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background: #dbdbdb url("/admin/img/boxed-bg.jpg") repeat fixed;
|
|
||||||
color: #333;
|
|
||||||
font: 1.4rem "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
line-height: 2.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* User is greeted with a splash page when browsing to Pi-hole IP address */
|
|
||||||
#splashpage {
|
|
||||||
background: #222;
|
|
||||||
color: rgba(255, 255, 255, 0.7);
|
|
||||||
text-align: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#splashpage img { margin: 5px; width: 256px; }
|
|
||||||
#splashpage b { color: inherit; }
|
|
||||||
|
|
||||||
#bpWrapper {
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width: 1250px;
|
|
||||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
background: #3c8dbc;
|
|
||||||
display: table;
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
header h1, header h1 a, header .spc, header #bpAlt label {
|
|
||||||
display: table-cell;
|
|
||||||
color: #fff;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: middle;
|
|
||||||
height: 50px; /* Must match #bpAbout top value */
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 a {
|
|
||||||
background-color: rgba(0, 0, 0, 0.1);
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 2rem;
|
|
||||||
font-weight: 400;
|
|
||||||
min-width: 230px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 a:hover, header #bpAlt:hover { background-color: rgba(0, 0, 0, 0.12); color: inherit; text-decoration: none; }
|
|
||||||
|
|
||||||
header .spc { width: 100%; }
|
|
||||||
|
|
||||||
header #bpAlt label {
|
|
||||||
background: url("/admin/img/logo.svg") no-repeat center left 15px;
|
|
||||||
background-size: 15px 23px;
|
|
||||||
padding: 0 15px;
|
|
||||||
text-indent: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
[type="checkbox"][id$="Toggle"] { display: none; }
|
|
||||||
[type="checkbox"][id$="Toggle"]:checked ~ #bpAbout,
|
|
||||||
[type="checkbox"][id$="Toggle"]:checked ~ #bpMoreInfo {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
html, body {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pihole_card {
|
|
||||||
width: 400px;
|
|
||||||
height: auto;
|
|
||||||
max-width: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pihole_card p, #pihole_card a {
|
|
||||||
font-size: 13pt;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pihole_logo_splash {
|
|
||||||
height: auto;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Click anywhere else on screen to hide #bpAbout */
|
|
||||||
#bpAboutToggle:checked {
|
|
||||||
display: block;
|
|
||||||
height: 300px; /* VH Fallback */
|
|
||||||
height: 100vh;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
opacity: 0;
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bpAbout {
|
|
||||||
background: #3c8dbc;
|
|
||||||
border-bottom-left-radius: 5px;
|
|
||||||
border: 1px solid #fff;
|
|
||||||
border-right-width: 0;
|
|
||||||
box-shadow: -1px 1px 1px rgba(0, 0, 0, 0.12);
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: none;
|
|
||||||
font-size: 1.7rem;
|
|
||||||
top: 50px;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
width: 280px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.aboutPH {
|
|
||||||
box-sizing: border-box;
|
|
||||||
color: rgba(255, 255, 255, 0.8);
|
|
||||||
display: block;
|
|
||||||
padding: 10px;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.aboutImg {
|
|
||||||
background: url("/admin/img/logo.svg") no-repeat center;
|
|
||||||
background-size: 90px 90px;
|
|
||||||
height: 90px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 2px;
|
|
||||||
width: 90px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.aboutPH p { margin: 10px 0; }
|
|
||||||
.aboutPH small { display: block; font-size: 1.2rem; }
|
|
||||||
|
|
||||||
.aboutLink {
|
|
||||||
background: #fff;
|
|
||||||
border-top: 1px solid #ddd;
|
|
||||||
display: table;
|
|
||||||
font-size: 1.4rem;
|
|
||||||
text-align: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.aboutLink a {
|
|
||||||
display: table-cell;
|
|
||||||
padding: 14px;
|
|
||||||
min-width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
background: #ecf0f5;
|
|
||||||
font-size: 1.65rem;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bpOutput {
|
|
||||||
background: #00c0ef;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.4rem;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
margin-top: 5px;
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bpOutput::before {
|
|
||||||
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='14' viewBox='0 0 7 14'%3E%3Cpath fill='%23fff' d='M6 11a1.371 1.371 0 011 1v1a1.371 1.371 0 01-1 1H1a1.371 1.371 0 01-1-1v-1a1.371 1.371 0 011-1h1V8H1a1.371 1.371 0 01-1-1V6a1.371 1.371 0 011-1h3a1.371 1.371 0 011 1v5h1zM3.5 0A1.5 1.5 0 112 1.5 1.5 1.5 0 013.5 0z'/%3E%3C/svg%3E") no-repeat center left;
|
|
||||||
display: block;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
text-indent: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bpOutput.hidden { display: none; }
|
|
||||||
#bpOutput.success { background: #00a65a; }
|
|
||||||
#bpOutput.error { background: #dd4b39; }
|
|
||||||
|
|
||||||
.blockMsg, .flagMsg {
|
|
||||||
font: 700 1.8rem Consolas, Courier, monospace;
|
|
||||||
padding: 5px 10px 10px;
|
|
||||||
text-indent: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bpHelpTxt { padding-bottom: 10px; }
|
|
||||||
|
|
||||||
.buttons {
|
|
||||||
border-spacing: 5px 0;
|
|
||||||
display: table;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons * {
|
|
||||||
-moz-appearance: none;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
box-sizing: content-box;
|
|
||||||
display: table-cell;
|
|
||||||
font-size: 1.65rem;
|
|
||||||
margin-right: 5px;
|
|
||||||
min-height: 20px;
|
|
||||||
padding: 6px 12px;
|
|
||||||
position: relative;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: top;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons a:hover { text-decoration: none; }
|
|
||||||
|
|
||||||
/* Button hover dark overlay */
|
|
||||||
.buttons *:not(input):not([disabled]):hover {
|
|
||||||
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1));
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Button active shadow inset */
|
|
||||||
.buttons *:not([disabled]):not(input):active {
|
|
||||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Input border color */
|
|
||||||
.buttons *:not([disabled]):hover, .buttons input:focus {
|
|
||||||
border-color: rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
#bpButtons * { width: 50%; color: #fff; }
|
|
||||||
#bpBack { background-color: #00a65a; }
|
|
||||||
#bpInfo { background-color: #3c8dbc; }
|
|
||||||
#bpWhitelist { background-color: #dd4b39; }
|
|
||||||
|
|
||||||
#blockpage .buttons [type="password"][disabled] { color: rgba(0, 0, 0, 1); }
|
|
||||||
#blockpage .buttons [disabled] { color: rgba(0, 0, 0, 0.55); background-color: #e3e3e3; }
|
|
||||||
#blockpage .buttons [type="password"]:-ms-input-placeholder { color: rgba(51, 51, 51, 0.8); }
|
|
||||||
|
|
||||||
input[type="password"] { font-size: 1.5rem; }
|
|
||||||
|
|
||||||
@-webkit-keyframes slidein { from { max-height: 0; opacity: 0; } to { max-height: 300px; opacity: 1; } }
|
|
||||||
|
|
||||||
@keyframes slidein { from { max-height: 0; opacity: 0; } to { max-height: 300px; opacity: 1; } }
|
|
||||||
#bpMoreToggle:checked ~ #bpMoreInfo { display: block; margin-top: 8px; -webkit-animation: slidein 0.05s linear; animation: slidein 0.05s linear; }
|
|
||||||
#bpMoreInfo { display: none; margin-top: 10px; }
|
|
||||||
|
|
||||||
#bpQueryOutput {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
line-height: 1.65rem;
|
|
||||||
margin: 5px 0 0;
|
|
||||||
overflow: auto;
|
|
||||||
padding: 0 5px;
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bpQueryOutput span { margin-right: 4px; }
|
|
||||||
|
|
||||||
#bpWLButtons { width: auto; margin-top: 10px; }
|
|
||||||
#bpWLButtons * { display: inline-block; }
|
|
||||||
#bpWLDomain { display: none; }
|
|
||||||
#bpWLPassword { width: 160px; }
|
|
||||||
#bpWhitelist { color: #fff; }
|
|
||||||
|
|
||||||
footer {
|
|
||||||
background: #fff;
|
|
||||||
border-top: 1px solid #d2d6de;
|
|
||||||
color: #444;
|
|
||||||
font: 1.2rem Consolas, Courier, monospace;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive Content */
|
|
||||||
@media only screen and (max-width: 500px) {
|
|
||||||
h1 a {
|
|
||||||
font-size: 1.8rem;
|
|
||||||
min-width: 170px;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer span::before {
|
|
||||||
content: "Generated ";
|
|
||||||
}
|
|
||||||
|
|
||||||
footer span {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 1251px) {
|
|
||||||
#bpWrapper, footer {
|
|
||||||
border-radius: 0 0 5px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bpAbout {
|
|
||||||
border-right-width: 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 400px) {
|
|
||||||
#pihole_card {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pihole_card p, #pihole_card a {
|
|
||||||
font-size: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 256px) {
|
|
||||||
#pihole_logo_splash {
|
|
||||||
width: 90% !important;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait fbcon=map:10 fbcon=font:VGA8x8 consoleblank=0
|
|
@ -1,17 +0,0 @@
|
|||||||
# CONFIGURATION FILE FOR SETUPCON
|
|
||||||
|
|
||||||
# Consult the console-setup(5) manual page.
|
|
||||||
|
|
||||||
ACTIVE_CONSOLES="/dev/tty[1-6]"
|
|
||||||
|
|
||||||
CHARMAP="UTF-8"
|
|
||||||
|
|
||||||
# For best results with the Adafruit 2.8 LCD and Pi-hole's chronometer
|
|
||||||
CODESET="guess"
|
|
||||||
FONTFACE="Terminus"
|
|
||||||
FONTSIZE="10x20"
|
|
||||||
|
|
||||||
VIDEOMODE=
|
|
||||||
|
|
||||||
# The following is an example how to use a braille font
|
|
||||||
# FONT='lat9w-08.psf.gz brl-8x8.psf'
|
|
@ -11,15 +11,6 @@ $serverName = htmlspecialchars($_SERVER["SERVER_NAME"]);
|
|||||||
// Remove external ipv6 brackets if any
|
// Remove external ipv6 brackets if any
|
||||||
$serverName = preg_replace('/^\[(.*)\]$/', '${1}', $serverName);
|
$serverName = preg_replace('/^\[(.*)\]$/', '${1}', $serverName);
|
||||||
|
|
||||||
if (!is_file("/etc/pihole/setupVars.conf"))
|
|
||||||
die("[ERROR] File not found: <code>/etc/pihole/setupVars.conf</code>");
|
|
||||||
|
|
||||||
// Get values from setupVars.conf
|
|
||||||
$setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
|
|
||||||
$svPasswd = !empty($setupVars["WEBPASSWORD"]);
|
|
||||||
$svEmail = (!empty($setupVars["ADMIN_EMAIL"]) && filter_var($setupVars["ADMIN_EMAIL"], FILTER_VALIDATE_EMAIL)) ? $setupVars["ADMIN_EMAIL"] : "";
|
|
||||||
unset($setupVars);
|
|
||||||
|
|
||||||
// Set landing page location, found within /var/www/html/
|
// Set landing page location, found within /var/www/html/
|
||||||
$landPage = "../landing.php";
|
$landPage = "../landing.php";
|
||||||
|
|
||||||
@ -34,21 +25,6 @@ if (!empty($_SERVER["FQDN"])) {
|
|||||||
array_push($authorizedHosts, $_SERVER["VIRTUAL_HOST"]);
|
array_push($authorizedHosts, $_SERVER["VIRTUAL_HOST"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Set mobile friendly viewport
|
|
||||||
$viewPort = '<meta name="viewport" content="width=device-width, initial-scale=1">';
|
|
||||||
|
|
||||||
// Set response header
|
|
||||||
function setHeader($type = "x") {
|
|
||||||
header("X-Pi-hole: A black hole for Internet advertisements.");
|
|
||||||
if (isset($type) && $type === "js") header("Content-Type: application/javascript");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine block page type
|
// Determine block page type
|
||||||
if ($serverName === "pi.hole"
|
if ($serverName === "pi.hole"
|
||||||
|| (!empty($_SERVER["VIRTUAL_HOST"]) && $serverName === $_SERVER["VIRTUAL_HOST"])) {
|
|| (!empty($_SERVER["VIRTUAL_HOST"]) && $serverName === $_SERVER["VIRTUAL_HOST"])) {
|
||||||
@ -58,7 +34,7 @@ if ($serverName === "pi.hole"
|
|||||||
// When directly browsing via IP or authorized hostname
|
// When directly browsing via IP or authorized hostname
|
||||||
// Render splash/landing page based off presence of $landPage file
|
// Render splash/landing page based off presence of $landPage file
|
||||||
// Unset variables so as to not be included in $landPage or $splashPage
|
// Unset variables so as to not be included in $landPage or $splashPage
|
||||||
unset($svPasswd, $svEmail, $authorizedHosts, $validExtTypes, $currentUrlExt);
|
unset($authorizedHosts);
|
||||||
// If $landPage file is present
|
// If $landPage file is present
|
||||||
if (is_file(getcwd()."/$landPage")) {
|
if (is_file(getcwd()."/$landPage")) {
|
||||||
unset($serverName, $viewPort); // unset extra variables not to be included in $landpage
|
unset($serverName, $viewPort); // unset extra variables not to be included in $landpage
|
||||||
@ -71,347 +47,34 @@ if ($serverName === "pi.hole"
|
|||||||
<html lang='en'>
|
<html lang='en'>
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
$viewPort
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<title>● $serverName</title>
|
<title>● $serverName</title>
|
||||||
<link rel='stylesheet' href='/pihole/blockingpage.css'>
|
|
||||||
<link rel='shortcut icon' href='/admin/img/favicons/favicon.ico' type='image/x-icon'>
|
<link rel='shortcut icon' href='/admin/img/favicons/favicon.ico' type='image/x-icon'>
|
||||||
|
<style>
|
||||||
|
html, body { height: 100% }
|
||||||
|
body { margin: 0; font: 13pt "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; }
|
||||||
|
body { background: #222; color: rgba(255, 255, 255, 0.7); text-align: center; }
|
||||||
|
p { margin: 0; }
|
||||||
|
a { color: #3c8dbc; text-decoration: none; }
|
||||||
|
a:hover { color: #72afda; text-decoration: underline; }
|
||||||
|
#splashpage { display: flex; align-items: center; justify-content: center; }
|
||||||
|
#splashpage img { margin: 5px; width: 256px; }
|
||||||
|
#splashpage b { color: inherit; }
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body id='splashpage'>
|
<body id='splashpage'>
|
||||||
<div id="pihole_card">
|
<div>
|
||||||
<img src='/admin/img/logo.svg' alt='Pi-hole logo' id="pihole_logo_splash" />
|
<img src='/admin/img/logo.svg' alt='Pi-hole logo' width='256' height='377'>
|
||||||
<p>Pi-<strong>hole</strong>: Your black hole for Internet advertisements</p>
|
<br>
|
||||||
<a href='/admin'>Did you mean to go to the admin panel?</a>
|
<p>Pi-<strong>hole</strong>: Your black hole for Internet advertisements</p>
|
||||||
|
<a href='/admin'>Did you mean to go to the admin panel?</a>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
EOT;
|
EOT;
|
||||||
exit($splashPage);
|
exit($splashPage);
|
||||||
} elseif ($currentUrlExt === "js") {
|
|
||||||
// Serve Pi-hole JavaScript for blocked domains requesting JS
|
|
||||||
exit(setHeader("js").'var x = "Pi-hole: A black hole for Internet advertisements."');
|
|
||||||
} 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
|
|
||||||
exit(setHeader().'<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8"><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, 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">
|
|
||||||
<circle cx="8" cy="8" r="7" fill="none" stroke="rgba(152,2,2,.5)" stroke-width="2"/>
|
|
||||||
<path fill="rgba(152,2,2,.5)" d="M11.526 3.04l1.414 1.415-8.485 8.485-1.414-1.414z"/>
|
|
||||||
<text x="19.3" y="12" opacity=".3" style="font:11px Arial">
|
|
||||||
Blocked by Pi-hole
|
|
||||||
</text>
|
|
||||||
</svg>
|
|
||||||
</a>';
|
|
||||||
exit(setHeader()."<!doctype html>
|
|
||||||
<html lang='en'>
|
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'>
|
|
||||||
$viewPort
|
|
||||||
</head>
|
|
||||||
<body>$blockImg</body>
|
|
||||||
</html>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start processing Block Page from here */
|
exit(header("HTTP/1.1 404 Not Found"));
|
||||||
|
|
||||||
// Define admin email address text based off $svEmail presence
|
|
||||||
$bpAskAdmin = !empty($svEmail) ? '<a href="mailto:'.$svEmail.'?subject=Site Blocked: '.$serverName.'"></a>' : "<span/>";
|
|
||||||
|
|
||||||
// Get possible non-standard location of FTL's database
|
|
||||||
$FTLsettings = parse_ini_file("/etc/pihole/pihole-FTL.conf");
|
|
||||||
if (isset($FTLsettings["GRAVITYDB"])) {
|
|
||||||
$gravityDBFile = $FTLsettings["GRAVITYDB"];
|
|
||||||
} else {
|
|
||||||
$gravityDBFile = "/etc/pihole/gravity.db";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect to gravity.db
|
|
||||||
try {
|
|
||||||
$db = new SQLite3($gravityDBFile, SQLITE3_OPEN_READONLY);
|
|
||||||
} catch (Exception $exception) {
|
|
||||||
die("[ERROR]: Failed to connect to gravity.db");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all adlist addresses
|
|
||||||
$adlistResults = $db->query("SELECT address FROM vw_adlist");
|
|
||||||
$adlistsUrls = array();
|
|
||||||
while ($row = $adlistResults->fetchArray()) {
|
|
||||||
array_push($adlistsUrls, $row[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($adlistsUrls))
|
|
||||||
die("[ERROR]: There are no adlists enabled");
|
|
||||||
|
|
||||||
// Get total number of blocklists (Including Whitelist, Blacklist & Wildcard lists)
|
|
||||||
$adlistsCount = count($adlistsUrls) + 3;
|
|
||||||
|
|
||||||
// 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"];
|
|
||||||
|
|
||||||
// Determine which protocol should be used
|
|
||||||
$protocol = "http";
|
|
||||||
if ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ||
|
|
||||||
(isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https') ||
|
|
||||||
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
|
|
||||||
) {
|
|
||||||
$protocol = "https";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format the URL
|
|
||||||
$queryAdsURL = sprintf(
|
|
||||||
"%s://127.0.0.1:%s/admin/scripts/pi-hole/php/queryads.php?domain=%s&bp",
|
|
||||||
$protocol,
|
|
||||||
$_SERVER["SERVER_PORT"],
|
|
||||||
$serverName
|
|
||||||
);
|
|
||||||
|
|
||||||
// Request the file and receive the response
|
|
||||||
$queryAdsFile = file($queryAdsURL, FILE_IGNORE_NEW_LINES);
|
|
||||||
|
|
||||||
// $queryAdsFile must be an array (to avoid PHP 8.0+ error)
|
|
||||||
if (is_array($queryAdsFile)) {
|
|
||||||
$queryAds = array_values(array_filter(preg_replace("/data:\s+/", "", $queryAdsFile)));
|
|
||||||
} else {
|
|
||||||
// if not an array, return an error message
|
|
||||||
return array("0" => "error", "1" => "<br>(".gettype($queryAdsFile).")<br>".print_r($queryAdsFile, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
$queryTime = sprintf("%.0f", (microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"]) - $preQueryTime);
|
|
||||||
|
|
||||||
// Exception Handling
|
|
||||||
try {
|
|
||||||
// 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) {
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// 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>");
|
|
||||||
|
|
||||||
// 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
|
|
||||||
if (strpos($queryAds[0], "blacklist") !== FALSE) {
|
|
||||||
$notableFlagClass = "blacklist";
|
|
||||||
$adlistsUrls = array("π" => substr($queryAds[0], 2));
|
|
||||||
} elseif (strpos($queryAds[0], "whitelist") !== FALSE) {
|
|
||||||
$notableFlagClass = "noblock";
|
|
||||||
$adlistsUrls = array("π" => substr($queryAds[0], 2));
|
|
||||||
$wlInfo = "recentwl";
|
|
||||||
} elseif (strpos($queryAds[0], "wildcard") !== FALSE) {
|
|
||||||
$notableFlagClass = "wildcard";
|
|
||||||
$adlistsUrls = array("π" => substr($queryAds[0], 2));
|
|
||||||
} elseif ($queryAds[0] === "none") {
|
|
||||||
$featuredTotal = "0";
|
|
||||||
$notableFlagClass = "noblock";
|
|
||||||
|
|
||||||
// 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'];
|
|
||||||
} else {
|
|
||||||
$wlInfo = "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set #bpOutput notification
|
|
||||||
$wlOutputClass = (isset($wlInfo) && $wlInfo === "recentwl") ? $wlInfo : "hidden";
|
|
||||||
$wlOutput = (isset($wlInfo) && $wlInfo !== "recentwl") ? "<a href='http://$wlInfo'>$wlInfo</a>" : "";
|
|
||||||
|
|
||||||
// Get Pi-hole Core version
|
|
||||||
$phVersion = exec("cd /etc/.pihole/ && git describe --long --tags");
|
|
||||||
|
|
||||||
// Print $execTime on development branches
|
|
||||||
// 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 localized
|
|
||||||
// language without the need to edit this file
|
|
||||||
|
|
||||||
setHeader();
|
|
||||||
?>
|
?>
|
||||||
<!doctype html>
|
|
||||||
<!-- 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.
|
|
||||||
*
|
|
||||||
* This file is copyright under the latest version of the EUPL. -->
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<?=$viewPort ?>
|
|
||||||
<meta name="robots" content="noindex,nofollow">
|
|
||||||
<meta http-equiv="x-dns-prefetch-control" content="off">
|
|
||||||
<link rel="stylesheet" href="pihole/blockingpage.css">
|
|
||||||
<link rel="shortcut icon" href="admin/img/favicons/favicon.ico" type="image/x-icon">
|
|
||||||
<title>● <?=$serverName ?></title>
|
|
||||||
<script src="admin/scripts/vendor/jquery.min.js"></script>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
<?php
|
|
||||||
// Remove href fallback from "Back to safety" button
|
|
||||||
if ($featuredTotal > 0) {
|
|
||||||
echo '$("#bpBack").removeAttr("href");';
|
|
||||||
|
|
||||||
// Enable whitelisting if JS is available
|
|
||||||
echo '$("#bpWhitelist").prop("disabled", false);';
|
|
||||||
|
|
||||||
// Enable password input if necessary
|
|
||||||
if (!empty($svPasswd)) {
|
|
||||||
echo '$("#bpWLPassword").attr("placeholder", "Password");';
|
|
||||||
echo '$("#bpWLPassword").prop("disabled", false);';
|
|
||||||
}
|
|
||||||
// Otherwise hide the input
|
|
||||||
else {
|
|
||||||
echo '$("#bpWLPassword").hide();';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body id="blockpage"><div id="bpWrapper">
|
|
||||||
<header>
|
|
||||||
<h1 id="bpTitle">
|
|
||||||
<a class="title" href="/"><?php //Website Blocked ?></a>
|
|
||||||
</h1>
|
|
||||||
<div class="spc"></div>
|
|
||||||
|
|
||||||
<input id="bpAboutToggle" type="checkbox">
|
|
||||||
<div id="bpAbout">
|
|
||||||
<div class="aboutPH">
|
|
||||||
<div class="aboutImg"></div>
|
|
||||||
<p>Open Source Ad Blocker
|
|
||||||
<small>Designed for Raspberry Pi</small>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="aboutLink">
|
|
||||||
<a class="linkPH" href="https://docs.pi-hole.net/"><?php //About PH ?></a>
|
|
||||||
<?php if (!empty($svEmail)) echo '<a class="linkEmail" href="mailto:'.$svEmail.'"></a>'; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="bpAlt">
|
|
||||||
<label class="altBtn" for="bpAboutToggle"><?php //Why am I here? ?></label>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<div id="bpOutput" class="<?=$wlOutputClass ?>"><?=$wlOutput ?></div>
|
|
||||||
<div id="bpBlock">
|
|
||||||
<p class="blockMsg"><?=$serverName ?></p>
|
|
||||||
</div>
|
|
||||||
<?php if(isset($notableFlagClass)) { ?>
|
|
||||||
<div id="bpFlag">
|
|
||||||
<p class="flagMsg <?=$notableFlagClass ?>"></p>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
<div id="bpHelpTxt"><?=$bpAskAdmin ?></div>
|
|
||||||
<div id="bpButtons" class="buttons">
|
|
||||||
<a id="bpBack" onclick="javascript:history.back()" href="about:home"></a>
|
|
||||||
<?php if ($featuredTotal > 0) echo '<label id="bpInfo" for="bpMoreToggle"></label>'; ?>
|
|
||||||
</div>
|
|
||||||
<input id="bpMoreToggle" type="checkbox">
|
|
||||||
<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="JavaScript disabled" disabled>
|
|
||||||
<button id="bpWhitelist" type="button" disabled></button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer><span><?=date("l g:i A, F dS"); ?>.</span> Pi-hole <?=$phVersion ?> (<?=gethostname()."/".$_SERVER["SERVER_ADDR"]; if (isset($execTime)) printf("/%.2fs", $execTime); ?>)</footer>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function add() {
|
|
||||||
$("#bpOutput").removeClass("hidden error exception");
|
|
||||||
$("#bpOutput").addClass("add");
|
|
||||||
var domain = "<?=$serverName ?>";
|
|
||||||
var pw = $("#bpWLPassword");
|
|
||||||
if(domain.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$.ajax({
|
|
||||||
url: "/admin/scripts/pi-hole/php/add.php",
|
|
||||||
method: "post",
|
|
||||||
data: {"domain":domain, "list":"white", "pw":pw.val()},
|
|
||||||
success: function(response) {
|
|
||||||
if(response.indexOf("Pi-hole blocking") !== -1) {
|
|
||||||
setTimeout(function(){window.location.reload(1);}, 10000);
|
|
||||||
$("#bpOutput").removeClass("add");
|
|
||||||
$("#bpOutput").addClass("success");
|
|
||||||
$("#bpOutput").html("");
|
|
||||||
} else {
|
|
||||||
$("#bpOutput").removeClass("add");
|
|
||||||
$("#bpOutput").addClass("error");
|
|
||||||
$("#bpOutput").html(""+response+"");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function(jqXHR, exception) {
|
|
||||||
$("#bpOutput").removeClass("add");
|
|
||||||
$("#bpOutput").addClass("exception");
|
|
||||||
$("#bpOutput").html("");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
<?php if ($featuredTotal > 0) { ?>
|
|
||||||
$(document).keypress(function(e) {
|
|
||||||
if(e.which === 13 && $("#bpWLPassword").is(":focus")) {
|
|
||||||
add();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$("#bpWhitelist").on("click", function() {
|
|
||||||
add();
|
|
||||||
});
|
|
||||||
<?php } ?>
|
|
||||||
</script>
|
|
||||||
</body></html>
|
|
||||||
|
@ -78,10 +78,21 @@ include_shell "find /etc/lighttpd/conf-enabled -name '*.conf' -a ! -name 'letsen
|
|||||||
|
|
||||||
# If the URL starts with /admin, it is the Web interface
|
# If the URL starts with /admin, it is the Web interface
|
||||||
$HTTP["url"] =~ "^/admin/" {
|
$HTTP["url"] =~ "^/admin/" {
|
||||||
# Create a response header for debugging using curl -I
|
# X-Pi-hole is a response header for debugging using curl -I
|
||||||
|
# X-Frame-Options prevents clickjacking attacks and helps ensure your content is not embedded into other sites via < frame >, < iframe > or < object >.
|
||||||
|
# X-XSS-Protection sets the configuration for the cross-site scripting filters built into most browsers. This is important because it tells the browser to block the response if a malicious script has been inserted from a user input.
|
||||||
|
# X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. This is important because the browser will only load external resources if their content-type matches what is expected, and not malicious hidden code.
|
||||||
|
# Content-Security-Policy tells the browser where resources are allowed to be loaded and if it’s allowed to parse/run inline styles or Javascript. This is important because it prevents content injection attacks, such as Cross Site Scripting (XSS).
|
||||||
|
# X-Permitted-Cross-Domain-Policies is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains.
|
||||||
|
# Referrer-Policy allows control/restriction of the amount of information present in the referral header for links away from your page—the URL path or even if the header is sent at all.
|
||||||
setenv.add-response-header = (
|
setenv.add-response-header = (
|
||||||
"X-Pi-hole" => "The Pi-hole Web interface is working!",
|
"X-Pi-hole" => "The Pi-hole Web interface is working!",
|
||||||
"X-Frame-Options" => "DENY"
|
"X-Frame-Options" => "DENY",
|
||||||
|
"X-XSS-Protection" => "1; mode=block",
|
||||||
|
"X-Content-Type-Options" => "nosniff",
|
||||||
|
"Content-Security-Policy" => "default-src 'self' 'unsafe-inline';",
|
||||||
|
"X-Permitted-Cross-Domain-Policies" => "none",
|
||||||
|
"Referrer-Policy" => "same-origin"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,10 +86,21 @@ fastcgi.server = (
|
|||||||
|
|
||||||
# If the URL starts with /admin, it is the Web interface
|
# If the URL starts with /admin, it is the Web interface
|
||||||
$HTTP["url"] =~ "^/admin/" {
|
$HTTP["url"] =~ "^/admin/" {
|
||||||
# Create a response header for debugging using curl -I
|
# X-Pi-hole is a response header for debugging using curl -I
|
||||||
|
# X-Frame-Options prevents clickjacking attacks and helps ensure your content is not embedded into other sites via < frame >, < iframe > or < object >.
|
||||||
|
# X-XSS-Protection sets the configuration for the cross-site scripting filters built into most browsers. This is important because it tells the browser to block the response if a malicious script has been inserted from a user input.
|
||||||
|
# X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. This is important because the browser will only load external resources if their content-type matches what is expected, and not malicious hidden code.
|
||||||
|
# Content-Security-Policy tells the browser where resources are allowed to be loaded and if it’s allowed to parse/run inline styles or Javascript. This is important because it prevents content injection attacks, such as Cross Site Scripting (XSS).
|
||||||
|
# X-Permitted-Cross-Domain-Policies is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains.
|
||||||
|
# Referrer-Policy allows control/restriction of the amount of information present in the referral header for links away from your page—the URL path or even if the header is sent at all.
|
||||||
setenv.add-response-header = (
|
setenv.add-response-header = (
|
||||||
"X-Pi-hole" => "The Pi-hole Web interface is working!",
|
"X-Pi-hole" => "The Pi-hole Web interface is working!",
|
||||||
"X-Frame-Options" => "DENY"
|
"X-Frame-Options" => "DENY",
|
||||||
|
"X-XSS-Protection" => "1; mode=block",
|
||||||
|
"X-Content-Type-Options" => "nosniff",
|
||||||
|
"Content-Security-Policy" => "default-src 'self' 'unsafe-inline';",
|
||||||
|
"X-Permitted-Cross-Domain-Policies" => "none",
|
||||||
|
"Referrer-Policy" => "same-origin"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update versi
|
|||||||
PI_HOLE_INSTALL_DIR="/opt/pihole"
|
PI_HOLE_INSTALL_DIR="/opt/pihole"
|
||||||
PI_HOLE_CONFIG_DIR="/etc/pihole"
|
PI_HOLE_CONFIG_DIR="/etc/pihole"
|
||||||
PI_HOLE_BIN_DIR="/usr/local/bin"
|
PI_HOLE_BIN_DIR="/usr/local/bin"
|
||||||
PI_HOLE_BLOCKPAGE_DIR="${webroot}/pihole"
|
PI_HOLE_404_DIR="${webroot}/pihole"
|
||||||
if [ -z "$useUpdateVars" ]; then
|
if [ -z "$useUpdateVars" ]; then
|
||||||
useUpdateVars=false
|
useUpdateVars=false
|
||||||
fi
|
fi
|
||||||
@ -330,7 +330,7 @@ package_manager_detect() {
|
|||||||
# Packages required to run this install script (stored as an array)
|
# Packages required to run this install script (stored as an array)
|
||||||
INSTALLER_DEPS=(git iproute2 dialog ca-certificates)
|
INSTALLER_DEPS=(git iproute2 dialog ca-certificates)
|
||||||
# Packages required to run Pi-hole (stored as an array)
|
# Packages required to run Pi-hole (stored as an array)
|
||||||
PIHOLE_DEPS=(cron curl iputils-ping psmisc sudo unzip idn2 libcap2-bin dns-root-data libcap2 netcat-openbsd procps)
|
PIHOLE_DEPS=(cron curl iputils-ping psmisc sudo unzip idn2 libcap2-bin dns-root-data libcap2 netcat-openbsd procps jq)
|
||||||
# Packages required for the Web admin interface (stored as an array)
|
# Packages required for the Web admin interface (stored as an array)
|
||||||
# It's useful to separate this from Pi-hole, since the two repos are also setup separately
|
# It's useful to separate this from Pi-hole, since the two repos are also setup separately
|
||||||
PIHOLE_WEB_DEPS=(lighttpd "${phpVer}-common" "${phpVer}-cgi" "${phpVer}-sqlite3" "${phpVer}-xml" "${phpVer}-intl")
|
PIHOLE_WEB_DEPS=(lighttpd "${phpVer}-common" "${phpVer}-cgi" "${phpVer}-sqlite3" "${phpVer}-xml" "${phpVer}-intl")
|
||||||
@ -360,12 +360,27 @@ package_manager_detect() {
|
|||||||
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l || true"
|
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l || true"
|
||||||
OS_CHECK_DEPS=(grep bind-utils)
|
OS_CHECK_DEPS=(grep bind-utils)
|
||||||
INSTALLER_DEPS=(git dialog iproute newt procps-ng which chkconfig ca-certificates)
|
INSTALLER_DEPS=(git dialog iproute newt procps-ng which chkconfig ca-certificates)
|
||||||
PIHOLE_DEPS=(cronie curl findutils sudo unzip libidn2 psmisc libcap nmap-ncat)
|
PIHOLE_DEPS=(cronie curl findutils sudo unzip libidn2 psmisc libcap nmap-ncat jq)
|
||||||
PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php-common php-cli php-pdo php-xml php-json php-intl)
|
PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php-common php-cli php-pdo php-xml php-json php-intl)
|
||||||
LIGHTTPD_USER="lighttpd"
|
LIGHTTPD_USER="lighttpd"
|
||||||
LIGHTTPD_GROUP="lighttpd"
|
LIGHTTPD_GROUP="lighttpd"
|
||||||
LIGHTTPD_CFG="lighttpd.conf.fedora"
|
LIGHTTPD_CFG="lighttpd.conf.fedora"
|
||||||
|
|
||||||
|
# If the host OS is centos (or a derivative), epel is required for lighttpd
|
||||||
|
if ! grep -qiE 'fedora|fedberry' /etc/redhat-release; then
|
||||||
|
if rpm -qa | grep -qi 'epel'; then
|
||||||
|
printf " %b EPEL repository already installed\\n" "${TICK}"
|
||||||
|
else
|
||||||
|
local RH_RELEASE EPEL_PKG
|
||||||
|
# EPEL not already installed, add it based on the release version
|
||||||
|
RH_RELEASE=$(grep -oP '(?<= )[0-9]+(?=\.?)' /etc/redhat-release)
|
||||||
|
EPEL_PKG="https://dl.fedoraproject.org/pub/epel/epel-release-latest-${RH_RELEASE}.noarch.rpm"
|
||||||
|
printf " %b Enabling EPEL package repository (https://fedoraproject.org/wiki/EPEL)\\n" "${INFO}"
|
||||||
|
"${PKG_INSTALL[@]}" "${EPEL_PKG}"
|
||||||
|
printf " %b Installed %s\\n" "${TICK}" "${EPEL_PKG}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# If neither apt-get or yum/dnf package managers were found
|
# If neither apt-get or yum/dnf package managers were found
|
||||||
else
|
else
|
||||||
# we cannot install required packages
|
# we cannot install required packages
|
||||||
@ -375,144 +390,6 @@ package_manager_detect() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
select_rpm_php(){
|
|
||||||
# If the host OS is Fedora,
|
|
||||||
if grep -qiE 'fedora|fedberry' /etc/redhat-release; then
|
|
||||||
# all required packages should be available by default with the latest fedora release
|
|
||||||
: # continue
|
|
||||||
# or if host OS is CentOS,
|
|
||||||
elif grep -qiE 'centos|scientific' /etc/redhat-release; then
|
|
||||||
# Pi-Hole currently supports CentOS 7+ with PHP7+
|
|
||||||
SUPPORTED_CENTOS_VERSION=7
|
|
||||||
SUPPORTED_CENTOS_PHP_VERSION=7
|
|
||||||
# Check current CentOS major release version
|
|
||||||
CURRENT_CENTOS_VERSION=$(grep -oP '(?<= )[0-9]+(?=\.?)' /etc/redhat-release)
|
|
||||||
# Check if CentOS version is supported
|
|
||||||
if [[ $CURRENT_CENTOS_VERSION -lt $SUPPORTED_CENTOS_VERSION ]]; then
|
|
||||||
printf " %b CentOS %s is not supported.\\n" "${CROSS}" "${CURRENT_CENTOS_VERSION}"
|
|
||||||
printf " Please update to CentOS release %s or later.\\n" "${SUPPORTED_CENTOS_VERSION}"
|
|
||||||
# exit the installer
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
# php-json is not required on CentOS 7 as it is already compiled into php
|
|
||||||
# verify via `php -m | grep json`
|
|
||||||
if [[ $CURRENT_CENTOS_VERSION -eq 7 ]]; then
|
|
||||||
# create a temporary array as arrays are not designed for use as mutable data structures
|
|
||||||
CENTOS7_PIHOLE_WEB_DEPS=()
|
|
||||||
for i in "${!PIHOLE_WEB_DEPS[@]}"; do
|
|
||||||
if [[ ${PIHOLE_WEB_DEPS[i]} != "php-json" ]]; then
|
|
||||||
CENTOS7_PIHOLE_WEB_DEPS+=( "${PIHOLE_WEB_DEPS[i]}" )
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# re-assign the clean dependency array back to PIHOLE_WEB_DEPS
|
|
||||||
PIHOLE_WEB_DEPS=("${CENTOS7_PIHOLE_WEB_DEPS[@]}")
|
|
||||||
unset CENTOS7_PIHOLE_WEB_DEPS
|
|
||||||
fi
|
|
||||||
|
|
||||||
if rpm -qa | grep -qi 'epel'; then
|
|
||||||
printf " %b EPEL repository already installed\\n" "${TICK}"
|
|
||||||
else
|
|
||||||
# CentOS requires the EPEL repository to gain access to Fedora packages
|
|
||||||
if [[ CURRENT_CENTOS_VERSION -eq 7 ]]; then
|
|
||||||
EPEL_PKG="https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm"
|
|
||||||
elif [[ CURRENT_CENTOS_VERSION -eq 8 ]]; then
|
|
||||||
EPEL_PKG="https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm"
|
|
||||||
fi
|
|
||||||
printf " %b Enabling EPEL package repository (https://fedoraproject.org/wiki/EPEL)\\n" "${INFO}"
|
|
||||||
"${PKG_INSTALL[@]}" ${EPEL_PKG}
|
|
||||||
printf " %b Installed %s\\n" "${TICK}" "${EPEL_PKG}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# The default php on CentOS 7.x is 5.4 which is EOL
|
|
||||||
# Check if the version of PHP available via installed repositories is >= to PHP 7
|
|
||||||
AVAILABLE_PHP_VERSION=$("${PKG_MANAGER}" info php | grep -i version | grep -o '[0-9]\+' | head -1)
|
|
||||||
if [[ $AVAILABLE_PHP_VERSION -ge $SUPPORTED_CENTOS_PHP_VERSION ]]; then
|
|
||||||
# Since PHP 7 is available by default, install via default PHP package names
|
|
||||||
: # do nothing as PHP is current
|
|
||||||
printf "PHP 7 is installed"
|
|
||||||
else
|
|
||||||
REMI_PKG="remi-release"
|
|
||||||
REMI_REPO="remi-php72"
|
|
||||||
REMI_REPO_URL="https://rpms.remirepo.net/enterprise/${REMI_PKG}-$(rpm -E '%{rhel}').rpm"
|
|
||||||
|
|
||||||
# The PHP version available via default repositories is older than version 7
|
|
||||||
dialog --no-shadow --keep-tite \
|
|
||||||
--title "PHP 7 Update (recommended)" \
|
|
||||||
--defaultno \
|
|
||||||
--yesno "PHP 7.x is recommended for both security and language features.\
|
|
||||||
\\n\\nWould you like to install PHP7 via Remi's RPM repository?\
|
|
||||||
\\n\\nSee: https://rpms.remirepo.net for more information"\
|
|
||||||
"${r}" "${c}" && result=0 || result=$?
|
|
||||||
|
|
||||||
case ${result} in
|
|
||||||
"${DIALOG_OK}" )
|
|
||||||
printf " %b Installing PHP 7 via Remi's RPM repository\\n" "${INFO}"
|
|
||||||
"${PKG_INSTALL[@]}" "yum-utils" &> /dev/null
|
|
||||||
if rpm -q ${REMI_PKG} &> /dev/null; then
|
|
||||||
printf " %b Remi's RPM repository is already installed\\n" "${TICK}"
|
|
||||||
else
|
|
||||||
printf " %b Enabling Remi's RPM repository (https://rpms.remirepo.net)\\n" "${INFO}"
|
|
||||||
yum -y install "${REMI_REPO_URL}"
|
|
||||||
printf " %b Installed %s from %s\\n" "${TICK}" "${REMI_PKG}" "${REMI_REPO_URL}"
|
|
||||||
printf " %b Remi's RPM repository has been enabled for PHP7\\n" "${TICK}"
|
|
||||||
fi
|
|
||||||
yum-config-manager --disable 'remi-php*'
|
|
||||||
yum-config-manager --enable "${REMI_REPO}"
|
|
||||||
|
|
||||||
# trigger an install/update of PHP to ensure previous version of PHP is updated from REMI
|
|
||||||
if "${PKG_INSTALL[@]}" "php-cli" &> /dev/null; then
|
|
||||||
printf " %b PHP7 installed/updated via Remi's RPM repository\\n" "${TICK}"
|
|
||||||
else
|
|
||||||
printf " %b There was a problem updating to PHP7 via Remi's RPM repository\\n" "${CROSS}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
# User chose not to install PHP 7 via Remi's RPM repository
|
|
||||||
"${DIALOG_CANCEL}")
|
|
||||||
# User decided to NOT update PHP from REMI, attempt to install the default available PHP version
|
|
||||||
printf " %b User opt-out of PHP 7 upgrade on CentOS. Deprecated PHP may be in use.\\n" "${INFO}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
# User closed the dialog window
|
|
||||||
"${DIALOG_ESC}")
|
|
||||||
printf " %b Escape pressed, exiting installer at Remi dialog window\\n" "${CROSS}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
# Warn user of unsupported version of Fedora or CentOS
|
|
||||||
dialog --no-shadow --keep-tite \
|
|
||||||
--title "Unsupported RPM based distribution" \
|
|
||||||
--defaultno \
|
|
||||||
--no-button "Exit" \
|
|
||||||
--yes-button "Continue" \
|
|
||||||
--yesno "Would you like to continue installation on an unsupported RPM based distribution?\
|
|
||||||
\\n\\nPlease ensure the following packages have been installed manually:\
|
|
||||||
\\n\\n- lighttpd\\n- lighttpd-fastcgi\\n- PHP version 7+"\
|
|
||||||
"${r}" "${c}" && result=0 || result=$?
|
|
||||||
|
|
||||||
case ${result} in
|
|
||||||
# User chose to continue installation on an unsupported RPM based distribution
|
|
||||||
"${DIALOG_OK}")
|
|
||||||
printf " %b User opted to continue installation on an unsupported RPM based distribution.\\n" "${INFO}"
|
|
||||||
;;
|
|
||||||
# User chose not to continue installation on an unsupported RPM based distribution
|
|
||||||
"${DIALOG_CANCEL}")
|
|
||||||
printf " %b User opted not to continue installation on an unsupported RPM based distribution.\\n" "${INFO}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
"${DIALOG_ESC}")
|
|
||||||
printf " %b Escape pressed, exiting installer at unsupported RPM based distribution dialog window\\n" "${CROSS}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# A function for checking if a directory is a git repository
|
# A function for checking if a directory is a git repository
|
||||||
is_repo() {
|
is_repo() {
|
||||||
# Use a named, local variable instead of the vague $1, which is the first argument passed to this function
|
# Use a named, local variable instead of the vague $1, which is the first argument passed to this function
|
||||||
@ -805,7 +682,7 @@ testIPv6() {
|
|||||||
|
|
||||||
find_IPv6_information() {
|
find_IPv6_information() {
|
||||||
# Detects IPv6 address used for communication to WAN addresses.
|
# Detects IPv6 address used for communication to WAN addresses.
|
||||||
IPV6_ADDRESSES=($(ip -6 address | grep 'scope global' | awk '{print $2}'))
|
mapfile -t IPV6_ADDRESSES <<<"$(ip -6 address | grep 'scope global' | awk '{print $2}')"
|
||||||
|
|
||||||
# For each address in the array above, determine the type of IPv6 address it is
|
# For each address in the array above, determine the type of IPv6 address it is
|
||||||
for i in "${IPV6_ADDRESSES[@]}"; do
|
for i in "${IPV6_ADDRESSES[@]}"; do
|
||||||
@ -820,13 +697,13 @@ find_IPv6_information() {
|
|||||||
|
|
||||||
# Determine which address to be used: Prefer ULA over GUA or don't use any if none found
|
# Determine which address to be used: Prefer ULA over GUA or don't use any if none found
|
||||||
# If the ULA_ADDRESS contains a value,
|
# If the ULA_ADDRESS contains a value,
|
||||||
if [[ ! -z "${ULA_ADDRESS}" ]]; then
|
if [[ -n "${ULA_ADDRESS}" ]]; then
|
||||||
# set the IPv6 address to the ULA address
|
# set the IPv6 address to the ULA address
|
||||||
IPV6_ADDRESS="${ULA_ADDRESS}"
|
IPV6_ADDRESS="${ULA_ADDRESS}"
|
||||||
# Show this info to the user
|
# Show this info to the user
|
||||||
printf " %b Found IPv6 ULA address\\n" "${INFO}"
|
printf " %b Found IPv6 ULA address\\n" "${INFO}"
|
||||||
# Otherwise, if the GUA_ADDRESS has a value,
|
# Otherwise, if the GUA_ADDRESS has a value,
|
||||||
elif [[ ! -z "${GUA_ADDRESS}" ]]; then
|
elif [[ -n "${GUA_ADDRESS}" ]]; then
|
||||||
# Let the user know
|
# Let the user know
|
||||||
printf " %b Found IPv6 GUA address\\n" "${INFO}"
|
printf " %b Found IPv6 GUA address\\n" "${INFO}"
|
||||||
# And assign it to the global variable
|
# And assign it to the global variable
|
||||||
@ -889,9 +766,9 @@ getStaticIPv4Settings() {
|
|||||||
--cancel-label "Exit" \
|
--cancel-label "Exit" \
|
||||||
--backtitle "IP information" \
|
--backtitle "IP information" \
|
||||||
--title "FYI: IP Conflict" \
|
--title "FYI: IP Conflict" \
|
||||||
--msgbox "\\nIt is possible your router could still try to assign this IP to a device, which would cause a conflict\
|
--msgbox "\\nIt is possible your router could still try to assign this IP to a device, which would cause a conflict, \
|
||||||
But in most cases the router is smart enough to not do that.\
|
but in most cases the router is smart enough to not do that.\n\n\
|
||||||
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.\
|
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.\n\n\
|
||||||
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address."\
|
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address."\
|
||||||
"${r}" "${c}" && result=0 || result=$?
|
"${r}" "${c}" && result=0 || result=$?
|
||||||
|
|
||||||
@ -1250,8 +1127,8 @@ setAdminFlag() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# If the user wants to install the Web admin interface (i.e. it has not been deselected above)
|
# If the user wants to install the Web admin interface (i.e. it has not been deselected above) and did not deselect the web server via command-line argument
|
||||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
if [[ "${INSTALL_WEB_INTERFACE}" == true && "${INSTALL_WEB_SERVER}" == true ]]; then
|
||||||
# Get list of required PHP modules, excluding base package (common) and handler (cgi)
|
# Get list of required PHP modules, excluding base package (common) and handler (cgi)
|
||||||
local i php_modules
|
local i php_modules
|
||||||
for i in "${PIHOLE_WEB_DEPS[@]}"; do [[ $i == 'php'* && $i != *'-common' && $i != *'-cgi' ]] && php_modules+=" ${i#*-}"; done
|
for i in "${PIHOLE_WEB_DEPS[@]}"; do [[ $i == 'php'* && $i != *'-common' && $i != *'-cgi' ]] && php_modules+=" ${i#*-}"; done
|
||||||
@ -1525,7 +1402,7 @@ installConfigs() {
|
|||||||
install -m 644 /dev/null /etc/lighttpd/external.conf
|
install -m 644 /dev/null /etc/lighttpd/external.conf
|
||||||
fi
|
fi
|
||||||
# If there is a custom block page in the html/pihole directory, replace 404 handler in lighttpd config
|
# If there is a custom block page in the html/pihole directory, replace 404 handler in lighttpd config
|
||||||
if [[ -f "${PI_HOLE_BLOCKPAGE_DIR}/custom.php" ]]; then
|
if [[ -f "${PI_HOLE_404_DIR}/custom.php" ]]; then
|
||||||
sed -i 's/^\(server\.error-handler-404\s*=\s*\).*$/\1"\/pihole\/custom\.php"/' "${lighttpdConfig}"
|
sed -i 's/^\(server\.error-handler-404\s*=\s*\).*$/\1"\/pihole\/custom\.php"/' "${lighttpdConfig}"
|
||||||
fi
|
fi
|
||||||
# Make the directories if they do not exist and set the owners
|
# Make the directories if they do not exist and set the owners
|
||||||
@ -1751,9 +1628,9 @@ install_dependent_packages() {
|
|||||||
# Running apt-get install with minimal output can cause some issues with
|
# Running apt-get install with minimal output can cause some issues with
|
||||||
# requiring user input (e.g password for phpmyadmin see #218)
|
# requiring user input (e.g password for phpmyadmin see #218)
|
||||||
printf " %b Processing %s install(s) for: %s, please wait...\\n" "${INFO}" "${PKG_MANAGER}" "${installArray[*]}"
|
printf " %b Processing %s install(s) for: %s, please wait...\\n" "${INFO}" "${PKG_MANAGER}" "${installArray[*]}"
|
||||||
printf '%*s\n' "$columns" '' | tr " " -;
|
printf '%*s\n' "${c}" '' | tr " " -;
|
||||||
"${PKG_INSTALL[@]}" "${installArray[@]}"
|
"${PKG_INSTALL[@]}" "${installArray[@]}"
|
||||||
printf '%*s\n' "$columns" '' | tr " " -;
|
printf '%*s\n' "${c}" '' | tr " " -;
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
printf "\\n"
|
printf "\\n"
|
||||||
@ -1774,9 +1651,9 @@ install_dependent_packages() {
|
|||||||
# If there's anything to install, install everything in the list.
|
# If there's anything to install, install everything in the list.
|
||||||
if [[ "${#installArray[@]}" -gt 0 ]]; then
|
if [[ "${#installArray[@]}" -gt 0 ]]; then
|
||||||
printf " %b Processing %s install(s) for: %s, please wait...\\n" "${INFO}" "${PKG_MANAGER}" "${installArray[*]}"
|
printf " %b Processing %s install(s) for: %s, please wait...\\n" "${INFO}" "${PKG_MANAGER}" "${installArray[*]}"
|
||||||
printf '%*s\n' "$columns" '' | tr " " -;
|
printf '%*s\n' "${c}" '' | tr " " -;
|
||||||
"${PKG_INSTALL[@]}" "${installArray[@]}"
|
"${PKG_INSTALL[@]}" "${installArray[@]}"
|
||||||
printf '%*s\n' "$columns" '' | tr " " -;
|
printf '%*s\n' "${c}" '' | tr " " -;
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
printf "\\n"
|
printf "\\n"
|
||||||
@ -1785,19 +1662,14 @@ install_dependent_packages() {
|
|||||||
|
|
||||||
# Install the Web interface dashboard
|
# Install the Web interface dashboard
|
||||||
installPiholeWeb() {
|
installPiholeWeb() {
|
||||||
printf "\\n %b Installing blocking page...\\n" "${INFO}"
|
printf "\\n %b Installing 404 page...\\n" "${INFO}"
|
||||||
|
|
||||||
local str="Creating directory for blocking page, and copying files"
|
local str="Creating directory for 404 page, and copying files"
|
||||||
printf " %b %s..." "${INFO}" "${str}"
|
printf " %b %s..." "${INFO}" "${str}"
|
||||||
# Install the directory,
|
# Install the directory
|
||||||
install -d -m 0755 ${PI_HOLE_BLOCKPAGE_DIR}
|
install -d -m 0755 ${PI_HOLE_404_DIR}
|
||||||
# and the blockpage
|
# and the 404 handler
|
||||||
install -D -m 644 ${PI_HOLE_LOCAL_REPO}/advanced/{index,blockingpage}.* ${PI_HOLE_BLOCKPAGE_DIR}/
|
install -D -m 644 ${PI_HOLE_LOCAL_REPO}/advanced/index.php ${PI_HOLE_404_DIR}/
|
||||||
|
|
||||||
# Remove superseded file
|
|
||||||
if [[ -e "${PI_HOLE_BLOCKPAGE_DIR}/index.js" ]]; then
|
|
||||||
rm "${PI_HOLE_BLOCKPAGE_DIR}/index.js"
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||||
|
|
||||||
@ -1939,6 +1811,7 @@ finalExports() {
|
|||||||
|
|
||||||
# Bring in the current settings and the functions to manipulate them
|
# Bring in the current settings and the functions to manipulate them
|
||||||
source "${setupVars}"
|
source "${setupVars}"
|
||||||
|
# shellcheck source=advanced/Scripts/webpage.sh
|
||||||
source "${PI_HOLE_LOCAL_REPO}/advanced/Scripts/webpage.sh"
|
source "${PI_HOLE_LOCAL_REPO}/advanced/Scripts/webpage.sh"
|
||||||
|
|
||||||
# Look for DNS server settings which would have to be reapplied
|
# Look for DNS server settings which would have to be reapplied
|
||||||
@ -2248,11 +2121,7 @@ checkout_pull_branch() {
|
|||||||
|
|
||||||
git_pull=$(git pull --no-rebase || return 1)
|
git_pull=$(git pull --no-rebase || return 1)
|
||||||
|
|
||||||
if [[ "$git_pull" == *"up-to-date"* ]]; then
|
printf " %b %s\\n" "${INFO}" "${git_pull}"
|
||||||
printf " %b %s\\n" "${INFO}" "${git_pull}"
|
|
||||||
else
|
|
||||||
printf "%s\\n" "$git_pull"
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -2656,12 +2525,6 @@ main() {
|
|||||||
printf " %b Checking for / installing Required dependencies for this install script...\\n" "${INFO}"
|
printf " %b Checking for / installing Required dependencies for this install script...\\n" "${INFO}"
|
||||||
install_dependent_packages "${INSTALLER_DEPS[@]}"
|
install_dependent_packages "${INSTALLER_DEPS[@]}"
|
||||||
|
|
||||||
#In case of RPM based distro, select the proper PHP version
|
|
||||||
if [[ "$PKG_MANAGER" == "yum" || "$PKG_MANAGER" == "dnf" ]] ; then
|
|
||||||
select_rpm_php
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# If the setup variable file exists,
|
# If the setup variable file exists,
|
||||||
if [[ -f "${setupVars}" ]]; then
|
if [[ -f "${setupVars}" ]]; then
|
||||||
# if it's running unattended,
|
# if it's running unattended,
|
||||||
@ -2866,7 +2729,7 @@ main() {
|
|||||||
|
|
||||||
# Display where the log file is
|
# Display where the log file is
|
||||||
printf "\\n %b The install log is located at: %s\\n" "${INFO}" "${installLogLoc}"
|
printf "\\n %b The install log is located at: %s\\n" "${INFO}" "${installLogLoc}"
|
||||||
printf "%b%s Complete! %b\\n" "${COL_LIGHT_GREEN}" "${INSTALL_TYPE}" "${COL_NC}"
|
printf " %b %b%s complete! %b\\n" "${TICK}" "${COL_LIGHT_GREEN}" "${INSTALL_TYPE}" "${COL_NC}"
|
||||||
|
|
||||||
if [[ "${INSTALL_TYPE}" == "Update" ]]; then
|
if [[ "${INSTALL_TYPE}" == "Update" ]]; then
|
||||||
printf "\\n"
|
printf "\\n"
|
||||||
|
@ -44,8 +44,8 @@ source "${setupVars}"
|
|||||||
# package_manager_detect() sourced from basic-install.sh
|
# package_manager_detect() sourced from basic-install.sh
|
||||||
package_manager_detect
|
package_manager_detect
|
||||||
|
|
||||||
# Install packages used by the Pi-hole
|
# Uninstall packages used by the Pi-hole
|
||||||
DEPS=("${INSTALLER_DEPS[@]}" "${PIHOLE_DEPS[@]}")
|
DEPS=("${INSTALLER_DEPS[@]}" "${PIHOLE_DEPS[@]}" "${OS_CHECK_DEPS[@]}")
|
||||||
if [[ "${INSTALL_WEB_SERVER}" == true ]]; then
|
if [[ "${INSTALL_WEB_SERVER}" == true ]]; then
|
||||||
# Install the Web dependencies
|
# Install the Web dependencies
|
||||||
DEPS+=("${PIHOLE_WEB_DEPS[@]}")
|
DEPS+=("${PIHOLE_WEB_DEPS[@]}")
|
||||||
|
52
gravity.sh
52
gravity.sh
@ -139,9 +139,9 @@ update_gravity_timestamp() {
|
|||||||
# Import domains from file and store them in the specified database table
|
# Import domains from file and store them in the specified database table
|
||||||
database_table_from_file() {
|
database_table_from_file() {
|
||||||
# Define locals
|
# Define locals
|
||||||
local table source backup_path backup_file tmpFile type
|
local table src backup_path backup_file tmpFile list_type
|
||||||
table="${1}"
|
table="${1}"
|
||||||
source="${2}"
|
src="${2}"
|
||||||
backup_path="${piholeDir}/migration_backup"
|
backup_path="${piholeDir}/migration_backup"
|
||||||
backup_file="${backup_path}/$(basename "${2}")"
|
backup_file="${backup_path}/$(basename "${2}")"
|
||||||
tmpFile="$(mktemp -p "/tmp" --suffix=".gravity")"
|
tmpFile="$(mktemp -p "/tmp" --suffix=".gravity")"
|
||||||
@ -155,13 +155,13 @@ database_table_from_file() {
|
|||||||
|
|
||||||
# Special handling for domains to be imported into the common domainlist table
|
# Special handling for domains to be imported into the common domainlist table
|
||||||
if [[ "${table}" == "whitelist" ]]; then
|
if [[ "${table}" == "whitelist" ]]; then
|
||||||
type="0"
|
list_type="0"
|
||||||
table="domainlist"
|
table="domainlist"
|
||||||
elif [[ "${table}" == "blacklist" ]]; then
|
elif [[ "${table}" == "blacklist" ]]; then
|
||||||
type="1"
|
list_type="1"
|
||||||
table="domainlist"
|
table="domainlist"
|
||||||
elif [[ "${table}" == "regex" ]]; then
|
elif [[ "${table}" == "regex" ]]; then
|
||||||
type="3"
|
list_type="3"
|
||||||
table="domainlist"
|
table="domainlist"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -174,9 +174,9 @@ database_table_from_file() {
|
|||||||
rowid+=1
|
rowid+=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Loop over all domains in ${source} file
|
# Loop over all domains in ${src} file
|
||||||
# Read file line by line
|
# Read file line by line
|
||||||
grep -v '^ *#' < "${source}" | while IFS= read -r domain
|
grep -v '^ *#' < "${src}" | while IFS= read -r domain
|
||||||
do
|
do
|
||||||
# Only add non-empty lines
|
# Only add non-empty lines
|
||||||
if [[ -n "${domain}" ]]; then
|
if [[ -n "${domain}" ]]; then
|
||||||
@ -185,10 +185,10 @@ database_table_from_file() {
|
|||||||
echo "${rowid},\"${domain}\",${timestamp}" >> "${tmpFile}"
|
echo "${rowid},\"${domain}\",${timestamp}" >> "${tmpFile}"
|
||||||
elif [[ "${table}" == "adlist" ]]; then
|
elif [[ "${table}" == "adlist" ]]; then
|
||||||
# Adlist table format
|
# Adlist table format
|
||||||
echo "${rowid},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${source}\",,0,0,0" >> "${tmpFile}"
|
echo "${rowid},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${src}\",,0,0,0" >> "${tmpFile}"
|
||||||
else
|
else
|
||||||
# White-, black-, and regexlist table format
|
# White-, black-, and regexlist table format
|
||||||
echo "${rowid},${type},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${source}\"" >> "${tmpFile}"
|
echo "${rowid},${list_type},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${src}\"" >> "${tmpFile}"
|
||||||
fi
|
fi
|
||||||
rowid+=1
|
rowid+=1
|
||||||
fi
|
fi
|
||||||
@ -201,14 +201,14 @@ database_table_from_file() {
|
|||||||
status="$?"
|
status="$?"
|
||||||
|
|
||||||
if [[ "${status}" -ne 0 ]]; then
|
if [[ "${status}" -ne 0 ]]; then
|
||||||
echo -e "\\n ${CROSS} Unable to fill table ${table}${type} in database ${gravityDBfile}\\n ${output}"
|
echo -e "\\n ${CROSS} Unable to fill table ${table}${list_type} in database ${gravityDBfile}\\n ${output}"
|
||||||
gravity_Cleanup "error"
|
gravity_Cleanup "error"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Move source file to backup directory, create directory if not existing
|
# Move source file to backup directory, create directory if not existing
|
||||||
mkdir -p "${backup_path}"
|
mkdir -p "${backup_path}"
|
||||||
mv "${source}" "${backup_file}" 2> /dev/null || \
|
mv "${src}" "${backup_file}" 2> /dev/null || \
|
||||||
echo -e " ${CROSS} Unable to backup ${source} to ${backup_path}"
|
echo -e " ${CROSS} Unable to backup ${src} to ${backup_path}"
|
||||||
|
|
||||||
# Delete tmpFile
|
# Delete tmpFile
|
||||||
rm "${tmpFile}" > /dev/null 2>&1 || \
|
rm "${tmpFile}" > /dev/null 2>&1 || \
|
||||||
@ -719,10 +719,10 @@ gravity_DownloadBlocklistFromUrl() {
|
|||||||
|
|
||||||
# Parse source files into domains format
|
# Parse source files into domains format
|
||||||
gravity_ParseFileIntoDomains() {
|
gravity_ParseFileIntoDomains() {
|
||||||
local source="${1}" destination="${2}" firstLine
|
local src="${1}" destination="${2}" firstLine
|
||||||
|
|
||||||
# Determine if we are parsing a consolidated list
|
# Determine if we are parsing a consolidated list
|
||||||
#if [[ "${source}" == "${piholeDir}/${matterAndLight}" ]]; then
|
#if [[ "${src}" == "${piholeDir}/${matterAndLight}" ]]; then
|
||||||
# Remove comments and print only the domain name
|
# Remove comments and print only the domain name
|
||||||
# Most of the lists downloaded are already in hosts file format but the spacing/formatting is not contiguous
|
# Most of the lists downloaded are already in hosts file format but the spacing/formatting is not contiguous
|
||||||
# This helps with that and makes it easier to read
|
# This helps with that and makes it easier to read
|
||||||
@ -733,7 +733,7 @@ gravity_ParseFileIntoDomains() {
|
|||||||
# 4) Remove lines containing "/"
|
# 4) Remove lines containing "/"
|
||||||
# 5) Remove leading tabs, spaces, etc.
|
# 5) Remove leading tabs, spaces, etc.
|
||||||
# 6) Delete lines not matching domain names
|
# 6) Delete lines not matching domain names
|
||||||
< "${source}" tr -d '\r' | \
|
< "${src}" tr -d '\r' | \
|
||||||
tr '[:upper:]' '[:lower:]' | \
|
tr '[:upper:]' '[:lower:]' | \
|
||||||
sed 's/\s*#.*//g' | \
|
sed 's/\s*#.*//g' | \
|
||||||
sed -r '/(\/).*$/d' | \
|
sed -r '/(\/).*$/d' | \
|
||||||
@ -745,16 +745,16 @@ gravity_ParseFileIntoDomains() {
|
|||||||
|
|
||||||
# Individual file parsing: Keep comments, while parsing domains from each line
|
# Individual file parsing: Keep comments, while parsing domains from each line
|
||||||
# We keep comments to respect the list maintainer's licensing
|
# We keep comments to respect the list maintainer's licensing
|
||||||
read -r firstLine < "${source}"
|
read -r firstLine < "${src}"
|
||||||
|
|
||||||
# Determine how to parse individual source file formats
|
# Determine how to parse individual source file formats
|
||||||
if [[ "${firstLine,,}" =~ (adblock|ublock|^!) ]]; then
|
if [[ "${firstLine,,}" =~ (adblock|ublock|^!) ]]; then
|
||||||
# Compare $firstLine against lower case words found in Adblock lists
|
# Compare $firstLine against lower case words found in Adblock lists
|
||||||
echo -e " ${CROSS} Format: Adblock (list type not supported)"
|
echo -e " ${CROSS} Format: Adblock (list type not supported)"
|
||||||
elif grep -q "^address=/" "${source}" &> /dev/null; then
|
elif grep -q "^address=/" "${src}" &> /dev/null; then
|
||||||
# Parse Dnsmasq format lists
|
# Parse Dnsmasq format lists
|
||||||
echo -e " ${CROSS} Format: Dnsmasq (list type not supported)"
|
echo -e " ${CROSS} Format: Dnsmasq (list type not supported)"
|
||||||
elif grep -q -E "^https?://" "${source}" &> /dev/null; then
|
elif grep -q -E "^https?://" "${src}" &> /dev/null; then
|
||||||
# Parse URL list if source file contains "http://" or "https://"
|
# Parse URL list if source file contains "http://" or "https://"
|
||||||
# Scanning for "^IPv4$" is too slow with large (1M) lists on low-end hardware
|
# Scanning for "^IPv4$" is too slow with large (1M) lists on low-end hardware
|
||||||
echo -ne " ${INFO} Format: URL"
|
echo -ne " ${INFO} Format: URL"
|
||||||
@ -770,13 +770,13 @@ gravity_ParseFileIntoDomains() {
|
|||||||
/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ { next }
|
/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ { next }
|
||||||
# Print if nonempty
|
# Print if nonempty
|
||||||
length { print }
|
length { print }
|
||||||
' "${source}" 2> /dev/null > "${destination}"
|
' "${src}" 2> /dev/null > "${destination}"
|
||||||
chmod 644 "${destination}"
|
chmod 644 "${destination}"
|
||||||
|
|
||||||
echo -e "${OVER} ${TICK} Format: URL"
|
echo -e "${OVER} ${TICK} Format: URL"
|
||||||
else
|
else
|
||||||
# Default: Keep hosts/domains file in same format as it was downloaded
|
# Default: Keep hosts/domains file in same format as it was downloaded
|
||||||
output=$( { mv "${source}" "${destination}"; } 2>&1 )
|
output=$( { mv "${src}" "${destination}"; } 2>&1 )
|
||||||
chmod 644 "${destination}"
|
chmod 644 "${destination}"
|
||||||
|
|
||||||
if [[ ! -e "${destination}" ]]; then
|
if [[ ! -e "${destination}" ]]; then
|
||||||
@ -870,15 +870,19 @@ gravity_Cleanup() {
|
|||||||
|
|
||||||
database_recovery() {
|
database_recovery() {
|
||||||
local result
|
local result
|
||||||
local str="Checking integrity of existing gravity database"
|
local str="Checking integrity of existing gravity database (this can take a while)"
|
||||||
local option="${1}"
|
local option="${1}"
|
||||||
echo -ne " ${INFO} ${str}..."
|
echo -ne " ${INFO} ${str}..."
|
||||||
if result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA integrity_check" 2>&1)"; then
|
result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA integrity_check" 2>&1)"
|
||||||
|
|
||||||
|
if [[ ${result} = "ok" ]]; then
|
||||||
echo -e "${OVER} ${TICK} ${str} - no errors found"
|
echo -e "${OVER} ${TICK} ${str} - no errors found"
|
||||||
|
|
||||||
str="Checking foreign keys of existing gravity database"
|
str="Checking foreign keys of existing gravity database (this can take a while)"
|
||||||
echo -ne " ${INFO} ${str}..."
|
echo -ne " ${INFO} ${str}..."
|
||||||
if result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA foreign_key_check" 2>&1)"; then
|
unset result
|
||||||
|
result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA foreign_key_check" 2>&1)"
|
||||||
|
if [[ -z ${result} ]]; then
|
||||||
echo -e "${OVER} ${TICK} ${str} - no errors found"
|
echo -e "${OVER} ${TICK} ${str} - no errors found"
|
||||||
if [[ "${option}" != "force" ]]; then
|
if [[ "${option}" != "force" ]]; then
|
||||||
return
|
return
|
||||||
|
@ -11,8 +11,6 @@ Pi-hole : A black-hole for internet advertisements
|
|||||||
.br
|
.br
|
||||||
\fBpihole -a\fR (\fB-c|-f|-k\fR)
|
\fBpihole -a\fR (\fB-c|-f|-k\fR)
|
||||||
.br
|
.br
|
||||||
\fBpihole -a -e\fR email
|
|
||||||
.br
|
|
||||||
\fBpihole -a -i\fR interface
|
\fBpihole -a -i\fR interface
|
||||||
.br
|
.br
|
||||||
\fBpihole -a -l\fR privacylevel
|
\fBpihole -a -l\fR privacylevel
|
||||||
@ -132,9 +130,6 @@ Available commands and options:
|
|||||||
-f, fahrenheit Set Fahrenheit as preferred temperature unit
|
-f, fahrenheit Set Fahrenheit as preferred temperature unit
|
||||||
.br
|
.br
|
||||||
-k, kelvin Set Kelvin as preferred temperature unit
|
-k, kelvin Set Kelvin as preferred temperature unit
|
||||||
.br
|
|
||||||
-e, email Set an administrative contact address for the
|
|
||||||
Block Page
|
|
||||||
.br
|
.br
|
||||||
-i, interface Specify dnsmasq's interface listening behavior
|
-i, interface Specify dnsmasq's interface listening behavior
|
||||||
.br
|
.br
|
||||||
|
104
pihole
104
pihole
@ -16,7 +16,6 @@ readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
|||||||
# error due to modifying a readonly variable.
|
# error due to modifying a readonly variable.
|
||||||
setupVars="/etc/pihole/setupVars.conf"
|
setupVars="/etc/pihole/setupVars.conf"
|
||||||
PI_HOLE_BIN_DIR="/usr/local/bin"
|
PI_HOLE_BIN_DIR="/usr/local/bin"
|
||||||
readonly FTL_PID_FILE="/run/pihole-FTL.pid"
|
|
||||||
|
|
||||||
readonly colfile="${PI_HOLE_SCRIPT_DIR}/COL_TABLE"
|
readonly colfile="${PI_HOLE_SCRIPT_DIR}/COL_TABLE"
|
||||||
source "${colfile}"
|
source "${colfile}"
|
||||||
@ -36,19 +35,20 @@ listFunc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
debugFunc() {
|
debugFunc() {
|
||||||
local automated
|
local automated
|
||||||
local web
|
local web
|
||||||
|
local check_database_integrity
|
||||||
|
# Pull off the `debug` leaving passed call augmentation flags in $1
|
||||||
|
shift
|
||||||
|
|
||||||
# Pull off the `debug` leaving passed call augmentation flags in $1
|
for value in "$@"; do
|
||||||
shift
|
[[ "$value" == *"-a"* ]] && automated="true"
|
||||||
if [[ "$@" == *"-a"* ]]; then
|
[[ "$value" == *"-w"* ]] && web="true"
|
||||||
automated="true"
|
[[ "$value" == *"-c"* ]] && check_database_integrity="true"
|
||||||
fi
|
[[ "$value" == *"--check_database"* ]] && check_database_integrity="true"
|
||||||
if [[ "$@" == *"-w"* ]]; then
|
done
|
||||||
web="true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
AUTOMATED=${automated:-} WEBCALL=${web:-} "${PI_HOLE_SCRIPT_DIR}"/piholeDebug.sh
|
AUTOMATED=${automated:-} WEBCALL=${web:-} CHECK_DATABASE=${check_database_integrity:-} "${PI_HOLE_SCRIPT_DIR}"/piholeDebug.sh
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,25 +100,8 @@ versionFunc() {
|
|||||||
exec "${PI_HOLE_SCRIPT_DIR}"/version.sh "$@"
|
exec "${PI_HOLE_SCRIPT_DIR}"/version.sh "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get PID of main pihole-FTL process
|
|
||||||
getFTLPID() {
|
|
||||||
local pid
|
|
||||||
|
|
||||||
if [ -s "${FTL_PID_FILE}" ]; then
|
|
||||||
# -s: FILE exists and has a size greater than zero
|
|
||||||
pid="$(<"$FTL_PID_FILE")"
|
|
||||||
# Exploit prevention: unset the variable if there is malicious content
|
|
||||||
# Verify that the value read from the file is numeric
|
|
||||||
[[ "$pid" =~ [^[:digit:]] ]] && unset pid
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If FTL is not running, or the PID file contains malicious stuff, substitute
|
|
||||||
# negative PID to signal this to the caller
|
|
||||||
echo "${pid:=-1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
restartDNS() {
|
restartDNS() {
|
||||||
local svcOption svc str output status pid icon
|
local svcOption svc str output status pid icon FTL_PID_FILE
|
||||||
svcOption="${1:-restart}"
|
svcOption="${1:-restart}"
|
||||||
|
|
||||||
# Determine if we should reload or restart
|
# Determine if we should reload or restart
|
||||||
@ -127,7 +110,11 @@ restartDNS() {
|
|||||||
# Note 1: This will NOT re-read any *.conf files
|
# Note 1: This will NOT re-read any *.conf files
|
||||||
# Note 2: We cannot use killall here as it does
|
# Note 2: We cannot use killall here as it does
|
||||||
# not know about real-time signals
|
# not know about real-time signals
|
||||||
pid="$(getFTLPID)"
|
|
||||||
|
# get the current path to the pihole-FTL.pid
|
||||||
|
FTL_PID_FILE="$(getFTLPIDFile)"
|
||||||
|
|
||||||
|
pid="$(getFTLPID ${FTL_PID_FILE})"
|
||||||
if [[ "$pid" -eq "-1" ]]; then
|
if [[ "$pid" -eq "-1" ]]; then
|
||||||
svc="true"
|
svc="true"
|
||||||
str="FTL is not running"
|
str="FTL is not running"
|
||||||
@ -140,7 +127,7 @@ restartDNS() {
|
|||||||
elif [[ "${svcOption}" =~ "reload" ]]; then
|
elif [[ "${svcOption}" =~ "reload" ]]; then
|
||||||
# Reloading of the DNS cache has been requested
|
# Reloading of the DNS cache has been requested
|
||||||
# Note: This will NOT re-read any *.conf files
|
# Note: This will NOT re-read any *.conf files
|
||||||
pid="$(getFTLPID)"
|
pid="$(getFTLPID ${FTL_PID_FILE})"
|
||||||
if [[ "$pid" -eq "-1" ]]; then
|
if [[ "$pid" -eq "-1" ]]; then
|
||||||
svc="true"
|
svc="true"
|
||||||
str="FTL is not running"
|
str="FTL is not running"
|
||||||
@ -315,33 +302,37 @@ analyze_ports() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
statusFunc() {
|
statusFunc() {
|
||||||
# Determine if there is pihole-FTL service is listening
|
# Determine if there is pihole-FTL service is listening
|
||||||
local pid port ftl_api_port
|
local pid port ftl_api_port ftl_pid_file ftl_apiport_file
|
||||||
|
|
||||||
pid="$(getFTLPID)"
|
ftl_pid_file="$(getFTLPIDFile)"
|
||||||
ftl_api_port="$(getFTLAPIPort)"
|
|
||||||
if [[ "$pid" -eq "-1" ]]; then
|
pid="$(getFTLPID ${ftl_pid_file})"
|
||||||
case "${1}" in
|
|
||||||
"web") echo "-1";;
|
ftl_apiport_file="${getFTLAPIPortFile}"
|
||||||
*) echo -e " ${CROSS} DNS service is NOT running";;
|
ftl_api_port="$(getFTLAPIPort ${ftl_apiport_file})"
|
||||||
esac
|
if [[ "$pid" -eq "-1" ]]; then
|
||||||
return 0
|
case "${1}" in
|
||||||
else
|
"web") echo "-1";;
|
||||||
#get the DNS port pihole-FTL is listening on by using FTL's telnet API
|
*) echo -e " ${CROSS} DNS service is NOT running";;
|
||||||
port="$(echo ">dns-port >quit" | nc 127.0.0.1 "$ftl_api_port")"
|
esac
|
||||||
if [[ "${port}" == "0" ]]; then
|
return 0
|
||||||
case "${1}" in
|
|
||||||
"web") echo "-1";;
|
|
||||||
*) echo -e " ${CROSS} DNS service is NOT listening";;
|
|
||||||
esac
|
|
||||||
return 0
|
|
||||||
else
|
else
|
||||||
if [[ "${1}" != "web" ]]; then
|
#get the DNS port pihole-FTL is listening on by using FTL's telnet API
|
||||||
echo -e " ${TICK} FTL is listening on port ${port}"
|
port="$(echo ">dns-port >quit" | nc 127.0.0.1 "$ftl_api_port")"
|
||||||
analyze_ports "${port}"
|
if [[ "${port}" == "0" ]]; then
|
||||||
fi
|
case "${1}" in
|
||||||
|
"web") echo "-1";;
|
||||||
|
*) echo -e " ${CROSS} DNS service is NOT listening";;
|
||||||
|
esac
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
if [[ "${1}" != "web" ]]; then
|
||||||
|
echo -e " ${TICK} FTL is listening on port ${port}"
|
||||||
|
analyze_ports "${port}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
# Determine if Pi-hole's blocking is enabled
|
# Determine if Pi-hole's blocking is enabled
|
||||||
if grep -q "BLOCKING_ENABLED=false" /etc/pihole/setupVars.conf; then
|
if grep -q "BLOCKING_ENABLED=false" /etc/pihole/setupVars.conf; then
|
||||||
@ -455,6 +446,7 @@ Whitelist/Blacklist Options:
|
|||||||
|
|
||||||
Debugging Options:
|
Debugging Options:
|
||||||
-d, debug Start a debugging session
|
-d, debug Start a debugging session
|
||||||
|
Add '-c' or '--check-database' to include a Pi-hole database integrity check
|
||||||
Add '-a' to automatically upload the log to tricorder.pi-hole.net
|
Add '-a' to automatically upload the log to tricorder.pi-hole.net
|
||||||
-f, flush Flush the Pi-hole log
|
-f, flush Flush the Pi-hole log
|
||||||
-r, reconfigure Reconfigure or Repair Pi-hole subsystems
|
-r, reconfigure Reconfigure or Repair Pi-hole subsystems
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
FROM centos:7
|
|
||||||
RUN yum install -y dialog git python3
|
|
||||||
|
|
||||||
ENV GITDIR /etc/.pihole
|
|
||||||
ENV SCRIPTDIR /opt/pihole
|
|
||||||
|
|
||||||
RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
|
|
||||||
ADD . $GITDIR
|
|
||||||
RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/
|
|
||||||
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
|
|
||||||
|
|
||||||
ADD test/centos7.epel.override /etc/yum/pluginconf.d/fastestmirror.conf
|
|
||||||
RUN true && \
|
|
||||||
chmod +x $SCRIPTDIR/*
|
|
||||||
|
|
||||||
ENV SKIP_INSTALL true
|
|
||||||
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
|
|
||||||
|
|
||||||
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
|
|
@ -1,18 +0,0 @@
|
|||||||
FROM buildpack-deps:impish-scm
|
|
||||||
|
|
||||||
ENV GITDIR /etc/.pihole
|
|
||||||
ENV SCRIPTDIR /opt/pihole
|
|
||||||
|
|
||||||
RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
|
|
||||||
ADD . $GITDIR
|
|
||||||
RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/
|
|
||||||
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
|
|
||||||
RUN true && \
|
|
||||||
chmod +x $SCRIPTDIR/*
|
|
||||||
|
|
||||||
ENV SKIP_INSTALL true
|
|
||||||
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
|
|
||||||
|
|
||||||
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
|
|
@ -1,7 +0,0 @@
|
|||||||
[main]
|
|
||||||
verbose = 0
|
|
||||||
socket_timeout = 3
|
|
||||||
enabled = 1
|
|
||||||
hostfilepath = /var/cache/yum/timedhosts.txt
|
|
||||||
maxhostfileage = 1
|
|
||||||
exclude=.edu
|
|
@ -116,9 +116,9 @@ def test_installPiholeWeb_fresh_install_no_errors(host):
|
|||||||
source /opt/pihole/basic-install.sh
|
source /opt/pihole/basic-install.sh
|
||||||
installPiholeWeb
|
installPiholeWeb
|
||||||
''')
|
''')
|
||||||
expected_stdout = info_box + ' Installing blocking page...'
|
expected_stdout = info_box + ' Installing 404 page...'
|
||||||
assert expected_stdout in installWeb.stdout
|
assert expected_stdout in installWeb.stdout
|
||||||
expected_stdout = tick_box + (' Creating directory for blocking page, '
|
expected_stdout = tick_box + (' Creating directory for 404 page, '
|
||||||
'and copying files')
|
'and copying files')
|
||||||
assert expected_stdout in installWeb.stdout
|
assert expected_stdout in installWeb.stdout
|
||||||
expected_stdout = info_box + ' Backing up index.lighttpd.html'
|
expected_stdout = info_box + ' Backing up index.lighttpd.html'
|
||||||
@ -130,7 +130,6 @@ def test_installPiholeWeb_fresh_install_no_errors(host):
|
|||||||
assert expected_stdout in installWeb.stdout
|
assert expected_stdout in installWeb.stdout
|
||||||
web_directory = host.run('ls -r /var/www/html/pihole').stdout
|
web_directory = host.run('ls -r /var/www/html/pihole').stdout
|
||||||
assert 'index.php' in web_directory
|
assert 'index.php' in web_directory
|
||||||
assert 'blockingpage.css' in web_directory
|
|
||||||
|
|
||||||
|
|
||||||
def get_directories_recursive(host, directory):
|
def get_directories_recursive(host, directory):
|
||||||
@ -240,24 +239,14 @@ def test_installPihole_fresh_install_readableFiles(host):
|
|||||||
'r', '/etc/pihole/dns-servers.conf', piholeuser)
|
'r', '/etc/pihole/dns-servers.conf', piholeuser)
|
||||||
actual_rc = host.run(check_servers).rc
|
actual_rc = host.run(check_servers).rc
|
||||||
assert exit_status_success == actual_rc
|
assert exit_status_success == actual_rc
|
||||||
# readable GitHubVersions
|
|
||||||
check_version = test_cmd.format(
|
|
||||||
'r', '/etc/pihole/GitHubVersions', piholeuser)
|
|
||||||
actual_rc = host.run(check_version).rc
|
|
||||||
assert exit_status_success == actual_rc
|
|
||||||
# readable install.log
|
# readable install.log
|
||||||
check_install = test_cmd.format(
|
check_install = test_cmd.format(
|
||||||
'r', '/etc/pihole/install.log', piholeuser)
|
'r', '/etc/pihole/install.log', piholeuser)
|
||||||
actual_rc = host.run(check_install).rc
|
actual_rc = host.run(check_install).rc
|
||||||
assert exit_status_success == actual_rc
|
assert exit_status_success == actual_rc
|
||||||
# readable localbranches
|
# readable versions
|
||||||
check_localbranch = test_cmd.format(
|
|
||||||
'r', '/etc/pihole/localbranches', piholeuser)
|
|
||||||
actual_rc = host.run(check_localbranch).rc
|
|
||||||
assert exit_status_success == actual_rc
|
|
||||||
# readable localversions
|
|
||||||
check_localversion = test_cmd.format(
|
check_localversion = test_cmd.format(
|
||||||
'r', '/etc/pihole/localversions', piholeuser)
|
'r', '/etc/pihole/versions', piholeuser)
|
||||||
actual_rc = host.run(check_localversion).rc
|
actual_rc = host.run(check_localversion).rc
|
||||||
assert exit_status_success == actual_rc
|
assert exit_status_success == actual_rc
|
||||||
# readable logrotate
|
# readable logrotate
|
||||||
@ -605,10 +594,6 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage):
|
|||||||
'r', webroot + '/pihole/index.php', webuser)
|
'r', webroot + '/pihole/index.php', webuser)
|
||||||
actual_rc = host.run(check_index).rc
|
actual_rc = host.run(check_index).rc
|
||||||
assert exit_status_success == actual_rc
|
assert exit_status_success == actual_rc
|
||||||
check_blockpage = test_cmd.format(
|
|
||||||
'r', webroot + '/pihole/blockingpage.css', webuser)
|
|
||||||
actual_rc = host.run(check_blockpage).rc
|
|
||||||
assert exit_status_success == actual_rc
|
|
||||||
if test_webpage is True:
|
if test_webpage is True:
|
||||||
# check webpage for unreadable files
|
# check webpage for unreadable files
|
||||||
noPHPfopen = re.compile(
|
noPHPfopen = re.compile(
|
||||||
@ -1107,7 +1092,7 @@ def test_package_manager_has_installer_deps(host):
|
|||||||
install_dependent_packages ${INSTALLER_DEPS[@]}
|
install_dependent_packages ${INSTALLER_DEPS[@]}
|
||||||
''')
|
''')
|
||||||
|
|
||||||
assert 'No package' not in output.stdout # centos7 still exits 0...
|
assert 'No package' not in output.stdout
|
||||||
assert output.rc == 0
|
assert output.rc == 0
|
||||||
|
|
||||||
|
|
||||||
@ -1117,11 +1102,10 @@ def test_package_manager_has_pihole_deps(host):
|
|||||||
output = host.run('''
|
output = host.run('''
|
||||||
source /opt/pihole/basic-install.sh
|
source /opt/pihole/basic-install.sh
|
||||||
package_manager_detect
|
package_manager_detect
|
||||||
select_rpm_php
|
|
||||||
install_dependent_packages ${PIHOLE_DEPS[@]}
|
install_dependent_packages ${PIHOLE_DEPS[@]}
|
||||||
''')
|
''')
|
||||||
|
|
||||||
assert 'No package' not in output.stdout # centos7 still exits 0...
|
assert 'No package' not in output.stdout
|
||||||
assert output.rc == 0
|
assert output.rc == 0
|
||||||
|
|
||||||
|
|
||||||
@ -1131,9 +1115,8 @@ def test_package_manager_has_web_deps(host):
|
|||||||
output = host.run('''
|
output = host.run('''
|
||||||
source /opt/pihole/basic-install.sh
|
source /opt/pihole/basic-install.sh
|
||||||
package_manager_detect
|
package_manager_detect
|
||||||
select_rpm_php
|
|
||||||
install_dependent_packages ${PIHOLE_WEB_DEPS[@]}
|
install_dependent_packages ${PIHOLE_WEB_DEPS[@]}
|
||||||
''')
|
''')
|
||||||
|
|
||||||
assert 'No package' not in output.stdout # centos7 still exits 0...
|
assert 'No package' not in output.stdout
|
||||||
assert output.rc == 0
|
assert output.rc == 0
|
||||||
|
@ -50,25 +50,73 @@ def test_key_removal_works(host):
|
|||||||
assert expected_stdout == output.stdout
|
assert expected_stdout == output.stdout
|
||||||
|
|
||||||
|
|
||||||
|
def test_getFTLAPIPortFile_default(host):
|
||||||
|
''' Confirms getFTLAPIPortFile returns the default API port file path '''
|
||||||
|
output = host.run('''
|
||||||
|
source /opt/pihole/utils.sh
|
||||||
|
getFTLAPIPortFile
|
||||||
|
''')
|
||||||
|
expected_stdout = '/run/pihole-FTL.port\n'
|
||||||
|
assert expected_stdout == output.stdout
|
||||||
|
|
||||||
|
|
||||||
def test_getFTLAPIPort_default(host):
|
def test_getFTLAPIPort_default(host):
|
||||||
''' Confirms getFTLAPIPort returns the default API port '''
|
''' Confirms getFTLAPIPort returns the default API port '''
|
||||||
output = host.run('''
|
output = host.run('''
|
||||||
source /opt/pihole/utils.sh
|
source /opt/pihole/utils.sh
|
||||||
getFTLAPIPort
|
getFTLAPIPort "/run/pihole-FTL.port"
|
||||||
''')
|
''')
|
||||||
expected_stdout = '4711\n'
|
expected_stdout = '4711\n'
|
||||||
assert expected_stdout == output.stdout
|
assert expected_stdout == output.stdout
|
||||||
|
|
||||||
|
|
||||||
def test_getFTLAPIPort_custom(host):
|
def test_getFTLAPIPortFile_and_getFTLAPIPort_custom(host):
|
||||||
''' Confirms getFTLAPIPort returns a custom API port in a custom PORTFILE location '''
|
''' Confirms getFTLAPIPort returns a custom API port in a custom PORTFILE location '''
|
||||||
host.run('''
|
host.run('''
|
||||||
echo "PORTFILE=/tmp/port.file" > /etc/pihole/pihole-FTL.conf
|
tmpfile=$(mktemp)
|
||||||
echo "1234" > /tmp/port.file
|
echo "PORTFILE=${tmpfile}" > /etc/pihole/pihole-FTL.conf
|
||||||
|
echo "1234" > ${tmpfile}
|
||||||
''')
|
''')
|
||||||
output = host.run('''
|
output = host.run('''
|
||||||
source /opt/pihole/utils.sh
|
source /opt/pihole/utils.sh
|
||||||
getFTLAPIPort
|
FTL_API_PORT_FILE=$(getFTLAPIPortFile)
|
||||||
|
getFTLAPIPort "${FTL_API_PORT_FILE}"
|
||||||
|
''')
|
||||||
|
expected_stdout = '1234\n'
|
||||||
|
assert expected_stdout == output.stdout
|
||||||
|
|
||||||
|
|
||||||
|
def test_getFTLPIDFile_default(host):
|
||||||
|
''' Confirms getFTLPIDFile returns the default PID file path '''
|
||||||
|
output = host.run('''
|
||||||
|
source /opt/pihole/utils.sh
|
||||||
|
getFTLPIDFile
|
||||||
|
''')
|
||||||
|
expected_stdout = '/run/pihole-FTL.pid\n'
|
||||||
|
assert expected_stdout == output.stdout
|
||||||
|
|
||||||
|
|
||||||
|
def test_getFTLPID_default(host):
|
||||||
|
''' Confirms getFTLPID returns the default value if FTL is not running '''
|
||||||
|
output = host.run('''
|
||||||
|
source /opt/pihole/utils.sh
|
||||||
|
getFTLPID
|
||||||
|
''')
|
||||||
|
expected_stdout = '-1\n'
|
||||||
|
assert expected_stdout == output.stdout
|
||||||
|
|
||||||
|
|
||||||
|
def test_getFTLPIDFile_and_getFTLPID_custom(host):
|
||||||
|
''' Confirms getFTLPIDFile returns a custom PID file path '''
|
||||||
|
host.run('''
|
||||||
|
tmpfile=$(mktemp)
|
||||||
|
echo "PIDFILE=${tmpfile}" > /etc/pihole/pihole-FTL.conf
|
||||||
|
echo "1234" > ${tmpfile}
|
||||||
|
''')
|
||||||
|
output = host.run('''
|
||||||
|
source /opt/pihole/utils.sh
|
||||||
|
FTL_PID_FILE=$(getFTLPIDFile)
|
||||||
|
getFTLPID "${FTL_PID_FILE}"
|
||||||
''')
|
''')
|
||||||
expected_stdout = '1234\n'
|
expected_stdout = '1234\n'
|
||||||
assert expected_stdout == output.stdout
|
assert expected_stdout == output.stdout
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
from .conftest import (
|
|
||||||
tick_box,
|
|
||||||
info_box,
|
|
||||||
mock_command,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_php_upgrade_default_optout_centos_eq_7(host):
|
|
||||||
'''
|
|
||||||
confirms the default behavior to opt-out of installing PHP7 from REMI
|
|
||||||
'''
|
|
||||||
package_manager_detect = host.run('''
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
select_rpm_php
|
|
||||||
''')
|
|
||||||
expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. '
|
|
||||||
'Deprecated PHP may be in use.')
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
remi_package = host.package('remi-release')
|
|
||||||
assert not remi_package.is_installed
|
|
||||||
|
|
||||||
|
|
||||||
def test_php_upgrade_user_optout_centos_eq_7(host):
|
|
||||||
'''
|
|
||||||
confirms installer behavior when user opt-out of installing PHP7 from REMI
|
|
||||||
(php not currently installed)
|
|
||||||
'''
|
|
||||||
# dialog returns Cancel for user prompt
|
|
||||||
mock_command('dialog', {'*': ('', '1')}, host)
|
|
||||||
package_manager_detect = host.run('''
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
select_rpm_php
|
|
||||||
''')
|
|
||||||
expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. '
|
|
||||||
'Deprecated PHP may be in use.')
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
remi_package = host.package('remi-release')
|
|
||||||
assert not remi_package.is_installed
|
|
||||||
|
|
||||||
|
|
||||||
def test_php_upgrade_user_optin_centos_eq_7(host):
|
|
||||||
'''
|
|
||||||
confirms installer behavior when user opt-in to installing PHP7 from REMI
|
|
||||||
(php not currently installed)
|
|
||||||
'''
|
|
||||||
# dialog returns Continue for user prompt
|
|
||||||
mock_command('dialog', {'*': ('', '0')}, host)
|
|
||||||
package_manager_detect = host.run('''
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
select_rpm_php
|
|
||||||
''')
|
|
||||||
assert 'opt-out' not in package_manager_detect.stdout
|
|
||||||
expected_stdout = info_box + (' Enabling Remi\'s RPM repository '
|
|
||||||
'(https://rpms.remirepo.net)')
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
expected_stdout = tick_box + (' Remi\'s RPM repository has '
|
|
||||||
'been enabled for PHP7')
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
remi_package = host.package('remi-release')
|
|
||||||
assert remi_package.is_installed
|
|
@ -1,68 +0,0 @@
|
|||||||
from .conftest import (
|
|
||||||
tick_box,
|
|
||||||
info_box,
|
|
||||||
mock_command,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_php_upgrade_default_continue_centos_gte_8(host):
|
|
||||||
'''
|
|
||||||
confirms the latest version of CentOS continues / does not optout
|
|
||||||
(should trigger on CentOS7 only)
|
|
||||||
'''
|
|
||||||
package_manager_detect = host.run('''
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
select_rpm_php
|
|
||||||
''')
|
|
||||||
unexpected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS.'
|
|
||||||
' Deprecated PHP may be in use.')
|
|
||||||
assert unexpected_stdout not in package_manager_detect.stdout
|
|
||||||
# ensure remi was not installed on latest CentOS
|
|
||||||
remi_package = host.package('remi-release')
|
|
||||||
assert not remi_package.is_installed
|
|
||||||
|
|
||||||
|
|
||||||
def test_php_upgrade_user_optout_skipped_centos_gte_8(host):
|
|
||||||
'''
|
|
||||||
confirms installer skips user opt-out of installing PHP7 from REMI on
|
|
||||||
latest CentOS (should trigger on CentOS7 only)
|
|
||||||
(php not currently installed)
|
|
||||||
'''
|
|
||||||
# dialog dialog returns Cancel for user prompt
|
|
||||||
mock_command('dialog', {'*': ('', '1')}, host)
|
|
||||||
package_manager_detect = host.run('''
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
select_rpm_php
|
|
||||||
''')
|
|
||||||
unexpected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS.'
|
|
||||||
' Deprecated PHP may be in use.')
|
|
||||||
assert unexpected_stdout not in package_manager_detect.stdout
|
|
||||||
# ensure remi was not installed on latest CentOS
|
|
||||||
remi_package = host.package('remi-release')
|
|
||||||
assert not remi_package.is_installed
|
|
||||||
|
|
||||||
|
|
||||||
def test_php_upgrade_user_optin_skipped_centos_gte_8(host):
|
|
||||||
'''
|
|
||||||
confirms installer skips user opt-in to installing PHP7 from REMI on
|
|
||||||
latest CentOS (should trigger on CentOS7 only)
|
|
||||||
(php not currently installed)
|
|
||||||
'''
|
|
||||||
# dialog dialog returns Continue for user prompt
|
|
||||||
mock_command('dialog', {'*': ('', '0')}, host)
|
|
||||||
package_manager_detect = host.run('''
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
select_rpm_php
|
|
||||||
''')
|
|
||||||
assert 'opt-out' not in package_manager_detect.stdout
|
|
||||||
unexpected_stdout = info_box + (' Enabling Remi\'s RPM repository '
|
|
||||||
'(https://rpms.remirepo.net)')
|
|
||||||
assert unexpected_stdout not in package_manager_detect.stdout
|
|
||||||
unexpected_stdout = tick_box + (' Remi\'s RPM repository has '
|
|
||||||
'been enabled for PHP7')
|
|
||||||
assert unexpected_stdout not in package_manager_detect.stdout
|
|
||||||
remi_package = host.package('remi-release')
|
|
||||||
assert not remi_package.is_installed
|
|
@ -7,23 +7,6 @@ from .conftest import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_release_supported_version_check_centos(host):
|
|
||||||
'''
|
|
||||||
confirms installer exits on unsupported releases of CentOS
|
|
||||||
'''
|
|
||||||
# modify /etc/redhat-release to mock an unsupported CentOS release
|
|
||||||
host.run('echo "CentOS Linux release 6.9" > /etc/redhat-release')
|
|
||||||
package_manager_detect = host.run('''
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
select_rpm_php
|
|
||||||
''')
|
|
||||||
expected_stdout = cross_box + (' CentOS 6 is not supported.')
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
expected_stdout = 'Please update to CentOS release 7 or later'
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
|
|
||||||
|
|
||||||
def test_enable_epel_repository_centos(host):
|
def test_enable_epel_repository_centos(host):
|
||||||
'''
|
'''
|
||||||
confirms the EPEL package repository is enabled when installed on CentOS
|
confirms the EPEL package repository is enabled when installed on CentOS
|
||||||
@ -31,7 +14,6 @@ def test_enable_epel_repository_centos(host):
|
|||||||
package_manager_detect = host.run('''
|
package_manager_detect = host.run('''
|
||||||
source /opt/pihole/basic-install.sh
|
source /opt/pihole/basic-install.sh
|
||||||
package_manager_detect
|
package_manager_detect
|
||||||
select_rpm_php
|
|
||||||
''')
|
''')
|
||||||
expected_stdout = info_box + (' Enabling EPEL package repository '
|
expected_stdout = info_box + (' Enabling EPEL package repository '
|
||||||
'(https://fedoraproject.org/wiki/EPEL)')
|
'(https://fedoraproject.org/wiki/EPEL)')
|
||||||
@ -40,86 +22,3 @@ def test_enable_epel_repository_centos(host):
|
|||||||
assert expected_stdout in package_manager_detect.stdout
|
assert expected_stdout in package_manager_detect.stdout
|
||||||
epel_package = host.package('epel-release')
|
epel_package = host.package('epel-release')
|
||||||
assert epel_package.is_installed
|
assert epel_package.is_installed
|
||||||
|
|
||||||
|
|
||||||
def test_php_version_lt_7_detected_upgrade_default_optout_centos(host):
|
|
||||||
'''
|
|
||||||
confirms the default behavior to opt-out of upgrading to PHP7 from REMI
|
|
||||||
'''
|
|
||||||
# first we will install the default php version to test installer behavior
|
|
||||||
php_install = host.run('yum install -y php')
|
|
||||||
assert php_install.rc == 0
|
|
||||||
php_package = host.package('php')
|
|
||||||
default_centos_php_version = php_package.version.split('.')[0]
|
|
||||||
if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended
|
|
||||||
pytest.skip("Test deprecated . Detected default PHP version >= 7")
|
|
||||||
package_manager_detect = host.run('''
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
select_rpm_php
|
|
||||||
''')
|
|
||||||
expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. '
|
|
||||||
'Deprecated PHP may be in use.')
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
remi_package = host.package('remi-release')
|
|
||||||
assert not remi_package.is_installed
|
|
||||||
|
|
||||||
|
|
||||||
def test_php_version_lt_7_detected_upgrade_user_optout_centos(host):
|
|
||||||
'''
|
|
||||||
confirms installer behavior when user opt-out to upgrade to PHP7 via REMI
|
|
||||||
'''
|
|
||||||
# first we will install the default php version to test installer behavior
|
|
||||||
php_install = host.run('yum install -y php')
|
|
||||||
assert php_install.rc == 0
|
|
||||||
php_package = host.package('php')
|
|
||||||
default_centos_php_version = php_package.version.split('.')[0]
|
|
||||||
if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended
|
|
||||||
pytest.skip("Test deprecated . Detected default PHP version >= 7")
|
|
||||||
# dialog returns Cancel for user prompt
|
|
||||||
mock_command('dialog', {'*': ('', '1')}, host)
|
|
||||||
package_manager_detect = host.run('''
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
select_rpm_php
|
|
||||||
''')
|
|
||||||
expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. '
|
|
||||||
'Deprecated PHP may be in use.')
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
remi_package = host.package('remi-release')
|
|
||||||
assert not remi_package.is_installed
|
|
||||||
|
|
||||||
|
|
||||||
def test_php_version_lt_7_detected_upgrade_user_optin_centos(host):
|
|
||||||
'''
|
|
||||||
confirms installer behavior when user opt-in to upgrade to PHP7 via REMI
|
|
||||||
'''
|
|
||||||
# first we will install the default php version to test installer behavior
|
|
||||||
php_install = host.run('yum install -y php')
|
|
||||||
assert php_install.rc == 0
|
|
||||||
php_package = host.package('php')
|
|
||||||
default_centos_php_version = php_package.version.split('.')[0]
|
|
||||||
if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended
|
|
||||||
pytest.skip("Test deprecated . Detected default PHP version >= 7")
|
|
||||||
# dialog returns Continue for user prompt
|
|
||||||
mock_command('dialog', {'*': ('', '0')}, host)
|
|
||||||
package_manager_detect = host.run('''
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
select_rpm_php
|
|
||||||
install_dependent_packages PIHOLE_WEB_DEPS[@]
|
|
||||||
''')
|
|
||||||
expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. '
|
|
||||||
'Deprecated PHP may be in use.')
|
|
||||||
assert expected_stdout not in package_manager_detect.stdout
|
|
||||||
expected_stdout = info_box + (' Enabling Remi\'s RPM repository '
|
|
||||||
'(https://rpms.remirepo.net)')
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
expected_stdout = tick_box + (' Remi\'s RPM repository has '
|
|
||||||
'been enabled for PHP7')
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
remi_package = host.package('remi-release')
|
|
||||||
assert remi_package.is_installed
|
|
||||||
updated_php_package = host.package('php')
|
|
||||||
updated_php_version = updated_php_package.version.split('.')[0]
|
|
||||||
assert int(updated_php_version) == 7
|
|
||||||
|
@ -6,11 +6,8 @@ def test_epel_and_remi_not_installed_fedora(host):
|
|||||||
package_manager_detect = host.run('''
|
package_manager_detect = host.run('''
|
||||||
source /opt/pihole/basic-install.sh
|
source /opt/pihole/basic-install.sh
|
||||||
package_manager_detect
|
package_manager_detect
|
||||||
select_rpm_php
|
|
||||||
''')
|
''')
|
||||||
assert package_manager_detect.stdout == ''
|
assert package_manager_detect.stdout == ''
|
||||||
|
|
||||||
epel_package = host.package('epel-release')
|
epel_package = host.package('epel-release')
|
||||||
assert not epel_package.is_installed
|
assert not epel_package.is_installed
|
||||||
remi_package = host.package('remi-release')
|
|
||||||
assert not remi_package.is_installed
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
[tox]
|
|
||||||
envlist = py38
|
|
||||||
|
|
||||||
[testenv]
|
|
||||||
whitelist_externals = docker
|
|
||||||
deps = -rrequirements.txt
|
|
||||||
commands = docker build -f _centos_7.Dockerfile -t pytest_pihole:test_container ../
|
|
||||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_centos_common_support.py ./test_centos_7_support.py
|
|
@ -5,4 +5,4 @@ envlist = py38
|
|||||||
whitelist_externals = docker
|
whitelist_externals = docker
|
||||||
deps = -rrequirements.txt
|
deps = -rrequirements.txt
|
||||||
commands = docker build -f _centos_8.Dockerfile -t pytest_pihole:test_container ../
|
commands = docker build -f _centos_8.Dockerfile -t pytest_pihole:test_container ../
|
||||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_centos_common_support.py ./test_centos_8_support.py
|
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_centos_common_support.py
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
[tox]
|
|
||||||
envlist = py38
|
|
||||||
|
|
||||||
[testenv]
|
|
||||||
whitelist_externals = docker
|
|
||||||
deps = -rrequirements.txt
|
|
||||||
commands = docker build -f _ubuntu_21.Dockerfile -t pytest_pihole:test_container ../
|
|
||||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py
|
|
Loading…
Reference in New Issue
Block a user