aws / aws-toolkit-vscode

Amazon Q, CodeCatalyst, Local Lambda debug, SAM/CFN syntax, ECS Terminal, AWS resources
https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.amazon-q-vscode
Apache License 2.0
1.42k stars 359 forks source link

VSCode Remote to EC2 instance (via SSH over SSM) #941

Open jovanshernandez opened 4 years ago

jovanshernandez commented 4 years ago

Desktop (please complete the following information):

Anyway to connect to EC2 through VSCode without SSH Key?

Trying to connect to EC2 through VSCode without SSH Keys. I'm able to connect to EC2s using AWS Credentials, AWS Profiles, and AWS SSM, but is there a way to pass that connection through VSCode/?

awschristou commented 4 years ago

Hi @jovanshernandez , when you mention "Connect to EC2", are you trying to use VS Code's Remote Development feature, that allows users to open a remote folder in the VS Code file explorer? Or did you have something else in mind?

jovanshernandez commented 4 years ago

@awschristou Correct, I am trying to open say the /home/ubuntu/ folder on an EC2 in my VSCode desktop file explorer.

justinmk3 commented 3 years ago

Duplicate of https://github.com/aws/aws-toolkit-vscode/issues/918 ? If not, please explain

dmattia commented 3 years ago

I do not believe this to be a duplicate issue.

This issue is talking about a connection like aws ssm start-session --target "i-0012341ef010ffc4f", which uses the AWS CLI to open an SSH-like connection to a remote EC2. This is an AWS specific form of authentication, and is felt to be more secure by many because:

  1. You can use SSM to access instances in private subnets, whereas SSHing requires some instance in a public subnet
  2. SSM uses AWS creds, which has strong MFA support, whereas SSH is just SSH
  3. SSM access control is controlled by AWS IAM Policies, whereas SSH requires maintaining public keys
  4. All SSM access has built in monitoring and auditing by AWS Cloudtrail and the SSM service itself

So this issue is really just asking for almost a direct integration, or otherwise mirroring of functionality, of Microsoft's Remote Dev tooling but for SSM instead of SSH.

This is not related to ECS or EC2 metadata endpoints that issue #918 talks about

ragebiswas commented 3 years ago

+1 for this, I see this could be useful for many.

asherawelan commented 3 years ago

This would be the last piece in the puzzle for us...

twitu commented 3 years ago

This is a powerful feature and an important component in making AWS development experience secure but also seamless. + 💯 from my side.

thomas-anderson-bsl commented 3 years ago

As a workaround, you could update the ssh configuration file to run a proxy command, which routes ssh traffic via SSM. See https://pub.towardsai.net/how-to-do-remote-development-with-vs-code-using-aws-ssm-415881d249f3

justinmk3 commented 3 years ago

Related:

szukalski commented 3 years ago

This will work but you have to manually specify the AWS profile and region.

Outside of VS Code, your ssh config for SSM integration would look something like this:

host i-* mi-*
  User ec2-user
  ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

Then you would ssh to your instance directly. Ie. ssh i-xzyyxzzxyyxzzxy. Things work because you have an AWS profile and region loaded.

To get things working with VS Code, your ssh config would look like this:

host i-*.*.*
  User ec2-user
  ProxyCommand bash -c "aws ssm start-session --target $(echo %h|cut -d'.' -f1) --profile $(echo %h|/usr/bin/cut -d'.' -f2) --region $(echo %h|/usr/bin/cut -d'.' -f3) --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

You then connect to your instance with i-xzyyxzzxyyxzzxy.profile_name.region.

chm123 commented 2 years ago

I can confirm solution from @szukalski works, although I need to do some modifications due to our special AWS config. Our SSH port for EC2 instance is not open, but I can ssh through aws ssm. VS Code remote ssh works perfectly this way, and I can also forward ports in ssh config file.

jtele2 commented 2 years ago

@chm123 Can you elaborate? I cannot get this to work like so.

chm123 commented 2 years ago

@chm123 Can you elaborate? I cannot get this to work like so.

@jtele2 Basically you can follow https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html

And try SSH from terminal (not from VS Code). If this works for you, you should be able to connect via VS Code.

jtele2 commented 2 years ago

@chm123 Thank you for your response. I can get in via Windows Subsystem for Linux (WSL) but not from PowerShell with the proxy command. I have to use WSL because I cannot install SessionManagerPlugin directly to PowerShell (non-Admin rights), but can install to WSL.

Is there a way to make ProxyCommand use WSL.exe to setup the Remote-SSH session?

chm123 commented 2 years ago

@jtele2

