AWS SSH Tunneling with Amazon EC2

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.

Share this article: Tweet this post / Post on LinkedIn