Securing private Linux EC2 instance with Bastion Host
I have come up with an idea to write some articles about cloud and devops related to making hands-on tutorials and references. In this article, we are going to set up a bastion host to access private Linux EC2 instances on AWS.
Before we started into dive-in, we need to clear the concept of “what is bastion host”.
A bastion host is a special-purpose computer for administration to private instance(or)database sit on the private subnet (without dealing with internet). A bastion host sits within the public subnet of AWS VPC (Virtual Private Cloud) and acts as a “gateway of login” between the outside world to your private subnets.
The purpose of putting bastion host inside the public subnet is to secure login to your application and data hosting in your private instance. Outside login attempts can not connect directly to private instances. It can only connect via bastion host in your public subnet of VPC (Virtual Private Cloud).
Deployment Steps
Let’s dive into the step-by-step deployment of the bastion host.
Step One — Create private instances restricted to selected sources (Bastion Host) via SSH.
Step Two — Create bastion host on a public subnet with restricted to selected source (Your Public IP).
Step Three — (Login private instance via bastion host) Validate your private instance connectivity via bastion host with ssh proxy command.
Step Four — (Alternative login private instance via bastion host) Using ssh config file to log in to your private instance via bastion host.
Disclaimer: Public Domain or IP Address in this tutorial are only for demonstration purpose.
Step One — Creating private instance with selected security source
Firstly, create a private instance at a private subnet with a trusted source as a bastion host security group. You need to add and allow bastion security group id on your private instance security group inbound rule. Mean private instances can only connect via the following bastion host.
After creating the private instance, we need to download ssh pem key for the private instance login.
After the private instance is completely running in a private subnet, we will move on to the bastion host creation step.
Step Two— Creating bastion host on public subnet
In this step, we will create a bastion host on our public subnet dealing with the outside world (Internet). At this time we use AMI for Amazon Linux 2 for our bastion host setup.
For creating a bastion host, follow the steps from your AWS management console.
Normally bastion host instance is low utilization only for administration purposes that’s why you can choose the general-purpose t2.micro instance (free tire eligible).
Same setup and creation above private instance, we need to create a bastion host and download ssh pem key to your local desktop (or) laptop.
After the bastion host creates, We can see the two instances (Private Instance & bastion host) are running on the respective subnet.
Next step we are going to log in and verify our setup from the local desktop (or) laptop.
Step Three — Login private instance via bastion host (ssh proxy command way)
This step can be a final step or login step we can verify our above bastion and private instance setup. Login into the private instance via bastion host are two ways,
- Login with SSH Proxy Command.
- Login with SSH Config File.
Before we start login, we need to review our instances information (Public DNS & IP Address)
Bastion Host Public URL = ec2–3–208–93–134.compute-1.amazonaws.com Private Instance IP = 192.168.3.225
After we get information about our instances, we need to apply the SSH proxy command to log in directly to our private instance via bastion host. For use with this method, Please note down the below command and type it into your terminal.
$ ssh -i private-key.pem ec2-user@192.168.3.225 -o ProxyCommand="ssh -W %h:%p -i bastion-key.pem ec2-user@ec2-3-208-93-134.compute-1.amazonaws.com"
You can see your login attempt can be successful to your private instance via bastion host without any hesitation if your configurations are correct.
$ ssh -i private-key.pem ec2-user@192.168.3.225 -o ProxyCommand="ssh -W %h:%p -i bastion-key.pem ec2-user@ec2-3-208-93-134.compute-1.amazonaws.com"Last login: Thu Jan 9 17:49:38 2020 from ip-192-168-1-248.ec2.internal__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|https://aws.amazon.com/amazon-linux-2/[ec2-user@ip-192-168-3-225 ~]$ ip a | grep eth02: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000inet 192.168.3.225/24 brd 192.168.3.255 scope global dynamic eth0
Step Four— Login private instance via bastion host (add ssh configuration in ssh config file)
As I mentioned above, we have another way to log in private instance via bastion with the ssh config file. You can create an SSH config file under the path ~/.ssh/config and populate the below contents.
$ vim ~/.ssh/configHost private-instanceHostname 192.168.3.225IdentityFile /Users/phyominhtun/Desktop/private-key.pemForwardAgent yesUser ec2-userProxyCommand ssh -W %h:%p -i /Users/phyominhtun/Desktop/bastion-key.pem ec2-user@ec2-3-208-93-134.compute-1.amazonaws.com
This configuration block can log in to bastion host to forward a private instance directly from your local machine. After populating the configuration block in the config file, type the ssh command to directly log in to your private instance.
$ ssh private-instanceLast login: Thu Jan 9 17:56:04 2020 from ip-192-168-1-248.ec2.internal__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|https://aws.amazon.com/amazon-linux-2/[ec2-user@ip-192-168-3-225 ~]$
You can see the login is successfully directly to your private instance jump over bastion host.
Conclusion
I suppose the bastion host setup on AWS is quite interesting. It could be secure from external unwanted login access to your cloud resources.
Please bear in mind, the bastion host setup is only for login from the external world (Internet) into your VPC(Virtual Private Cloud). If you want to out to the external world (Internet) from your VPC (Virtual Private Cloud) Private network, Please consider using NAT Gateway for your reference. In my future blog post, I will cover applying NAT gateway on AWS compared with NAT instance.
I hope you could set up properly the bastion host on AWS with my article.Please don’t be hesitate to reach out my Linkedin profile to any query.
In the next blog post, we will look walk through the steps of Connect to EC2 via AWS Session Manager and without SSH.