Did you know that establishing an SSH connection with an EC2 instance is possible without configuring a key pair and allowing inbound traffic on port 22? How is that possible? The secret is a combination of EC2 Instance Connect and Systems Manager (SSM). When following this article, connecting with an EC2 instance is as simple as typing ssh i-059499e6abc8fbe6b
into your terminal.
First of all, the following video demonstrates how to establish an SSH connection with an EC2 instance by using EC2 Instance Connect and Systems Manager.
The following diagram explains the approach in more detail.
- The user sends her public key to EC2 Instance Connect using the AWS CLI.
- EC2 Instance connect pushes the key to the EC2 instance. The key remains for 60 seconds.
- An SSM agent running on the EC2 instance establishes a bidirectional channel with the SSM backend.
- The user establishes an SSH connection through a Websocket between Terminal and SSM.
- Authentication and authorization for the user and the SSM agent is IAM's job.
How do you make this approach happen on your local machine and EC2 instances?
- Make sure the SSM agent is running on your EC2 instances - which is already the case for Amazon Linux and Amazon Linux 2.
- Double check that the SSM agent running on your machines can connect with the SSM API through an internet gateway, NAT gateway, or VPC endpoint.
- Attach an IAM role - granting the SSM agent access to the SSM API - to each EC2 instance to
- Install the AWS CLI and the session manager plugin on your local machine.
- Configure your SSH client to use EC2 Instance Connect and Systems Manager to establish a tunnel for SSH connections.
Are you confused about the different options to connect by using EC2 Instance Connect and Systems Manager? Check out Petri's comparision: EC2 Instance Connect vs. SSM Session Manager
IAM role required by SSM agent
As mentioned before, the SSM agent is running on most EC2 instances already. That's because the agent is bundled into Amazon Linux, Amazon Linux 2, SUSE Linux Enterprise Server (12 and 15), and Ubuntu Server (16.04, 18.04, and 20.04) by default.
Learn how to Manually install SSM Agent on EC2 instances for Linux from the AWS documentation.
However, the SSM agent requires an IAM role attached to the EC2 instance granting access to the SSM API. That's not a default, so you probably need to create a new IAM role or add a policy to existing roles.
You can either use the predefined policy AmazonSSMManagedInstanceCore
(arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
) managed by AWS. Or create your own managed or in-line policy with the following contents.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:*",
"ec2messages:*",
"ssm:UpdateInstanceInformation"
],
"Resource": "*"
}
]
}
Install the AWS CLI and session manager plugin
You will use the AWS Command Line Interface (CLI) to push your public key via EC2 Instance Connect and establish a tunnel for your SSH connection with the EC2 instance.
Therefore, make sure to install the AWS CLI on your local machine. Besides that, you need to install the session manager plugin.
- Installing or updating the latest version of the AWS CLI
- Install the Session Manager plugin for the AWS CLI
I prefer brew
to install the AWS CLI and the session manager plugin on macOS.
brew install awscli session-manager-plugin
Configuring your SSH client
Next, you need to configure your SSH client. To do so, edit the ~/.ssh/config
file on your local machine. Please add the following snippet configuring connections for all hosts, starting with i-
at the end of the file. Do not forget to replace $PRIVATE_KEY
and $PUBLIC_KEY
with the path to your private and public key.
# SSH over Session Manager
host i-*
IdentityFile $PRIVATE_KEY
User ec2-user
ProxyCommand sh -c "aws ec2-instance-connect send-ssh-public-key --instance-id %h --instance-os-user %r --ssh-public-key 'file://$PUBLIC_KEY' --availability-zone '$(aws ec2 describe-instances --instance-ids %h --query 'Reservations[0].Instances[0].Placement.AvailabilityZone' --output text)' && aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
For me, the snippet looks as follows.
# SSH over Session Manager
host i-*
IdentityFile ~/.ssh/id_ed25519
User ec2-user
ProxyCommand sh -c "aws ec2-instance-connect send-ssh-public-key --instance-id %h --instance-os-user %r --ssh-public-key 'file://~/.ssh/id_ed25519.pub' --availability-zone '$(aws ec2 describe-instances --instance-ids %h --query 'Reservations[0].Instances[0].Placement.AvailabilityZone' --output text)' && aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
The ProxyCommand
contains a one-liner that I'd like to explain in more detail.
First, we need to find out the availability zone the instance is running in. The command aws ec2 describe-instances
returns the necessary information. Please note that %h
will be replaced with the host, for example, i-059499e6abc8fbe6b
.
aws ec2 describe-instances --instance-ids %h --query 'Reservations[0].Instances[0].Placement.AvailabilityZone' --output text
Next, you need to push your public key to the EC2 instance. That's why you need to execute the aws ssm start-session
command.
aws ec2-instance-connect send-ssh-public-key --instance-id %h --instance-os-user %r --ssh-public-key 'file://~/.ssh/id_ed25519.pub' --availability-zone '$(...)'
Last but not least, you need to establish the SSH session through a WebSocket connection. That's the job of the aws ssm start-session
command.
aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'
Connect to your EC2 instance using SSH
You are ready to connect with your EC2 instance using SSH. All you need to do is type ssh
followed by an EC2 instance ID into your terminal.
ssh i-059499e6abc8fbe6b
By the way, you can even copy files with scp
.
ssh example.txt i-059499e6abc8fbe6b:/tmp/
That's it. I hope you enjoy this approach to connect to your EC2 instances using SSH as much as I do.
Did you run into any issues while following my instructions? Do you love the approach to connect with your EC2 instances? Please let me know!
Top comments (0)