Hands-On Cloud Security with AWS: VPCs, NACLs, and More

Hands-On Cloud Security with AWS: VPCs, NACLs, and More

I recently came across an Instagram post, of all places, that outlined a brilliant project idea for getting hands-on with cloud security: build a secure yet accessible infrastructure on AWS. The core components?

  • A Virtual Private Cloud (VPC) with a public subnet
  • A web server accessible from the internet
  • Properly configured Security Groups and Network ACLs
  • Security best practices to protect your resources

I’ve decided to take on the challenge. I’ll be using AWS.

First things first: creating a VPC

Above, you can see the settings I used to create my VPC.

With the VPC now created, it’s worth pausing to understand AWS's two main layers of network security:

Security Groups

  • Act as virtual firewalls for individual resources
  • Stateful: if outbound traffic is allowed, the return traffic is automatically allowed
  • Only support allow rules (no explicit deny)
  • Rules are evaluated as a whole—if any rule allows traffic, it’s allowed

Network ACLs (NACLs)

  • Operate at the subnet level
  • Stateless: inbound and outbound rules are evaluated independently
  • Support both ALLOW and DENY rules
  • Processed in numerical order (lower numbers evaluated first)
  • Provide an additional layer of defence

We’ll be implementing both for a defence-in-depth approach.

Let’s start with creating a NACL.

Inbound rules are shown above (with my own IP redacted).

Outbound rules are shown here.
Following security best practices, I explicitly defined allow rules and denied everything else by default. I then associated my subnets with this NACL.

Next step: launching an EC2 instance.

After setting up inbound rules within the Security Group, I added the following script to the EC2 User Data section to bootstrap the web server:

#!/bin/bash
# Update the system packages
yum update -y

# Install Apache web server
yum install -y httpd

# Start the Apache web server
systemctl start httpd

# Configure Apache to start automatically on boot
systemctl enable httpd

# Create a simple HTML page
echo "<html><body><h1>Secure AWS Web Server</h1><p>This server is protected by security groups and NACLs</p></body></html>" > /var/www/html/index.html

All that remained was to launch the instance.

To further improve security, I went back to the VPC dashboard and:

  • Created a VPC flow log
  • Enabled Amazon GuardDuty

I also:

  • Created an IAM role with minimal permissions and attached it to the EC2 instance
  • Enabled MFA for the root account

After tightening up these security features, I tested the server.

Here’s a successful HTTP connection.

SSH without the key resulted in a “Permission denied” message (as expected).

Using the correct key resulted in a successful SSH login.

This project has pushed me to consider a number of cloud security best practices, including:

  • Network Segmentation: Only expose necessary resources to the internet
  • Defence in Depth: Use multiple layers like Security Groups and NACLs
  • Principle of Least Privilege: Assign the minimal access necessary
  • Regular Updates: Keep the OS and packages patched
  • Monitoring and Logging: Enable flow logs and GuardDuty, set up alerts
  • Encryption: Use HTTPS for data in transit and enable encryption at rest
  • IAM Best Practices: Use roles, avoid hardcoded credentials, enable MFA

Conclusion

Security in the cloud isn’t a one-time task—it’s an ongoing process. By configuring VPCs, subnets, Security Groups, and NACLs with intention, I’ve laid a secure foundation for future cloud projects.

The public subnet architecture I’ve built strikes a balance between accessibility and security, and it provides a practical starting point for anyone looking to learn cloud security hands-on.

For now, I’m pausing the instance. But next steps might include:

  • Adding an AWS WAF
  • Enabling CloudTrail and AWS Config
  • Setting up CloudWatch alarms for suspicious activity
  • Or maybe even turning this instance into a honeypot to analyse access attempts

Stay secure out there.