Docs / Security Groups

Security Groups

EC2 security group rules are enforced at the network level. A TCP proxy sits between the client and the Docker container, evaluating rules on every new connection. No restarts needed.

How It Works

1. When an EC2 instance is launched, LocalEmu starts a Docker container and maps its ports through a TCP proxy
2. On every incoming TCP connection, the proxy queries the Moto backend for the instance's security group rules
3. The client IP, destination port, and protocol are matched against the ingress rules
4. If a matching allow rule exists, the connection is proxied to the container. Otherwise it is dropped.
5. Rules are read live from Moto on every connection, so AuthorizeSecurityGroupIngress and RevokeSecurityGroupIngress take effect immediately

Supported Features

Feature Status Notes
CIDR matchingSupported0.0.0.0/0, 10.0.0.0/8, specific IPs, any valid CIDR
Protocol + port rangesSupportedTCP, UDP, protocol number, port ranges (e.g. 8000-9000)
Security group referencesSupportedAllow traffic from instances in another security group
Ingress rulesEnforcedEvaluated per connection, live updates
Egress rulesNot enforcedOutbound traffic is always allowed
VPC network ACLsNot implementedOnly security groups are enforced

Default Behavior

When an instance has no security group attached, all traffic is allowed. This preserves backward compatibility with existing workflows that do not use security groups. Once you attach a security group, only traffic matching the ingress rules is permitted.

Note: localhost traffic

Since all traffic to LocalEmu containers originates from 127.0.0.1 (localhost), use 0.0.0.0/0 for "allow all" rules and specific CIDRs (e.g. 10.0.0.0/8) to restrict access. A rule allowing only 10.0.0.0/8 will block connections from localhost, effectively denying all traffic.

Example: Allow and Revoke SSH

Step 1: Create a security group

Terminal
$ awsemu ec2 create-security-group \
    --group-name my-sg \
    --description "Allow SSH" \
    --vpc-id vpc-12345

GroupId: sg-abc123

Step 2: Allow SSH from anywhere

Terminal
$ awsemu ec2 authorize-security-group-ingress \
    --group-id sg-abc123 \
    --protocol tcp \
    --port 22 \
    --cidr 0.0.0.0/0

SecurityGroupRuleId: sgr-001

Step 3: Launch an instance with the security group

Terminal
$ awsemu ec2 run-instances \
    --image-id ami-ubuntu-latest \
    --instance-type t2.micro \
    --security-group-ids sg-abc123

InstanceId: i-abc12345
PublicIpAddress: 127.0.0.1
MappedPort: 22/tcp -> 0.0.0.0:32022

Step 4: SSH works because the rule allows port 22

Terminal
$ ssh -p 32022 root@127.0.0.1
Welcome to Ubuntu 22.04
root@i-abc12345:~#

Step 5: Revoke the SSH rule

Terminal
$ awsemu ec2 revoke-security-group-ingress \
    --group-id sg-abc123 \
    --protocol tcp \
    --port 22 \
    --cidr 0.0.0.0/0

Return: true

Step 6: SSH is now blocked immediately

Terminal
$ ssh -p 32022 root@127.0.0.1
ssh: connect to host 127.0.0.1 port 32022: Connection refused

No restart required. The proxy re-evaluates rules on every new connection.

Security Group References

You can reference another security group as the source instead of a CIDR block. This allows traffic only from instances that belong to the referenced group.

Terminal
$ awsemu ec2 authorize-security-group-ingress \
    --group-id sg-abc123 \
    --protocol tcp \
    --port 3306 \
    --source-group sg-web-tier

# Only instances in sg-web-tier can reach port 3306