如何在~/.ssh/config中运行时动态指定IdentityFile?
在~/.ssh/config中动态指定IdentityFile的可行方案
SSH的IdentityFile指令不支持直接执行外部命令或命令替换(比如你尝试的generic-executable %h %r或$(generic-executable %h %r)写法),它会把这些值当作普通文件路径解析,导致连接失败。以下是几种无需使用-i命令行参数的替代方案:
方案1:扩展ProxyCommand脚本结合ssh-agent
你已经在使用ProxyCommand处理SSM隧道,可以直接扩展ssm-proxy脚本,让它在生成临时密钥后自动添加到ssh-agent中,SSH会自动从agent中获取密钥,无需配置IdentityFile。
修改后的ssm-proxy脚本可以输出类似以下的命令:
# 生成临时密钥并获取路径 KEY_PATH=$(mktemp -t ssh-key-XXXXXX) ssh-keygen -t ed25519 -N "" -f "$KEY_PATH" >/dev/null 2>&1 # 将密钥添加到agent ssh-add "$KEY_PATH" # 设置退出陷阱,连接结束后清理密钥 trap 'ssh-add -d "$KEY_PATH"; rm -f "$KEY_PATH" "$KEY_PATH.pub"' EXIT # 原有的SSM隧道命令 aws ssm start-session ...
这样在执行ProxyCommand eval $(ssm-proxy ...)时,临时密钥会被自动加载到agent,SSH连接时会优先使用agent中的密钥。
方案2:自定义SSH wrapper脚本
编写一个简单的shell脚本(比如命名为ssh-dynamic),让它自动获取密钥路径并调用SSH:
#!/bin/bash # 从SSH配置中解析目标主机的用户名 TARGET_HOST=$1 REMOTE_USER=$(ssh -G "$TARGET_HOST" | grep -E '^user ' | awk '{print $2}') # 调用你的可执行程序获取密钥路径 KEY_PATH=$(generic-executable "$TARGET_HOST" "$REMOTE_USER") # 执行SSH连接并指定密钥 ssh -i "$KEY_PATH" "$@"
给脚本添加执行权限:
chmod +x ssh-dynamic
之后直接运行ssh-dynamic server即可完成连接,无需修改原有的~/.ssh/config。
方案3:使用Match块结合临时文件
在~/.ssh/config中通过Match块的exec指令预执行密钥路径获取命令,将结果写入临时文件后,让IdentityFile读取该文件:
Match host server exec "generic-executable %h %r > /tmp/ssh-server-key-path" IdentityFile /tmp/ssh-server-key-path Host server HostName server.example.com User foo ProxyCommand eval $(ssm-proxy -h %h -u %r -p %p -P)
注意:需要自行处理临时文件的清理(比如通过cron定时清理,或在exec指令中添加清理逻辑),避免残留无用文件。
内容的提问来源于stack exchange,提问作者thomas
相关产品推荐
相关产品推荐

