Skip to content

Instantly share code, notes, and snippets.

@thedanbob
Last active August 15, 2022 13:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thedanbob/13f88ca8c21cb2ab7904ec5a6e9fff7e to your computer and use it in GitHub Desktop.
Save thedanbob/13f88ca8c21cb2ab7904ec5a6e9fff7e to your computer and use it in GitHub Desktop.
Update IP
#!/bin/bash
echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6
echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6
echo 0 > /proc/sys/net/ipv6/conf/default/disable_ipv6
echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6
rc-service dhcpcd restart -q 2>/dev/null
#!/bin/sh
domain="[redacted]"
json="Content-Type: application/json"
unifi="https://unifi.$domain/api"
unifi_resolve="unifi.$domain:443:10.0.0.2"
unifi_user="[redacted]"
unifi_pass="[redacted]"
cloudflare="https://api.cloudflare.com/client/v4/zones/[redacted]/dns_records"
cf_token="Authorization: Bearer [redacted]"
# Get current DNS record
record=$(curl -X GET -H "$json" -H "$cf_token" -s $cloudflare | jq ".result[] | select(.name==\"$domain\")" 2>/dev/null)
if [ $? -ne 0 ]; then
echo "[Update IP] Failed to get current record from Cloudflare."
exit 1
fi
# Login to unifi controller and capture cookie
cookie=$(curl -X POST -H "$json" --resolve $unifi_resolve -d "{\"username\":\"$unifi_user\",\"password\":\"$unifi_pass\"}" -ks -o /dev/null -c - $unifi/login)
# Check if cookie was set by stripping out comments and blank lines
if [ -z "$(echo "$cookie" | sed -E '/^(#|$)/d')" ]; then
echo "[Update IP] Unifi login failed."
exit 1
fi
# Get WAN address of USG
ip=$(echo "$cookie" | curl -X GET -H "$json" --resolve $unifi_resolve -b - -ks $unifi/s/default/stat/device | jq -r '.data[] | select(.model=="UGW3") | .wan1.ip')
if [ -z "$ip" ]; then
echo "[Update IP] Failed to get external IP."
exit 1
fi
# Make sure we didn't get an erroneous address
if [ "$ip" = "0.0.0.0" ] || [ "${ip:0:3}" = "10." ] || ([ "${ip:0:4}" = "172." ] && [ "${ip:6:1}" = "." ] && [ ${ip:4:2} -ge 16 ] && [ ${ip:4:2} -lt 32 ]) || [ "${ip:0:8}" = "192.168." ]; then
echo "[Update IP] WAN IP in private range: $ip"
exit 1
fi
# Update A record if IP has changed
if [ -n "$record" ] && [ "$(echo $record | jq -r 'select(.type=="A").content')" != "$ip" ]; then
echo "[Update IP] IPv4 is now $ip"
curl -X PATCH -H "$json" -H "$cf_token" -d "{\"content\":\"$ip\"}" -s "$cloudflare/$(echo $record | jq -r 'select(.type=="A").id')"
fi
# Get our IPv6 address
ipv6=$(ip -6 addr show dev eth0 | sed -nr 's|\s+inet6 ([0-9a-f:]+)/[0-9]{2} scope global.+|\1|p')
if [ -z "$ipv6" ]; then
/root/scripts/fix-ipv6.sh
ipv6=$(ip -6 addr show dev eth0 | sed -nr 's|\s+inet6 ([0-9a-f:]+)/[0-9]{2} scope global.+|\1|p')
if [ -z "$ipv6" ]; then
echo "[Update IP] Failed to get IPv6."
exit 1
fi
fi
# Get our IPv6 address according to USG
usg_ipv6=$(echo "$cookie" | curl -X GET -H "$json" --resolve $unifi_resolve -b - -ks $unifi/s/default/rest/firewallgroup | jq -r '.data[] | select(.name=="Server IPv6")')
# Update USG if changed
if [ -n "$usg_ipv6" ] && [ "$(echo "$usg_ipv6" | jq -r '.group_members[]')" != "$ipv6" ]; then
echo "$cookie" | curl -X PUT -H "$json" --resolve $unifi_resolve -b - -d "{\"group_members\":[\"$ipv6\"]}" -ks $unifi/s/default/rest/firewallgroup/$(echo $usg_ipv6 | jq -r '._id')
fi
# Logout unifi
echo "$cookie" | curl -X POST --resolve $unifi_resolve -b - -ks -o /dev/null $unifi/logout
# Update AAAA record if IP has changed
if [ -n "$record" ] && [ "$(echo $record | jq -r 'select(.type=="AAAA").content')" != "$ipv6" ]; then
echo "[Update IP] IPv6 is now $ipv6"
curl -X PATCH -H "$json" -H "$cf_token" -d "{\"content\":\"$ipv6\"}" -s "$cloudflare/$(echo $record | jq -r 'select(.type=="AAAA").id')"
else
exit 0
fi
dockerdir=/srv/docker
composefile=$dockerdir/docker-compose.yml
prefix=$(echo $ipv6 | sed -r 's/(.+)(:[0-9a-f]{1,4}){4}/\1/')
# Update haproxy with new IPv6 subnet
sed -i -r 's|([0-9a-f:]{1,4}:){4}:/64|'$prefix'::/64|g' $dockerdir/haproxy/haproxy.cfg
docker-compose -f $composefile kill -s USR2 haproxy >/dev/null 2>&1
# Do the same for secondary DNS server
echo "
sed -i -r 's|([0-9a-f:]{1,4}:){4}:/64|$prefix::/64|g' $dockerdir/haproxy/haproxy.cfg
docker-compose -f $composefile kill -s USR2 haproxy >/dev/null 2>&1
" | ssh root@10.0.0.3 bash
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment