Как получить HostName из исполняемого скрипта в конфигурационном файле 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
    ...

Гравити показал, что это 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
Дэвид Б.
источник
Похожий вопрос о сбое сервера .
Майкл - Где Клэй Ширки

Ответы:

6

~/.ssh/config:

Host cluster
    ProxyCommand ~/bin/cluster-connect

~/bin/cluster-connect:

#!/bin/bash
socat stdio tcp:$(get_host):22
user1686
источник
Спасибо. Это (или netcat $(get_host) 22) прекрасно работает для связи. Но, похоже, он не проходит мои полномочия Kerberos. У меня есть GSSAPIAuthentication yesи GSSAPIDelegateCredentials yesпод Host clusterв моем .ssh/configфайле, и они работают , если HostName дается в явной форме , но если я маршрут через ProxyCommand. Мысли? Я тоже исправлю вопрос.
Дэвид Б.
Я не думаю, что вы можете достичь этого - вы sshдолжны знать целевое имя хоста, чтобы получить правильный билет, и просто нет способа предоставить его динамически (если не использовать обертку, которая просто запускается ssh $(get_host) "$@", что, как я понял, вам не нужно ). Это может сработать, если все серверы в кластере имеют один и тот же принцип Kerberos, но я не думаю, что кто-то когда-либо это делает.
user1686
К сожалению, но имеет смысл. Я написал быструю оболочку для динамического поиска / замены (добавлено в вопрос). Это сломается в некоторых сценариях, но работает для меня.
Дэвид Б.
Динамический поиск / замена? ...
user1686
Просто подстановка sed в аргументах командной строки для ssh, от host-alise до отображения сценария host-generation, хранящегося в сценарии.
Дэвид Б.