Amazon Virtual Private Cloud (VPC) allows you to provision a logically isolated real state inside AWS cloud where you can launch resources in a virtual network you define and have full control over the virtual network environment. When you first launch a resource like an EC2 instance without a custom VPC it’ll be launched inside the default VPC. It’s easy and user friendly but you don’t have much control over it. With a custom VPC you can create your own subnets, choose the IP address ranges, configure routing tables and have much more fun!
When you create a custom VCP,
- A default routing table, a network access control list (NACL), and a default security group will be created.
- But no subnets and an internet gateway will be created.
Let’s create a custom VPC!
- Logging to your AWS console and move to VPC dash board,
Services → Networking & Content Delivery → VPC
- Your VPCs → Create VPC
- Give your VPC a name and IPv4 CIDR block (Block size must be between a /16 and /28 netmask) and choose whether you use IPv6 as well. (I’m not in this case).
- Choose the default tenancy (Dedicated tenancy ensures all EC2 instances that are launched in a VPC run on hardware that’s dedicated to a single customer.) and finally hit Create VPC.
Let’s create a couple of subnets. One public and one private.
The Public Subnet
- Name your subnet and choose the VPC (choose the VPC you created not the default one)
- Choose an Availability zone (I’m using us-east-1a for the public subnet) and IPv4 CIDR block. (I’m using 10.0.1.0/24 for the public subnet)
The Private Subnet
- It’s same procedure as creating the public subnet.
So, how do we make our “Public subnet” public?🤔
The only adjustment you have to make is to enable ‘auto-assign public IPv4 address’ feature in your public subnet.
- Choose your pubic subnet → Actions → Modify auto-assign IP settings → Check auto-assign IPv4
Let’s create an internet gateway and attach it to our VPC.
- Internet Gateways → Create internet gateway
- Choose your new internet gateway → Actions → Attach to VPC
- You can have only one internet gateway per VPC.
Remember, by default you get a route table when you create a VPC. That’ll be your main route table for the VPC and the two subnets you created are associated with it.
If you add a route out to the internet in your main route table both the subnets will be public. Therefore you need to configure route tables such that only the public subnet has a route out to the internet.
- Let’s create a route table with a route out to the internet and associate the public subnet to the new route table.
- Route Tables → Create route table
- Add an route out to the internet via the internet gateway
- Choose your route table → Routes → Edit routes
- Choose the internet gateway you created as the target.
- Associate the public subnet to this route table.
- Choose the route table → Subnet Associations → Edit subnet associations
- Choose the public subnet.
- let’s launch a coupe if ec2 instances in each subnet.
- Pay attention to the VPC and subnet when launching ec2 instance.
- Configure the security group for public ec2 instance to allow http traffic.
Let’s try SSH into the subnets.
Since you have allowed both http and SSH in the security group you should be able SSH into the public server and access the internet from the ec2 instance.
How do you SSH into the private server using the private IP address (You don’t have a public IP address). There are two ways you can achieve this.
- Copying the .pem file into the public instance and SSH into the private instance via the public instance.
This is not a recommended method and could be a huge security risk. Also you need to configure a new security group for the private ec2 instance allowing SSH and http traffic.
2.Using a Bastion Host
As mentioned earlier copying your private key onto a public ec2 instance is not secure. Therefore, use SSH agent forwarding and Bastion host (Jump Box) to SSH into the private server securely.
- Launch another ec2 instance in your public subnet to use as the Bastion host.
- Allows SSH from trusted hosted in your security group.
- Allows SSH from the Bastion host in private servers security group.
- Setup SSH agent.
$ ssh-agent bash
- Add the private key to the key-chain.
$ ssh-add ".pem"
- Check whether the key is added or not.
$ ssh-add -l
- Access the bastion host using the public IP address.
$ ssh -A ec2-user@"public IP"
- SSH to the private server from the Bastion host.
$ ssh ec2-user@"private IP"
Now that you can SSH into the private server, can you access internet from the private server? Nope😫
Like earlier, there’s two solutions for this.
1.Using a NAT instance
- Create a new instance in the public subnet.
- Choose an AMI from community AMIs for the NAT instance.
- Allow web access in the security group.
- Disable source destination check.
Actions → Networking → Change source/destination check → Stop
- Add an route out to the NAT instance in the main routing table. (Private subnet is associated with the main route table.)
Even though NAT instances work fine there are few downfalls.
- Not scalable
- Single point of failure
2.Using a NAT Gateway
Due to the downfalls of NAT instances, NAT gateways have become the preferred choice in the industry. They are redundant inside the AZ and don’t require much work to setup.
- VPC Dashboard → NAT Gateways → Create NAT gateway
- Choose your public subnet and allocate an elastic IP.
- Finally add a route out to the NAT gateway in the main route table.
Voila! Now you can access internet from the private server.