├── LICENSE ├── pihole_static_sort ├── pihole_ipv6_check ├── pihole_dns4_sync └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Steve Jenkins 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /pihole_static_sort: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################################################### 4 | 5 | # pihole_static_sort 6 | # Sorts the dnsmasq configuration file used by Pi-hole's DHCP server 7 | # for static DHCP reservations. 8 | 9 | # Version 1.1 - Jan 15, 2019 - Steve Jenkins (stevejenkins.com) 10 | 11 | # USAGE 12 | # Run ./pihole_static_sort from the command line 13 | 14 | ########################################################################### 15 | 16 | # Constants 17 | dnsmasq_dir='/etc/dnsmasq.d' 18 | static_file='04-pihole-static-dhcp.conf' 19 | 20 | # Only used for debugging 21 | # set -x 22 | 23 | # Backup original static file and make working copy 24 | printf "\nBacking up $dnsmasq_dir/$static_file to /tmp...\n" 25 | cp $dnsmasq_dir/$static_file /tmp/$static_file.orig 26 | cp $dnsmasq_dir/$static_file /tmp 27 | 28 | # Sort working copy 29 | printf "\nSorting static DHCP entries:\n" 30 | #sort -u -n -t, -k2V /tmp/$static_file | tr '[:upper:]' '[:lower:]' > /tmp/$static_file.sort 31 | sort -u -n -t, -k2V /tmp/$static_file > /tmp/$static_file.sort 32 | 33 | # Display entry counts 34 | orig_file_count="$(wc -l < /tmp/$static_file.orig)" 35 | sort_file_count="$(wc -l < /tmp/$static_file.sort)" 36 | printf "$orig_file_count original entries!\n$sort_file_count sorted entries!\n" 37 | 38 | # Copy sorted file to original location 39 | printf "\nWriting sorted entries to $dnsmasq_dir/$static_file...\n" 40 | sudo cp -f /tmp/$static_file.sort $dnsmasq_dir/$static_file 41 | 42 | # Restarting pihole-FTL service 43 | printf "\nRestarting pihole-FTL service...\n" 44 | sudo service pihole-FTL restart 45 | 46 | # All done! 47 | printf "\nDone!\n" 48 | exit 49 | -------------------------------------------------------------------------------- /pihole_ipv6_check: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################################################### 4 | 5 | # pihole_ipv6_check 6 | 7 | # Checks the Pi-hole server's current IPv6 address and updates the 8 | # IPv6 address configured in /etc/pihole/setupVars.conf if necessary. 9 | # Fixes Pi-hole timeout issue reported at http://bit.ly/2EHWSFy. 10 | 11 | # Part of https://github.com/stevejenkins/pihole-utils/ 12 | 13 | # Version 2.2 - Mar 24, 2019 - Steve Jenkins (stevejenkins.com) 14 | # Rename script for uniformity 15 | # Add repo link in script comments 16 | 17 | # Version 2.1 - Jan 20, 2019 - Steve Jenkins (stevejenkins.com) 18 | # User can select which adapter is used for IPv6 check 19 | 20 | # Version 2.0 - Jan 20, 2019 - Steve Jenkins (stevejenkins.com) 21 | # Changed local IPv6 check method to support wider range of Linux variants 22 | 23 | # Version 1.1 - Feb 14, 2018 - Steve Jenkins (stevejenkins.com) 24 | # Fixed awk statement for current Pi-hole configured address 25 | # Modernized shell script expressions 26 | # Added comments to script 27 | 28 | # Version 1.0 - linuxpng (https://pastebin.com/Wd0Qyfyw) 29 | # Original version of script 30 | 31 | # USAGE 32 | # You can run ./pihole_ipv6_check from the command line, or run it hourly by 33 | # adding the following to your crontab: 34 | 35 | # @hourly /usr/local/bin/pihole-utils/pihole_ipv6_check > /dev/null 2>&1 #Check Pi-hole IPv6 configuration 36 | 37 | ########################################################################### 38 | # USER-CONTROLLED OPTIONS 39 | 40 | PIHOLE_ADAPTER=eth1 41 | 42 | ########################################################################### 43 | 44 | # Only used for debugging 45 | # set -x 46 | 47 | # Check host's current Global IPv6 address 48 | current_ipv6=$(ip -6 addr show dev $PIHOLE_ADAPTER | awk '/inet6/{print $2}' | head -n 1 | awk -F'/' '{print $1}') 49 | printf "\nCurrent adapter IPv6 address: $current_ipv6\n" 50 | 51 | # Check IPv6 address configured in Pi-hole 52 | pihole_ipv6=$(grep IPV6_ADDRESS < /etc/pihole/setupVars.conf | awk -F '=' '{print $2}') 53 | 54 | printf "Pi-hole configured IPv6 address: $pihole_ipv6\n" 55 | 56 | # Exit if IPv6 addresses match 57 | if [ "$current_ipv6" = "$pihole_ipv6" ]; then 58 | printf '\nIPv6 addresses match! No action required.\n' 59 | exit 0 60 | 61 | else 62 | 63 | # Update the IPv6 address in setupVars.conf with the host's IPv6 address 64 | printf '\nUpdating Pi-hole configuration...\n' 65 | sed -i "s/IPV6_ADDRESS=.*/IPV6_ADDRESS=${current_ipv6}/g" /etc/pihole/setupVars.conf; 66 | 67 | # Run pihole -g to pick up changes 68 | printf '\nReloading Pi-hole...\n\n' 69 | pihole -g 70 | 71 | # All done! 72 | printf '\nDone!\n' 73 | exit 1 74 | fi 75 | -------------------------------------------------------------------------------- /pihole_dns4_sync: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################################################### 4 | 5 | # pihole_dns4_sync 6 | 7 | # In a dual Pi-hole setup, this script fetches the IPv6 of the remote Pi-hole 8 | # at sets it as the custom DNS4 setting (using port 5353) on the local Pi-hole. 9 | # This is useful in configurations where the Pi-holes use Unbound as a local 10 | # resolver on a LAN with dynamic IPv6 addressing. 11 | 12 | # REQUIREMENTS 13 | # Two Pi-holes on the same LAN with functioning IPv6 addresses. 14 | # Both Pi-holes running Unbound as a local DNS resolver on port 5353. 15 | # SSH key-based authentication (login without password) configured so the 16 | # local Pi-hole server running this script can log into the remote Pi-hole 17 | # without a password. See: 18 | # https://www.raspberrypi.org/documentation/remote-access/ssh/passwordless.md 19 | 20 | # Version 1.0 - Mar 24, 2019 - Steve Jenkins (stevejenkins.com) 21 | # Original version of script 22 | 23 | # USAGE 24 | # You can run ./pihole_dns4_sync from the command line, or run it 25 | # hourly by adding the following to your crontab: 26 | 27 | # @hourly /usr/local/bin/pihole-utils/pihole_dns4_sync > /dev/null 2>&1 #Sync dual Pi-hole IPv6 DNS4 config 28 | 29 | ########################################################################### 30 | # USER-CONTROLLED OPTIONS 31 | LOCAL_PIHOLE_CONFIG=/etc/pihole/setupVars.conf 32 | REMOTE_PIHOLE_USER=root 33 | REMOTE_PIHOLE_HOST=192.168.1.106 34 | UNBOUND_PORT=5353 35 | # REMEMBER TO SET UP SSH KEYS SO THIS HOST CAN SSH TO OTHER PIHOLE WITHOUT PASSWORD! 36 | ########################################################################### 37 | 38 | # Only used for debugging 39 | # set -x 40 | 41 | # Copy remote Pi-hole's setupVars.conf to temp folder 42 | printf "Fetching remote Pi-hole setupVars.conf...\n" 43 | scp "$REMOTE_PIHOLE_USER"@"$REMOTE_PIHOLE_HOST":/etc/pihole/setupVars.conf /tmp/setupVars.remote 44 | 45 | printf "\nComparing remote IPv6 address to local custom DNS4 entry...\n" 46 | 47 | # Check remote IPv6 address configured in Pi-hole 48 | pihole_ipv6_remote=$(grep IPV6_ADDRESS < /tmp/setupVars.remote | awk -F '=' '{print $2}') 49 | printf "Remote Pi-hole IPv6 address: %s\n" "$pihole_ipv6_remote" 50 | 51 | # Check local IPv6 address configured in Pi-hole 52 | dns4_ipv6_local=$(grep PIHOLE_DNS_4 < ${LOCAL_PIHOLE_CONFIG} | awk -F '=' '{print $2}' | awk -F '#' '{print $1}') 53 | printf "Local Pi-hole custom DNS4: %s\n" "$dns4_ipv6_local" 54 | 55 | if [ "$pihole_ipv6_remote" = "$dns4_ipv6_local" ]; then 56 | printf "\nIPv6 addresses match! No action required.\n" 57 | exit 1 58 | else 59 | # Update the DNS4 entry in /etc/setupVars.conf with the remote Pi-hole's IPv6 address on Unbound port 60 | printf '\nAddresses do not match! Updating Pi-hole configuration...\n' 61 | grep -q 'PIHOLE_DNS_4' ${LOCAL_PIHOLE_CONFIG} && sed -i "s/PIHOLE_DNS_4=.*/PIHOLE_DNS_4=${pihole_ipv6_remote}#${UNBOUND_PORT}/" ${LOCAL_PIHOLE_CONFIG} || echo "PIHOLE_DNS_4=${pihole_ipv6_remote}#5353" >> ${LOCAL_PIHOLE_CONFIG} 62 | 63 | 64 | # Run pihole -g to pick up changes 65 | printf '\nReloading Pi-hole...\n\n' 66 | pihole -g 67 | 68 | # All done! 69 | printf '\nDone!\n' 70 | exit 1 71 | fi 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pihole-utils - A Growing Collection of Utilities for the Pi-hole Ad Blocker 2 | This repo contains a collection of helper scripts I use in conjunction with the popular [Pi-hole](https://pi-hole.net/) ad blocking server. For more info visit the Pi-hole [website](https://pi-hole.net/) or [GitHub repo](https://github.com/pi-hole/pi-hole). 3 | 4 | ## Installing the pihole-utils Collection 5 | You can download the latest stable version of these Pi-hole helper scripts directly to your Raspberry Pi (or to any other Linux-based Pi-hole server) directly from GitHub. If you don't already have ```git``` installed on your system, do: 6 | 7 | ```sudo apt-get update && sudo apt-get -y install git``` 8 | 9 | then install the ```pihole-utils``` collection with: 10 | 11 | ```sudo git clone https://github.com/stevejenkins/pihole-utils.git``` 12 | 13 | Please feel free to improve these scripts and/or submit your own Pi-hole helper scripts for inclusion in this repo. 14 | 15 | ## pihole_static_sort - Sorts the Pi-hole Static DHCP Lease File 16 | A script that sorts the DHCP static lease file (```/etc/dnsmasq.d/04-pihole-static-dhcp.conf```) by IP address for easier manual editing and verification. If this file is misconfigured or contains duplicates, dnsmasq won't start and Pi-hole won't issue DHCP addresses. The ability to visually scan through a sorted file is helpful when troubleshooting... and also makes those of us with OCD tendencies breathe easier when we cat the file. :) 17 | 18 | I plan on adding command-line options in a future version that allow a choice of whether to sort by MAC address, IP address, or hostname. But for now, if you're familiar with the Linux ```sort``` command, you can edit the appropriate line of the script to make the ```sort``` command do what you want before it writes the sorted file back to the ```/etc/dnsmasq.d``` directory. 19 | 20 | ### Requirements 21 | ```pihole_static_sort``` requires that you have Pi-hole running on your system. 22 | 23 | ### Usage 24 | 1. Clone or download the ```pihole-utils``` repo to your host's `/usr/local/bin/` directory. 25 | 2. Run ```/usr/local/bin/pihole-utils/pihole_static_sort``` from the command line. 26 | 27 | ### Credits 28 | * Original version of the IPv6 address-checking script written by *linuxpng* in this thread on the Pi-hole support forums. 29 | 30 | ## pihole_ipv6_check - Pi-hole IPv6 Configuration Updater 31 | A script that checks the Pi-hole server's current IPv6 address, compares it to the IPv6 address configured in ```/etc/pihole/setupVars.conf```, then updates the configuration if necessary. 32 | 33 | ### Why pihole_ipv6_check? 34 | If your ISP changes your Pi-hole host's IPv6 Global Unicast Address, Pi-hole becomes misconfigured and your clients will time out when trying to load certain pages. Running ```pihole_ipv6_check``` fixes the issue... at least until your ISP changes your IPv6 address again! 35 | 36 | More info about what causes certain Pi-hole slowdowns can be found here: 37 | 38 | https://pi-hole.net/2018/02/02/why-some-pages-load-slow-when-using-pi-hole-and-how-to-fix-it/ 39 | 40 | ### Requirements 41 | ```pihole_ip6_check``` requires that you have Pi-hole running on your system. 42 | 43 | ### Usage 44 | 1. Clone or download the ```pihole-utils``` repor to your host's `/usr/local/bin/` directory. 45 | 2. Run ```/usr/local/bin/pihole-utils/pihole_ipv6_check``` from the command line. 46 | 47 | Once you're satisfied with pihole_ipv6_check's performance, set an hourly cron job for the ```root``` user to run ```pihole_ipv6_check``` like this: 48 | 49 | @hourly /usr/local/bin/pihole-utils/pihole_ipv6_check > /dev/null 2>&1 #Check Pi-hole IPv6 configuration 50 | 51 | ## pihole_dns4_sync - Pi-hole + Unbound IPv6 Custom DNS4 Sync 52 | In a dual Pi-hole setup, this script fetches the IPv6 of the remote Pi-hole from its ```/etc/pihole/setupVars.conf``` file and sets it as the custom DNS4 setting (using port 5353) in the local Pi-hole ```/etc/pihole/setupVars.conf``` file. This is useful in configurations where the Pi-holes use Unbound as a local resolver on a dynamically-addressed IPv6 LAN. 53 | 54 | ### Requirements 55 | - Two Pi-holes running on your LAN with valid IPv6 addresses. 56 | - Both Pi-holes running Unbound as a local DNS resolver on port 5353. 57 | - SSH key-based authentication (login without password) configured so the local Pi-hole server running this script can log into the remote Pi-hole without a password. 58 | 59 | ### Usage 60 | 1. Clone or download the ```pihole-utils``` repor to your host's `/usr/local/bin/` directory. 61 | 2. Set up "passwordless" SSH access from the local Pi-hole to the remote Pi-hole so that the local ```root``` user can access the remote Pi-hole via SSH without a password. This must be set up for the local ```root``` user, which allows the script to operate properly when executed via ```sudo```. Instructions can be found here. 62 | 3. Run ```/usr/local/bin/pihole-utils/pihole_dns4_sync``` from the command line. 63 | 64 | It's vitally important that a local Pi-hole's ```setupVars.conf``` file contain the host's correct IPv6 address before a remote Pi-hole fetches the address it via ```pihole_dns4_sync```. Therefore, I recommend that dynamic IPv6 addressed Pi-holes run the ```pihole_ipv6_check``` script via cron a few minutes before running the ```pihole_dns4_sync``` script. 65 | 66 | Once you've tested and are satisfied with ```pihole_dns4_sync```'s performance, set two cron jobs for the ```root``` user to run ```pihole_ipv6_check``` and ```pihole_dns4_sync``` 5 minutes apart like this: 67 | 68 | 30 * * * * /usr/local/bin/pihole-utils/pihole_ipv6_check > /dev/null 2>&1 #Check Pi-hole IPv6 configuration 69 | 35 * * * * /usr/local/bin/pihole-utils/pihole_dns4_sync > /dev/null 2>&1 #Sync dual Pi-hole IPv6 DNS4 config 70 | --------------------------------------------------------------------------------