You may argue that interactive login to EC2 instances should never be needed. Everything is dynamic, automated, self healing, centrally logged, and so on and there is no place for human interaction, right? But lets be honest – the world isn’t perfect and we all sometimes need to jump into bash to do stuff for one reason or another.
Traditionally our EC2 instances would have a SSH KeyPair assigned and a Security Group with SSH port open. If they were on private IPs only we would also need a jump host or VPN to access them. That works but it’s got its own problems – for example rotation of the SSH keys, keeping the Security Group up to date, etc.
SSM Session Manager
AWS Systems Manager offers a better solution – the SSM Session Manager.
Session Manager enables ad-hoc shell access for any authorised IAM User completely outside of your Network / VPC / Security Group infrastructure. In fact your instance doesn’t even need to have sshd
running! All it needs is a running amazon-ssm-agent
, which comes preinstalled in all recent AMIs, and a correct EC2 IAM Policy for connecting to the SSM service.
EC2 Instance prerequisities
Any recent Amazon Linux, Amazon Linux 2 as well as the official Ubuntu and RedHat AMIs come with SSM Agent ready to use. If it is not installed on your instance check out Installing and Configuring SSM Agent on Amazon EC2 Linux Instances.
The next requirement is AmazonEC2RoleforSSM managed policy attached to your instance role. In my CloudFormation templates I use this role definition:
InstanceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: ec2.amazonaws.com Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM
Provided the instance can connect from its subnet to ssm.{region}.amazonaws.com
– either directly, through NAT or through a Proxy – you are now all set on the instance side.
Session from AWS Console
One way to open a new shell session is from the AWS Console. Simply go to AWS Systems Manager service dashboard, under Actions open the Session Manager, select your instance and click Start session. It can’t be any easier!
Unfortunately I’ve got two problems with this setup:
- You can’t work on instances in more than one AWS account at the same time. That’s the nature of AWS Console unfortunately.
- I keep closing the browser window!
Whenever I press Ctrl+W to delete the previous word in the shell or invim
my Chrome intercepts it and closes the open tab. Arrrgghhh!!
Shell Session through AWS-CLI
I find it much better to open the shell session through aws cli. There I can keep pressing Ctrl+W as much as I want 🙂
Make sure you’ve got the session-manager-plugin installed. Otherwise you will get a message prompting you to do so.
~ $ aws ssm start-session --target i-0123abcd1234abcd SessionManagerPlugin is not found. Please refer to SessionManager Documentation here: http://docs.aws.amazon.com/console/systems-manager/session-manager-plugin-not-found
With the plugin installed the usage is really simple:
~ $ aws ssm start-session --target i-0123abcd1234abcd Starting session with SessionId: michael.ludvig-006c1ff2b131a2531 sh-4.2$ bash ssm-user@test1 /usr/bin $ id uid=1001(ssm-user) gid=1001(ssm-user) groups=1001(ssm-user) ssm-user@test1 /usr/bin $ sudo su - Last login: Thu May 23 17:14:29 NZST 2019 on pts/0 root@test1 ~ # id uid=0(root) gid=0(root) groups=0(root)
UPDATE: I wrote a script to start SSM Sessions by instance name, IP, etc. Check it out here:
ssm-session
– SSM Sessions the easy way
SSM Agent has automatically created this ssm-user for us and gave it sudo privileges. You can check what has been done in /var/log/amazon/ssm/amazon-ssm-agent.log
:
2019-05-24 22:05:58 INFO [MessageGatewayService] Successfully created ssm-user 2019-05-24 22:05:58 INFO [MessageGatewayService] Successfully created file /etc/sudoers.d/ssm-agent-users 2019-05-24 22:05:58 INFO [MessageGatewayService] Successfully changed mode of /etc/sudoers.d/ssm-agent-users to 288
One little unsettling thing is that this session doesn’t appear in who
, w
or last
outputs…
root@test1 ~ # w 22:20:09 up 3:53, 0 users, load average: 0.00, 0.01, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root@test1 ~ # who root@test1 ~ # last reboot system boot 3.10.0-957.1.3.e Thu May 23 13:26 wtmp begins Thu May 23 13:26:23 2019 root@test1 ~ #
It would be nice to have a record of these logins in the standard places – if you know how to do that let me know in the comments.
Windows instances
Quite surprisingly SSM Sessions also works with Windows EC2 instances. However don’t expect a full graphical interface, you will only get a PowerShell command prompt…
~ $ aws start-session --target i-1234abcd1234abcd Starting session with SessionId: botocore-session-1558574990-abcd1234abcd1234 Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. PS C:\Windows\system32> PS C:\Windows\system32> exit Exiting session with sessionId: botocore-session-1558574990-abcd1234abcd1234.
Behind the scenes
As I mentioned above the Session Manager doesn’t need inbound access to the instances. Instead all the traffic is relayed through the SSM service.
- When the instance boots up it connects to AWS SSM service endpoint and awaits the commands.
- When we run aws ssm start-session also connects to the AWS SSM service endpoint (very likely a different node though).
- AWS-CLI then executes the session-manager-plugin that we installed above which then negotiates a secure WebSocket channel with SSM. Something similar then happens on the instance where a ssm-session-worker process is in charge of its side of the WebSockets stream.
- All the keystrokes and all the screen outputs is passed from the instance through this channel between the instance and us. Note that at no time there is a direct connection between us and the instance. Everything is passed through the AWS SSM service.
I found the SSM Session Manager to be a very good option for the occasional ad-hoc access to our instances. No need to keep track of SSH keys, opening Security Group ports, etc. Give it a try!
Hi Michael,
I found your post really interesting and well done explained.
I need to install a GUI in my AMI Ubuntu in a private subnet connected to SSM agent.
I have already intsalled AWS CLI and Session Manager plugin in my local machine.
I can start the session from my private instance.
Can I install a GUI in some way from AWS CLI or I should have to use other way?
Hi, not sure what kind of GUI you’re after. SSM Session gives you shell access to your instance, from there on it’s Linux as usual. Note that GUI apps are not likely to work over SSM though.
Wonderful article, thank you sir.
Just check the directory you get login initially and then you will understand why there is nothing on ‘last’ or ‘who’. ssm method is different from normal shell/tty one. You cannot use any bash profile with it as well.
Just in case if you need to know how to enable bash profiles: https://aws.amazon.com/blogs/mt/bring-your-own-cli-session-manager-configurable-shell-profiles/
True for the default “ssm-user”. However you can directly login as whoever you want with the -u parameter:
ssm-session {instance} -u ec2-user
Hello Michael,
I have 4 ec2 instance, 2 instance using Dev purpose and 2 for production.
After connecting ssm, it will list all my ec2 instance.
How to give only access dev instance to developer and production ssm access to production iam users.
Can you please explain.