diff --git a/README.md b/README.md index 656d118..4d01554 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,10 @@ Open an SSH connection to your AWS SSM connected instances without the need to o IdentityFile ~/.ssh/id_ed25519 ProxyCommand ~/.ssh/aws-ssm-ssh-proxy-command.sh %h %r %p ~/.ssh/id_ed25519.pub StrictHostKeyChecking no + host + IdentityFile ~/.ssh/id_ed25519 + ProxyCommand ~/.ssh/aws-ssm-ssh-proxy-command.sh %h %r %p ~/.ssh/id_ed25519.pub + StrictHostKeyChecking no ``` - **Windows** ```ssh-config @@ -37,6 +41,10 @@ Open an SSH connection to your AWS SSM connected instances without the need to o IdentityFile ~/.ssh/id_ed25519 ProxyCommand powershell.exe ~/.ssh/aws-ssm-ssh-proxy-command.ps1 %h %r %p ~/.ssh/id_ed25519.pub StrictHostKeyChecking no + host + IdentityFile ~/.ssh/id_ed25519 + ProxyCommand powershell.exe ~/.ssh/aws-ssm-ssh-proxy-command.ps1 %h %r %p ~/.ssh/id_ed25519.pub + StrictHostKeyChecking no ``` - Adjust `IdentityFile` and corresponding publickey (last argument of `ProxyCommand`) if needed. @@ -62,8 +70,11 @@ Open an SSH connection to your AWS SSM connected instances without the need to o - **Linux & MacOS** `export AWS_PROFILE=...` or `AWS_PROFILE=... ssh...` - **Windows** `$env:AWS_PROFILE = ...` or `$env:AWS_PROFILE = ...; ssh.exe...` - Open SSH Connection to AWS SSM connected instance - - **Linux & MacOS** `ssh @` e.g. `ssh ec2-user@i-1234567890` - - **Windows** `ssh.exe @` e.g. `ssh.exe ec2-user@i-1234567890` + - **Linux & MacOS with InstanceId** `ssh @` e.g. `ssh ec2-user@i-1234567890` + - **Linux & MacOS with InstanceName** `ssh @` e.g. `ssh ec2-user@aws-ec2-custom-name-instance` + - **Windows with InstanceId** `ssh.exe @` e.g. `ssh.exe ec2-user@i-1234567890` + - ⚠️ Unfortunately on Windows is not possible to show output while running ProxyCommand, script output is interpreted as SSH banner which is available with SSH verbose options. + - **Windows with InstanceName** `ssh.exe @` e.g. `ssh.exe ec2-user@aws-ec2-custom-name-instance` - ⚠️ Unfortunately on Windows is not possible to show output while running ProxyCommand, script output is interpreted as SSH banner which is available with SSH verbose options. - [EC2 Intances Only] If default region does not match instance region you need to provide it as part of hostname - `@--` diff --git a/aws-ssm-ssh-proxy-command.ps1 b/aws-ssm-ssh-proxy-command.ps1 index f1d3abb..ec78ad3 100755 --- a/aws-ssm-ssh-proxy-command.ps1 +++ b/aws-ssm-ssh-proxy-command.ps1 @@ -8,11 +8,41 @@ $ErrorActionPreference = "Stop" # ################################################################################ -$instance_id = $args[0] +# +# Set ExecutionPolicy in Powershell: +# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser +# Unblock-File -Path $HOME\.ssh\aws-ssm-ssh-proxy-command.ps1 +# + +function Get-InstanceId { + param ( + [string]$instanceName + ) + + $instanceId = aws ec2 describe-instances --filters "Name=tag:Name,Values=$instanceName" --query "Reservations[].Instances[?State.Name == 'running'].InstanceId" --output text + + return $instanceId +} + +$instance_name = $args[0] $ssh_user = $args[1] $ssh_port = $args[2] $ssh_public_key_path = $args[3] +$ec2InstanceIdPattern = '^m?i-[0-9a-f]{8,17}$' +if ($instance_name -match $ec2InstanceIdPattern) { + $instance_id = $instance_name +} else { + $instance_id = Get-InstanceId -instanceName $instance_name + + if (-not $instance_id) { + Write-Output 'Found no running instances with name "' + $instance_name + '".' + Exit + } else { + Write-Output 'Instance ID for "' + $instance_name + '": "' + $instance_id + '"' + } +} + $REGION_SEPARATOR = "--" $splitted_instance = $instance_id -split $REGION_SEPARATOR if ($splitted_instance.Length -gt 1) { @@ -21,27 +51,27 @@ if ($splitted_instance.Length -gt 1) { } Write-Output "Add public key $ssh_public_key_path for $ssh_user at instance $instance_id for 10 seconds" -$ssh_public_key = (Get-Content $ssh_public_key_path | Select-Object -first 1) -aws ssm send-command ` - --instance-ids "$instance_id" ` - --document-name 'AWS-RunShellScript' ` - --comment "Add an SSH public key to authorized_keys for 10 seconds" ` - --parameters commands=@" - \" - set -eu - - mkdir -p ~$ssh_user/.ssh && cd ~$ssh_user/.ssh - - authorized_key='$ssh_public_key ssm-session' - - echo \\\"`$authorized_key\\\" >> authorized_keys - - sleep 10 - - (grep -v -F \\\"`$authorized_key\\\" authorized_keys || true) > authorized_keys~ - mv authorized_keys~ authorized_keys - \" - "@ +$ssh_public_key = (Get-Content $ssh_public_key_path | Select-Object -first 1) + ' ssm-session' + +$command = 'aws ssm send-command ' + + '--instance-ids "' + $instance_id + '" ' + + '--document-name "AWS-RunShellScript" ' + + '--comment "Add an SSH public key to authorized_keys for 10 seconds" ' + + '--parameters commands=" + set -eu + + mkdir -p ~$ssh_user/.ssh && cd ~$ssh_user/.ssh + + echo $ssh_public_key >> authorized_keys + + sleep 10 + + (grep -v -F ssm-session authorized_keys || true) > authorized_keys~ + mv authorized_keys~ authorized_keys + "' + +Invoke-Expression $command + Write-Output "Start ssm session to instance $instance_id" aws ssm start-session ` diff --git a/aws-ssm-ssh-proxy-command.sh b/aws-ssm-ssh-proxy-command.sh index eadb183..cc506c8 100755 --- a/aws-ssm-ssh-proxy-command.sh +++ b/aws-ssm-ssh-proxy-command.sh @@ -7,11 +7,32 @@ set -eu # ################################################################################ -instance_id="$1" +getInstanceId() { + local instance_name="$1" + local instance_id=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=${instance_name}" --query "Reservations[].Instances[?State.Name == 'running'].InstanceId" --output text) + + echo "${instance_id}" +} + +instance_name="$1" ssh_user="$2" ssh_port="$3" ssh_public_key_path="$4" +ec2InstanceIdPattern='^m?i-[0-9a-f]{8,17}$' +if [[ $instance_name =~ $ec2InstanceIdPattern ]]; then + instance_id=$instance_name +else + instance_id=$( getInstanceId "$instance_name" ) + + if [[ -z $instance_id ]]; then + echo "Found no running instances with name \"${instance_name}\"." + exit 1 + else + echo "Instance ID for \"${instance_name}\": \"${instance_id}\"" + fi +fi + REGION_SEPARATOR='--' if echo "$instance_id" | grep -q -e "${REGION_SEPARATOR}" then