AWS || automatically update all AWS EC2 security groups with dynamic IP changes
-
AWS CLI is requiered!
The only other requirement is to have the jq tool to better handle the JSON returned by the aws command.apt install jq
Script:
update-securitygroups.sh:#! /bin/bash #set -x # This script finds all the security groups that have an IP range that meets the condition of affecting the defined ports and whose description has # a given keyword, and then replace that IP range by the one defined at the beginning of the script or the one obtained as the current public IP of # our Internet connection, so that we can continue accessing all servers and services protected by those security groups when our dynamic IP changes. regions='eu-west-1' description_keyword='PFSENSE0103' ports="22 80 443 10021 21000" # Get current public IP from opendns.com service my_public_ip="$(dig +short myip.opendns.com @resolver1.opendns.com)/32" if [ $? -ne 0 ];then echo "ERROR: couldn't get current public IP from opendns.com service! Aborting!" exit 2 fi # Check if /usr/local/bin/scripts/update-securitygroups.ip file already exists, otherwise create it if [ ! -f /usr/local/bin/scripts/update-securitygroups.ip ];then echo "WARNING: file update-securitygroup.ip doesn't exist! Creating a new one..." echo "${my_public_ip}" > /usr/local/bin/scripts/update-securitygroups.ip update_security_groups=1 else # Check if public ip changed my_old_public_ip="$(cat /usr/local/bin/scripts/update-securitygroups.ip)" if [ "${my_old_public_ip}" != "${my_public_ip}" ];then update_security_groups=1 echo "WARNING: current public IP ${my_public_ip} is different from old public IP ${old_public_ip}!" else update_security_groups=0 echo "INFO: current public IP ${my_public_ip} didn't change. Exiting..." exit 0 fi fi echo "INFO: updating security groups..." for region in ${regions};do for port in ${ports};do # Get all security groups that give access to given port security_group_ids=$(aws ec2 describe-security-groups --region "${region}" --filters Name=ip-permission.to-port,Values=${port} \ --query "SecurityGroups[*].[GroupId]" --output text) for security_group_id in ${security_group_ids};do # Get existing IP range that match our keyword within the security group IP permissions description my_old_public_ip=$(aws ec2 describe-security-groups --region "${region}" --group-ids "${security_group_id}" \ | jq -c '.SecurityGroups[].IpPermissions[] | select(.FromPort=='${port}' and .ToPort=='${port}') | .IpRanges[] | select(.Description=="'${description_keyword}'") | .CidrIp' | sed 's/"//g') if [ $? -eq 0 ] && [ ! -z "${my_old_public_ip}" ];then # Update IP range: first remove old IP range and then create new range with new public IP aws ec2 revoke-security-group-ingress --region "${region}" --group-id "${security_group_id}" --protocol tcp --port ${port} \ --cidr "${my_old_public_ip}" && \ aws ec2 authorize-security-group-ingress --region "${region}" --group-id "${security_group_id}" --ip-permissions \ "IpProtocol=tcp,FromPort=${port},ToPort=${port},IpRanges=[{CidrIp=${my_public_ip},Description=${description_keyword}}]" if [ $? -eq 0 ];then echo "OK: ${region} | ${security_group_id} -> replaced previous ${my_old_public_ip} IP range with current ${my_public_ip} public IP on security group $security_group_id for port ${port}" else echo "ERROR: couldn't replace previous ${my_old_public_ip} IP range with current ${my_public_ip} public IP on security group $security_group_id (${region}) for port ${port}!" fi fi done done done
Cron Job erstellen:
crontab -e
* * * * * /bin/bash /usr/local/bin/scripts/update-securitygroups.sh