Secara dinamis menghasilkan entri Host SSH di ~ / .ssh / config

9

Saya harus mengelola setumpuk host lebih dari ssh. Namun saya hanya dapat mengaksesnya melalui server ssh gateway tertentu.

Saya memiliki yang berikut ini di ~/.ssh/config:

Host mygateway-www
Hostname www
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh mygateway nc %h 22

Namun saya harus terhubung ke banyak mesin ini. Alih-alih meletakkan lusinan entri di saya ~/.ssh/config, apakah ada saya bisa memiliki sesuatu seperti ini:

Host mygateway-*
Hostname ???WHAT GOES HERE????
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh mygateway nc %h 22

Saya tahu Anda bisa menggunakannya %hdalam Hostnameargumen, tapi itu akan menjadi nama host. Yang benar-benar saya butuhkan adalah semacam substitusi string, seperti bash ${VAR%thingie}. Apakah ini mungkin?

Rory
sumber

Jawaban:

24

Ini dapat dilakukan dengan file konfigurasi SSH berikut:

Host *
  ServerAliveInterval 120

Host gateway.somewhere.com
  User jdoe

Host gateway+*
  User jdoe
  ProxyCommand ssh -T -a $(echo %h |cut -d+ -f1).somewhere.com nc $(echo %h |cut -d+ -f2) %p 2>/dev/null
  ControlMaster auto
  ControlPath ~/.ssh/ssh-control_%r@%h:%p

Anda kemudian mengakses host internal Anda seperti:

ssh gateway+internalhost01.somewhere.com
ssh gateway+internalhost02.somewhere.com

Nama yang Anda pilih untuk bagian kanan harus dapat diselesaikan oleh host lompat.

Parameter Pengguna ditentukan jika Anda perlu memetakan secara manual ke pengguna yang berbeda di kelas host yang berbeda. ControlMaster dan ControlPath ditentukan untuk memungkinkan koneksi SSH digunakan kembali.

lampu tembaga
sumber
6

Anda tidak perlu menentukan HostName secara manual karena akan datang dari baris perintah.

Coba saja:

Host *.domain  
  IdentityFile ~/.ssh/id_rsa  
  ProxyCommand ssh mygateway /usr/bin/nc %h 22
Dan Carley
sumber
Masalah dengan pendekatan itu adalah bahwa Hostname cukup umum (mis. Db1, www, mail2), sedangkan saya ingin mereka juga diawali dengan proyek, karena saya mungkin perlu ssh ke mesin lain yang disebut 'db2'. Oleh karena itu awalan di Host
Rory
2
Jadi Anda sebenarnya ingin mengkonfigurasi ulang DNS Anda. Solusi paling sederhana (tetapi paling tidak praktis) adalah memodifikasi file host Anda. Di sisi lain Anda bisa selalu menambahkan server DNS lokal ke workstation Anda dengan domain .inid dan menggunakan nama host yang Anda inginkan.
Martin M.
Memberi +1 pada yang sebelumnya. Buat subdomain untuk setiap proyek. DNS ada untuk membuat hidup Anda lebih mudah;)
Dan Carley
1

Sepertinya tidak ada cara untuk melakukan ini.

Rory
sumber
1

Saya memiliki masalah yang sama dan akhirnya menulis naskah yang menghasilkan semua pelat untuk saya. Saya tidak lagi mengubah ~ / ssh / config, saya mengubah ~ / ssh / config.in dan jalankan kembali skrip saya.

