Jak uzyskać nazwę hosta ze skryptu wykonywalnego w pliku konfiguracyjnym SSH?

10

Często muszę ssh do dowolnego komputera z określonego klastra (wszystkie komputery w klastrze są identyczne). Jednak zestaw dostępnych komputerów w klastrze często się zmienia, więc mam skrypt, który zwraca dowolną nazwę hosta z klastra, który jest dostępny i odpowiada moim wymaganiom (np. Online i działający prawidłowy system operacyjny).

Zauważ też, że używam przekazywania uwierzytelnienia Kerberos (GSSAPIAuthentication) do uwierzytelnienia.

W tej chwili używam ssh ssh `get_host`. Chciałbym zamiast tego wykonać ssh cluster. W przypadku znanej nazwy hosta jest to łatwe dzięki /ssh/config:

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

Jak mogę wybrać HostNamedynamicznie, używając mojego skryptu? (Lub czy SSH ma inną metodę do obsługi mojej pożądanej funkcji?) Chciałbym zrobić coś takiego, ale to nie działa:

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

Grawity pokazał, że ProxyCommandmoże to być skrypt, który pobiera nazwę hosta i przekazuje sshpołączenie do niego za pomocą netcatlub socat. Nie oznacza to jednak przekazywania poświadczeń Kerberos. Doceniana jest również pomoc w tym zakresie.

EDYTOWAĆ:

Nie możesz tego zrobić z Kerberos, tak jak chciałbym (patrz komentarze w zaakceptowanej odpowiedzi). Tak więc używam tego skryptu ssh-wrapperjako sshaliasu do dynamicznego przepisywania przy użyciu sshargumentu wiersza poleceń. Nie jest solidny, ale działa dla mnie.

#!/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.
źródło
Podobne pytanie o awarię serwera .
Michael - Where's Clay Shirky

Odpowiedzi:

6

~/.ssh/config:

Host cluster
    ProxyCommand ~/bin/cluster-connect

~/bin/cluster-connect:

#!/bin/bash
socat stdio tcp:$(get_host):22
użytkownik1686
źródło
Dzięki. To (lub netcat $(get_host) 22) działa świetnie dla połączenia. Ale wydaje się, że nie przechodzi przez moje dane uwierzytelniające Kerberos. Mam GSSAPIAuthentication yesi GSSAPIDelegateCredentials yesponiżej Host clusterw moim .ssh/configpliku, i działają one, jeśli nazwa hosta jest zrozumiała, ale nie, jeśli trasy przez ProxyCommand. Myśli? Zmienię również pytanie.
David B.
Nie sądzę, że możesz to osiągnąć - sshmusisz znać docelową nazwę hosta, aby uzyskać prawidłowy bilet, i po prostu nie ma sposobu, aby zapewnić go dynamicznie (bez użycia opakowania, które po prostu działa ssh $(get_host) "$@", co, jak zrozumiałem, nie chcesz ). To może działać, jeśli wszystkie serwery w klastrze mają taką samą Kerberos kapitał, ale nie sądzę, ktoś kiedykolwiek robi.
user1686,
Niestety, ale ma sens. Napisałem szybkie opakowanie, aby wykonać dynamiczne wyszukiwanie / zamianę (dodane do pytania). Zepsuje się w niektórych scenariuszach, ale działa dla mnie.
David B.
Dynamiczne wyszukiwanie / zamiana? ...
1686
Tylko sed podstawienie argumentów wiersza poleceń do ssh, od alise hosta do mapowania generowania hosta skryptu przechowywanego w skrypcie.
David B.