Run Security Groups and NACLs by Hand
Goal
The only difference between the two devices is whether they remember state, and all the other differences come from that. In this lab, without a cloud account, you write the rule tables yourself and hand-write an evaluator that reads those tables, so you can see that difference with your own eyes.
Conditions
- The VPC is
10.42.0.0/16and has three tiers: web, app and db. - The internet comes in only through web's port 443.
- web calls app's 8080, and app calls db's 5432.
- app goes out to the outside over HTTPS (443). db does not go out.
Rule table format
A security group has five columns. In the peer position you can write the name of another security group.
그룹,방향,프로토콜,포트,상대
sg-db,inbound,tcp,5432,sg-app
A network ACL has six columns. It looks from the smallest number and ends at the first matching rule.
번호,방향,동작,프로토콜,포트범위,상대
100,outbound,allow,tcp,443,0.0.0.0/0
32767,outbound,deny,all,all,0.0.0.0/0
포트범위 (port range) is written either as a single value like 443 or as a range like 1024-65535. 프로토콜 (protocol) and 포트범위 (port range) can take all.
What you make
| File | Contents |
|---|---|
/root/sgnacl/sg.csv |
Security group rules for the three tiers |
/root/sgnacl/nacl.csv |
The app subnet's NACL |
/root/sgnacl/nacl-ssh.csv · 03-order.md |
The ordering trap and its explanation |
/root/sgnacl/nacl_eval.py |
An evaluator that reads rule tables |
/root/sgnacl/05-return.md |
The gates a reply passes through |
/root/sgnacl/nacl-db.csv |
The db subnet guardrail |
/root/sgnacl/07-notes.md |
Summary |
Notes
The evaluator in step 4 is tested by the grader with a rule table it keeps hidden. It contains a table in which a broad allow has a lower number and a narrow deny comes later, so if you give deny priority out of the habit of security groups, you get caught there.
Tie the three tiers together with group references
Write the security group rules for the three tiers in /root/sgnacl/sg.csv in five columns, 그룹,방향,프로토콜,포트,상대 (group, direction, protocol, port, peer). The internet comes in only through sg-web's 443, web calls sg-app's 8080, and app calls sg-db's 5432.
Do not write IPs in the peer of sg-app and sg-db. You can write the name of another security group as it is — that is a group reference.
No matter how many app servers there are, or whether they grow and shrink with autoscaling, you no longer need to edit the rules. If you write by IP, the rules grow every time servers increase, and the rules remain even when the servers disappear.
Do not create a line that opens port 22 to 0.0.0.0/0. The grader checks for that too.
Open the way out and the way back together
Write the app subnet's network ACL in /root/sgnacl/nacl.csv in six columns, 번호,방향,동작,프로토콜,포트범위,상대 (number, direction, action, protocol, port range, peer). It must go out over HTTPS (443) and the replies must come back, while inbound 22 from outside and outbound 3306 must stay blocked.
A NACL does not remember state. Even if you open outbound 443, the reply has to pass through a rule of its own, and the reply comes back to our ephemeral port (1024–65535).
If you put a deny-all line with a large number at the end, anything not written is blocked automatically. Then you do not need to block 22 and 3306 separately.
Number with gaps, like 100 and 200. If you number 1, 2, 3, there is no room to insert later and you would have to renumber everything.
It ends at the first matching rule
A rule table with 100 전체 허용 (100 allow all) followed by 200 tcp 22 거부 (200 tcp 22 deny) cannot block port 22. Write inbound rules that block only port 22 and let the rest through in /root/sgnacl/nacl-ssh.csv, and write in /root/sgnacl/03-order.md why the original table does not work.
A NACL looks from the smallest number and ends at the first matching rule. It is not that deny takes priority, as in a security group.
So put the narrow deny at the small number and the broad allow at the large number. Just by changing the order, the same two lines work as intended.
The explanation must include 번호 (number), 처음 (first) and 22.
Write the evaluator yourself
Create /root/sgnacl/nacl_eval.py. When called as python3 /root/sgnacl/nacl_eval.py <규칙파일> <방향> <포트> <상대IP> (rule file, direction, port, peer IP), it must print only allow or deny on the first line.
There are three rules. Look only at rules of the same direction, scan them in ascending number order, and output the action of the first rule in which protocol, port and peer all match. If nothing matches, it is deny.
Check whether an address falls within a range with ipaddress.ip_address(x) in ipaddress.ip_network(cidr). For the port range you only need to handle three forms: 443, 1024-65535 and all.
The grader tests with a hidden rule table. It contains a table in which a broad allow has a lower number and a narrow deny comes later, so if you give deny priority, you get caught there.
Count the gates a reply passes through
When the reply to a request that came in from the internet to sg-web's 443 goes out, write at least four lines in /root/sgnacl/05-return.md on what more is needed in the security group and in the network ACL, respectively.
A security group remembers connections that came in. So you never have to write a rule for the reply separately.
A NACL does not remember. The reply also has to pass through the rules, and the place the reply heads to is the peer's ephemeral port. Write that range as numbers.
Because of this one difference, people spend half a day on "I opened inbound but no reply comes."
Put a guardrail on the whole subnet
Use a NACL to shut off the db subnet from going out to the internet altogether, while keeping communication inside the VPC (10.42.0.0/16) alive. Write the rules in /root/sgnacl/nacl-db.csv.
A security group attaches to each instance, but a NACL attaches to the whole subnet. That is why it suits a broad guardrail such as "this subnet does not go out to the internet."
Put the rule that allows the VPC range at a small number and the rule that denies 0.0.0.0/0 at a large number. If the order is reversed, the allow never applies.
What must stay alive includes app coming in on 5432 and the replies to it going out on ephemeral ports.
Summarize the three points
Write at least three lines in /root/sgnacl/07-notes.md: the difference in how the two devices handle state, what the NACL number decides, and what happens when you write security group rules by IP.
The text must include 상태 (state), 번호 (number) and 그룹 참조 (group reference).