Created
August 31, 2025 16:35
-
-
Save amard33p/2d218b1d9ded5cfa478633f93c362ee2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| function usage() { | |
| echo "\ | |
| Usage: $0 <firewall name> <command> | |
| Example: | |
| $0 block-ssh-firewall ssh -i ~/.ssh/your_host holu@your_host\ | |
| " 1>&2 | |
| exit 1 | |
| } | |
| function handle_api_error() { | |
| if [ "$(echo "$1" | jq .error)" != "null" ] | |
| then | |
| echo $1 1>&2 | |
| exit 2 | |
| fi | |
| } | |
| if [ $# -lt 2 ]; then | |
| usage | |
| fi | |
| # Exit on error. | |
| set -e | |
| # Determine my public IPv4 and IPv6 addresses. | |
| my_ipv4=$(curl -4 https://ip.hetzner.com) | |
| my_ipv6=$(curl -6 https://ip.hetzner.com) | |
| # Get the ID and the current rules of the passed firewall. | |
| response=$(curl \ | |
| --silent \ | |
| -H "Authorization: Bearer $HETZNER_API_TOKEN" \ | |
| "https://api.hetzner.cloud/v1/firewalls?name=$1") | |
| handle_api_error "$response" | |
| firewall_id=$(echo $response | jq ".firewalls[0].id") | |
| original_rules=$(echo $response | jq ".firewalls[0].rules") | |
| # Add to the current rules a new rule that allows incoming SSH traffic from my IP addresses. | |
| allow_ssh_rule=$(cat << END | |
| { | |
| "direction": "in", | |
| "port": "22", | |
| "protocol": "tcp", | |
| "source_ips": ["$my_ipv4/32", "$my_ipv6/128"] | |
| } | |
| END | |
| ) | |
| new_rules=$(echo $original_rules | jq ". = . + [$allow_ssh_rule]") | |
| # Make the firewall adopt the new ruleset. | |
| response=$(curl \ | |
| --silent \ | |
| -X POST \ | |
| -H "Authorization: Bearer $HETZNER_API_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"rules\":$new_rules}" \ | |
| "https://api.hetzner.cloud/v1/firewalls/$firewall_id/actions/set_rules") | |
| handle_api_error "$response" | |
| # Reset ruleset when the script exits (even upon receiving a SIGTERM or SIGINT signal). | |
| function cleanup() { | |
| response=$(curl \ | |
| --silent \ | |
| -X POST \ | |
| -H "Authorization: Bearer $HETZNER_API_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"rules\":$original_rules}" \ | |
| "https://api.hetzner.cloud/v1/firewalls/$firewall_id/actions/set_rules") | |
| handle_api_error "$response" | |
| } | |
| trap "cleanup" EXIT | |
| # Remove first argument, which is the firewall name. | |
| shift | |
| # Execute the other arguments as shell command. | |
| $@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment