Bagaimana cara mendapatkan HostName dari skrip yang dapat dieksekusi di file konfigurasi SSH?

10

Saya sering perlu ssh ke komputer sewenang-wenang dari cluster tertentu (semua mesin di cluster identik). Namun, set mesin yang tersedia di cluster sering berubah, jadi saya memiliki skrip yang mengembalikan nama host sewenang-wenang dari cluster yang tersedia dan cocok dengan persyaratan saya (mis. Online dan menjalankan OS yang benar).

Perhatikan juga, bahwa saya menggunakan penerusan kredensial Kerberos (GSSAPIAuthentication) untuk otentikasi.

Saat ini, saya ssh dalam menggunakan ssh `get_host`. Saya ingin mengeksekusi ssh cluster. Dengan nama host yang dikenal, ini mudah dengan yang berikut di /ssh/config:

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

Bagaimana saya bisa memilih HostNamesecara dinamis, menggunakan skrip saya? (Atau apakah SSH memiliki metode berbeda untuk mendukung fungsi yang saya inginkan?) Saya ingin melakukan sesuatu seperti yang berikut ini, tetapi tidak berhasil:

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

Grawity menunjukkan bahwa ProxyCommandbisa berupa skrip yang mendapatkan nama host dan meneruskan sshkoneksi ke sana menggunakan netcatatau socat. Namun, ini tidak meneruskan kredensial Kerberos. Bantuan dengan ini juga dihargai.

EDIT:

Anda tidak dapat melakukan ini dengan Kerberos seperti yang saya inginkan (lihat komentar dalam jawaban yang diterima). Jadi, saya menggunakan skrip ini ssh-wrapper,, sebagai sshalias untuk melakukan penulisan ulang dinamis pada sshargumen baris perintah. Itu tidak kuat, tetapi itu bekerja untuk saya.

#!/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.
sumber
Pertanyaan terkait tentang Kesalahan Server .
Michael - Di mana Clay Shirky

Jawaban:

6

~/.ssh/config:

Host cluster
    ProxyCommand ~/bin/cluster-connect

~/bin/cluster-connect:

#!/bin/bash
socat stdio tcp:$(get_host):22
pengguna1686
sumber
Terima kasih. Ini (atau netcat $(get_host) 22) berfungsi baik untuk koneksi. Tapi, sepertinya tidak lulus kredensial kerberos saya. Saya memiliki GSSAPIAuthentication yesdan di GSSAPIDelegateCredentials yesbawah Host clusterdalam .ssh/configfile saya , dan mereka berfungsi jika HostName diberikan kejelasan, tetapi tidak jika saya merutekan melalui ProxyCommand. Pikiran? Saya akan mengubah pertanyaan itu juga.
David B.
Saya tidak berpikir Anda bisa mencapainya - sshharus tahu nama host target untuk mendapatkan tiket yang benar, dan tidak ada cara untuk memberikannya secara dinamis (singkat menggunakan pembungkus yang hanya berjalan ssh $(get_host) "$@", yang seperti yang saya mengerti Anda tidak ingin ). Ini mungkin bekerja jika semua server di cluster memiliki Kerberos kepala sekolah yang sama, tapi saya tidak berpikir ada yang pernah melakukan itu.
user1686
Sayangnya, tapi masuk akal. Saya menulis pembungkus cepat untuk melakukan pencarian / penggantian dinamis (ditambahkan ke pertanyaan). Itu akan pecah dalam beberapa skenario, tetapi bekerja untuk saya.
David B.
Cari / ganti dinamis? ...
user1686
Hanya substitusi sed pada argumen commandline ke ssh, dari host-alise ke host-generasi-skrip pemetaan yang disimpan dalam skrip.
David B.