Skip to content

Instantly share code, notes, and snippets.

@kriansa
Created February 8, 2022 03:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kriansa/d02c14f452262d25863b43b3f783274d to your computer and use it in GitHub Desktop.
Save kriansa/d02c14f452262d25863b43b3f783274d to your computer and use it in GitHub Desktop.
Update your Vultr firewall rules for your ingress SSH
#!/usr/bin/env bash
#
# Automatically updates the IP addresses for the ingress rules for SSH access on Vultr
#
# Requires: jq, curl, dig
main() {
export VULTR_API_KEY="YOUR-VULTR-API-KEY"
# Get existing rules at the Vultr firewall
firewall_id=$(get_firewalls)
rules=$(get_rules_by_firewall_id "$firewall_id")
firewall_ips=$(echo "$rules" | jq -cr "[.[].subnet] | sort")
# Get the current external IP addresses
current_ips=$(get_current_ips)
# If existing firewall whitelisted IPs are the same as current IPs, do nothing
test "$firewall_ips" = "$current_ips" && return
log "Updating firewall rules"
for id in $(echo "$rules" | jq -cr ".[].id"); do
log "Deleting firewall rule ID ${id}"
call DELETE "firewalls/${firewall_id}/rules/${id}"
done
log "Creating new rules"
call POST "firewalls/${firewall_id}/rules" "$(rule_create_payload "$current_ip1")" > /dev/null
call POST "firewalls/${firewall_id}/rules" "$(rule_create_payload "$current_ip2")" > /dev/null
}
get_current_ips(){
# Use your custom logic if you have more than one IP address, as long as you return
# a JSON-encoded string with the IPs in an array.
echo "[\"${(curl ifconfig.me)\"]" | jq -cr sort
}
rule_create_payload() {
ip=$1
echo "{
\"ip_type\":\"v4\",
\"protocol\": \"tcp\",
\"port\": 22,
\"subnet_size\": 32,
\"notes\": \"[AUTO] Home network external IP\",
\"subnet\": \"${ip}\"
}"
}
log() {
msg=$1
date=$(date -u +'%Y-%m-%dT%H:%M:%S.%3NZ')
echo "[$date] $msg"
}
get_firewalls() {
call GET firewalls | jq -r '.firewall_groups[] | select(.description == "Home proxy") .id'
}
get_rules_by_firewall_id() {
local firewall_id=$1
call GET "firewalls/${firewall_id}/rules" | jq -r '[.firewall_rules[] | select(.notes | contains("[AUTO]"))]'
}
call() {
local method=$1
local url=$2
local params=$3
curl "https://api.vultr.com/v2/${url}" -X "${method}" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${VULTR_API_KEY}" \
--data "$params"
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment