简体   繁体   English

SSH ProxyCommand 使用 aws SSM session 管理器和 bash 脚本与 select 命令

[英]SSH ProxyCommand using aws SSM session manager and bash script with select command

In my company when we SSH to our AWS EC2 instances we are required to use the aws CLI session-manager plugin for auth.在我的公司,当我们 SSH 到我们的 AWS EC2 实例时,我们需要使用 aws CLI session-manager 插件进行身份验证。 Using this SSH config snippet works:使用此 SSH 配置片段有效:

Host my-aws-host
    ProxyCommand bash -c "aws ssm start-session --target 'i-0abc123def456hij' \
        --document-name AWS-StartSSHSession --parameters 'portNumber=22' \
        --region us-west-1 --profile MAIN"

However, when the EC2 instance is relaunched, which happens semi-regularly, the 'target' instance ID changes.但是,当 EC2 实例重新启动时(这种情况半定期发生),“目标”实例 ID 会发生变化。 When this happens, all users need to update their SSH config with the new ID.发生这种情况时,所有用户都需要使用新 ID 更新其 SSH 配置。 We don't have any sort of DNS that resolves these instances to a static hostname unfortunately, and so would need to somehow publish the new instance ID to all interested users.不幸的是,我们没有任何类型的 DNS 可以将这些实例解析为 static 主机名,因此需要以某种方式将新实例 ID 发布给所有感兴趣的用户。

So instead I wrote a bash script ( ssh_proxy_command.sh ) that first queries our AWS account to grab the current instance ID based on a known tag value, and use that for the target - here's a cut-down version:因此,我编写了一个 bash 脚本 ( ssh_proxy_command.sh ),它首先查询我们的 AWS 账户以根据已知标签值获取当前实例 ID,并将其用于目标——这是一个简化版本:

#!/bin/bash

INSTANCE_ID=$(aws ec2 describe-instances --region us-west-1 \
        --filters Name=tag:Name,Values=my-server-nametag* \
        --query "Reservations[*].Instances[*].{Instance:InstanceId}" --output text)

aws ssm start-session --target $INSTANCE_ID --document-name AWS-StartSSHSession --parameters 'portNumber=22' --region us-west-1 --profile MAIN

Now the SSH config looks like现在 SSH 配置看起来像

Host my-aws-host
    ProxyCommand bash -c "/path/to/my/ssh_proxy_command.sh %h"

This has been working fine.这一直很好用。 However, we have just started running multiple instances built from the same base image (AMI), and which use the same tags, etc. so the given describe-instances query now returns multiple instance IDs.但是,我们刚刚开始运行从相同的基础映像 (AMI) 构建的多个实例,它们使用相同的标签等,因此给定的 describe-instances 查询现在返回多个实例 ID。 So I tried wrapping the output returned by the query in a bash select loop, thinking I could offer the user a list of instance IDs and let them choose the one they want.因此,我尝试将查询返回的 output 包装在 bash select循环中,认为我可以为用户提供实例 ID 列表,让他们选择他们想要的。 This works when running the script directly, but not when it's used as the ProxyCommand.这在直接运行脚本时有效,但在用作 ProxyCommand 时无效。 In the latter case when it reaches the select statement it prints out the options as expected, but doesn't wait for the user input - it just continues straight to the end of the script with an empty $INSTANCE_ID variable, which makes the aws ssm command fail.在后一种情况下,当它到达select语句时,它会按预期打印出选项,但不会等待用户输入 - 它只是直接使用空 $INSTANCE_ID 变量继续到脚本末尾,这使得aws ssm命令失败。

I'm guessing this is a side-effect of the way SSH runs its ProxyCommands — from the ssh_config man page:我猜这是 SSH 运行其 ProxyCommands 方式的副作用——来自ssh_config手册页:

[the proxy command] is executed using the user's shell 'exec' directive [...] [代理命令] 使用用户的 shell 'exec' 指令执行 [...]

I'm hoping I can find a way around this problem while still using SSH config and ProxyCommand, rather than resorting to a complete stand-alone wrapper around the ssh executable and requiring everyone use that.我希望我能找到解决这个问题的方法,同时仍然使用 SSH 配置和 ProxyCommand,而不是求助于ssh可执行文件周围的完整独立包装器并要求每个人都使用它。 Any suggestions gratefully accepted...任何建议感激地接受...

host my-aws-host
    ProxyCommand aws ssm start-session --target $(aws ec2 describe-instances --filter "Name=tag:Name,Values=%h" --query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" --output text) --document-name AWS-StartSSHSession --parameters portNumber=%p

The above will dynamically filter for your target-id based on host name (%h) provided so you can login using ssh my-aws-host .以上将根据提供的主机名 (%h) 动态过滤您的目标 ID,以便您可以使用ssh my-aws-host登录。 I personally have a prefix for all my machines in AWS so I ssh config is as follows:我个人在 AWS 中为我的所有机器设置了一个前缀,因此我的 ssh 配置如下:

host your-custom-prefix-*
    ProxyCommand aws ssm start-session --target $(aws ec2 describe-instances --filter "Name=tag:Name,Values=%h" --query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" --output text) --document-name AWS-StartSSHSession --parameters portNumber=%p

This works only when the name of your machines in AWS match the host name provided.只有当您在 AWS 中的机器名称与提供的主机名匹配时,这才有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM