#!/usr/bin/bash # clusterfix: Quick fixer for DNS cluster issues # Nathan P. # 0.5a set -euo pipefail # Version information VERSION='0.5a' # Nice text formatting options TEXT_BOLD='\e[1m' TEXT_UNSET='\e[0m' # Help message show_help() { cat << EOF $(echo -e "${TEXT_BOLD}")clusterfix:$(echo -e "${TEXT_UNSET}") Quick fixer for DNS cluster issues USAGE: clusterfix [-m] --help -h Show this message --version -v Show version information --message -m Get a free compliment EOF } # Who doesn't like receiving a compliment? NICE_MESSAGES=('Is that a new shirt?' "I'd back you up in a bear cage deathmatch any day." "You're the human version of a perfectly toasted marshmallow." "Lookin' good today!" 'Your taste in socks is impeccable.' "Don't listen to Steve. Stamp collecting is cool.") # Get all our variables and ducks in a row and do all the things fix_cluster() { # First we check what control panel we have. If neither cPanel nor CWP is # found, there's no reason to keep going. if [[ -e '/usr/local/cpanel/version' ]]; then # We use rsync to copy the updated config to resellers on cPanel servers if ! command -v rsync > /dev/null; then echo 'Error: rsync not found in PATH. clusterfix on cPanel requires rsync to work.' >&2 exit 1 fi server='cPanel' dns_cluster_dir='/var/cpanel/cluster' dns_auth_file="${dns_cluster_dir}/root/config/imh" dns_command='/opt/dedrads/dns-sync' if grep -Evq ': root$' /etc/trueuserowners; then resellers="$(grep -Ev ': root$' /etc/trueuserowners | awk -F ': ' '{print $2}' | sort -u)" fi fi if [[ -e '/usr/local/cwp/.conf/cwp.ini' ]]; then server='CWP' dns_cluster_dir='/opt/imh-cwp-dns' dns_auth_file="${dns_cluster_dir}/config/key" dns_command='/opt/imh-cwp-dns/update_all_zones' fi if [[ ! -v server ]]; then echo -e "Couldn't detect the server's control panel. Is this a cPanel or CWP server?" >&2 exit 1 fi # Sometimes there might not be any DNS cluster configuration set up. In # that case, we want to let the user know and exit here. if [[ ! -e "${dns_auth_file}" ]]; then echo 'The root DNS cluster configuration is missing!' >&2 if [[ "${server}" = 'cPanel' ]]; then echo echo 'Check WHM => Clusters => DNS Cluster and make sure the IMH DNS backend is' >&2 echo 'configured and enabled.' >&2 fi exit 1 fi # CWP normally has BIND active, but cPanel might not have a DNS server # installed at all. No reason to waste time with this if the domains aren't # even using our name servers. if [[ "$(systemctl is-active named)" = 'active' ]] || [[ "$(systemctl is-active pdns)" = 'active' ]]; then echo -e "${TEXT_BOLD}Heads up!${TEXT_UNSET} BIND or PowerDNS is currently active. Make sure our DNS cluster is" echo 'actually being used before continuing.' echo fi echo 'Enter the DNS auth user and key. They look like this:' echo '* User: 867530-fernando@example.com' echo '* Key: TURDVkZCcmZ3NUNJSXM5 [...] dlJya0NLVzdYV3NFU1A2' echo read -erp '🧔 User: ' dns_auth_user read -erp '🔑 Key: ' dns_auth_key echo # Now we update the DNS auth config file with our new values if [[ "${server}" = 'cPanel' ]]; then sed -Ei "s/^user=.+/user=${dns_auth_user}/" "${dns_auth_file}" sed -Ei "s/^apikey=.+/apikey=${dns_auth_key}/" "${dns_auth_file}" # We also sync the changes to any resellers if [[ -v resellers ]]; then for reseller in ${resellers}; do rsync -az "${dns_cluster_dir}/root/" "${dns_cluster_dir}/${reseller}/" done fi # Running clusterfix usually means some or none of the domains have # up-to-date DNS. So a mass resync is done after the config is updated. while read -rd '' domain; do domain="$(basename "${domain}" .db)" "${dns_command}" -s "${domain}" done < <(find /var/named -maxdepth 1 -type f -name '*.db' -print0) fi if [[ "${server}" = 'CWP' ]]; then sed -Ei "s/^.+:.+/${dns_auth_user}:${dns_auth_key}/" "${dns_auth_file}" "${dns_command}" fi echo echo 'Done! Check the output above for errors and fix as needed. Have a beefy day! 🌭' } # Command options while [[ "${#}" -gt 0 ]]; do case "${1}" in --help | -h) show_help exit 0 ;; --version | -v) echo -e "${TEXT_BOLD}clusterfix${TEXT_UNSET} ${VERSION}" exit 0 ;; --message | -m) echo "${NICE_MESSAGES[${RANDOM} % ${#NICE_MESSAGES[@]}]}" exit 0 ;; -*) echo -e "Not sure what \"${*}\" is supposed to mean..." >&2 echo show_help exit 1 ;; *) echo -e "clusterfix doesn't like arguments. Please don't \"${*}\" at it." echo break ;; esac done # Run main fuction fix_cluster