Skip to content
This repository has been archived by the owner on Jul 26, 2024. It is now read-only.

Commit

Permalink
4.0.4 (#343)
Browse files Browse the repository at this point in the history
* Start 4.0.4

* SDHCP replication

* Fix typo of SDHCP

* another SDHCP reference

* Update readme
  • Loading branch information
vmstan authored May 3, 2022
1 parent 53bc721 commit 15867c0
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 11 deletions.
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,25 @@ But if you have redundant Pi-hole in your network you'll want a simple way to ke

## Features

Gravity Sync replicates the core of Pi-hole's resolver settings, which includes:
Gravity Sync replicates the core of Pi-hole's ad/telemetry blocking settings, which includes:

- Adlist settings with status and comments.
- Domain whitelist and blacklist along with status with comments.
- Custom RegEx whitelist and blacklists.
- Clients and groups, along with any list assignments.
- Domain/RegEx whitelists and blacklist along with status and comments.
- Clients and group assignments, along with status and descriptions.

Gravity Sync also replicates local network DNS/DHCP settings, which includes:

- Local DNS Records.
- Local CNAME Records.
- Static DHCP Assignments.

### Limitations

Gravity Sync will **not**:

- Modify the individual Pi-hole's upstream DNS resolvers.
- Sync DHCP settings or monitor device leases.
- Merge long term data, query logs, or statistics.
- Modify or sync the individual Pi-hole's upstream DNS resolvers.
- Merge query logs, statistics, long-term data, caches, or other resolution information.
- Sync individual Pi-hole DHCP scoping information or leases.

## Setup Steps

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.0.3
4.0.4
219 changes: 216 additions & 3 deletions gravity-sync
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ GS_RUN_START=$SECONDS

# GRAVITY SYNC BY VMSTAN #####################
PROGRAM='Gravity Sync'
GS_VERSION='4.0.3'
GS_VERSION='4.0.4'

# For documentation or the changelog/updates visit https://github.com/vmstan/gravity-sync
# Requires Pi-Hole 5.x or higher already be installed, for help visit https://pi-hole.net
Expand Down Expand Up @@ -51,6 +51,7 @@ PIHOLE_CONTAINER_IMAGE='pihole/pihole' # Official Pi-hole container ima
PH_GRAVITY_FI='gravity.db' # Pi-hole database file name
PH_CUSTOM_DNS='custom.list' # Pi-hole DNS lookup filename
PH_CNAME_CONF='05-pihole-custom-cname.conf' # DNSMASQ CNAME alias file
PH_SDHCP_CONF='04-pihole-static-dhcp.conf' # DNSMASQ Static DHCP file

# Backup Customization
GS_BACKUP_TIMEOUT='240' # replace in gravity-sync.conf to overwrite
Expand All @@ -65,6 +66,7 @@ GS_SYNCING_LOG='gs-sync.log' # replace in grav
GS_GRAVITY_FI_MD5_LOG='gs-gravity.md5' # replace in gravity-sync.conf to overwrite
GS_CUSTOM_DNS_MD5_LOG='gs-clist.md5' # replace in gravity-sync.conf to overwrite
GS_CNAME_CONF_MD5_LOG='05-pihole-custom-cname.conf.md5' # replace in gravity-sync.conf to overwrite
GS_SDHCP_CONF_MD5_LOG='04-pihole-static-dhcp.conf.md5' # replace in gravity-sync.conf to overwrite

# SSH Customization
GS_SSH_PORT='22' # replace in gravity-sync.conf to overwrite
Expand All @@ -82,6 +84,7 @@ OS_SSH_CMD='ssh'
UI_GRAVITY_NAME='Gravity Database'
UI_CUSTOM_NAME='DNS Records'
UI_CNAME_NAME='DNS CNAMEs'
UI_SDHCP_NAME='Static DHCP Addresses'
# Reused UI Text
UI_CORE_LOADING='Loading'
UI_CORE_EVALUATING='Evaluating arguments'
Expand Down Expand Up @@ -384,6 +387,28 @@ function pull_gs_cname {
fi
}

## Pull DHCP
function pull_gs_sdhcp {
if [ "$REMOTE_SDHCP_DNS" == "1" ]; then
backup_local_sdhcp
backup_remote_sdhcp

MESSAGE="${UI_PULL_REMOTE} ${UI_SDHCP_NAME}"
echo_stat
RSYNC_REPATH="sudo rsync"
RSYNC_SOURCE="${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PIHOLE_DIRECTORY}/${PH_SDHCP_CONF}.${GS_BACKUP_EXT}"
RSYNC_TARGET="${OS_TMP}/${PH_SDHCP_CONF}.${GS_BACKUP_EXT}"
create_rsync_cmd

MESSAGE="${UI_REPLACE_LOCAL} ${UI_SDHCP_NAME}"
echo_stat
sudo mv ${OS_TMP}/${PH_SDHCP_CONF}.${GS_BACKUP_EXT} ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} >/dev/null 2>&1
error_validate

validate_sdhcp_permissions
fi
}

## Pull Reload
function pull_gs_reload {
sleep 1
Expand All @@ -394,7 +419,7 @@ function pull_gs_reload {
error_validate

if [ "${GS_TASK_TYPE}" == SMART ]; then
if [ "${REMOTE_DNS_CHANGE}" == "1" ] || [ "${LOCAL_DNS_CHANGE}" == "1" ] || [ "${REMOTE_CNAME_CHANGE}" == "1" ] || [ "${LOCAL_CNAME_CHANGE}" == "1" ]; then
if [ "${REMOTE_DNS_CHANGE}" == "1" ] || [ "${LOCAL_DNS_CHANGE}" == "1" ] || [ "${REMOTE_CNAME_CHANGE}" == "1" ] || [ "${LOCAL_CNAME_CHANGE}" == "1" ] || [ "${REMOTE_SDHCP_CHANGE}" == "1" ] || [ "${LOCAL_SDHCP_CHANGE}" == "1" ]; then
MESSAGE="${UI_FTLDNS_CONFIG_PULL_RELOAD}"
echo_stat
${PH_EXEC} restartdns >/dev/null 2>&1
Expand All @@ -415,6 +440,7 @@ function pull_gs {
pull_gs_grav
pull_gs_custom
pull_gs_cname
pull_gs_sdhcp
pull_gs_reload
md5_recheck
logs_export
Expand Down Expand Up @@ -517,6 +543,34 @@ function push_gs_cname {
fi
}

## Push Custom
function push_gs_sdhcp {
if [ "$REMOTE_SDHCP_DNS" == "1" ]; then
backup_remote_sdhcp
backup_local_sdhcp

MESSAGE="${UI_PUSH_LOCAL} ${UI_SDHCP_NAME}"
echo_stat
RSYNC_REPATH="sudo rsync"
RSYNC_SOURCE="${LOCAL_PIHOLE_DIRECTORY}/${PH_SDHCP_CONF}.${GS_BACKUP_EXT}"
RSYNC_TARGET="${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}"
create_rsync_cmd

MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_SDHCP_NAME}"
echo_stat
CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
CMD_REQUESTED="sudo chown root:root ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}"
create_ssh_cmd


MESSAGE="${UI_SET_FILE_PERMISSION} ${UI_SDHCP_NAME}"
echo_stat
CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
CMD_REQUESTED="sudo chmod 644 ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}"
create_ssh_cmd
fi
}

## Push Reload
function push_gs_reload {
sleep 1
Expand All @@ -528,7 +582,7 @@ function push_gs_reload {
create_ssh_cmd

if [ "${GS_TASK_TYPE}" == SMART ]; then
if [ "${REMOTE_DNS_CHANGE}" == "1" ] || [ "${LOCAL_DNS_CHANGE}" == "1" ] || [ "${REMOTE_CNAME_CHANGE}" == "1" ] || [ "${LOCAL_CNAME_CHANGE}" == "1" ]; then
if [ "${REMOTE_DNS_CHANGE}" == "1" ] || [ "${LOCAL_DNS_CHANGE}" == "1" ] || [ "${REMOTE_CNAME_CHANGE}" == "1" ] || [ "${LOCAL_CNAME_CHANGE}" == "1" ] || [ "${REMOTE_SDHCP_CHANGE}" == "1" ] || [ "${LOCAL_SDHCP_CHANGE}" == "1" ]; then
MESSAGE="${UI_FTLDNS_CONFIG_PUSH_RELOAD}"
echo_stat
CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
Expand All @@ -551,6 +605,7 @@ function push_gs {
push_gs_grav
push_gs_custom
push_gs_cname
push_gs_sdhcp
push_gs_reload
md5_recheck
logs_export
Expand Down Expand Up @@ -586,6 +641,8 @@ function smart_gs {
LOCAL_DNS_CHANGE="0"
REMOTE_CNAME_CHANGE="0"
LOCAL_CNAME_CHANGE="0"
REMOTE_SDHCP_CHANGE="0"
LOCAL_SDHCP_CHANGE="0"

if [ "${REMOTE_DB_MD5}" != "${LAST_REMOTE_DB_MD5}" ]; then
REMOTE_GRAVITY_CHANGE="1"
Expand Down Expand Up @@ -716,6 +773,51 @@ function smart_gs {
pull_gs_cname
GS_PULL_RESTART="1"
fi

if [ "${REMOTE_SDHCP_MD5}" != "${LAST_REMOTE_SDHCP_MD5}" ]; then
REMOTE_SDHCP_CHANGE="1"
fi

if [ "${LOCAL_SDHCP_MD5}" != "${LAST_LOCAL_SDHCP_MD5}" ]; then
LOCAL_SDHCP_CHANGE="1"
fi

if [ -f "${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}" ]; then
if [ "${REMOTE_SDHCP_CHANGE}" == "${LOCAL_SDHCP_CHANGE}" ]; then
if [ "${REMOTE_SDHCP_CHANGE}" != "0" ]; then
MESSAGE="Both ${UI_SDHCP_NAME} have Changed"
echo_warn

REMOTE_SDHCP_DATE=$(${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "stat -c %Y ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}")
LOCAL_SDHCP_DATE=$(stat -c %Y ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF})

if (( "$REMOTE_SDHCP_DATE" >= "$LOCAL_SDHCP_DATE" )); then
MESSAGE="Remote ${UI_SDHCP_NAME} was last changed"
echo_warn

pull_gs_sdhcp
GS_PULL_RESTART="1"
else
MESSAGE="Local ${UI_SDHCP_NAME} was last changed"
echo_warn

push_gs_sdhcp
GS_PUSH_RESTART="1"
fi
fi
else
if [ "${REMOTE_SDHCP_CHANGE}" != "0" ]; then
pull_gs_sdhcp
GS_PULL_RESTART="1"
elif [ "${LOCAL_SDHCP_CHANGE}" != "0" ]; then
push_gs_sdhcp
GS_PUSH_RESTART="1"
fi
fi
else
pull_gs_sdhcp
GS_PULL_RESTART="1"
fi

if [ "$GS_PULL_RESTART" == "1" ]; then
pull_gs_reload
Expand Down Expand Up @@ -804,6 +906,19 @@ function backup_local_cname {
fi
}

function backup_local_sdhcp {
if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} ]; then
MESSAGE="${UI_BACKUP_LOCAL} ${UI_SDHCP_NAME}"
echo_stat

sudo cp ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} ${LOCAL_PIHOLE_DIRECTORY}/${PH_SDHCP_CONF}.${GS_BACKUP_EXT}
error_validate
else
MESSAGE="No local ${PH_SDHCP_CONF} detected"
echo_warn
fi
}

function backup_remote_gravity {
MESSAGE="${UI_BACKUP_REMOTE} ${UI_GRAVITY_NAME}"
echo_stat
Expand Down Expand Up @@ -873,6 +988,15 @@ function backup_remote_cname {
create_ssh_cmd
}

function backup_remote_sdhcp {
MESSAGE="${UI_BACKUP_REMOTE} ${UI_SDHCP_NAME}"
echo_stat

CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
CMD_REQUESTED="sudo cp ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} ${REMOTE_PIHOLE_DIRECTORY}/${PH_SDHCP_CONF}.${GS_BACKUP_EXT}"
create_ssh_cmd
}

function backup_cleanup {
MESSAGE="Purging backups"
echo_stat
Expand Down Expand Up @@ -980,6 +1104,43 @@ function md5_compare {
MESSAGE="${UI_CNAME_NAME} ${UI_HASHING_NOT_DETECTED} ${UI_HASHING_LOCAL}"
echo_warn
fi

if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} ]; then
if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}; then
REMOTE_SDHCP_DNS="1"
MESSAGE="${UI_HASHING_HASHING} ${UI_SDHCP_NAME}"
echo_stat

REMOTE_SDHCP_MD5=$(${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "md5sum ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} | sed 's/\s.*$//'")
error_validate

MESSAGE="${UI_HASHING_COMPARING} ${UI_SDHCP_NAME}"
echo_stat
LOCAL_SDHCP_MD5=$(md5sum ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} | sed 's/\s.*$//')
error_validate

if [ "$REMOTE_SDHCP_MD5" == "$LAST_REMOTE_SDHCP_MD5" ] && [ "$LOCAL_SDHCP_MD5" == "$LAST_LOCAL_SDHCP_MD5" ]; then
GS_HASH_MARK=$((GS_HASH_MARK+0))
else
MESSAGE="${UI_HASHING_DIFFERENCE} ${UI_SDHCP_NAME}"
echo_warn
GS_HASH_MARK=$((GS_HASH_MARK+1))
fi
else
MESSAGE="${UI_SDHCP_NAME} ${UI_HASHING_NOT_DETECTED} ${UI_HASHING_REMOTE}"
echo_warn
fi
else
if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}; then
REMOTE_SDHCP_DNS="1"
MESSAGE="${UI_SDHCP_NAME} ${UI_HASHING_DETECTED} ${UI_HASHING_REMOTE}"
GS_HASH_MARK=$((GS_HASH_MARK+1))
echo_warn
fi

MESSAGE="${UI_SDHCP_NAME} ${UI_HASHING_NOT_DETECTED} ${UI_HASHING_LOCAL}"
echo_warn
fi

if [ "$GS_HASH_MARK" != "0" ]; then
MESSAGE="Replication of ${UI_CORE_APP} settings is required"
Expand Down Expand Up @@ -1016,6 +1177,14 @@ function previous_md5 {
LAST_REMOTE_CN_MD5="0"
LAST_LOCAL_CN_MD5="0"
fi

if [ -f "${GS_ETC_PATH}/${GS_SDHCP_CONF_MD5_LOG}" ]; then
LAST_REMOTE_SDHCP_MD5=$(sed "1q;d" ${GS_ETC_PATH}/${GS_SDHCP_CONF_MD5_LOG})
LAST_LOCAL_SDHCP_MD5=$(sed "2q;d" ${GS_ETC_PATH}/${GS_SDHCP_CONF_MD5_LOG})
else
LAST_REMOTE_SDHCP_MD5="0"
LAST_LOCAL_SDHCP_MD5="0"
fi
}

function md5_recheck {
Expand Down Expand Up @@ -1088,6 +1257,34 @@ function md5_recheck {
MESSAGE="${UI_CNAME_NAME} ${UI_HASHING_NOT_DETECTED} ${UI_HASHING_LOCAL}"
echo_warn
fi

if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} ]; then
if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}; then
REMOTE_SDHCP_DNS="1"
MESSAGE="${UI_HASHING_REHASHING} ${UI_SDHCP_NAME}"
echo_stat

REMOTE_SDHCP_MD5=$(${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "md5sum ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} | sed 's/\s.*$//'")
error_validate

MESSAGE="${UI_HASHING_RECOMPARING} ${UI_SDHCP_NAME}"
echo_stat
LOCAL_SDHCP_MD5=$(md5sum ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} | sed 's/\s.*$//')
error_validate
else
MESSAGE="${UI_SDHCP_NAME} ${UI_HASHING_NOT_DETECTED} ${UI_HASHING_REMOTE}"
echo_warn
fi
else
if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}; then
REMOTE_SDHCP_DNS="1"
MESSAGE="${UI_SDHCP_NAME} ${UI_HASHING_NOT_DETECTED} ${UI_HASHING_REMOTE}"
echo_warn
fi

MESSAGE="${UI_SDHCP_NAME} ${UI_HASHING_NOT_DETECTED} ${UI_HASHING_LOCAL}"
echo_warn
fi
}

