Pravesh Sudha

Understanding NACLs with AWS EC2 instances 🚀

·

6 min read

Cover Image for Understanding NACLs with AWS EC2 instances 🚀

🌐 Introduction

Hola Amigos!
I hope you're all doing great and having a productive day. Today, we’re diving into a crucial but often overlooked aspect of AWS security—NACLs (Network Access Control Lists).

While Security Groups get most of the spotlight, NACLs serve as an additional layer of security—this time, at the subnet level. Think of them as the gatekeepers that control traffic in and out of your VPC’s subnets.

In this blog, we’ll start by understanding what NACLs are, how they differ from Security Groups, and then move on to a hands-on demonstration where we’ll simulate a real-world scenario: blocking access to an EC2 instance from a specific IP address that could be malicious.

So, buckle up! Whether you're studying for an AWS certification or just want to upskill in cloud security, this guide will help you get a practical understanding of how NACLs can protect your infrastructure. 🚀


🛠️ Pre-requisites

Before we jump into the hands-on part, let’s make sure we have everything set up properly. Here’s what you’ll need on your system to follow along smoothly:

An AWS Account
Since we're doing a practical demonstration involving EC2 instances and NACLs, you’ll need access to an AWS account. Make sure you have an IAM user configured with sufficient permissions for EC2 and CloudFormation. This will allow you to create and manage the necessary resources without any permission hiccups.

AWS CLI Installed & Configured
I’m not totally against ClickOps (😉), but in production environments and company standards, it’s best practice to use the AWS CLI, SDKs, or Infrastructure as Code (IaC) tools like Terraform. In this blog, we’ll be using the AWS CLI to provision and manage our infrastructure efficiently.

Enable AWS CLI Auto-Prompt (Optional, but Helpful)
Typing out long CLI commands can get tricky—and making a typo halfway through is frustrating. To make life easier, you can enable the AWS CLI's auto-prompt feature, which helps you autocomplete commands and options interactively.

Just run this in your terminal:

export AWS_CLI_AUTO_PROMPT="on-partial"

This way, if you ever fumble with a command, AWS CLI has your back.


🔍 What the Heck is a NACL (and How is it Different from a Security Group)?

Before we dive into the demo, let’s break down the basics—What exactly is a NACL, and how does it differ from the more commonly used Security Group?

🛡️ Network Access Control List (NACL)

A NACL (Network Access Control List) is a stateless virtual firewall that exists within your Virtual Private Cloud (VPC). It acts as an additional security layer at the subnet level, inspecting both inbound and outbound traffic independently. Since it’s stateless, every request—whether coming in or going out—is checked separately.

That’s like a security guard who doesn’t remember if someone already entered the building—they’ll check you every time you pass through the gate.

🔐 Security Groups

In contrast, Security Groups (SGs) operate at the instance level and are stateful. This means they remember connections. If an inbound rule allows traffic, the response is automatically allowed—there’s no need to define explicit outbound rules.

So, think of Security Groups like personal bodyguards: if they let you in once, they trust you while you’re around.

⚖️ NACLs vs Security Groups – Quick Breakdown

FeatureNACLSecurity Group
LevelSubnetInstance
Stateful?❌ No (Stateless)✅ Yes (Stateful)
Traffic CheckInbound & Outbound (independent)Inbound only (Outbound inferred)
Default BehaviorDeny allAllow all outbound traffic
Use CaseSubnet-wide rules, IP blockingFine-grained access per instance

In essence, NACLs are like a perimeter firewall—ideal for broader subnet-level control, while Security Groups are your instance-level shield, designed for more precise access management.

Understanding both is essential for building secure and well-architected cloud environments.


🚀 Setting Up the EC2 Instance – Let’s Get Practical!

Alright amigos! Now that we understand what NACLs are and how they differ from Security Groups, it’s time to get our hands dirty with a practical demonstration. 🎯

We’ll spin up an EC2 instance using a CloudFormation template and then simulate blocking access to our own IP address using NACLs. Let’s go!

