diff --git a/src/content/unix/reverse-proxy.md b/src/content/unix/reverse-proxy.md index 54df59a..d1e51f0 100644 --- a/src/content/unix/reverse-proxy.md +++ b/src/content/unix/reverse-proxy.md @@ -1,7 +1,7 @@ --- title: 'Bypass Network Lockdowns' description: 'Reverse Proxies and SDWAN' -updateDate: 'Apr 21 2024' +updateDate: 'July 17 2024' --- I manage the network infrastructure for a [robotics club](https://arvp.org) on @@ -213,22 +213,28 @@ changes. I use the script below to do this. Fill in the `HOST`, `DOMAIN`, #!/usr/bin/env bash declare wan_ip_record wan_ip cf_records host_record cf_host_ip cf_rec_id -declare -r HOST='mycomputer' +declare -r HOST4='mycomputer' +declare -r HOST6='mycomputer6' declare -r DOMAIN='example.com' -declare -r TOKEN='...' -declare -r ZONE_ID='...' +declare -r TOKEN='CLOUDFLARE_TOKEN_HERE' +declare -r ZONE_ID='CLOUDFLARE_ZONEID_HERE' + +utc_date() { + date -u +'%Y-%m-%d_%H-%M-%S_UTC' +} #╔─────────────────────────────────────────────────────────────────────────────╗ #│ Gετ WΛN IP | #╚─────────────────────────────────────────────────────────────────────────────╝ -if ! wan_ip_record="$(curl ifconfig.me)"; then - echo "Hosts timed out" >&2 +# Comment out as needed. Many home networks don't have ipv6 support +if ! wan_ipv4="$(curl -s https://api4.ipify.org)"; then + echo "Request for ipv4 WAN timed out" >&2 + exit 1 +elif ! wan_ipv6="$(curl -s https://api6.ipify.org)"; then + echo "Request for ipv6 WAN timed out" >&2 exit 1 fi -wan_ip="$wan_ip_record" -#wan_ip="$(echo "$wan_ip_record" | tail -n1 | awk '{ split($0, a, " "); print a[4] }')" - #╔─────────────────────────────────────────────────────────────────────────────╗ #│ Gετ Λ rεcδrd δη Clδμdflαrε | #╚─────────────────────────────────────────────────────────────────────────────╝ @@ -241,57 +247,65 @@ then exit 1 fi -for i in {0..4000}; do # Assuming 4000 is enough - record="$(echo "$cf_records" | jq --raw-output ".result[${i}].name")" +declare -r cf_ipv4_record="$(echo "$cf_records" | + jq '.result[] | select(.name == "'"${HOST4}.${DOMAIN}"'")')" +declare -r cf_ipv4_ip="$(echo "$cf_ipv4_record" | jq --raw-output '.content')" +declare -r cf_ipv4_id="$(echo "$cf_ipv4_record" | jq --raw-output '.id')" - if [[ "$record" == "${HOST}.${DOMAIN}" ]]; then - host_record="$(echo "$cf_records" | jq -r ".result[${i}]")" - break - elif [[ "$record" == null ]]; then - echo "No record found for ${HOST}.${DOMAIN}" >&2 - exit 1 - fi -done +declare -r cf_ipv6_record="$(echo $cf_records | + jq --raw-output '.result[] | select(.name == "'"${HOST6}.${DOMAIN}"'")')" +declare -r cf_ipv6_ip="$(echo "$cf_ipv6_record" | jq --raw-output '.content')" +declare -r cf_ipv6_id="$(echo "$cf_ipv6_record" | jq --raw-output '.id')" #╔─────────────────────────────────────────────────────────────────────────────╗ #│ Sετ Λ rεcδrd τδ cμrrεητ WΛN | #╚─────────────────────────────────────────────────────────────────────────────╝ -cf_host_ip="$(echo "$host_record" | jq -r '.content')" -cf_rec_id="$(echo "$host_record" | jq -r '.id')" +cf_update_ip() { + local -r my_ip="$1" + local -r cf_ip="$2" + local -r cf_id="$3" + local -r host="$4" + local -r domain="$5" + local -r url="${host}.${domain}" -if [[ -z "$cf_host_ip" || "$cf_host_ip" == null ]]; then - echo "Failed to find content of A record for ${HOST}.${DOMAIN}" >&2 - exit 1 -elif [[ -z "$cf_rec_id" || "$cf_rec_id" == null ]]; then - echo "Failed to find A record ID for ${HOST}.${DOMAIN}" >&2 - exit 1 -fi - -if [[ "$cf_host_ip" == "$wan_ip" ]]; then - echo "Cloudflare is up to date @ $(date)" >&2 -else - echo "Updating Cloudflare's A record from $cf_host_ip to $wan_ip" >&2 - - patch_response="$(curl -s --request PATCH \ - --url "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${cf_rec_id}" \ - --header 'Content-Type: application/json' \ - --header "Authorization: Bearer $TOKEN" \ - --data '{ - "comment": "'"${HOST} @ $(date)"'", - "content": "'"$wan_ip"'", - "name": "'"${HOST}.${DOMAIN}"'", - "proxied": false, - "ttl": 1 - }')" - - if [[ "$(echo "$patch_response" | jq -r '.success')" == true ]]; then - echo "Update to $wan_ip succeeded @ $(date)" >&2 + if [[ -z "$my_ip" || "$my_ip" == null ]]; then + echo "Failed to find local WAN ip: $my_ip" >&2 + return 1 + elif [[ -z "$cf_ip" || "$cf_ip" == null ]]; then + echo "Failed to find content of A record for $url" >&2 + return 1 + elif [[ -z "$cf_id" || "$cf_id" == null ]]; then + echo "Failed to find A record ID for $url" >&2 + return 1 + elif [[ "$my_ip" == "$cf_ip" ]]; then + echo "Cloudflare for $url is up to date @ $(utc_date)" >&2 else - echo "Failed to update A record. DUMP:" - echo "$patch_response" - exit 1 + echo "Updating Cloudflare's for $url from $cf_ip to $my_ip" >&2 + + patch_response="$(curl -s --request PATCH \ + --url "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${cf_id}" \ + --header 'Content-Type: application/json' \ + --header "Authorization: Bearer $TOKEN" \ + --data '{ + "comment": "'"${host} @ $(utc_date)"'", + "content": "'"$my_ip"'", + "name": "'"$url"'", + "proxied": false, + "ttl": 1 + }')" + + if [[ "$(echo "$patch_response" | jq -r '.success')" == true ]]; then + echo "Update to $my_ip for $url succeeded @ $(utc_date)" >&2 + else + echo "Failed to update $url. DUMP:" + echo "$patch_response" + exit 1 + fi fi -fi +} + +cf_update_ip "$wan_ipv4" "$cf_ipv4_ip" "$cf_ipv4_id" "$HOST4" "$DOMAIN" +cf_update_ip "$wan_ipv6" "$cf_ipv6_ip" "$cf_ipv6_id" "$HOST6" "$DOMAIN" ``` Now we need a systemd-timer to run this script. I run it once every 15 minutes. diff --git a/src/pages/index.astro b/src/pages/index.astro index 440bf65..63d339f 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -21,7 +21,7 @@ import { SITE_TITLE, SITE_DESCRIPTION } from '../consts'; Akemi Izuko

- Hey! I'm Akemi, a 4th year CS honors student at + Hey! I'm Akemi, a 1st year computing sciences MSc student at UAlberta. Email is the best way to get in touch with me. Some of my interests include