In the previous AWS article, we’ve gone through the main overview of the VPC service and we provided steps to create a custom VPC with two subnets, one public and one private.

We’ve also provisioned two EC2 instances, one in each subnet. However, to test the connections to our EC2 instance, we were not using best practices and we’ve mentioned that the best way to access our servers through SSH it was using Bastion Host. Including this type of host in your cloud environment enables you to securely connect to your EC2 instances whether they are public or private without exposing your environment to everyone. Also, we are going to configure the security groups to provide fine-grained control.

Let’s launch an EC2 instance for the Bastion host in our public subnet. To perform this operation, we need to navigate to the EC2 dashboard and click on the “Launch Instance” option.

A screenshot of a cell phone

Description automatically generated
Figure 1 – shows the instance configuration details.

The Bastion host will be provisioned to the public subnet and we are going to create a security group with an inbound rule to allow SSH. For now, we are going to leave the source anywhere, but it is recommended that you configure a range of IPs of the people that are going to connect to our Bastion host.

A screenshot of a social media post

Description automatically generated
Figure 2 – Shows the config of the new security group.

Another good practice is to create a separate key for the Bastion host separate from the rest of the EC2 instances.

A screenshot of a social media post

Description automatically generated
Figure 3 – shows the creation of the new key pair for our Bastion host.

Now let’s take a look at our security groups. For our WebDMZ we only accept HTTP connections to port 80 from the internet and we only receive SSH connection from within our private IP addresses.

A screenshot of a cell phone

Description automatically generated
Figure 4 – shows the different rules for the WebDMZ.

For the security group that we assigned to our private servers, we added an SSH inbound rule from our public servers.

A screenshot of a social media post

Description automatically generated
Figure 5 – shows the rules for the security group assigned to our private servers.

Finally, the security group assigned to our Bastion host has only one rule that accepts SSH connections from the internet.

A screenshot of a cell phone

Description automatically generated
Figure 6 – shows the rules for the security group assigned to our Bastion host.

Now let’s take a look at how we are going to connect to our servers using ssh. We have the following IP addresses for our servers:

  • Bastion: 18.144.66.162 (Public)
  • BackendServer:  10.0.2.13 (Private)
  • WebServer: 10.0.1.76 (Private)
A screenshot of a social media post

Description automatically generated
Figure 7 – shows the instance configuration of the Bastion host and its IP addresses.
A screenshot of a social media post

Description automatically generated
Figure 8 – shows the instance configuration of the Web server and its IP addresses.
A screenshot of a social media post

Description automatically generated
Figure 9 – shows the instance configuration of the Backend server and its private IP address.

To connect to our servers, first we are going to create the ssh config under our ~/.ssh folder. In there we are going to add the bastion host ssh configuration and the connections to our private servers using a proxy ssh command. With this technique we don’t need to store any keys on our Bastion host.

A screenshot of a social media post

Description automatically generated
Figure 10 – shows the config file.

To Connect to the Bastion host, we just need to execute the command ssh bastion. Also, if we try to connect to the rest of the servers, from the bastion host we can’t because there are no keys stored in there. In fact, the keys are on my computer.

A screenshot of a cell phone

Description automatically generated
Figure 11 – shows the connection to the Bastion host and also the rejection of the connection to the web Server.

However, when I use the proxy command, I’m able to connect to the web server and the private backend server as well.

A screenshot of a cell phone

Description automatically generated
Figure 12 – connection to the web server.
A screenshot of a cell phone

Description automatically generated
Figure 13 – connection to the backend server.

Finally, there are many more best practices to implement according to AWS (2018):

  • Deploy Bastion hosts to multiple availability zones to support high availability.
  • Configure auto-scaling groups to ensure that the numbers of bastion host instances match with the capacity that you need.
  • Always provision Bastion hosts in the public subnets.
  • Limit all connections using security groups.

References

AWS(2018) Linux Bastion Hosts on the AWS Cloud [Online] Available at: https://aws-quickstart.s3.amazonaws.com/quickstart-linux-bastion/doc/linux-bastion-hosts-on-the-aws-cloud.pdf (Accessed 30 March 2020)

Leave a Reply

Your email address will not be published. Required fields are marked *