📁 Step 1: Clone the GitHub Repository

We’ll use a pre-built CloudFormation template to create our infrastructure. Head over to my GitHub repo:

🔗 https://github.com/Pravesh-Sudha/AWS_EXAMPLES/tree/main/vpc/nacls

Inside this directory, you’ll find a file named template.yml. Before using it, we need to make some edits to match your environment.

✏️ Step 2: Edit the Template with Your AWS Resource Details

In template.yml, update the following fields:

  • VPC ID

  • Subnet ID (make sure it’s a public subnet)

  • AMI ID (use the latest Amazon Linux 2 image)

👉 Get the latest AMI ID:

aws ec2 describe-images \
--owners amazon \
--filters "Name=name,Values=amzn2-ami-hvm-*-x86_64-gp2" "Name=state,Values=available" \
--query "Images[?starts_with(Name, 'amzn2')]|sort_by(@, &CreationDate)[-1].ImageId" \
--region us-east-1 \
--output text

👉 Get the Subnet and VPC ID:

aws ec2 describe-subnets --query Subnets --subnet-ids

Once you have those values, replace them in your template.yml like this:

ImageId:
  Type: String
  Default: ami-xxxxxxxxxxxxxxxxx
SubnetId:
  Type: String
  Default: subnet-xxxxxxxxxxxxxxxxx
VpcId:
  Type: String
  Default: vpc-xxxxxxxxxxxxxxxxx

📦 Step 3: Deploy the EC2 Stack with CloudFormation

Navigate to the directory where template.yml is located and run:

aws cloudformation deploy \
--template-file template.yml \
--stack-name ec2-stack \
--capabilities CAPABILITY_IAM

✅ Once deployed, head over to the EC2 dashboard and copy the public IP of the instance. Open it in your browser—you should see:

"Hello from Apache on Amazon Linux 2!"

Awesome, your EC2 instance is up and running! Now, let’s lock it down with NACLs. 🔒

🔒 Step 4: Block Your Own IP Using a Network ACL (NACL)

Let’s simulate blocking your own IP address using a NACL. This is how we add an ingress rule to deny traffic from a specific IP.

👉 First, find your public IP address:

Go to https://whatismyipaddress.com and copy your IPv4 address.

👉 Then, get your Network ACL ID:

aws ec2 describe-network-acls --query NetworkAcls

Look for the ACL associated with the subnet where your EC2 instance is deployed.

👉 Add a Deny Rule to Block Your IP:

aws ec2 create-network-acl-entry \
--network-acl-id <YOUR_NETWORK_ACL_ID \
--ingress \
--rule-number 90 \
--protocol -1 \
--port-range From=0,To=65535 \
--cidr-block <YOUR_IP>/32 \
--rule-action deny

🎯 Boom! You’ve now blocked your own IP from accessing the EC2 instance.

🔍 Step 5: Validate the NACL Rule

Try accessing your EC2 instance in the browser again. You’ll notice it doesn’t load. That’s NACLs doing their job.

To verify that the server is still accessible, try:

  • Switching to mobile data on your phone and reloading the IP

  • Asking a friend or colleague to access the IP

They should still see the “Hello from Apache” message because the deny rule only targets your specific IP.


Clean up 🧹

Use the following command to cleanup your AWS System:

aws cloudformation delete-stack --stack-name ec2-stack

🎉 Wrapping It Up!

And that’s a wrap, folks! 🛠️

In this blog, we explored how to deploy an EC2 instance using a CloudFormation template via the AWS CLI, and more importantly, how NACLs can be configured to serve as an additional security layer in your AWS architecture.

We not only understood the difference between NACLs and Security Groups, but also blocked our own IP to see NACLs in action. Pretty cool, right?

🙌 Stay Connected

I hope you found this blog helpful and fun to follow. If you did, don’t forget to:

👍 Give it a thumbs up
🔁 Share it with fellow cloud learners
🤝 Follow me on:

Until next time,
Happy Learnings and Happy Clouding! ☁️🚀