aws ssm proxycommand for interactive session

Viewed 487

Goal: Log into ec2 instance via SSM to an ssh terminal using a proxycommand

I can log into my instance fine using 'aws ssm start-session --target intance-id'. However to make life simpler, I want to be able to have a proxycommand in my .ssh/config that will allow me to ssh into the instance with a shorter command such as 'ssh i-awsguid' and the proxycommand will fill in the rest.

However, when I do this, I get a session that hangs without ever seeing the prompt of the remote machine, and on control-c, I see the json output of the aws action.

$ ssh i-076efab920fd7a5e2 -v
OpenSSH_8.1p1, LibreSSL 2.7.3
debug1: Reading configuration data /Users/user/.ssh/config
debug1: /Users/user/.ssh/config line 49: Applying options for *
debug1: /Users/user/.ssh/config line 70: Applying options for *
debug1: /Users/user/.ssh/config line 86: Applying options for i-*
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 47: Applying options for *
debug1: Executing proxy command: exec aws ssm start-session --target i-076efab920fd7a5e2
debug1: identity file /Users/user/.ssh/id_rsa type 0
debug1: identity file /Users/user/.ssh/id_rsa-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.1
debug1: kex_exchange_identification: banner line 0: 
debug1: kex_exchange_identification: banner line 1: Starting session with SessionId: user@email.com-0a7ca620b0b70ba7c
debug1: kex_exchange_identification: banner line 2: This session is encrypted using AWS KMS.
debug1: kex_exchange_identification: banner line 3: echo Connected to $(hostname)
debug1: kex_exchange_identification: banner line 4: $ Connected to ip-10-147-34-181
^C

Command '['session-manager-plugin', '{"SessionId": "user@email.com-0a7ca620b0b70ba7c", "TokenValue": "scrubbed", "StreamUrl": "wss://ssmmessages.us-east-1.amazonaws.com/v1/data-channel/user@email.com-0a7ca620b0b70ba7c?role=publish_subscribe", "ResponseMetadata": {"RequestId": "cd75db36-3cc0-415f-b849-b5995e1701ec", "HTTPStatusCode": 200, "HTTPHeaders": {"server": "Server", "date": "Wed, 07 Apr 2021 17:49:22 GMT", "content-type": "application/x-amz-json-1.1", "content-length": "678", "connection": "keep-alive", "x-amzn-requestid": "cd75db36-3cc0-415f-b849-b5995e1701ec"}, "RetryAttempts": 0}}', 'us-east-1', 'StartSession', '', '{"Target": "i-076efab920fd7a5e2"}', 'https://ssm.us-east-1.amazonaws.com']' died with <Signals.SIGPIPE: 13>.

example calling same instance directly from shell.

$ aws ssm start-session --target i-076efab920fd7a5e2

Starting session with SessionId: user@email.com-0bcfc5bf3d8325cb1
This session is encrypted using AWS KMS.
echo Connected to $(hostname)
$ Connected to ip-10-147-34-181
$ whoami
ssm-user
$ exit


Exiting session with sessionId: user@email.com-0bcfc5bf3d8325cb1.

relevant part of .ssh/config

# SSH over Session Manager
host i-*
    ProxyCommand aws ssm start-session --target %h
1 Answers

I think the problem is that your proxy command is the aws cli. The JSON output does say that the command succeeded. But you haven't asked for a shell, you just asked for executing an aws command.

According to the AWS docs on SSH sessions through SSM, you pass the aws command as an argument to a shell:

  • sh for MacOS and Linux (I presume sh exists in MacOS as in Linux)
  • Windows PowerShell for Windows (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe), although I guess that it would work with the command line

Also, I only got it working by

  • having a SSH private key on my PC
  • having my SSH public key in my VM's ~/.ssh/config/authorized_keys
  • specifying my username in my VM in the host config
  • specifying an AWS document in the proxy command, AWS-StartSSHSession
  • passing the port number variable %p

Having to use my username and a SSH key may be because my IAM account does not have the right permissions, so it's not a perfect solution. (But I don't control those permissions in my workplace.)

Judging by the debug info, you're on a Mac, right? So your .ssh/config host should be:

# SSH over Session Manager
# you may need the region as a parameter to aws, e.g. --region us-east-1
host i-*
    User YourUsername
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

In my case, in PowerShell, since I have to use many AWS accounts, I specify the right AWS profile in the proxy command:

# SSH over Session Manager on a specific hostname
# using PowerShell and a specific AWS profile
Host myVM
  HostName i-xxxxxxxxxxx
  User myusername
  ProxyCommand C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe "aws ssm start-session --profile myAwsProfile --target %h --document-name AWS-StartSSHSession --parameters portNumber=%p"
Related