Skip to content

Instantly share code, notes, and snippets.

@mikeflynn
Last active December 9, 2022 17:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikeflynn/e132011202dcecdb976d7d8cf854e74c to your computer and use it in GitHub Desktop.
Save mikeflynn/e132011202dcecdb976d7d8cf854e74c to your computer and use it in GitHub Desktop.
A bash script wrapper to better manage AWS EC2 security groups from the command line.
#!/bin/bash
# A script that wraps the aws-cli to automate the auditing of EC2 security groups
# Requires: https://aws.amazon.com/cli/ and https://stedolan.github.io/jq/
if [ -z $(which aws) ]; then
echo "ERROR: The aws-cli command is not installed or not in your path."
exit 1
fi
if [ -z $(which jq) ]; then
echo "ERROR: The jq command is not installed or not in your path."
exit 1
fi
print_usage() {
echo "AWS Security Group Automation"
echo " "
echo "$0 [options] -g GROUP_NAME -u IP_RANGE"
echo " "
echo "Options:"
echo "-h Show brief help"
echo "-g REQUIRED: Security group name or ID"
echo "-i IP block, in cidr notation"
echo "-n Note or description of the rule"
echo "-p Port"
echo "-a Action: add, remove, search, or list"
echo " "
echo "Examples:"
echo "$0 -g nginx -a search"
echo "$0 -g sg-000000 -i 127.0.0.1/32 -p 443 -n 'Home - Flynn' -a add"
echo "$0 -g sg-000000 -i 127.0.0.1/32 -p 443 -a remove"
echo "$0 -g sg-000000 -p 443 -a list"
exit 0
}
id_lookup() {
if [ "${GROUP:0:2}" != "sg" ]; then
GROUP=$(aws ec2 describe-security-groups --filters Name=group-name,Values="$GROUP" --output json | jq -r '.SecurityGroups[].GroupId')
fi
}
search_groups() {
if [[ "$GROUP" == "" ]]; then
echo "You must supply a security group name or ID."
exit 1
fi
aws ec2 describe-security-groups --filters Name=group-name,Values="*$GROUP*" --output json | jq -r '.SecurityGroups[] | . as $p | $p.GroupName + " " + $p.GroupId'
}
list_ips() {
if [[ "$GROUP" == "" ]]; then
echo "You must supply a security group name or ID."
exit 1
fi
JQ_IP=""
if [[ "$IP" != "" ]]; then
JQ_IP='| select( .CidrIp | contains("'"$IP"'"))'
fi
JQ_PORT=""
if [[ "$PORT" != "" ]]; then
JQ_PORT='| select( .FromPort | contains('"$PORT"'))'
fi
aws ec2 describe-security-groups --group-ids $GROUP --output json | jq -r '.SecurityGroups[].IpPermissions[] '"$JQ_PORT"' | . as $p | $p.IpRanges[] '"$JQ_IP"'| . as $x | [$p.FromPort|tostring] + [$x[]] | @sh'
}
add_ip() {
if [[ "$GROUP" == "" || "$IP" == "" || "$PORT" == "" ]]; then
echo "You must supply a security group ID and IP range."
exit 1
fi
RES=$(aws ec2 authorize-security-group-ingress --group-id $GROUP --ip-permissions IpProtocol=tcp,FromPort=$PORT,ToPort=$PORT,IpRanges='[{CidrIp='"$IP"',Description='"$NOTE"'}]')
echo "$RES"
}
remove_ip() {
if [[ "$GROUP" == "" || "$IP" == "" || "$PORT" == "" ]]; then
echo "You must supply a security group ID and IP range."
exit 1
fi
RES=$(aws ec2 revoke-security-group-ingress --group-id $GROUP --protocol tcp --port $PORT --cidr $IP)
echo "$RES"
}
IP=""
GROUP=""
PORT=""
NOTE="Added by aws-security-group.sh"
ACTION=""
while getopts 'g:i:p:n:a:' flag; do
case "${flag}" in
g) GROUP="${OPTARG}" ;;
i) IP="${OPTARG}" ;;
p) PORT="${OPTARG}" ;;
n) NOTE="${OPTARG}" ;;
a) ACTION="${OPTARG}" ;;
*) print_usage
exit 1 ;;
esac
done
if [[ "$ACTION" == "" ]]; then
echo "You must supply an action: add, remove, search or list"
exit 1
fi
case "$ACTION" in
list)
id_lookup
list_ips ;;
search)
search_groups ;;
add)
id_lookup
add_ip ;;
remove)
id_lookup
remove_ip ;;
*) echo "Invalid action." ;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment