Skip to content

Instantly share code, notes, and snippets.

@kriansa
Created October 22, 2022 21:54
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/f0adcac6dc4c488bbfd2fca240b18a42 to your computer and use it in GitHub Desktop.
Save kriansa/f0adcac6dc4c488bbfd2fca240b18a42 to your computer and use it in GitHub Desktop.
Update your Vultr firewall rules to only accept your IP address as incoming SSH
#!/usr/bin/env bash
#
# Automatically updates the IP addresses for the ingress rules for SSH access
# at my home proxy instance on Vultr
#
# Requires: jq, curl, dig
config() {
# Define your Vultr API Key
export VULTR_API_KEY=YOUR-VULTR-API-KEY
# Get the current external IP addresses
current_ip1=$(command-to-get-ip-1) # dig +short ip-1.yourdomain.com
current_ip2=$(command-to-get-ip-1) # dig +short ip-2.yourdomain.com
current_ips=$(echo "[\"${current_ip1}\",\"${current_ip2}\"]" | jq 'sort')
}
main() {
config
# Get existing rules at the Vultr firewall
firewall_id=$(get_firewalls)
rules=$(get_rules_by_firewall_id "$firewall_id")
firewall_ips=$(echo "$rules" | jq -r "[.[].subnet] | sort")
# 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 -r ".[].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
}
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