Connecting to a Private Instance using a Bastion Host in a Custom VPC in AWS

Matthew Mendez
DevOps Engineer Documentation
7 min readMay 9, 2021

Scenario

You have been tasked with setting up a custom VPC. You will use a bastion host to connect to your private instance in a private subnet for only your team to have access to.

1.What is a VPC?

2.Creating a custom VPC.

3. Create a public instance.

4. Create a private instance.

5. Connect successfully to your private instance from your bastion host!

6. Conclusion.

1. What is a VPC?

A VPC is a virtual network in the cloud dedicated to your AWS account where you can launch AWS resources. A virtual private cloud (VPC) allows you to specify an IP address range for the VPC, add subnets, associate security groups, and configure route tables.

2. Creating a custom VPC

In the AWS console, Navigate to VPC.

Click on Your VPC

Click on Create VPC

Name VPC: my-custom-vpc

Ipv4 CIDR block: 10.0.0.0/16

IPv6 CIDR block: No

Click Create VPC

Next we will need to create a internet gateway to attach to our VPC to allow communication between our bastion host in our VPC and the internet.

In the drop down in VPC, click Internet Gateways

Name internet gateway: my-custom-internet-gateway

Click create Internet Gateway

In actions, Attach Internet Gateway to the custom VPC we created

Next we’ll have to configure a Public Subnet for our bastion host to reside in.

In the VPC dropdown, click Subnets

Click create Subnet

Associate this subnet with the custom VPC we created

Name our Subnet: custom-public-subnet

Choose Availability zone

IPv 4 CIDR block: 10.0.1.0/24

Click create subnet

Next we will want to create a Private subnet for our private instance to reside in.

Click subnets

Click create subnet

Associate this subnet with the custom VPC we created

Name our subnet: custom-private-subnet

Choose a different availability zone for the private subnet

IPv4 CIDR block: 10.0.2.0/24

Click create subnet

Next, we will want to create two separate route tables for our public and private subnets. A route table contains a set of rules, called routes, that are used to determine where network traffic is directed.

In the VPC dropdown, click Route Tables

Click create route table

Name route table custom-public-RT

Associate this route table with the custom VPC we created

Click create route table

Next we will want to edit our public route table to target the internet gateway we created.

Click edit routes

Destination: 0.0.0.0/0

Target: the custom internet gateway we created

Click save routes

Next we will want to associate our public route table with our public subnet.

Click on edit subnet association

Choose the custom public subnet we created

Click save

Next we will want to create a private route table.

Click create route table

Name route table: custom-private-RT

Associate the private route table with the custom VPC we created

Click create route table

We will come back to the private route table and edit the route and associate the route table with the private subnet after we create our bastion host and private instance.

3. Create a public instance

We will create a public instance that will be used as our bastion host to SSH into our private instance.

Navigate to EC2 instances and Click Launch instances.

Step 1. Select AMI Amazon Linux 2

Step 2. Select t2. micro

Step 3. Configure instance details. Below, Take note that I configured my EC2 Instance to be launched in the custom VPC we created, launched it in the public subnet we created and enabled Auto-assign Public IP.

Step 4. Select default storage

Step 5. Add tags

Step 6. Configure security Group. For the bastion host make sure you only have port 22 traffic coming from the IP you need, not other security groups from other instances. For this example, choose My IP as the source. See my example below.

Step 7. Review and launch.

Step 8. You will be asked to select an existing key pair or create a new key pair. Select a new key pair and download it. Do not lose this key pair. We will need it to connect to our bastion host.

4. Create a private instance

Step 1. Click Launch instances.

Step 2. Select Amazon Linux 2 AMI.

Step 3. Select t2. micro

Step 4. Select our custom VPC in network settings. Select our custom private subnet in subnet settings. Make sure auto assign public IP is disabled.

Step 5. Select default storage.

Step 6. Add tags.

Step 7. Configure the security group. Keep SSH but configure the source to be the CIDR of our VPC. We only want SSH from within our VPC. See my example below.

Step 8. Review and launch.

Step 9. Create a new key pair for our private instance and download it.

We will now to go back to our private route table and edit the routes and edit the subnet associations.

In our private route table, click edit routes. For destination select 0.0.0.0/0. For the target, select instance and in the drop down select our bastion host (public instance).

Next, we will need to associate our private route table with our custom private subnet.

5. Connect successfully to your private instance from your bastion host!

I’ll be using a window terminal to connect to my bastion host. Please see the official AWS documentation on how to connect securely to Linux instances running in a private VPC.

Locate your public key and grab the full path to the key. See below.

Go to your public instance in the AWS console and copy the public IPv4 address. Open up terminal on windows and run SSH with full path to key, key name and IPv4 address of public instance. See my example below.

We have successfully logged in to our bastion host!

We will now use this bastion host to securely connect to our private instance.

Locate your private key pair. (There are much more secure ways to do this but for example purposes, this is the way I will show you.) Copy your private key pair. In the bastion host, type command vim (your private key pair.)

type command vim (yourkeypair.pem)

Copy and paste your key pair in the text editor

vim text editor

Hit esc on keyboard while in the editor. Then hold shift and the colon key. Press wq! to save and quit the text editor.

You will now need to change permissions on the key pair. Use command chmod 0400 (yourprivatekey.pem) and then hit enter.

Navigate back to the AWS console in EC2 and find the private IP address.

Now we can SSH into our private instance using our bastion host!

Type ssh ec2-user@(yourprivateip) -i (yourprivatekey).pem (See example below)

Success! We’ve now connected into our private instance through our bastion host!

6. Conclusion

We can now delete our instances and our custom VPC if there is no more need for them.

For more resources on how to connect to your instances check out:

For more resources on bastion hosts check out:

https://aws.amazon.com/blogs/security/tag/bastion-host/#:~:text=A%20bastion%20host%20is%20a,minimize%20the%20chances%20of%20penetration.

For more information on AWS VPC check out:

--

--

Matthew Mendez
DevOps Engineer Documentation

Documenting my journey from bartender to a career as a devops engineer