In this blog post we'll go beyond standard security and create our own VPC with a private subnet. We'll then create a bastion host in a public subnet that we'll leverage to instantiate a NAT gateway to enable our instance in a private subnet to receive updates from the internet even though it has no route to an internet gateway.
There are many layers of security available in AWS. Most people are content with the security group acting as a firewall at the instance level. This is probably mostly because the Ec2 creation wizard prompts them to select a security group or create a new one. This alone, can act a very effective firewall. Restricting ssh traffic to originate from your own external IP address is a very effective filter. However, AWS allows you to firewall an entire subnet and create your own virtual network where your security paranoia will be given free reign to run amok.
AWS Security Infrastructure
Upon deeper inspection of the AWS infrasturue you'll probably figure out that the difference between a public and a private subnet is the route to the internet gateway. If we create our own VPC and attach a internet gateway to it then any subnet that has a route table associated with it and a route to the internet gateway becomes a public subnet. You can get a deeper level of security if you launch your instances into a private subnet and then only shell into them from a public instance that acts as the bastion host. Let's walk through it so we can understand the risk/reward ratio at each step of the configuration.
A Custom VPC
Your AWS account comes with a default VPC that will likely suit most of your needs. While I don't recommend that you delete it, you certainly can if you are the adventurous type. You can make a VPC from scratch and I recommend that you don't use the creation wizard. Building it from scratch will force you to encounter each security concern. Once your VPC is created you can also create a new internet gateway and associate it to your new VPC. I'm using 10.0.0.0/24 for the CIDR range of my VPC. This will impact my choice of CIRD blocks for my subnets later.
Creating Subnets in your VPC
I'm making two subnets. One is public with a route to the internet gateway you created above, and one is private. Here is how it looks so you are familiar with the creation process.
For your bastion host create a route table, associate your public subnet and define a route to your internet gateway. Notice the tab for subnet association as well as the the tab for route enumeration.
While you are busy creating route tables make another and associate your private subnet you created above. You won't need any other routes. This will keep the riffraff of the internet out of your business.
Launch your Bastion Host and Private Instance
We are ready to launch the bastion host. Follow the basic creation wizard but make sure you use your new VPC, your public subnet and enable a public IP so you can actually shell into it. You can similarly launch your private instance but make sure you use your private subnet and disable the public IP. It will be created with a private ip that your bastion host will be able to use.
Risk Reward Ratio
We now have the benefit of increased security because our instance is in a private subnet but it can't receive updates because it has no route to the internet to receive them. Let's see how it works. Shell into your bastion host and copy over your cert with the copy command
scp -i temp.pem temp.pem [email protected]:/home/ec2-user From the bastion host you can now login to your private instance. This is possible because of the default local route that Amazon provides. Once you are in your private instance you'll notice that
sudo yum update fails because your private instance has not route to the internet because it is in a private subnet. We can get around this issue by using the NAT Gateway service and hence get strong security with no consequences.
Getting Updates Through a NAT Gateway
Create a NAT gateway from the VPC menu.
Be sure to use the public subnet and you can create a new elastic IP. Here is what it looks like.
Update your private route table to have a route to the NAT like this.
With this new route in place return to your private instance and again run
sudo yum update and you'll see it gets the updates successfully. Check it out.
If you have been using AWS for a for a few years you'll notice that the NAT gateway is a new service. You used to have to create a separate instance to act as your NAT.
I hope this post has showed you some of the security possibilities that are available in AWS. Play with them yourself and discover the ideal setup for your needs. Security is the biggest argument against cloud computing so you should invest in a deep understanding on this issue.