I'm using MacBook, so I'm not familiar with WSL. You can try this https://stackoverflow.com/questions/60150466/can-i-ssh-from-wsl-in-visual-studio-code

jtele2 commented 2 years ago

@szukalski Any ideas on how to get this to work with Windows (AWS CLI on PowerShell)?

PeterBaker0 commented 2 years ago

+1 for this feature - would be very useful - going to try and setup workaround as above for now.

mrgum commented 2 years ago

one thing to note, vscode needs your credentials, so if you use temporary credentials, say via SSO to an IdP you need to close vscode and open it again from a terminal that has your session token, a PITA

if anyone knows a work-around, that doesn't involve session up a credentials file or iam user, that would be great

szukalski commented 2 years ago

@mrgum Source your credentials from an external process: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html

sholtomaud commented 2 years ago

Is there any update on the requirement to connect to EC2 through VSCode without SSH Key/.pem file?

mrgum commented 2 years ago

I managed to do this following https://aws.amazon.com/blogs/developer/introducing-aws-sso-support-in-the-aws-toolkit-for-vs-code/ I had to remove the other entries I had in credentials file as they were confusing it

in vscode aws: choose profile that opens up sso in browser and once you accept you can connect to host using its i-1234 id (you need the .ssh/config as above)

it still needs ssh key authorized though :(

sholtomaud commented 2 years ago

What if we go the other way around and ask, why is it that an AWS Systems Manager session doesn't need the .pem file?

mrgum commented 2 years ago

I think we need a key because we are using Remote-SSH to connect, and an alternative Remote-SSM extension would need to be created?

sholtomaud commented 2 years ago

What if we go the other way around and ask, why is it that an AWS Systems Manager session doesn't need the .pem file?

I mean VSCode is just a browser right? And ssm session window is just in a browser right?

mrgum commented 1 year ago

systems manager does not need the keys. the remote-ssh (which is tunnelled over ssm as a transport) does.

sholtomaud commented 1 year ago

My point is that I can get a ssm "terminal" session into an EC2 file system from a browser, right?

So why can't the same feature of the ssm "terminal" be implemented in VSCode? Maybe you don't in fact need to use the remote-ssh?

sholtomaud commented 1 year ago

For example what is this awsui-app-layout? Why can't that be implemented as a part of a VSCode extension?

image

thomas-anderson-bsl commented 1 year ago

For example what is this awsui-app-layout? Why can't that be implemented as a part of a VSCode extension?

image

As mentioned above, this particular issue is asking about Remote Development using SSH, but using SSH over SSM.

What you're describing isn't resolving the issue, you're talking about embedding an SSM terminal into VSCode.

antunesdq commented 1 year ago

For example what is this awsui-app-layout? Why can't that be implemented as a part of a VSCode extension? image

As mentioned above, this particular issue is asking about Remote Development using SSH, but using SSH over SSM.

What you're describing isn't resolving the issue, you're talking about embedding an SSM terminal into VSCode.

"via SSM, without SSH"

image

justinmk3 commented 1 year ago

I've renamed the issue title to avoid confusion.

sholtomaud commented 1 year ago

It's unclear to me how my previous comment was off topic. Note that the first comment by @jovanshernandez describes, "Anyway to connect to EC2 through VSCode without SSH Key?"

The initial title was "without SSH" and the topic change totally reverses the meaning of this issue and I think misses the point.

"without SSH Key" is what I understood this issue to be about.

"Embedding an SSM terminal into VSCode" (as my comment was described) would meet the requirement of connecting to EC2 through VSCode without SSH Key as described by @jovanshernandez

justinmk3 commented 1 year ago

The thread is getting long so I minimized comments that are outdated.

"without SSH Key" is what I understood this issue to be about.

Ok, that's also my understanding. The common vscode-remote extension uses SSH, and we can connect via SSM-over-SSH (without local SSH keys).

sholtomaud commented 1 year ago

How was my comment outdated? Are you now able to connect to EC2 without keypair?

How do you connect via SSM-over-SSH (without local SSH keys)?

Could you please provide an example?

mrgum commented 1 year ago

@justinmk3 I think the title should be say SSH over SSM rather than the other way about

mrgum commented 1 year ago

Should we open a separate issue asking for remote-SSM, a different implementation based on remote-SSH but solely using SSM with no SSH or public keys involved?

sholtomaud commented 1 year ago

Should we open a separate issue asking for remote-SSM, a different implementation based on remote-SSH but solely using SSM with no SSH or public keys involved?

why not work on this issue which started with the Q.

Anyway to connect to EC2 through VSCode without SSH Key?

justinmk3 commented 1 year ago

Should we open a separate issue asking for remote-SSM, a different implementation based on remote-SSH but solely using SSM with no SSH or public keys involved?

vscode-remote doesn't allow extensions or forks, AFAIK. That's why I would guess the most feasible approach is to use SSH over SSM via https://github.com/aws/session-manager-plugin .

So why can't the same feature of the ssm "terminal" be implemented in VSCode? Maybe you don't in fact need to use the remote-ssh?

vscode-remote allows you to use vscode in a remote context. However to use the ssm web console, we are exploring a general approach: "deep linking": https://github.com/aws/aws-toolkit-vscode/pull/2685

sholtomaud commented 1 year ago

Thanks for the response @justinmk3 - you mentioned previously that "we can connect via SSM-over-SSH (without local SSH keys)" do you have an example of how I can do that? Or is this actually not the case?

justinmk3 commented 1 year ago

The approach in https://github.com/aws/aws-toolkit-vscode/issues/941#issuecomment-873096740 can be used with vscode-remote-ssh.

sholtomaud commented 1 year ago

I'll give it a go

sholtomaud commented 1 year ago

you could get a list of all ec2's and then for each ec2 append something like the following for any given aws profile to .ssh/config, and then implement ssh key rotation for ec2-user on a schedule from VSCode extension:

Host LinuxHost
   ProxyCommand sh -c "aws ec2-instance-connect send-ssh-public-key \
      --instance-id  $(aws ec2 describe-instances --filter "Name=tag:Name,Values= HOSTNAME"  \
      --query "Reservations[].Instances[?State.Name =='running'].InstanceId[]"  \
      --output text --profile profilename) \
      --availability-zone ap-southeast-2a \
      --instance-os-user ec2-user \
      --ssh-public-key file:///Users/someuser/.ssh/somekey.pub --profile profilename > /dev/null; \
      aws ssm start-session --profile profilename \ 
      --target $(aws ec2 describe-instances --filter "Name=tag:Name,Values= HOSTNAME" \
      --query "Reservations[].Instances[?State.Name =='running'].InstanceId[]" 
      --output text --profile profilename) --profile profilename  \
      --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
   User ec2-user
   ForwardAgent yes
   UserKnownHostsFile /dev/null
   StrictHostKeyChecking no
sawaca96 commented 1 year ago

WSL

ssm-ec2-proxy-command.ps1

$AWS_PROFILE="default"
$AWS_REGION=""
$PUBLIC_KEY_PATH="file://C:\Users\<username>\.ssh\<public key>"

$ssh_user = $args[0]
$ssh_port = $args[1]
$ec2_instance_id = $args[2]

aws ec2-instance-connect send-ssh-public-key `
    --instance-id "$ec2_instance_id" `
    --availability-zone "$AWS_REGION" `
    --instance-os-user "$ssh_user" `
    --ssh-public-key "$PUBLIC_KEY_PATH" `
    --profile "$AWS_PROFILE"

aws ssm start-session `
  --target "$ec2_instance_id" `
  --document-name 'AWS-StartSSHSession' `
  --parameters "portNumber=$ssh_port"

vscode remote config

Host ec2
  ProxyCommand C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File C:\Users\<username>\.ssh\ssm-ec2-proxy-command.ps1 %r %p <instance_id>
  User ec2-user
  ForwardAgent yes
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no

Mac

ssm-ec2-proxy-command.sh

#!/bin/bash

AWS_PROFILE=default
AWS_REGION=ap-northeast-2a
PUBLIC_KEY_PATH=file:///Users/<username>/.ssh/<public key>

# Arguments passed from SSH client
USER=$1
PORT=$2
INSTANCE_ID=$3

aws ec2-instance-connect send-ssh-public-key \
    --instance-id ${INSTANCE_ID} \
    --availability-zone ${AWS_REGION} \
    --instance-os-user ${USER} \
    --ssh-public-key ${PUBLIC_KEY_PATH} --profile ${AWS_PROFILE} > /dev/null; 

aws ssm start-session --profile ${AWS_PROFILE} \
    --target ${INSTANCE_ID} --profile ${AWS_PROFILE}  \
    --document-name AWS-StartSSHSession --parameters portNumber=${PORT}

vsocde remote config

Host ec2
    ProxyCommand sh -c "~/.ssh/ssm-ec2-proxy-command.sh %r %p <instance id>"
    User <user-name>
    ForwardAgent yes
    UserKnownHostsFile /dev/null
    StrictHostKeyChecking no
jraj002 commented 1 year ago

@sawaca96 Followed your instructions for mac. However, get this error: Resolver error: Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic)

