New AWS SSM feature to tunnel SSH with port forwarding support
AWS SSM already had a “session manager” feature that allowed users to get command prompts through a web browser. The big advantage this had over providing an SSH bastion host is that SSM is covered by the same governance context as other AWS services: authentication and authorization via IAM, with audit via CloudTrail.
SSM session manager only solves for a command prompt, though. It doesn’t give you a way to establish connectivity to resources in private subnets for development purposes – for example, I’m running Eclipse locally and need to test code that depends on Redshift. Typically, that use case relies on a VPN, Direct Connect, or SSH port forwarding through a bastion host.
But, a new feature for AWS SSM allows you to tunnel a legit SSH connection through AWS SSM, and it supports port forwarding.
The documentation is pretty good. I also found an AWS blog post on the topic and another blog post with decent instructions.
The general idea is it works through SSH’s ProxyCommand
. The ProxyCommand
option is used to invoke aws ssm start-session
to establish a connection between your SSH client and sshd
on the target EC2, rather than connecting directly over
port 22. The AWS CLI is making API calls over HTTPS, so you only need port 443 open locally; and those calls are secured
by IAM authentication and policies. So this works even if your network blocks outbound traffic besides ports 80/443.
Most of the instructions work by setting up .ssh/config
to recognize any hostname of the form i-*
(EC2 instance ID)
to be proxied through SSM. So once you set it up, your SSH command line would look like ssh user@i-12345...
Because we’re using aws ssm
commands to tunnel a real SSH connection, though, other SSH options like port forwarding
work as usual. You can add -L 5439:redshift-cluster.xxx..redshift.amazonaws.com:5439
and then use tools like SQL Workbench
locally to connect to Redshift. So if you were setting up a VPN or a Direct Connect just for use cases like this, you might
not need to do that anymore.
The downside is that you need to have a username/password on the target SSH server, or your SSH public key needs to be in
.ssh/authorized_keys
. One way to get started is, if you can already get a shell through Session Manager in the AWS console, you
can log in that way and add your public key to .ssh/authorized_keys
under ssm-user
. Then you can ssh ssm-user@i-12345...
Otherwise you’d need some mechanism to set up individual accounts per user.