AWS Security Groups - Once And For All

4 mins
Published on 02 June 2021

As part of securing applications in the cloud, it’s important to set the proper network rules, for maximum security and to minimize collateral damage.

Here’s a quote from the official HIPAA requirement for Transmission Security.

A covered entity must implement technical security measures that guard against unauthorized access to e-PHI that is being transmitted over an electronic network.

HIPAA

For those of you who are not familiar with HIPAA, it’s a very strict regulation that requires protecting medical records and other personal health information (PHI).

Most startup companies that develop a product for the medical-healthcare sector, aspire to become HIPAA compliant.

Here’s the question you need to ask yourself when it comes to Transmission Security

What security measures are currently used to protect e-PHI during transmission? HIPAA - Security Rule - Technical Safeguards

Network Security Layers Overview

I’d have to write a book to cover all the network security layers, so let’s get a quick glance at the most common network security layers in AWS.

  1. Application - AWS Web Application Firewall (WAF)
  2. Subnet - AWS Network Access Lists (NACLs)
  3. (Virtual) Firewall - AWS Security Groups
  4. Network - AWS Network Firewall

In this blog post, I’ll focus on the Virtual Firewall layer. In AWS, the implementation of a Virtual Firewall is done with AWS Security Groups.

Stateful Vs. Stateless

Security groups are stateful, the official docs, describe it as follows:

If you send a request from your instance, the response traffic for that request is allowed to flow in regardless of inbound security group rules. Responses to allowed inbound traffic are allowed to flow out, regardless of outbound rules.

By default, a security group is created without any inbound rules. That means it doesn’t accept traffic from any device that attempts to initiate a connection.

The default outbound rule is 0.0.0.0/0 which allows devices to initiate connections to anywhere. Once a connection is initiated, the security group rule is ignored.

So what is stateless? We’ll cover that in the Blocking Specific IPs section.

Security Groups Ground Rules

  1. Once a connection is initiated, the security group rules are ignored and traffic is allowed for the new connection.
  2. There’s no way to enforce security group rules on existing connections. Rules are applied to new connections only, so you must terminate existing connections, to force new security group rules.

Practical Example

Let’s say you want to SSH from your local machine to an EC2 instance, that has a public IP address.

To achieve that, you’ll add an inbound security rule that allows SSH connections from My IP (your IP). And then, you’ll SSH to the EC2 and it’ll work as expected.

Here comes the tricky part; What would happen if, during your SSH session, someone removes your inbound security group rule? Nothing. As mentioned earlier, security group rules apply to new connections only, since your SSH session is active, you can still continue with your work. If by any chance, you get disconnected for even a split second, the new security group rules will take place and you’ll get disconnected.

Allow Or Deny?

This is very confusing; One might want to deny traffic from a known set of IP addresses. It is common to think that Security Groups can be used to block traffic explicitly, though it is impossible.

Security Groups are designed to Allow access from/to sources, and implicitly block unknown sources. When you add a security group rule, you don’t have an option to set its type (Allow/Deny), it is Allowed by design.

Blocking Specific IPs

To address the need for explicitly blocking specific sources, you can use AWS Network Access Lists (NACLs), which are stateless, and as part of setting a Network Access Rule, you’ll have the option to set its type (Allow/Deny). It’s important to mention that NACLs operate at the Subnet level, while Security Groups operate at the VPC level.

Reminding you that NACLs are stateless, which means you’ll need to create a rule for both inbound and outbound for any source/target device. Unlike Security Groups, if you haven’t explicitly allowed a connection both inbound/outbound, it is denied by default. The default NACLs rules, for both inbound and outbound, are All traffic, from/to: 0.0.0.0/0.

NOTE: I rarely use NACLs, unless there’s a specific need to block a set of IP addresses at the subnet’s level, which in my experience, is quite rare and should be used with cautious.

Allow Access According To IP and Request URI-Path

One might think “but hey, I want to allow access to https://myapp.com/admin/dashboard from my IP only, how can I do that? Since HTTP requests are handled at the application layer, you can use the AWS Web Application Firewall.

Here’s the pseudo-code of the set of rules that should be created

if AND(
URI-Path == https://myapp.com/admin/dashboard,
SourceIP != Whitelisted-IPs
)
then Block

Selecting The Right Defense

  1. Security Groups are designed to Allow traffic from/to sources, at the VPC level.
  2. NACLs can be used for blocking a set of IP addresses (bots, bad reputation, etc.) at the Subnet level.
  3. AWS WAF can be used for blocking all traffic to a specific URI-Path, and allowing traffic only from a specific set of IP addresses (whitelisted).

References

Final Words

When I first started my journey with AWS, Security Groups were one of the first components that I encountered. I also didn’t have any background with networks, so stateless and stateful didn’t mean anything to me. Once I broke it down and found out which service should be used for each purpose, it was all clear.

Related Posts