The AWS Well-Architected Framework consists of five pillars that represent the key areas of focus for building and operating reliable, secure, efficient, and cost-effective systems in the cloud - Operational Excellence, Security, Reliability, Performance Efficiency, Cost Optimization.
By using AWS SSM for secure EC2 access we are matching Security pillar in several ways:
Centralized access control through AWS Identity and Access Management (IAM) policies
Encrypted communications - all data is encrypted in transit between the SSM client and the SSM service, and between the SSM service and the EC2 instance
No inbound ports - With AWS SSM, you can access your EC2 instances without opening inbound ports in your security groups
Auditing and logging - AWS SSM provides audit trails and logs that help you monitor and track user activity, access to resources, and changes to your systems
How to adopt SSH with AWS SSM in your project - try on test EC2 instance first, it’s pretty easy
create EC2 instance in AWS Console, make sure EC2 instances must have access to ssm.{region}.amazonaws.com on port 443 - either SSM Endpoint should be provisioned inside VPC or allow outgoing access to ssm.{region}.amazonaws.com:443
create
ssm-agent
IAM policy (or you can skip and use AWS-managedAmazonSSMManagedInstanceCore
)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:DescribeAssociation",
"ssm:GetDeployablePatchSnapshotForInstance",
"ssm:GetDocument",
"ssm:DescribeDocument",
"ssm:GetManifest",
"ssm:GetParameter",
"ssm:GetParameters",
"ssm:ListAssociations",
"ssm:ListInstanceAssociations",
"ssm:PutInventory",
"ssm:PutComplianceItems",
"ssm:PutConfigurePackageResult",
"ssm:UpdateAssociationStatus",
"ssm:UpdateInstanceAssociationStatus",
"ssm:UpdateInstanceInformation"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2messages:AcknowledgeMessage",
"ec2messages:DeleteMessage",
"ec2messages:FailMessage",
"ec2messages:GetEndpoint",
"ec2messages:GetMessages",
"ec2messages:SendReply"
],
"Resource": "*"
}
]
}
- attach newly created
ssm-agent
or AWS-managedAmazonSSMManagedInstanceCore
IAM policy to EC2 instance
Install requirements
- python3 -
brew install python3
- awscli
- session-manager-plugin
- clone
ssh-over-ssm
repo -git clone git@github.com:elpy1/ssh-over-ssm.git
- copy
ssh-ssm.sh
to your PATH -cp ssh-ssm.sh /usr/local/bin/
- add ssh config block below to your
~/.ssh/config
Match Host i-*
ProxyCommand ssh-ssm.sh %h %r
IdentityFile ~/.ssh/ssm-ssh-tmp
StrictHostKeyChecking no
PasswordAuthentication no
ChallengeResponseAuthentication no
Login to AWS using CLI / generate AWS CLI credentials - yawsso
/ leapp
/ use your own CLI
Check that AWS CLI credentials are valid - aws sts get-caller-identity
should return your UserId/Account/Arn
Check that EC2 instance is registered in AWS SSM
aws ssm describe-instance-information
should return EC2 instance list with SSM agent installed / ready to connect.
Try to connect to EC2 with SSH via AWS SSM
ssh -v ubuntu@i-0ced59ae123456789
ubuntu@ip-172-35-1-75:~$
Done!
Now you can remove 22 port from incoming port list in security groups attached to EC2 instance.
How it works: on AWS side ssm-agent
daemon on EC2 is establishing connection with AWS ssm endpoint ssm.{region}.amazonaws.com:443
(private inside VPC or public in the Internet) and registering itself in SSM instance list.
When user is ssh-ing to instance - under the hood command like this is executed (try set -x
in ProxyCommand script)
aws ssm start-session --document-name AWS-StartSSHSession --target i-0ced59ae123456789
Then incoming TCP connection to SSM endpoint is proxying to EC2 instance using AWS magic.
GitHub repos / gists used
https://gist.github.com/elpy1/9839ce2a06850fb25b35144bb2f70564 https://github.com/elpy1/ssh-over-ssm