Como obter o HostName do script executável no arquivo de configuração SSH?

10

Frequentemente, preciso ssh em um computador arbitrário de um cluster específico (todas as máquinas no cluster são idênticas). No entanto, o conjunto de máquinas disponíveis no cluster muda frequentemente, portanto, tenho um script que retorna um nome de host arbitrário do cluster que está disponível e corresponde aos meus requisitos (por exemplo, online e executando o sistema operacional correto).

Observe também que estou usando o encaminhamento de credenciais Kerberos (GSSAPIAuthentication) para autenticação.

No momento, eu uso usando ssh `get_host`. Eu gostaria de executar ssh cluster. Com um nome de host conhecido, isso é fácil com o seguinte em /ssh/config:

Host cluster
    HostName static_host.cluster.domain.tld
    GSSAPIAuthentication yes
    GSSAPIDelegateCredentials yes

Como posso selecionar HostNamedinamicamente, usando meu script? (Ou o SSH tem um método diferente para oferecer suporte à minha função desejada?) Gostaria de fazer algo parecido com o seguinte, mas não funciona:

Host cluster
    HostName `get_host`   # This does not work
    ...

O Grawity mostrou que ProxyCommandpode ser um script que obtém o nome do host e encaminha a sshconexão a ele usando netcator socat. No entanto, isso não está encaminhando as credenciais do Kerberos. Ajuda com isso também é apreciada.

EDITAR:

Você não pode fazer isso com o Kerberos como eu gostaria (veja os comentários na resposta aceita). Então, eu estou usando esse script ,, ssh-wrappercomo um sshalias para fazer a reescrita dinâmica no sshargumento da linha de comando. Não é robusto, mas funciona para mim.

#!/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
David B.
fonte
Pergunta relacionada sobre falha do servidor .
Michael - Onde está Clay Shirky

Respostas:

6

~/.ssh/config:

Host cluster
    ProxyCommand ~/bin/cluster-connect

~/bin/cluster-connect:

#!/bin/bash
socat stdio tcp:$(get_host):22
user1686
fonte
Obrigado. Isso (ou netcat $(get_host) 22) funciona muito bem para a conexão. Mas, parece não passar minhas credenciais kerberos. Eu tenho GSSAPIAuthentication yese GSSAPIDelegateCredentials yessob Host clusterno meu .ssh/configarquivo, e eles trabalham, se o nome do host é dada explicitamente, mas não se eu rota através do ProxyCommand. Pensamentos? Vou alterar a questão também.
David B.
Eu não acho que você pode conseguir isso - sshdeve saber o nome do host de destino para obter o ticket correto, e não há maneira de fornecê-lo dinamicamente (exceto usar um wrapper que simplesmente seja executado ssh $(get_host) "$@", o que, como eu entendi, você não quer ) Ele pode funcionar se todos os servidores no cluster têm a mesma Kerberos principal, mas eu não acho que ninguém nunca faz isso.
user1686
Infeliz, mas faz sentido. Eu escrevi um wrapper rápido para fazer uma busca / substituição dinâmica (adicionada à pergunta). Vai quebrar em alguns cenários, mas funciona para mim.
David B.
Localizar
Apenas uma substituição sed nos argumentos da linha de comando para ssh, de um mapeamento de host-alise para script de geração de host armazenado no script.
David B.