## Determine SSH Pathways
Expand Down Expand Up @@ -1177,6 +1374,8 @@ function logs_export {
echo -e ${LOCAL_CL_MD5} | sudo tee -a ${GS_ETC_PATH}/${GS_CUSTOM_DNS_MD5_LOG} 1> /dev/null
echo -e ${REMOTE_CN_MD5} | sudo tee -a ${GS_ETC_PATH}/${GS_CNAME_CONF_MD5_LOG} 1> /dev/null
echo -e ${LOCAL_CN_MD5} | sudo tee -a ${GS_ETC_PATH}/${GS_CNAME_CONF_MD5_LOG} 1> /dev/null
echo -e ${REMOTE_SDHCP_MD5} | sudo tee -a ${GS_ETC_PATH}/${GS_SDHCP_CONF_MD5_LOG} 1> /dev/null
echo -e ${LOCAL_SDHCP_MD5} | sudo tee -a ${GS_ETC_PATH}/${GS_SDHCP_CONF_MD5_LOG} 1> /dev/null

if [ "${GS_PEERLESS_MODE}" != "1" ]; then
sudo rm -f ${OS_TMP}/*.md5
Expand All @@ -1186,6 +1385,8 @@ function logs_export {
echo -e ${REMOTE_CL_MD5} | sudo tee -a ${OS_TMP}/${GS_CUSTOM_DNS_MD5_LOG} 1> /dev/null
echo -e ${LOCAL_CN_MD5} | sudo tee -a ${OS_TMP}/${GS_CNAME_CONF_MD5_LOG} 1> /dev/null
echo -e ${REMOTE_CN_MD5} | sudo tee -a ${OS_TMP}/${GS_CNAME_CONF_MD5_LOG} 1> /dev/null
echo -e ${LOCAL_SDHCP_MD5} | sudo tee -a ${OS_TMP}/${GS_SDHCP_CONF_MD5_LOG} 1> /dev/null
echo -e ${REMOTE_SDHCP_MD5} | sudo tee -a ${OS_TMP}/${GS_SDHCP_CONF_MD5_LOG} 1> /dev/null
error_validate

MESSAGE="Sending hashes to ${PROGRAM} peer"
Expand Down Expand Up @@ -1386,6 +1587,18 @@ function validate_cname_permissions {
error_validate
}

function validate_sdhcp_permissions {
MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_SDHCP_NAME}"
echo_stat
sudo chown root:root ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} >/dev/null 2>&1
error_validate

MESSAGE="${UI_SET_FILE_PERMISSION} ${UI_SDHCP_NAME}"
echo_stat
sudo chmod 644 ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} >/dev/null 2>&1
error_validate
}

## Validate Intent
function intent_validate {
PHASER=$((( RANDOM % 4 ) + 1 ))
Expand Down

0 comments on commit 15867c0

Please sign in to comment.