added synchole script, first working version
This commit is contained in:
parent
920842fe7d
commit
821e37cc3f
43
README.md
43
README.md
|
@ -1,3 +1,44 @@
|
||||||
# synchole
|
# synchole
|
||||||
|
|
||||||
Shell script to syncronize two or more [pi-hole](https://pi-hole.net) servers. It replicates all changes to _blacklist.txt_, _whitelist.txt_, _regex.txt_ and runs `updateGravity` on all members.
|
Shell script to syncronize two or more [pi-hole](https://pi-hole.net) servers. It replicates all changes to _blacklist.txt_, _whitelist.txt_, _regex.list_, _/etc/hosts_ and runs `updateGravity`/`restartdns` on all members.
|
||||||
|
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. Login via SSH to the `MASTER` server.
|
||||||
|
2. Create symlinks for all files you want to sync within the webroot of the `MASTER` pihole.
|
||||||
|
```
|
||||||
|
cd /var/www/html
|
||||||
|
sudo mkdir synchole
|
||||||
|
cd synchole
|
||||||
|
sudo ln -s /etc/pihole/whitelist.txt .
|
||||||
|
sudo ln -s /etc/pihole/blacklist.txt .
|
||||||
|
sudo ln -s /etc/pihole/regex.list .
|
||||||
|
sudo ln -s /etc/hosts .
|
||||||
|
```
|
||||||
|
3. Login via SSH to the `SLAVE` server.
|
||||||
|
4. Install synchole on the `SLAVE` server.
|
||||||
|
```
|
||||||
|
cd /opt
|
||||||
|
sudo git clone https://socialg.it/david/synchole.git
|
||||||
|
```
|
||||||
|
5. Configure the synchole script.
|
||||||
|
```
|
||||||
|
sudo vim /opt/synchole.sh
|
||||||
|
```
|
||||||
|
The config section is at the top of the script.
|
||||||
|
6. Create a cron job for synchole on the `SLAVE` server.
|
||||||
|
```
|
||||||
|
sudo crontab -e
|
||||||
|
```
|
||||||
|
Example cronjob: `*/5 * * * * /opt/synchole/synchole.sh -q` (this runs the synchole every 5 minutes)
|
||||||
|
7. Setup postfix to send notifications (from cron) on the `SLAVE` server.
|
||||||
|
```
|
||||||
|
<placeholder>
|
||||||
|
```
|
||||||
|
8. Repeat steps 3 through 5 for additional `SLAVE` servers.
|
||||||
|
9. Happy syncholeing!
|
||||||
|
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
- https://discourse.pi-hole.net/t/what-files-does-pi-hole-use/1684
|
||||||
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# synchole.sh
|
||||||
|
#
|
||||||
|
|
||||||
|
# **** configuration ****
|
||||||
|
LISTS="whitelist.txt blacklist.txt regex.list" #pihole files to sync
|
||||||
|
LISTS_PATH="/etc/pihole" #pihole files path
|
||||||
|
HOSTS="hosts" #hosts file
|
||||||
|
HOSTS_PATH="/etc" #hosts file path
|
||||||
|
SYNC_HOSTS=1 #enable sync of the hosts file (1=on, 0=off)
|
||||||
|
MASTER="10.1.3.2" #IP or hostname of the MASTER server
|
||||||
|
DEPENDENCIES="wget"
|
||||||
|
DEBUG=1 #enable verbose output (1=on, 0=off)
|
||||||
|
BACKUP_PATH="/etc/pihole/synchole-backups" #path to backups
|
||||||
|
TEMP_PATH="/tmp/synchole-downloads" #path to list downloads
|
||||||
|
TIMESTAMP=$(date +"%Y%m%d%H%M")
|
||||||
|
|
||||||
|
|
||||||
|
# **** functions ****
|
||||||
|
|
||||||
|
## check for elevated privileges
|
||||||
|
amiroot() {
|
||||||
|
if [ $(whoami) != "root" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## check for local environment
|
||||||
|
amipihole() {
|
||||||
|
if [ ! $(which pihole) ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## check if system is debian based
|
||||||
|
amidebian() {
|
||||||
|
if [ ! $(which apt-get) ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## output handling
|
||||||
|
log() {
|
||||||
|
case $1 in
|
||||||
|
"error")
|
||||||
|
level="\033[31m✗\033[0m"
|
||||||
|
sleep 0.2; echo -e "[$level] $2"
|
||||||
|
;;
|
||||||
|
"warn")
|
||||||
|
level="\033[33m!\033[0m"
|
||||||
|
sleep 0.2; echo -e "[$level] $2"
|
||||||
|
;;
|
||||||
|
"debug")
|
||||||
|
if [ $DEBUG -eq 1 ]; then
|
||||||
|
level="\033[2md\033[0m"
|
||||||
|
sleep 0.2; echo -e "[$level] $2"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
level="\033[32m✓\033[0m"
|
||||||
|
sleep 0.2; echo -e "[$level] $*"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
## update package sources
|
||||||
|
update_repos() {
|
||||||
|
apt-get update > /dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## install debian package
|
||||||
|
install() {
|
||||||
|
if [ -n $1 ]; then
|
||||||
|
apt-get install -y $1 &> /dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# **** start of script ****
|
||||||
|
|
||||||
|
log "Mission takeoff!"
|
||||||
|
|
||||||
|
## preflight checks
|
||||||
|
if ! amiroot; then
|
||||||
|
log error "You must be root. Exiting."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
log debug "I am root. Continuing."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! amidebian; then
|
||||||
|
log error "I am no debian based system. Exiting."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
log debug "I am debian based. Continuing."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! amipihole; then
|
||||||
|
log error "I am no pihole. Exiting."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
log debug "I am a pihole system. Continuing."
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Preflight checks passed."
|
||||||
|
|
||||||
|
##installing missing dependencies
|
||||||
|
for DEPENDENCY in $DEPENDENCIES; do
|
||||||
|
if install $DEPENDENCY; then
|
||||||
|
log debug "$DEPENDENCY successfully installed. Continuing."
|
||||||
|
else
|
||||||
|
log error "$DEPENDENCY could not be installed. Exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
log debug "All dependencies available. Continuing."
|
||||||
|
|
||||||
|
#backup local and download remote files from MASTER
|
||||||
|
if [ ! -d $BACKUP_PATH ]; then
|
||||||
|
log debug "$BACKUP_PATH does not exist. Creating."
|
||||||
|
mkdir -p $BACKUP_PATH
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log error "Something went wrong while creating $BACKUP_PATH. Exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log debug "$BACKUP_PATH exists. Continuing"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d $TEMP_PATH ]; then
|
||||||
|
mkdir -p $TEMP_PATH
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log error "Something went wrong while creating $TEMP_PATH. Exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log debug "$TEMP_PATH exists. Continuing."
|
||||||
|
fi
|
||||||
|
|
||||||
|
CHANGES=0
|
||||||
|
for LIST in $LISTS; do
|
||||||
|
if [ -r $LISTS_PATH/$LIST ]; then
|
||||||
|
cp $LISTS_PATH/$LIST $BACKUP_PATH/$LIST\_$TIMESTAMP
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log error "Something went wrong while backing up $LIST. Exiting."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
log "Successfully backed up $LIST."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log warn "$LIST not found. Skipping."
|
||||||
|
fi
|
||||||
|
|
||||||
|
wget http://$MASTER/synchole/$LIST -q -O $TEMP_PATH/$LIST
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log error "Something went wrong while downloading http://$MASTER/synchole/$LIST. Exiting."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
log "Successfully downloaded $LIST."
|
||||||
|
fi
|
||||||
|
|
||||||
|
diff $TEMP_PATH/$LIST $LISTS_PATH/$LIST
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
cp $TEMP_PATH/$LIST $LISTS_PATH/$LIST
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log error "Something went wrong installing updated file to $LIST_PATH/$LIST"
|
||||||
|
else
|
||||||
|
log debug "Successfully installed updated $LIST. Continuing."
|
||||||
|
CHANGES=1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log warn "No changes in $LIST. Skipping."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
#run updateGravity
|
||||||
|
if [ $CHANGES -eq 1 ]; then
|
||||||
|
pihole -g > /dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log error "Something went wrong while updating Gravity. Exiting."
|
||||||
|
else
|
||||||
|
log "Successfully updated Gravity."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log warn "No files have been changed. Skipping Gravity update."
|
||||||
|
fi
|
||||||
|
|
||||||
|
#sync hosts
|
||||||
|
#run restartdns (if hosts updates)
|
||||||
|
|
||||||
|
log "Touchdown! Mission success."
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
# **** end of script ****
|
Reference in New Issue