AWS (EC2) Security Groups
Knocknoc can easily connect to AWS using common utilities and IAM credentials, and update the allowed IP dynamically. The agent ships with a script built in for this already, which requires credentials placed where the agent can read them.
Backend for AWS Security Group
In the example above, there is a backend called "AWSSecurityGroup." You are required to select an agent, being the host where the script is installed, equipped with necessary credentials. Finally, there is the command required to initiate the backend. Please note that the provided sample script may need to be customised to suit your needs.
ACL for AWS Security Group
Then the admin creates an ACL:
The ACL Name as the security group is an argument passed to the script, and then updated with the IP of the Knocknoc user when they login.
Here is copy of the script. As you can see, the credentials file needs to be written out, and it can of course be tailored to your needs.
#!/bin/bash
# Check for AWS CLI
if ! command -v aws &> /dev/null; then
echo "Error: AWS CLI is not installed."
exit 1
fi
# Check arguments
if [ "$#" -lt 3 ]; then
echo "Usage: $0 <ACTION> <IP_ADDRESS> <SECURITY_GROUP_ID>"
exit 1
fi
IP_ADDRESS=$3
ACTION=$1
SECURITY_GROUP_ID=$2
# standard aws credential file
# please ensure your IAM cred has least privileges
CREDENTIAL_FILE=/opt/knocknoc-agent/etc/aws-sg.creds
# Load credentials if provided
if [ ! -z "$CREDENTIAL_FILE" ]; then
if [ ! -f "$CREDENTIAL_FILE" ]; then
echo "Error: Credential file does not exist."
exit 1
fi
export AWS_ACCESS_KEY_ID=$(grep 'aws_access_key_id' $CREDENTIAL_FILE | cut -d '=' -f 2 | tr -d '[:space:]')
export AWS_SECRET_ACCESS_KEY=$(grep 'aws_secret_access_key' $CREDENTIAL_FILE | cut -d '=' -f 2 | tr -d '[:space:]')
export AWS_DEFAULT_REGION=$(grep 'region' $CREDENTIAL_FILE | cut -d '=' -f 2 | tr -d '[:space:]')
fi
case $ACTION in
"add")
# Check if the IP is already allowed
CURRENT_IPS=$(aws ec2 describe-security-groups --group-ids $SECURITY_GROUP_ID --query 'SecurityGroups[0].IpPermissions[?ToPort==`22` && FromPort==`22`].IpRanges[].CidrIp' --output text)
if echo "$CURRENT_IPS" | grep -q "$IP_ADDRESS"; then
echo "IP $IP_ADDRESS is already allowed. Skipping addition."
else
aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol tcp --port 22 --cidr $IP_ADDRESS/32
fi
;;
"del")
aws ec2 revoke-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol tcp --port 22 --cidr $IP_ADDRESS/32
;;
"flush")
# Get current IPs and remove them one by one
CURRENT_IPS=$(aws ec2 describe-security-groups --group-ids $SECURITY_GROUP_ID --query 'SecurityGroups[0].IpPermissions[?ToPort==`22` && FromPort==`22`].IpRanges[].CidrIp' --output text)
for ip in $CURRENT_IPS; do
aws ec2 revoke-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol tcp --port 22 --cidr $ip
done
;;
*)
echo "Invalid action. Valid actions are 'add', 'del', and 'flush'."
exit 1
;;
esac
An example IAM policy to create a user for an EC2 security group might be as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SGPermissions",
"Effect": "Allow",
"Action": [
"ec2:DescribeSecurityGroups",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:RevokeSecurityGroupEgress"
],
"Resource": "arn:aws:ec2:ap-southeast-2:691650234881:security-group/sg-0eea61b7e43fcd9a5"
}
]
}
There are of course many ways you could take these examples and adapt them to your needs. You could also create real problems if you aren't careful with the syntax of scripts and IAM policies etc, so please be mindful of the principals of least privilege to get this job done.