如何从SSH配置文件中的可执行脚本获取主机名?


10

我经常需要从特定群集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
    ...

Grawity表明,ProxyCommand可以是一个脚本,该脚本获取主机名并ssh使用netcat或将连接转发到主机名socat。但是,这并不转发Kerberos凭据。对此的帮助也将受到赞赏。

编辑:

您无法按照我的意愿使用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

Answers:


6

~/.ssh/config

Host cluster
    ProxyCommand ~/bin/cluster-connect

~/bin/cluster-connect

#!/bin/bash
socat stdio tcp:$(get_host):22

谢谢。这(或netcat $(get_host) 22)对于连接非常有用。但是,它似乎没有通过我的kerberos凭证。我有GSSAPIAuthentication yesGSSAPIDelegateCredentials yesHost cluster我的.ssh/config文件,以及他们的工作,如果主机名是明确地给出,而是通过ProxyCommand不是,如果我的路线。有什么想法吗?我也会修改这个问题。
David B.

我认为您无法实现这一点- ssh必须知道目标主机名才能获取正确的票证,而且没有办法动态提供它(缺少使用简单运行的包装器的方法,ssh $(get_host) "$@"据我所知,您不需要)。它可以工作,如果集群中的所有服务器都具有相同的Kerberos主体,但我不认为有谁做到这一点。
user1686 2011年

不幸的是,但有道理。我写了一个快速包装器来进行动态查找/替换(添加到问题中)。在某些情况下会中断,但对我有用。
David B.

动态查找/替换?...
2011年

仅仅是ssh命令行参数上的sed替代品,从主机别名到脚本中存储的主机生成脚本映射。
David B.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.