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.
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.
Another good practice is to create a separate key for the Bastion host separate from the rest of the EC2 instances.
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.
For the security group that we assigned to our private servers, we added an SSH inbound rule from our public servers.
Finally, the security group assigned to our Bastion host has only one rule that accepts SSH connections from the internet.
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: 188.8.131.52 (Public)
- BackendServer: 10.0.2.13 (Private)
- WebServer: 10.0.1.76 (Private)
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.
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.
However, when I use the proxy command, I’m able to connect to the web server and the private backend server as well.
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.
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)