Chapter 15: Amazon VPC — Subnets, Route Tables, NACL, NAT Gateway and Bastion Host
15.7 Network ACL: inbound and outbound rules, rule numbers and blocking an IP
A security guard stands at the entrance of the wing. He has a list of rules – he reads them in order and applies the first rule that matches. And this guard is forgetful: a person who went in is checked again when coming out. That is stateless. Note – technically, the NACL checks every packet at the boundary of the subnet.
Wing च्या entrance वर एक security guard उभा आहे. त्याच्याकडे rules ची list आहे – तो क्रमाने वाचतो, आणि जो पहिला rule लागू होतो, तेच करतो. आणि हा guard विसरभोळा आहे: आत गेलेल्या माणसाला बाहेर येताना पुन्हा check करतो. हेच stateless. लक्ष द्या – technically NACL subnet च्या boundary वर प्रत्येक packet check करतो.
Wing के entrance पर एक security guard खड़ा है. उसके पास rules की list है – वह क्रम से पढ़ता है, और जो पहला rule लागू होता है, वही करता है. और यह guard भुलक्कड़ है: अंदर गए आदमी को बाहर आते समय फिर से check करता है. यही stateless है. ध्यान दो – technically NACL subnet की boundary पर हर packet check करता है.
A network ACL (NACL) is a firewall at the subnet level. It has inbound and outbound rules, and each rule either allows or denies traffic.
- Every subnet is associated with exactly one network ACL; one network ACL can serve many subnets.
- The default network ACL of a VPC allows all inbound and all outbound traffic.
- A custom network ACL denies all inbound and outbound traffic until you add rules.
- Each rule has a number from 1 to 32766. Rules are evaluated from the lowest number upwards, and the first matching rule wins; higher rules are not checked.
- The last rule, shown as
*, denies anything that matched no numbered rule. You cannot delete it. - Network ACLs are stateless: a reply is checked again as new traffic, so return traffic needs its own rule.
- Rules are checked when traffic enters or leaves the subnet, not between instances inside the same subnet.
- Quota: 20 inbound and 20 outbound rules per network ACL by default (adjustable up to 40 each).
The network ACL checks rules from the lowest number. The request from 203.0.113.25 matches rule 90 Deny and is dropped at the subnet edge. The request from 198.51.100.7 skips rule 90, matches rule 100 Allow and reaches Nginx. Both addresses are documentation examples.
Network ACL rules सगळ्यात लहान number पासून check करतो. 203.0.113.25 वरून आलेली request rule 90 Deny ला match होते आणि subnet च्या edge वरच drop होते. 198.51.100.7 वरून आलेली request rule 90 सोडून rule 100 Allow ला match होते आणि Nginx पर्यंत पोहोचते. दोन्ही addresses documentation examples आहेत.
Network ACL rules को सबसे छोटे number से check करता है. 203.0.113.25 से आई request rule 90 Deny से match होती है और subnet के edge पर ही drop हो जाती है. 198.51.100.7 से आई request rule 90 छोड़कर rule 100 Allow से match होती है और Nginx तक पहुँचती है. दोनों addresses documentation examples हैं.
Why ephemeral ports 1024–65535 are needed
When a browser opens http://<WEB_PUBLIC_IP>, it connects from a random high source port (for example 52814) to port 80. The server's reply goes back to port 52814. That random port is an ephemeral port. Linux clients use 32768–60999, Windows clients 49152–65535, and a NAT gateway uses 1024–65535. So AWS suggests allowing 1024–65535:
- outbound, for replies to visitors who connected to your servers,
- inbound, for replies to connections your servers started (for example
yumdownloading updates).
Forget this, and the request arrives but the reply is dropped. A security group never needs this, because it is stateful.
Example: a custom network ACL for the public subnet
Inbound rules:
| Rule # | Type | Protocol | Port range | Source | Allow / Deny |
|---|---|---|---|---|---|
| 90 | All traffic | All | All | 203.0.113.25/32 (documentation example of a bad IP) |
Deny |
| 100 | HTTP | TCP | 80 | 0.0.0.0/0 |
Allow |
| 110 | HTTPS | TCP | 443 | 0.0.0.0/0 |
Allow |
| 120 | SSH | TCP | 22 | 198.51.100.7/32 (documentation example of your IP) |
Allow |
| 130 | Custom TCP | TCP | 1024–65535 | 0.0.0.0/0 |
Allow |
| * | All traffic | All | All | 0.0.0.0/0 |
Deny |
Outbound rules:
| Rule # | Type | Protocol | Port range | Destination | Allow / Deny |
|---|---|---|---|---|---|
| 100 | HTTP | TCP | 80 | 0.0.0.0/0 |
Allow |
| 110 | HTTPS | TCP | 443 | 0.0.0.0/0 |
Allow |
| 120 | Custom TCP | TCP | 1024–65535 | 0.0.0.0/0 |
Allow |
| 130 | SSH | TCP | 22 | 10.0.0.0/16 |
Allow |
| 140 | Custom TCP | TCP | 9000 | 10.0.2.0/24 |
Allow |
| * | All traffic | All | All | 0.0.0.0/0 |
Deny |
Rule 90 is checked before rule 100, so the blocked address is dropped even though rule 100 allows port 80 for everyone. Outbound rules 130 and 140 let the bastion reach the private servers on SSH and let Nginx reach PHP-FPM on port 9000. The addresses 203.0.113.0/24 and 198.51.100.0/24 are reserved for documentation, so they are safe examples; use real addresses in your own rules.
How do I block one IP address or a whole range?
Security groups have no deny rules, so blocking is a network ACL job. The quickest way is to add a deny rule with a lower number than the allow rule to the network ACL that is associated with the subnet:
- VPC → Subnets → select
web-public-1a→ Network ACL tab → click the ACL ID. - Inbound rules → Edit inbound rules → Add new rule.
- Rule number
90, Type All traffic, Source203.0.113.25/32, Allow/Deny Deny. - For a whole range, add another rule, for example Rule number
80, Source203.0.113.0/24, Deny. - Save changes. The change applies to every subnet using this ACL after a short time.
aws ec2 create-network-acl-entry --network-acl-id acl-0123456789abcdef0 --ingress \
--rule-number 90 --protocol -1 --cidr-block 203.0.113.25/32 --rule-action deny
/32 means exactly one address; /24 blocks 256 addresses. A deny rule with a number higher than the allow rule (for example 200 after an allow-all rule 100) does nothing, because rule 100 matches first. Because every packet is checked, even an already open connection from the blocked address stops working.
Ravindra Bagale's Tip
Many students create a custom NACL, allow inbound 80, and the website times out. The reason: the NACL is stateless – replies need an outbound 1024-65535 rule. A security group doesn't need this, a NACL does. If the site went down after you changed the NACL, check the ephemeral ports rule first.
Ravindra Bagale's Tip – मराठी
बरेच students custom NACL बनवतात, inbound 80 allow करतात आणि website timeout होते. कारण NACL stateless आहे – reply साठी outbound 1024-65535 rule लागतो. Security group ला हे लागत नाही, NACL ला लागतं. NACL बदलला आणि site बंद झाली, तर आधी ephemeral ports चा rule बघा.
Ravindra Bagale's Tip – हिंदी
बहुत से students custom NACL बनाते हैं, inbound 80 allow करते हैं और website timeout हो जाती है. वजह: NACL stateless है – reply के लिए outbound 1024-65535 rule चाहिए. Security group को यह नहीं चाहिए, NACL को चाहिए. NACL बदला और site बंद हो गई, तो पहले ephemeral ports वाला rule देखो.
Ravindra Bagale's Tip
To block an IP, keep the deny rule's number lower than the allow rule – 90 before 100. Many students give the deny rule number 200 and then say "it doesn't block", because rule 100 matches first. And if you block your own IP by mistake, SSH goes too – remove the rule from the console. Remember the order.
Ravindra Bagale's Tip – मराठी
IP block करायचा असेल तर deny rule चा number allow rule पेक्षा कमी ठेवा – 90 before 100. बरेच students deny rule ला 200 number देतात आणि मग "block होत नाही" म्हणतात, कारण rule 100 आधीच match होतो. आणि तुमचाच IP चुकून block केला तर SSH पण जातो – rule console मधून काढा. क्रम लक्षात ठेवा.
Ravindra Bagale's Tip – हिंदी
IP block करना हो तो deny rule का number allow rule से कम रखो – 90 before 100. बहुत से students deny rule को 200 number देते हैं और फिर कहते हैं "block नहीं होता", क्योंकि rule 100 पहले ही match हो जाता है. और अपना ही IP गलती से block कर दिया तो SSH भी चला जाता है – rule console से हटाओ. क्रम याद रखो.
Lab
Chala, find your own public IP with curl -s https://checkip.amazonaws.com. Add inbound rule 90, Deny, <YOUR_IP>/32 to the network ACL of the web server's subnet, and watch the web page time out in your browser (mobile data on your phone still works). Then delete rule 90 and refresh.
Step-by-step guide