sawaca96 commented 1 year ago

@sawaca96 Followed your instructions for mac. However, get this error: Resolver error: Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic)

@jraj002 can you check your id_rsa.pub permission? try again after execute chmod 400 id_rsa.pub

Roseidon commented 1 year ago

This will work but you have to manually specify the AWS profile and region.

Outside of VS Code, your ssh config for SSM integration would look something like this:

host i-* mi-*
  User ec2-user
  ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

Then you would ssh to your instance directly. Ie. ssh i-xzyyxzzxyyxzzxy. Things work because you have an AWS profile and region loaded.

To get things working with VS Code, your ssh config would look like this:

host i-*.*.*
  User ec2-user
  ProxyCommand bash -c "aws ssm start-session --target $(echo %h|cut -d'.' -f1) --profile $(echo %h|/usr/bin/cut -d'.' -f2) --region $(echo %h|/usr/bin/cut -d'.' -f3) --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

You then connect to your instance with i-xzyyxzzxyyxzzxy.profile_name.region.

This helped me a lot. With this we were finally able to configure this for us! However we had some troubles with also enabling usages of MFA.

  1. configure your vs-code
    • "remote.SSH.showLoginTerminal": true, (to enable the prompt to enter the MFA on log in at the remote)
    • "remote.SSH.useLocalServer": false, (to disable sharing the connection)
  2. configure your profiles
    • the profile needs to have the word profile as prefix (some just used [required-role] which worked for awsume but not here)
    • the profile-name needs to be lower-case (somehow the proxy-command makes everything lower-case in the execution)
    • the mfa_serial needs o be defined on the profile (it does not work when it is defined in the default profile, that seems to be a known issue)
      [profile required-role]
      role_arn = arn:aws:iam::012301230123:role/Role_Name
      mfa_serial = arn:aws:iam::012301230123:mfa/your.identity@company.com
      source_profile = default
  3. Then you can add configs to your ssh-config, e.g.
    Host ssm-*
      ProxyCommand bash -c "…" (see quoted comment)
    Host ssm-customer-foo
      HostName mi-12345678901234567.required-role.eu-central-1
  4. And connect via vs-code to the remote
    • When the remote opens, you will see the prompt for MFA. Enter it quickly, there seems to be some timeout
    • When a timeout occurs, press retry
    • It is a bit hacky so far, but after some attempts on typing the MFA fast enough and retrying it worked. So if you know a stable way, let me know 😁
