256 lines
5.1 KiB
Bash
Executable File
256 lines
5.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
#
|
|
# synchole.sh
|
|
# Pi-Hole syncronizer
|
|
#
|
|
|
|
# **** configuration ****
|
|
|
|
MASTER="10.1.3.2" #IP or hostname of the MASTER server
|
|
DEBUG=1 #enable verbose output (1=on, 0=off)
|
|
BACKUP_VERSIONS=10 #how many backups should be kept
|
|
BACKUP_PATH="/etc/pihole/synchole-backups" #path to backups
|
|
DOWNLOAD_PATH="/tmp/synchole-downloads" #path to list downloads
|
|
|
|
LISTS="whitelist.txt blacklist.txt regex.list" #pihole files to sync
|
|
LISTS_PATH="/etc/pihole" #pihole files path
|
|
|
|
NAME="synchole"
|
|
VERSION="0.1"
|
|
AUTHOR="david@socialnerds.org"
|
|
LICENSE="GPLv3"
|
|
DEPENDENCIES="wget"
|
|
|
|
|
|
# **** functions ****
|
|
|
|
## check for elevated privileges
|
|
amiroot() {
|
|
if [ $(whoami) != "root" ]; then
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
## check if pi-hole is installed
|
|
amipihole() {
|
|
if [ ! $(which /usr/local/bin/pihole) ]; then
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
## output handling
|
|
log() {
|
|
|
|
if [ -t 1 ]; then
|
|
CRON=0
|
|
else
|
|
CRON=1
|
|
fi
|
|
|
|
case $1 in
|
|
"error")
|
|
level="\033[31m✗\033[0m"
|
|
;;
|
|
"warn")
|
|
level="\033[33m!\033[0m"
|
|
;;
|
|
"debug")
|
|
if [ $DEBUG -eq 1 ] && [ $CRON -eq 0 ]; then
|
|
level="\033[2md\033[0m"
|
|
else
|
|
return 0
|
|
fi
|
|
;;
|
|
"success")
|
|
if [ $CRON -eq 0 ]; then
|
|
level="\033[32m✓\033[0m"
|
|
else
|
|
return 0
|
|
fi
|
|
;;
|
|
"info")
|
|
if [ $CRON -eq 0 ]; then
|
|
level="i"
|
|
else
|
|
return 0
|
|
fi
|
|
;;
|
|
*)
|
|
level="\033[31mLoglevel unknown. Programming error? ($1)\033[0m"
|
|
;;
|
|
esac
|
|
|
|
sleep 0.5; echo -e "[$NAME]-[$level] ${@:2}"
|
|
}
|
|
|
|
## backup single list file to $BACKUP_PATH
|
|
backup_list() {
|
|
if [ -z $1 ]; then
|
|
return 1
|
|
else
|
|
for VERSION in $(eval echo {$BACKUP_VERSIONS..1}); do
|
|
if [ -w $BACKUP_PATH/$1.$VERSION ]; then
|
|
if [ $VERSION -eq $BACKUP_VERSIONS ]; then
|
|
rm $BACKUP_PATH/$1.$VERSION
|
|
else
|
|
mv $BACKUP_PATH/$1.$VERSION $BACKUP_PATH/$1.$(($VERSION+1))
|
|
fi
|
|
fi
|
|
done
|
|
if [ -w $BACKUP_PATH/$1 ]; then
|
|
cp $BACKUP_PATH/$1 $BACKUP_PATH/$1.1
|
|
fi
|
|
if [ -r $LISTS_PATH/$1 ]; then
|
|
cp $LISTS_PATH/$1 $BACKUP_PATH/$1
|
|
if [ $? -ne 0 ]; then
|
|
return 1
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
## create path/to/folder if it does not exist
|
|
create_path() {
|
|
if [ -z $1 ]; then
|
|
return 1
|
|
else
|
|
if [ ! -d $1 ]; then
|
|
mkdir -p $1
|
|
if [ $? -ne 0 ]; then
|
|
return 1
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
## update pi-hole lists (run updateGravity)
|
|
update_gravity() {
|
|
/usr/local/bin/pihole -g > /dev/null
|
|
if [ $? -ne 0 ]; then
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
## install new list
|
|
install_list() {
|
|
if [ -z $1 ]; then
|
|
return 1
|
|
else
|
|
cp $DOWNLOAD_PATH/$1 $LISTS_PATH/$1
|
|
if [ $? -ne 0 ]; then
|
|
return 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
## download remote file
|
|
download_list() {
|
|
if [ -z $1 ]; then
|
|
return 1
|
|
else
|
|
wget http://$MASTER/synchole/$1 -q -O $DOWNLOAD_PATH/$1
|
|
if [ $? -ne 0 ]; then
|
|
return 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# **** start of script ****
|
|
|
|
log debug "Starting synchole"
|
|
|
|
## preflight checks
|
|
log debug "Running preflight checks"
|
|
|
|
|
|
if ! amiroot; then
|
|
log error "You must be root"
|
|
exit 1
|
|
fi
|
|
|
|
if ! amipihole; then
|
|
log error "I am no pihole"
|
|
exit 1
|
|
fi
|
|
|
|
for DEPENDENCY in $DEPENDENCIES; do
|
|
if [ ! $(which $DEPENDENCY) ]; then
|
|
log error "$DEPENDENCY is not installed"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
log success "Preflight checks passed successfully"
|
|
|
|
## generate $BACKUP_PATH and $DOWNLOAD_PATH if not available
|
|
if ! create_path $DOWNLOAD_PATH; then
|
|
log error "Something went wrong while creating $DOWNLOAD_PATH"
|
|
exit 1
|
|
fi
|
|
|
|
if ! create_path $BACKUP_PATH; then
|
|
log error "Something went wrong while creating $BACKUP_PATH"
|
|
exit 1
|
|
fi
|
|
|
|
## download remote files from MASTER and backup local lists
|
|
CHANGES=0
|
|
for LIST in $LISTS; do
|
|
log debug "Downloading $LIST from $MASTER"
|
|
if ! download_list $LIST; then
|
|
log error "Something went wrong while downloading $LIST"
|
|
exit 1
|
|
else
|
|
log success "Successfully downloaded $LIST"
|
|
fi
|
|
|
|
#TODO: don't install new list if to many changes or
|
|
# somehow verify if new file is an actual list
|
|
# maybe check if wget actually downloaded a file or were we redirected
|
|
diff $DOWNLOAD_PATH/$LIST $LISTS_PATH/$LIST
|
|
if [ $? -ne 0 ]; then
|
|
log debug "Backing up $LIST"
|
|
if [ -r $LISTS_PATH/$LIST ]; then
|
|
if ! backup_list $LIST; then
|
|
log error "Something went wrong while backing up $LIST"
|
|
exit 1
|
|
else
|
|
log debug "Successfully backed up $LIST"
|
|
fi
|
|
else
|
|
log debug "$LIST not found, skipping"
|
|
fi
|
|
|
|
log debug "Installing $LIST."
|
|
if ! install_list $LIST; then
|
|
log error "Something went wrong while installing $LIST"
|
|
exit 1
|
|
else
|
|
log success "Successfully installed new $LIST"
|
|
CHANGES=1
|
|
fi
|
|
else
|
|
log debug "No changes in $LIST"
|
|
fi
|
|
done
|
|
|
|
## run updateGravity
|
|
if [ $CHANGES -eq 1 ]; then
|
|
log debug "Updating gravity"
|
|
if ! update_gravity; then
|
|
log error "Something went wrong while updating gravity"
|
|
exit 1
|
|
else
|
|
log success "Gravity has been successfully updated"
|
|
fi
|
|
else
|
|
log debug "No files have been changed, skipping gravity update"
|
|
fi
|
|
|
|
#TODO: sync hosts and restartdns on changes
|
|
|
|
exit 0
|
|
|
|
# **** end of script ****
|