Release Management/Managing EC2 firewall
Amazon EC2 includes a security service that allows defining groups, launching instances in these groups and a firewall that allows managing the permissions on these groups. This document has two main goals:
- Use this EC2 fireall as the first the security layer.
- Avoid specifying internal IP addresses.
The second point requires a clarification. Whenever you start a new instance you get a new external IP address, but also a new internal IP address. Having a fixed external IP address is solved by using the Elastic IP feature, which allows assigning a static IP to a running instance. There is no way, however, to keep the same IP address.
This is very important if you aim to "High availability". That is, having to start a new instance of a running machine is not so strange, and could happen for various reasons (The hardware behind the instance is degraded, you want to migrate to another instance with better features, an attack has accessed your instance, etc.). And there are many places in the infrastructure where specifying the internal IP address seems unavoidable (firewall rules, program configurations, etc).
This document explains how to achieve these goals.
External IPs: Elastic IPs
Whenever you start a new instance you can assign a Elastic IP to it, which means it will have a static IP address. The syntax is simple.
Request a new static IP address:
ec2-allocate-address ADDRESS xx.xx.xx.xx
Assign the given IP to a running instance:
ec2-associate-address -i i-yyyyyy xx.xx.xx.xx
And the i-yyyyyy will have the xx.xx.xx.xx IP address in a matter of seconds.
There is no tool such as the Elastic IPs to solve this problem.
However, there are alternatives to specifying the IPs in the situations describes in the following subsections.
If you use the internal IP address inside the EC2 network all the traffic is free. That is, if you access instance A from instance B using the internal IP address there's no additional cost. But if you use the external IP for this communication then you pay for the traffic.
One option is to specify the internal IP address everywhere it is needed: programs using a database server in another instance, monitoring services, etc. But this is tedious because you need to change this configuration every time you start a new instance.
There solution for this is to use DNS CNAME records. That is, register a DNS address for every critical instance you have, by adding it as a CNAME to ec2-79-125-3-243.eu-west-1.compute.amazonaws.com (in EU region). Then the good thing is that if you use ec2-79-125-3-243.eu-west-1.compute.amazonaws.com in the ourside world it will resolve to 18.104.22.168. But if you try to use it inside the EC2 network it will resolve to its internal IP address. Example:
$ host ec2-79-125-3-243.eu-west-1.compute.amazonaws.com ec2-79-125-3-243.eu-west-1.compute.amazonaws.com has address 22.214.171.124
$ host ec2-79-125-3-243.eu-west-1.compute.amazonaws.com ec2-79-125-3-244.eu-west-1.compute.amazonaws.com has address 10.226.14.202
It is also typical to specify access to an instance by using the internal IP address. For example, let's imagine we have a database server instance running in the dbserver security group. And an application server instance running in the appserver security group. This is what you'd typically do to allow the application server access the database server:
$ ec2-authorize -p 3306 -s 10.226.14.202/32 dbserver
Where 10.226.14.202/32 would be the internal IP address in this case.
Instead of doing it, it fits better our needs to use a group based authorization, so that you allow the appserver group access the dbserver group on that port:
$ ec2-authorize dbserver -p 3306 -P tcp -u AWS_USER_ID -o appserver
Two notes in this command:
- Do not forget adding -P tcp explicitly or it will not work. This argument is not mandatory in the first command where we specified the source IP, but it is mandatory in this one.
- You must specify the Amazon user ID owning the source security group (appserver in this case).