Basim Hennawi's blog

Basim Hennawi's blog

Update an Existing AWS Security Group with my New Public IP Address

Update an Existing AWS Security Group with my New Public IP Address

Subscribe to my newsletter and never miss my upcoming articles

During Corona times, I'm doing home-office often my home country, Egypt, where setting up and connecting to a VPN to my company's office, Germany, was gruelling at times. On the other hand, I want to access resources protected by AWS security groups.

Hmm, easy-peasy I could just add a Security Group Rule whitelisting my IP, right?

Correct! but I shouldn't get too attached because most likely, my Internet Service Provider (ISP) issues me a dynamic IP address, which means it’s subject to change on me, like when:

  • I unplug my router
  • I suffer a blackout

If it weren’t a dynamic IP address, it would be referred to as a static IP address…unchanging - then tbh you should haven't landed here for this blog ;).

So to cut it short, I could do that with a lot of clicking on the AWS console, but it's even harder for me cause I usually have more than one AWS account opened, that means jumping between those accounts is wasted effort.

SecurityGroupsConsoleScreenshot.png

So what about running a script from my local machine doing this for me...!

Here’s how the Bash script would look:

#!/bin/bash

group_id="sg-12345678";
port="27017";

curl v4.ifconfig.co > ip.txt
awk '{ print $0 "/32" }' < ip.txt > ipfull.txt
export foo=$(cat ipfull.txt)
aws ec2 authorize-security-group-ingress --region=eu-central-1 \
    --group-id $group_id \
    --ip-permissions IpProtocol=tcp,FromPort=$port,ToPort=$port,IpRanges="[{CidrIp=${foo},Description='tmp'}]"

Now let's go through the script line by line:

  1. In the beginning we need to set the values of the security group ID (better create a new one) and the port number. This example assumes the security group ID as sg-12345678 and the port number as 27017 (as I need it to access MongoDb but the SSH default, 22).
  2. I fetch my IP address from v4.ifconfig.co page and write to a .txt file I'll name ip.txt and since I’m using only one > rather than two, this operation will either create the file or, if it already exists, overwrite any text that might currently live there.
  3. Since a security group requires a full address in CIDR format, I’ll use awk to read ip.txt, append the characters /32, and output it into a new file I'll name ipfull.txt. That file will now contain my full IP in CIDR format.
  4. Now I’ll export the contents of the ipfull.txt file to a shell variable I’ll name $foo.
  5. Finally, we arrive at the money line. The EC2 subset of the general AWS CLI includes a command called authorize-security-group-ingress which can be used to add a new rule to the inbound policies of an existing security group. In this example we set the protocol as tcp and then pass the value of $foo to the — cidr argument. Also, you could set Description for it, like tmp or so.

Assuming that you named the script whitelist-ip.sh, you’ll need to make the file executable and then run it like this:

chmod +x whitelist-ip.sh
./whitelist-ip.sh

UPDATE (30.08.2021)

Of course every time you run this script it will add a new SG rule but without deleting the old ones that you don't want them to be whitelisted anymore, so here will show how you delete SG rules within a SG, but most importantly to take care that it is going to delete all rules within that SG, that'S why we need first to create our own SG and attached it to the main SG as an inbound rule.

Now we can easily edit the script so we first loop through the rules matching this specific port and delete them before adding the new one with the current IP address.

#!/bin/bash

group_id="sg-12345678";
port="27017";

# Get existing IP rules for group matching port
ips=$(aws ec2 describe-security-groups --filters Name=ip-permission.to-port,Values=$port Name=ip-permission.from-port,Values=$port Name=ip-permission.protocol,Values=tcp --group-ids $group_id --output text --query 'SecurityGroups[*].{IP:IpPermissions[?ToPort==`'$port'`].IpRanges}' | sed 's/IP    //g');

# Loop through IPs
for ip in $ips
do
    # Delete IP rules matching port
    aws ec2 revoke-security-group-ingress --group-id $group_id --protocol tcp --port $port --cidr $ip --region=eu-central-1
done

Done.

Here you can check out the whole script as a Github Gist .

I'd love for you to leave me a feedback below in the comments!

 
Share this