我经常需要通过 ssh 连接到特定集群中的任意计算机(集群中的所有计算机都相同)。但是,集群中可用的计算机集合经常发生变化,因此我编写了一个脚本,该脚本可从可用且符合我要求的集群中返回任意主机名(例如,在线且运行正确的操作系统)。
另请注意,我正在使用 Kerberos(GSSAPIAuthentication)凭证转发进行身份验证。
现在,我使用 ssh 进入ssh `get_host`
。我想改为执行ssh cluster
。有了已知的主机名,在 中执行以下命令即可轻松完成此操作/ssh/config
:
Host cluster
HostName static_host.cluster.domain.tld
GSSAPIAuthentication yes
GSSAPIDelegateCredentials yes
我如何HostName
使用我的脚本动态选择?(或者 SSH 是否有不同的方法来支持我想要的功能?)我想做类似以下的事情,但它不起作用:
Host cluster
HostName `get_host` # This does not work
...
重力表明 可以是一个获取主机名并使用或将连接ProxyCommand
转发到该主机名的脚本。但是,这不会转发 Kerberos 凭据。如果对此有所帮助,我们将不胜感激。ssh
netcat
socat
编辑:
您无法像我希望的那样使用 Kerberos 执行此操作(请参阅已接受答案中的评论)。因此,我使用此脚本ssh-wrapper
作为别名对命令行参数ssh
进行动态重写。它并不强大,但对我来说很有效。ssh
#!/bin/bash
# Mapping between host aliases and dynamically-generated hostname
declare -A MAP
MAP[cluster]=`gethost`
# Find and replace on all positional args
args=$*
for key in ${!MAP[@]}; do
replace=${MAP[$key]}
args=`echo ${args} | sed "s/\(^\|[[:space:]]\)${key}\(\$\|[[:space:]]\)/${replace}/"`
done
# Execute using called-name if not this script
if [ "ssh-wrapper" != "`basename $0`" ]; then
exec $0 ${args}
# Otherwise, assume ssh and execute
else
exec ssh ${args}
fi
答案1
~/.ssh/config
:
Host cluster
ProxyCommand ~/bin/cluster-connect
~/bin/cluster-connect
:
#!/bin/bash
socat stdio tcp:$(get_host):22