bordenit commented 1 year ago

The problem I am having is that it almost connects, but keeps putting in the fqdn for the user and assumes that fdqn is the user @instance-id. My ssh_config does not have an fqdn for the user on purpose. I don't want to use fqdn for an individual server since I am using identity center with SSMSessionRunAs passed in through aws sso. aws ssm-start-session works fine outside of vscode. Wish AWS would make a VSCode ssm module where the experience is similar and the SAML attribute for SSMSessionRunAs just passes in as it does outside of VSCode.

mrgum commented 1 year ago

I've found another option to connect to things without SSH or SSM and thought it might be useful to someone here too. https://code.visualstudio.com/docs/remote/tunnels you download and install a cli version of code on the remote machine and authorize it to github then all the traffic goes via them (so no good on isolated networks but fine elsewhere)

serverhorror commented 1 year ago

why not work on this issue which started with the Q.

Anyway to connect to EC2 through VSCode without SSH Key?

If the subject changed from what you're referencing, that changes the whole meaning of the issue, no?

SSH via SSM already works fine.

SSM without any additional things does not.

Can we get "just SSM"?

justinmk3 commented 1 year ago

Can we get "just SSM"?

To open a terminal? Or some other tasks (please specify)?

SSH via SSM already works fine.

https://github.com/aws/aws-toolkit-vscode/issues/941#issuecomment-692745060 reflects my understanding of this issue. I.e. Toolkit should automatically enable:

serverhorror commented 1 year ago

To open a terminal? Or some other tasks (please specify)?

To connect via VS Code (and ideally I can talk JetBrains into supporting something similar)

  • connect with vscode remote-ssh (over SSM), without any configuration (just select an EC2 instance).

Not quite, I do not want to have SSH on my system as a requirement. Maybe call that "vscode remote-aws-ssm"?

Excellent hints! I will take a look what these do. Thank you.

Just to clarify:

I want to be able to use VS Code remote to connect to an EC2 instance. Currently this requires:

fine so far!

I would like this to work with "just work" without having any ssh binary, ssh key or ssh configuration:

2023-03-13_23-55-50

(just to be clear, this is the current method that requires me to have SSH and an SSH key)