This page will guide you through creating a NAT instance that will be used by your private instance as a gateway to the internet. We will first go through creating the instances and afterwards, we will then continue through to locking it down so that the private instance is able to communicate with the internet.
Before proceeding, you should have already completed the “Create a Bastian” host section under the linux drop down. If not, please proceed to complete that first before proceeding with creating a NAT instance as a bastian is required for this section.
Lets jump straight into creating a private instance :
-Launch an instance on AWS
- Heres what to do….
- Go to the EC2 management console and select launch instance
- Select an Amazon Linux AMI:
- and select the instance type, for testing purposes, I would suggest the t1 or t2 micro as its much cheaper.
- Select the VPC you will be using and select a private subnet to be used and disable auto assign public ip. (Why, because its a private instance DUUURRR)
- Anyway moving on, add the volume size… 8GiB should be enough.
- create a tag (optional):
- configure your security groups by just adding ssh to 0.0.0.0/0 for now.
Click Launch and select the keypair you will be using.
Now, testing time. Remember, we havent assigned a public IP to the instance so how will we gain access? Thats where the Bastian comes in. Ssh into your bastian host and add the keypair selected for the private instance as previously shown under how to create a bastian. Seriously, if you havent created a bastian, please do it now, this page isnt going anywhere.
Lets get into our bastian first, using ssh -i keypair.pem ec2-user@ip
Once done, use the same command to SSH into the private instance. However, instead of using the public IP, we will use the private IP of the instance instead. Remember, we didnt assign a public IP to the instance as we disabled auto assign, mainly because we want this instance to remain private.
OK, so use the command ssh -i keypair.pem ec2-user@privateip as shown below:
PLEASE: If you get a permission denied publickey error, use sudo like I did above. Works like a charm. But hey look, we have ssh’d into an instance with no public IP. Nice hey, but what next??
OK, so the problem is now is that we have no access to the internet. How are we going to fix this? By creating a NAT instance, here’s how:
Following the same process as launching a private instance via the EC2 management console, you will need to select a NAT ami. AWS has preconfigured NAT ami’s available. Heres hows to get them:
-click on community AMI’s
-Type in NAT and hit enter
-Select the NAT ami of your choice
Now as with the private instance, select the instance type and click continue. Next, under configure instance details, select the same VPC and now select the public subnet. Remember, the public and private instances have to both be on there own subnet.
WAIT!!! Subnets!!!! I’m confused…????
Ok, let me explain the quick difference between a public and private subnet. Its simply really, a public subnet has something called an IGW( INTERNET GATEWAY) that allows it to talk to the internet whereas a private subnet does not. So what we going to do a bit later on, is configure the routing tables, subnets and security groups to allow the private instance to talk to the internet through the public instance reducing risk of directly being attacked through the internet.
Moving on, just follow the steps on launching the instance leaving everything default and click launch using the same keypair as the private instance(Just to make it easier, if you wanna be a bad ass you can use a different one).
Lets test connectivity to the public instance just to make sure it works. We’ll do this by just ssh’ing into the instance as normal, that is public IP and the .ppk keypair.
OK, so we have one VPC, with two subnets, one private subnet and one public subnet, we launched an instance with no public IP into the private subnet only allowing SSH on port 0.0.0.0/0 and we launched an instance with a public IP into the public subnet also only allowing access to SSH on port 0.0.0.0/0.
So what next?
Well, even though this private and public instances are on the same VPC, how will they talk to one another? How does the Public instance know that the private instance wants to use it to gain access to the internet?
For this, we will need to go VPC management console but before we do, on the EC2 management console go to network interfaces and take down the ENI (network interface) for the public instance you created as well will be using this later.
Example of what an ENI looks like:
Now we can move on to the VPC management console:
On the VPC console, click on Subnets. Remember, we are using two subnets, one for the public instance and one for the private instance. If you are using the default VPC which AWS gives, both subnets should have the following the following routes by default:
First, we are going to configure our private subnet so that it can talk to the public instance being used as our NAT. Go ahead and click on routing tables and select the routing table being used for your private subnet.
- Click on routes and select edit
- Remove the default IGW and add the ENI you copied earlier into target.
Please note: Both subnets are given an IGW by default.
- The destination will be 0.0.0.0/0
- Click save and you should have the following :
As you can see from the above pic, the ENI reflects and auto populates the instance ID associated to the ENI which belongs to your public instance. What we have done now, is created a route for the private instance to get to the public instance. But can the private instance reach the internet??? Lets test this out. SSH into your bastian again and then SSH into the private instance using the private ip as we followed earlier.
Once in, run the following command to test if the private instance can talk to the public instance:
The command above should be added as follows :
nc -vz publicipofpublic instance 22 (22 is the port number for SSH) .
Remember on launching both instances, we allowed access to port 22 on 0.0.0.0/0 which allows access from anywhere. We did that all for this test, see there was a good reason for leaving port 22 open.
OK, so the private instance can talk to the public instance, what now?
Remember, the whole point of this is to give the private instance access to the internet, so does this private instance have access to the internet??? Lets test it out…. Use the following command:
$ sudo yum update
Why update command, well in order to the instance to install any updates it needs access to the internet.
As you can see from the output above, just a whole bunch of errors after errors after errors. Because??? You got it, no way to the outside world (The internet). How do we fix this?
Well we will need to look at the public instance. The routing table should be fine, with the local route and an IGW which is gets by default. However, we need to look at the security groups of the public instance to make sure its allows the private instance to do what it wants to. For now the private instance can only SSH, but lets test something. Lets try running a PING command which uses ICMP(A Protocol for communication over the internet).
So lets try and ping google.com for exmaple which uses the ip 126.96.36.199.
As you can see, nothing happens, it just stands. Leave this terminal open, and go to the security group of the public instance and add the following:
- Select add Rule and then select ALL ICMP with the source of 0.0.0.0/0.
- Select save and quickly go back to your terminal. AHA….. You see, ping is working now because we added it to the security group of the public instance.
Lets try another one, lets try HTTP. But before, run sudo yum update and see what happens, Nothing right!!!!
Now again, go to the security group of the public instance and add HTTP and add the source as anywhere which is 0.0.0.0/0.
Now run the command sudo yum update again, and see what happens?? Ag, you becoming a pro now…. the following should of happened:
But yeah, your private instance now has internet access. And you can control what it has accessing to by playing around with the security groups.
Thats it…. You now have a private instance which is accessed by a bastian and that has accesses to the internet through a NAT instance.