Michael Hoffman
sumber
1
Ingin membagikan skrip Anda? Saya sudah berpikir untuk melakukan ini, tetapi tampaknya solusi yang kuat dan generik mungkin membutuhkan banyak pekerjaan untuk memperbaikinya. Sekalipun solusi Anda belum mencapai itu, akan berguna untuk mengetahui apa yang Anda pikir itu benar, dan apa yang akan Anda lakukan secara berbeda jika Anda ingin menyelesaikannya.
iconoclast
Pikiranku adalah memiliki .ssh/config.dfile untuk setiap template, di mana setiap template akan menghasilkan satu atau lebih entri di final ~/.ssh/config. Akan ada file dengan variabel universal, tetapi masing-masing template dapat memiliki variabel sendiri yang akan diutamakan daripada global, terdaftar di bagian atas. The ~/.ssh/configfile yang bisa dihasilkan pada permintaan atau pada jadwal-akan tidak peduli-selama Anda tidak pernah membuat suntingan langsung untuk itu bahwa Anda ingin melestarikan.
iconoclast
Naskah saya benar-benar tidak berdokumen dan saya pikir itu tidak akan bisa dipahami tanpa dokumentasi atau contoh, yang saya tidak punya waktu untuk membuatnya.
Michael Hoffman
Bisa dimengerti Setiap umpan balik tentang pendekatan yang saya uraikan akan dihargai, terutama jika saya mengabaikan beberapa kebutuhan penting atau kasus penggunaan, atau beberapa kendala besar (atau kecil).
iconoclast
1
Saya pikir itu pendekatan yang baik, mungkin sedikit kurang membingungkan daripada pendekatan yang saya gunakan. Saya membaca sejumlah deklarasi Host ke dalam memori, kemudian sejumlah deklarasi non-host. Deklarasi non-host diterapkan ke setiap Host dalam grup saat ini hingga ada Host lain. Saya juga mengizinkan Host untuk dideklarasikan beberapa kali dalam file, termasuk menggunakan globbing. Pada akhirnya saya menulis semua yang telah saya bangun dalam ingatan.
Michael Hoffman
1

Abaikan menentukan menimpa nama host secara langsung melalui Hostnamedeklarasi dan alih-alih tentukan saat runtime. Lakukan ini dengan mengevaluasinya sebagai bagian dari ProxyCommand, gunakan %huntuk merujuknya pada perintah (juga gunakan %pbukan port hardcoding sebagai 22) yaitu

Host mygateway-*
   #Hostname ???WHAT GOES HERE????
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh mygateway nc $(echo %h|sed 's/^mygateway-//') %p

Seseorang bahkan dapat memiliki bait yang lebih umum, di mana Anda dapat menentukan host apa pun tanpa -hanya diperlakukan sebagaimana adanya, atau sesuai bait yang cocok lainnya, tetapi memiliki -pendekatan generik untuk menentukan <gateway>-<target>:

Host *-*
   # Assume LHS of "-" is GW and RHS of "-" is target host
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh $(echo %h|cut -d - -f1) nc $(echo %h|cut -d - -f2-) %p

Selain itu, versi yang lebih baru dari klien SSH mendukung [-W host:port]opsi untuk secara langsung melakukan fungsi yang sama dengan nc(netcat). Dengan demikian, kita dapat menggunakan yang dimodifikasi:

Host *-*
   # Assume LHS of "-" is GW and RHS of "-" is target host
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh -W $(echo %h|cut -d - -f2-):%p $(echo %h|cut -d - -f1)

Tentu saja, jika Anda memiliki daftar host yang terbatas, Anda selalu dapat melakukannya:

Host host1 host2 host3 hostN
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh mygateway nc %h %p

Semoga ini membantu!

Taz
sumber
0

Saya punya klien dengan pengaturan yang sama dan saya menggunakan DSSH untuk menyelesaikan masalah saya.
DSSH antara lain memungkinkan Anda untuk masuk secara transparan ke host jarak jauh melalui host gateway.

Gunakan kasing

  • Kumpulkan parameter konfigurasi dari router Cisco yang membutuhkan login "ena"
  • Masuk ke server, yang menonaktifkan PermitRootLogin secara langsung sebagai root (dengan mengetikkan su - dan kata sandi secara otomatis), sambil mempertahankan status keluar
  • Tambahkan logika khusus seperti pencatatan lanjutan
  • tunnel melalui beberapa koneksi untuk mencapai server target
aussielunix
sumber
5
Saya lebih suka tidak mulai menggunakan beberapa klien ssh pihak ketiga acak yang menggunakan java, untuk hal-hal yang dapat saya lakukan di ~ / .ssh / config.
Rory
tautannya sudah mati
iconoclast
Sumber perangkat lunak dapat ditemukan di Github: github.com/digmia/dssh
Guest