Monday 12 June 2017

AWS security with Security Groups and NACLs

Security is a layered approach. On premises when we implement a security strategy we do it in layers. We have a firewall device, we may have ACLs configured on our routers, the servers may have OS firewalls enabled like iptables or Windows firewall and finally the application end may apply certain security features.
In AWS, we apply layered security with Security Groups and NACLs.


Security Groups:

Security groups are a resource level traffic firewall that can be applied to an instance, an ELB etc.
Ingress and egress traffic filtering is available and return traffic is allowed by default. This implies that a response to a HTTP request will be allowed by default. They allow destination port filtering. The instances can't communicate unless they are allowed because we apply security groups to an instance and we do not add instances to a security group. Default SG allows communication from other instances within the same SG. Security groups when created (without any rules) are going to deny all inbound traffic until we add a rule to allow. We can only add allow rules in a SG. All outbound traffic is allowed by default until allow. This means that all outbound traffic is allowed by default. But when we explicitly add an outbound rule for allow then only the traffic mentioned in the allowed rule is allowed and all other traffic is denied.

SG maximums:




  • Up to 100 SGs per VPC
  • Up to 50 lines in each SG
  • to 5 SG per instance

Demo and examples:

When we create a security group with default settings, all inbound traffic among resources within the security group is allowed because the traffic source is set to the security group itself as shown below:



Now let's look at the security group I associated with the instance I created in the previous article:


Since this is a linux instance I've allowed inbound traffic on port 22 from 0.0.0.0/0 (anywhere) so that I could connect to it via internet.

I'm able to ssh from my local system with my key file without issues:

[user.DESKTOP-4NUE93O] ➤ ssh -i "sahil-ec2-test-keypair.pem" ec2-user@ec2-52-44-99-240.compute-1.amazonaws.com
Warning: Permanently added 'ec2-52-44-99-240.compute-1.amazonaws.com' (RSA) to the list of known hosts.
X11 forwarding request failed on channel 0

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.03-release-notes/
[ec2-user@ip-192-168-1-150 ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 12:c0:01:7a:c7:7c brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.150/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::10c0:1ff:fe7a:c77c/64 scope link
       valid_lft forever preferred_lft forever


But I'm not able to ping my instance:

[user.DESKTOP-4NUE93O] ➤ ping ec2-52-44-99-240.compute-1.amazonaws.com

Pinging ec2-52-44-99-240.compute-1.amazonaws.com [52.44.99.240] with 32 bytes of data:
Request timed out.
Request timed out.


That is because I don't have any rules to allow incoming ICMP ping traffic.

So, now we go to the security group, select it and click edit and add a rule to allow incoming ping traffic.


With that done we'll now be able to ping our instance.

[2017-06-12 10:11.52]  ~
[user.DESKTOP-4NUE93O] ➤ ping ec2-52-44-99-240.compute-1.amazonaws.com

Pinging ec2-52-44-99-240.compute-1.amazonaws.com [52.44.99.240] with 32 bytes of data:
Reply from 52.44.99.240: bytes=32 time=279ms TTL=237
Reply from 52.44.99.240: bytes=32 time=279ms TTL=237
Reply from 52.44.99.240: bytes=32 time=278ms TTL=237
Reply from 52.44.99.240: bytes=32 time=279ms TTL=237

Ping statistics for 52.44.99.240:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 278ms, Maximum = 279ms, Average = 278ms



Network Access Control Lists (NACLs):

They are at the subnet level and not at the instance or resource level. They allow source and protocol filtering. They are stateful i.e. traffic is strictly filtered. They provide allow and deny rules. We can apply only one NACL per subnet. A NACL consists of numbered rules with the lower numbered rules being processed first. While the rules are being filtered NACL will not process further beyond the first match.


Demo and examples:

So here is the NACL that got created with the VPC we created in the previous article.


From the above details we can ascertain that the NACL is associated with one subnet and all inbound traffic from anywhere is allowed.

Now let's do something drastic and deny everything by clicking on edit and updating the rule.





So now if we try to connect our instance via ssh:

[user.DESKTOP-4NUE93O] ➤ ssh -i "sahil-ec2-test-keypair.pem" ec2-user@ec2-52-44-99-240.compute-1.amazonaws.com
ssh: connect to host ec2-52-44-99-240.compute-1.amazonaws.com port 22: Connection timed out

We get a connection timed out.

You may wonder that the security group is allowing ssh traffic then we couldn't we connect. The security group was applied against the instance to allow ssh traffic. But any incoming traffic gets dropped at the NACL and never reaches the instance for the security group to come into play.

1 comment:

Using capture groups in grep in Linux

Introduction Let me start by saying that this article isn't about capture groups in grep per se. What we are going to do here with gr...