SSM-Bastion : How to connect on AWS Private instance's from Internet
Tags: aws, security, bastion, architecture
Published: 2021-04-08 15:17:30

One of the classical challenge in Security and Accessibility of a project in AWS when you want to access on EC2 or private Databases is with Bastion.

Bastion is the central point to access its private instances.

![SSH Bastion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sp1bg2dclfwj11y38cbj.png)

*Classical architecture of a bastion via SSH Tunnel.*

What about **resilience** ? 
**filter** inbound ip's via Security Group ? 
SSH key **rotation** ?

it will be a lot of extra work...

So how to access to your private instance securely ?

With browser, directly, you can use [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-sessions-start.html) or also in some cases with [EC2 Serial Console]  (https://aws.amazon.com/fr/blogs/aws/troubleshoot-boot-and-networking-issues-with-new-ec2-serial-console/)

Ok, but how to access a database (Redshift, Aurora, DocumentDB, RDS,...) ? or still connect in SSH without using session manager directly in the EC2 of destination ?

### SSM-Bastion
I am very happy to share with you SSM-Bastion, how it works ?

![SSM-Bastion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ulu5mr5cibjmqe5nhht.png)
*Architecture of SSM-Bastion*

Let's see it more closely, first the instance will **not need to be exposed in public subnet**.
Resilience and cost savings with **Spot instances** in an **Auto Scaling Group**.

1/ Via a [script](https://github.com/Menahem1/SSM-Bastion/tree/main/script) the user launch a port forwarding command, authenticated by its AWS Access Key and Secret Key.
EC2 instance need to communicate with some AWS endpoint's, so if you're in an **isolated VPC without NAT Gateway** you will need the following endpoints :

![SSM-Bastion Endpoints](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wocrbjc8ppodzoxlgm3l.png)

Note for KMS you will need to activate it via the [console](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-preferences-enable-encryption.html) or [cli](https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-preferences-cli.html)

2/ After the user launch a port forwarding command (via Run Command) the EC2 SSM-Bastion creates a tunnel to the destination

3/ After the tunnel (via socket) is created, a session is opened on the local laptop to be able to connect to it from localhost.

### Launch a connection - Example
For launching a port forwarding session with the script you have 2 alternatives.

1/ Interactive session 
`./ssm-bastion-port-forwarding.sh`

![Interactive session](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xs1q5lqdfliogwj6jt4l.png)
> *A connection in a private EC2 with IP 10.0.0.1 and listening port 3006, the port open in the laptop will be 9090*


2/ Line arguments
You can launch directly the session in line arguments, with the following parameters

 `   ./ssm-bastion-port-forwarding.sh hostname_destination port_destination port_source `

![Line arguments](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nbel1jgr9knnmesftqsp.png)
> *Example of a connection with a mysterious endpoint and port of destination 4567, port open in the laptop 8768*


After that you can use your connection on *localhost:port_open* and... enjoy 🙂

You can find the Terraform and Bash script in [github](https://github.com/Menahem1/SSM-Bastion)