Skip to content
ProfessionalProNACL / Security GroupsAWS VPC

Lab 23: The Rule That Was Removed And The Session That Stayed Open

Two identical hosts, two identical long-lived connections, one change that removes the inbound rule admitting the client from both at the same instant. One connection dies. The other keeps working with no rule permitting it, and will for days. The difference is one word in the rule that was removed.

Debugging time
~25 min
Reading time
14 min
Reported by
Cloud Security
Tier
Professional
INC-1840SEV-2InvestigatingOpened 2026-10-02 15:10 UTC

Security group change to revoke a client took effect on one host and not the other; the groups are now identical

Reported by Cloud Security

We revoked a client's access to two service hosts this afternoon as part of an offboarding. One Terraform apply, removing the inbound rule for the service port from both hosts' security groups at the same time. Apply succeeded, both rules are gone, I have checked the console on both groups.

The client's connection to the first host dropped immediately, as expected. Its connection to the second host is still open and still working. I can see traffic on it. It has been forty minutes.

Both security groups now have zero inbound rules. Neither permits anything from this client. The client has not reconnected — it is the same TCP session from before the change. I do not understand how a security group with no inbound rules is passing inbound traffic, and I need to know whether this is a bug before I file it as a security incident.

What you are working with

One VPC, one subnet, three instances.

Starting state — one client, two servers, two rules that look equivalent
VPC 10.230.0.0/16 AZ a · 10.230.1.0/24 contains client , holding Client; server, rule by /32 , holding TRACKED; server, rule by 0.0.0.0/0 , holding UNTRACKED.VPC 10.230.0.0/16AZ a · 10.230.1.0/24clientpublicClient10.230.1.50server, rule by /32publicTRACKED10.230.1.60 · in: 5000 from 10.230.1.50/32server, rule by 0.0.0.0/0publicRisk — its connection dies the instant the rule goesUNTRACKED10.230.1.70 · in: 5000 from 0.0.0.0/0

Three hosts in one subnet. Both servers run the same echo service on port 5000 and both admit the client on it — one by naming the client's address, one by admitting the port from anywhere. Both have an all-outbound egress rule. From the client's point of view the two connections are indistinguishable, and from the console both rules do the same job. The labels on the servers give the answer away, which is deliberate: the lab is about why, not which.

ResourceConfiguration
Client10.230.1.50, outbound-only security group
Server TRACKED10.230.1.60, inbound TCP 5000 from 10.230.1.50/32, outbound all
Server UNTRACKED10.230.1.70, inbound TCP 5000 from 0.0.0.0/0, outbound all
Servicencat echo listener on 5000, both servers
Instance typet3.micro — Nitro, not Nitro v6, which matters for the timeout
The changeRemove the inbound 5000 rule from both groups in one apply

Nothing else differs. Same subnet, same image, same service, same client, same change.

client → server, after the inbound rule is removed
  1. EC2

    Client

    next packet on the existing TCP connection

  2. FILTER

    Server security group, inbound

    zero inbound rules

  3. RTB

    Connection state lookup

    is this packet part of a connection the group is tracking?

    Dropped — For one server the answer is yes, and the packet is admitted as part of an established connection with no rule consulted. For the other the answer is no, because that flow was never tracked, so the packet is evaluated against the rules — of which there are none.

  4. DEST

    Echo service

    answers, or never hears the packet

The decisive hop is not the rule evaluation. It is the lookup before it, which asks whether the security group already knows about this connection. One flow is in that table and one is not, and the rule change is irrelevant to the one that is.

Scope and constraints

  • In scope: why a security group with no inbound rules continues to pass one existing connection and not another, when the two connections were admitted by rules that did the same thing.
  • Out of scope: the client, the service, the subnet, network ACLs, and the Terraform. All correct.
  • The reporter is right that both groups are now identical and that neither admits the client. Both facts are true. One connection still works. Resolve that before you call it a bug.
  • Nothing is broken. This is a security finding: a revocation that did not revoke.
  • The fix is not a security group change. Pay attention to why.

Deploy the broken state

cd lab-23-security-group-connection-tracking
terraform init
terraform apply

Under three minutes. The state deployed is the before — both rules present, both connections possible. The change that produces the incident is made in the Reproduction, by you, so you are watching when it happens.