Perintah Proxy Bersyarat di ~ / .ssh / config?

14

Saya telah ~/.ssh/configmengkonfigurasi saya dengan berbagai host yang dapat diakses baik saat di VPN perusahaan kami, atau melalui server proxy SSH.

Saat ini saya baru saja punya

Host internal-server
    ProxyCommand ssh -W internal.ip:22 external-server

Namun jika saya berada di jaringan internal saya dapat langsung mengakses ip internal, jadi proksi melalui server eksternal hanya menambah penundaan untuk menghubungkan.

Apakah ada cara saya dapat sementara proksi jika ip internal tidak dapat dijangkau, dan terhubung langsung sebaliknya?

alt
sumber

Jawaban:

8

Saya biasanya mengatur sesuatu seperti ini. Diasumsikan host perantara akan dapat menyelesaikan nama.

Host *%homeproxy
    ProxyCommand ssh user@proxyhost /bin/netcat -w 1 $(echo %h | cut -d%% -f1) 22

Jadi saya akan terhubung ke suka ssh blah%homeproxy.

Sakit kepala
sumber
Google-fu saya gagal. Bisakah Anda menjelaskan lebih lanjut? Saya belum pernah melihat sintaks *% ini sebelumnya.
fukawi2
3
Tidak ada yang spesial dari %karakter tersebut. Anda bisa menggunakan apa saja. Persentase digunakan karena tidak valid dalam nama host, atau nama pengguna. The cutperintah withing ProxyCommand menggunakan %sebagai pembatas untuk menarik keluar nama host.
Zoredache
1
Ini bagus, namun itu berarti saya harus mengeja nama host lengkap daripada alias ssh.
alt
@mobiusnz Ini sebenarnya berarti bahwa Anda memerlukan nama yang berbeda untuk setiap cara menghubungkan yang berbeda . Dalam kasus saya, misalnya, jika saya di rumah, saya menggunakan ssh targetH, yang berarti target dari rumah . Jika dalam jaringan lokal menargetkan, cukup ssh target. Sudah menyenangkan untuk mengatakan ini dengan lebih jelas dalam jawabannya.
Rubens
4

Saya menggunakan metode berbeda menggunakan Match. Dalam kasus saya, saya ingin menggunakan proxy lokal jika sedang berjalan, atau tidak, jika tidak. Arahan berikut menyelesaikan ini dengan baik:

Match Exec "nc -z 127.0.0.1 1086"
    ProxyCommand nc -X 5 -x 127.0.0.1:1086 %h %p

Ini cocok dengan setiap upaya ssh, dan menjalankan pemeriksaan cepat menggunakan ncuntuk melihat apakah proxy saya aktif dan berjalan pada 1086 (dalam hal ini, nckeluar tanpa kesalahan). Jika itu terjadi, ia menetapkan ProxyCommand.

domoarigato
sumber
2

Satu dekade yang lalu saya menulis perintah proxy untuk skenario semacam ini. Dalam kasus penggunaan Anda, perintah proxy saya dapat digunakan seperti ini:

Host internal-server
    ProxyCommand ssh-multipath-proxy %h:%p -- ssh -W %h:%p external-server

Beberapa peringatan: Saya agak malu untuk mengakui, bahwa itu tidak menangani IPv6, dan bahwa itu hanya akan mencoba satu alamat IP per hostname. Juga, itu tidak akan mentransfer spanduk klien ke server sebelum spanduk server telah dikirim. Tapi itu tidak mungkin menyebabkan masalah.

kasperd
sumber
2

Terima kasih untuk @ till's Answer , itu menginspirasi saya banyak.

Saya menemukan bahwa Anda dapat mengarahkan koneksi Anda dengan paksa ProxyCommand nc dst dst-port .

Misalnya, Anda sebenarnya akan terhubung B.comjika menggunakan

ssh A.com -o ProxyCommand="nc B.com 22"

Tapi UserKnownHostsFile masih akan mencatat sebagaiA.com

Jadi, Anda dapat menambahkan domain "otomatis" ke ssh_config

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c '(timeout 0.1 nc -z %h %p) && nc %h %p || ssh -W %h:%p external-server'

Saya diganti nc -w 1 %h %pdengan (timeout 0.1 nc -z %h %p) && nc %h %p, akan lebih cepat jika Anda dapat mencapai server internal kurang dari 100 ms.

Atau Anda dapat diganti dengan ping, tetapi ini mungkin menunjukkan informasi yang buruk jika Anda menggunakan proxy berbasis TCP seperti proxychains, atau server tidak mengizinkan gema ICMP.

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c '(ping %h &>/dev/null) && nc %h %p || ssh -W %h:%p external-server'

Anda dapat mengganti (timeout 0.1 nc -z %h %p)dengan apa pun yang mendeteksi apakah Anda berada di server internal.

Jika Anda memiliki beberapa IP kandidat, bahkan Anda dapat menggunakan ini:

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c 'f(){(timeout 0.1 ping -c 1 $1 &>/dev/null) && nc $1 %p;}; f 1.1.1.1 || f 2.2.2.2 || f 3.3.3.3'

Itu akan mencoba untuk terhubung 1.1.1.1, jika gagal mencoba untuk terhubung 2.2.2.2, dan kemudian 3.3.3.3.

Komeiji Kuroko
sumber
0

Ini bekerja sedikit lebih otomatis dengan penundaan 1 detik tambahan kecil jika Anda tidak berada di belakang firewall dan firewall tidak menolak:

Host proxyhost.example.com
ProxyCommand none

Host *.example.com
ProxyCommand sh -c "nc -w 1 %h %p || ssh -W  %h:%p proxyhost.example.com"
sampai
sumber
0

Saya biasanya akan membuat entri lain seperti ini -

Host myVM
    ProxyCommand ssh -W internal.ip:22 external-server
    User ubuntu

Host myVM-np
    User ubuntu

Kemudian panggil saja yang Anda inginkan, tergantung pada lingkungan proxy Anda saat ini ..

Sharath Srinivasan
sumber