Automatically Update AWS Security Group with Your Dynamic IP

📆 · ⏳ 4 min read · ·

Introduction

Managing secure access to AWS resources like bastion servers can be challenging when you’re dealing with dynamic IPs or CGNAT. I am in the same boat where I have a bastion server that needs to be accessible from my current IP address, which changes frequently since its CGNAT-based.

So here’s the solution that I came up with: A simple Bash script that automatically updates the AWS security group rules to include my current public IP address. This ensures that you can always securely access your bastion server without manually updating the security group every time my IP changes.

This is similar to the Dynamic DNS service via Cloudflare which I talked about in past but instead of updating IP in Cloudflare, we are now updating it for AWS security group.

Prerequisites

  1. AWS CLI: Ensure you have AWS CLI ↗️ installed and configured with appropriate permissions to update the security group. If you are using homebrew then the command would be: brew install awscli

    Run aws configure to set up your AWS access key, secret key, and region and then you should be good to go.

  2. jq: This script uses jq for JSON parsing, so ensure it’s installed on your system. You can install it using your package manager (e.g., brew install jq via homebrew).

The Script

#!/bin/bash
set -e
SECURITY_GROUP_ID="sg-xxx" # REPLACE THIS
SECURITY_GROUP_RULE_ID="sgr-xxx" # REPLACE THIS
AWS_COMMAND=$(which aws)
JQ_COMMAND=$(which jq)
CURRENT_IP=$(curl -s https://checkip.amazonaws.com)
if [[ -z "$CURRENT_IP" ]]; then
echo "Failed to retrieve current IP address."
exit 1
fi
EXISTING_RULE=$($AWS_COMMAND ec2 describe-security-group-rules \
--filter Name=group-id,Values="$SECURITY_GROUP_ID" Name=security-group-rule-id,Values="$SECURITY_GROUP_RULE_ID" \
--query "SecurityGroupRules[0]" \
--output json)
if [[ -z "$EXISTING_RULE" || "$EXISTING_RULE" == "null" ]]; then
echo "No rule found with ID $SECURITY_GROUP_RULE_ID in security group $SECURITY_GROUP_ID."
exit 1
fi
EXISTING_IP=$(echo "$EXISTING_RULE" | $JQ_COMMAND -r '.CidrIpv4' | cut -d'/' -f1)
if [[ "$EXISTING_IP" == "$CURRENT_IP" ]]; then
echo "No update needed. Current IP ($CURRENT_IP) is already authorized."
exit 0
fi
echo "Updating rule $SECURITY_GROUP_RULE_ID from $EXISTING_IP to $CURRENT_IP."
$AWS_COMMAND ec2 modify-security-group-rules \
--group-id "$SECURITY_GROUP_ID" \
--security-group-rules "SecurityGroupRuleId=$SECURITY_GROUP_RULE_ID,SecurityGroupRule={CidrIpv4=$CURRENT_IP/32\"}"
if [[ $? -eq 0 ]]; then
echo "Successfully updated the rule to allow IP $CURRENT_IP."
else
echo "Failed to update the rule. Please check your aws permissions or configuration."
exit 1
fi

Here’s how it works:

  1. Fetches Your Current IP

    we use curl to retrieve your public IP from checkip.amazonaws.com.

  2. Checks Existing Security Group Rules:

    Next we use the AWS CLI to inspect the current rule of the specified security group and security group rule.

    đź’ˇ

    Pre-requisite

    Make sure that you have initially added a new security group rule for your IP address one time and then take a note of the security group rule id from it.

  3. Compares and Updates

    If the IP has changed, the script updates the security group rule with your new IP.

Update the permissions for running the script:

Terminal window
chmod +x update-security-group.sh

And run it like this:

Terminal window
./update-security-group.sh

Run it Periodically

Running it once is fine, but what we really want is a way to periodically run this script so that our current IP address is in sync with the one added in the AWS security group. To achieve this, we can use SystemD timers or Cron Jobs.

For something like this, a cron job is more than enough so let’s set it up.

Open the crontab editor first using this command:

Terminal window
crontab -e

And add the contents at the last line:

Terminal window
0 11 * * * path/to/update-security-group.sh

Replace /path/to with the actual path where you have stored the script.

The above mentioned config will run this script every day at 11:00AM. Feel free to update the frequency as per your need.

Conclusion

By automating IP updates in AWS security groups, you save time and ensure seamless access to your AWS resources. With this simple script, you can focus on what really matters without worrying about IP changes. Try it out and make your AWS environment smarter!

If you have any questions or comments, feel free to reach out to me on Twitter ↗️ / Reddit ↗️ or drop a comment below.

You may also like

  • # cloudflare# devops

    How to setup Cloudflare proxy for your website hosted on Vercel or Netlify

    In this article, I will show you how to properly set up Cloudflare proxy for any of your website which is hosted on some other service like Vercel or Netlify.

  • # bash# postgres

    3 simple steps to create a local backup of Postgres database using Bash script

    In this article, I will show you how I back up the Postgres database hosted on Supabase (ideally can be anywhere) to the local system and automate this process.

  • # bash# linux

    Increase Root Partition Size On Fedora

    Learn how to increase root partition size on fedora in 2 simple steps.