In my last blog about AWS Secure Shell (SSH) setup with EC2 and CloudFormation we have automated creating an EC2 instance with a KeyPair. With the KeyPair we can initiate a connection to the instance and get access to the terminal. In this blog we will use SSH to setup a SSH tunnel to the virtual network in AWS. With SSH tunnels we can access servers in AWS that do not have public network connectivity.
Architecture
We will create an EC2 instance in a private subnet that has NAT connectivity. The private instance will host a simple webpage on port 80. The private instance can connect to a basion host in the public subnet. The public subnet is reachable via SSH using RSA keys. We will connect to the bastion host via SSH and setup a tunnel to the private instance so that the webpage is reachable from our local computer only.
SSH and Tunnels
To setup SSH local port forwarding from localhost:8080
to the private host ip-10-0-1-92.eu-west-1.compute.internal:80
type:
$ ssh -N -L8080:ip-10-0-1-92.eu-west-1.compute.internal:80 -i bastion.pem ec2-user@ec2-34-254-194-35.eu-west-1.compute.amazonaws.com
Connecting to the private instance
When a SSH tunnel is created, open a browser and open http://localhost:8080. The browser will connect to the local computer, and all data to port 8080 will be forwarded from the SSH server to the private instance. The tunnel is bidirectional which means that the private instance can answer with a web page that will be rendered by the web browser. The connection is encrypted and all data will be sent encrypted via the tunnel to your local computer.
Example
The example project shows how to configure a project to setup a public and private network. There is also a bastion host that acts as a NAT router for the private network. The bastion host can be used to manage the private instance. The example can be deployed with make deploy
and removed with make delete
. To login type make ssh
and to create a tunnel on port 8080 type make tunnel
. When you close the SSH session, the tunnel is shut down and no further communication with the private instance is possible.
Conclusion
In this blog we have seen how to setup a SSH tunnel to the private instance in AWS that is running a simple web server and web page. By using SSH with local port forwarding, all communication is private and encrypted between your computer and the private instance. A bastion host with port forwarding can be used with other services like the Elasticsearch service that is running in a private subnet. When Kibana is running on port 443 (SSL), you can forward traffic to localhost to Kibana running in the private subnet. This way you can access the service in a secure way.