Pertanyaan Sebuah terowongan SSH melalui beberapa lompatan


Tunneling data melalui SSH cukup lurus ke depan:

ssh -D9999 username@example.com

set up port 9999 pada Anda localhost sebagai sebuah terowongan untuk example.com, tetapi saya memiliki kebutuhan yang lebih spesifik:

  • Saya bekerja secara lokal localhost
  • host1 dapat diakses oleh localhost
  • host2 hanya menerima koneksi dari host1
  • Saya perlu membuat terowongan dari localhost untuk host2

Secara efektif, saya ingin membuat terowongan SSH "multi-hop". Bagaimana saya bisa melakukan ini? Idealnya, saya ingin melakukan ini tanpa perlu superuser apa saja mesin-mesin.


289
2018-01-16 05:58


asal


Untuk apa kamu menggunakannya? Saya ingin menggunakannya untuk proxy kaus kaki. Apakah itu akan berhasil? - prongs
Ya, Anda harus dapat menggunakan koneksi tunneled sebagai proxy SOCKS, kecuali host2 menolak penerusan - Mala
Saya sedang berpikir tentang membuat pembungkus atas SSH yang akan mengatur bahwa menggunakan beberapa penggunaan ProxyCommand. - Pavel Šimerda
@prongs Apakah Anda berhasil menggunakan ini untuk proxy SOCKS (bertahun-tahun yang lalu)? - Drux


Jawaban:


Pada dasarnya Anda memiliki tiga kemungkinan:

  1. Terowongan dari localhost untuk host1:

    ssh -L 9999:host2:1234 -N host1
    

    Seperti disebutkan di atas, koneksi dari host1 untuk host2 tidak akan diamankan.

  2. Terowongan dari localhost untuk host1 dan dari host1 untuk host2:

    ssh -L 9999:localhost:9999 host1 ssh -L 9999:localhost:1234 -N host2
    

    Ini akan membuka terowongan dari localhost untuk host1 dan terowongan lain dari host1 untuk host2. Namun portnya 9999 untuk host2:1234 dapat digunakan oleh siapa saja host1. Ini mungkin atau mungkin bukan masalah.

  3. Terowongan dari localhost untuk host1 dan dari localhost untuk host2:

    ssh -L 9998:host2:22 -N host1
    ssh -L 9999:localhost:1234 -N -p 9998 localhost
    

    Ini akan membuka terowongan dari localhost untuk host1 melalui mana layanan SSH host2 dapat digunakan. Kemudian terowongan kedua dibuka dari localhost untuk host2 melalui terowongan pertama.

Biasanya, saya akan pergi dengan opsi 1. Jika koneksi dari host1 untuk host2 perlu diamankan, pergi dengan opsi 2. Opsi 3 terutama berguna untuk mengakses layanan host2 yang hanya dapat dijangkau dari host2 diri.


274
2018-01-17 21:31



pilihan 3 adalah apa yang saya cari, terima kasih! - Mala
Saya ingin melakukan penelusuran dengan cara ini. Yang mana yang terbaik? Saya mencoba yang pertama tetapi tidak berhasil. Saya menetapkan proxy kaus kaki di browser lokal saya: 1234 tetapi tidak berhasil. :( tolong bantu.. - prongs
@ Prash coba opsi 3 - Mala
adakah cara untuk meneruskan kunci publik saya dari localhost, melalui tunnel host 1, ke host2? - Noli
@Noli Jika Anda menggunakan ssh-agent (yang Anda harus), Anda dapat meneruskannya melalui koneksi menggunakan -Apilihan untuk ssh. - Mika Fischer


Ada sebuah jawaban yang sangat baik menjelaskan penggunaan ProxyCommand direktif konfigurasi untuk SSH:

Tambahkan ini ke Anda ~/.ssh/config (Lihat man 5 ssh_config untuk detail):

Host host2
  ProxyCommand ssh host1 -W %h:%p

Kemudian ssh host2 secara otomatis akan melalui terowongan host1 (Juga berfungsi dengan X11 forwarding dll.).

Ini juga berfungsi untuk seluruh kelas host mis. diidentifikasi oleh domain:

Host *.mycompany.com
  ProxyCommand ssh gateway.mycompany.com -W %h:%p

Memperbarui

OpenSSH 7.3 memperkenalkan Sebuah ProxyJump direktif, menyederhanakan contoh pertama ke

Host host2
  ProxyJump host1

138
2017-08-01 17:10



Apakah ada cara untuk melakukan ini secara kondisional? Saya hanya ingin melakukan ini kadang-kadang. Juga, ini khusus untuk perintah, tapi saya mencari sesuatu untuk semua port 22 (ssh, sftp, dll). - Stephane
@Stephane apa yang Anda maksud dengan khusus untuk perintah? Konfigurasi SSH Anda digunakan oleh apa pun yang menggunakan ssh, termasuk git, sftp dll. afaik. - kynan
@Stephane Saya tidak mengetahui cara mengaktifkan ini secara kondisional (misalnya hanya ketika Anda berada di luar jaringan host target). Saya mengatur opsi ini untuk semua host yang dimaksud dalam blok konfigurasi dan kemudian (un) komentar baris sesuai kebutuhan. Tidak sempurna, tetapi berhasil. - kynan
@Stephane yakin: ssh -F /path/to/altconfig. Hati-hati ini akan mengabaikan sistem yang luas /etc/ssh/ssh_config. - kynan
Cara mudah untuk membuat pengaturan "kondisional" adalah mendefinisikan dua host yang berbeda di .ssh / config, yang memiliki HostName yang sama. Hubungkan ke host2-tunnel ketika Anda menginginkan tunnel, dan host2 ketika Anda tidak. - Steve Bennett


Kami memiliki satu gerbang ssh ke jaringan pribadi kami. Jika saya berada di luar dan menginginkan remote shell pada mesin di dalam jaringan pribadi, saya harus ssh ke gateway dan dari sana ke mesin pribadi.

Untuk mengotomatiskan prosedur ini, saya menggunakan skrip berikut:

#!/bin/bash
ssh -f -L some_port:private_machine:22 user@gateway "sleep 10" && ssh -p some_port private_user@localhost

Apa yang terjadi:

  1. Buat terowongan untuk protokol ssh (port 22) ke mesin pribadi.
  2. Hanya jika ini berhasil, ssh ke mesin pribadi menggunakan terowongan. (operator && memastikan ini).
  3. Setelah menutup sesi ssh pribadi, saya ingin terowongan ssh menutup juga. Ini dilakukan melalui trik "tidur 10". Biasanya, perintah ssh pertama akan ditutup setelah 10 detik, tetapi selama waktu ini, perintah ssh kedua akan membuat koneksi menggunakan tunnel. Akibatnya, perintah ssh pertama membuat terowongan terbuka sampai dua kondisi berikut dipenuhi: tidur 10 selesai dan terowongan tidak lagi digunakan.

20
2018-01-24 18:47



Sangat pintar!!! SUKA! - Hendy Irawan


Setelah membaca di atas dan merekatkan semuanya bersama-sama, saya telah membuat skrip Perl berikut (simpan sebagai mssh di / usr / bin dan membuatnya bisa dijalankan):

#!/usr/bin/perl

$iport = 13021;
$first = 1;

foreach (@ARGV) {
  if (/^-/) {
    $args .= " $_";
  }
  elsif (/^((.+)@)?([^:]+):?(\d+)?$/) {
    $user = $1;
    $host = $3;
    $port = $4 || 22;
    if ($first) {
      $cmd = "ssh ${user}${host} -p $port -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
      $args = '';
      $first = 0;
    }
    else {
      $cmd .= " -L $iport:$host:$port";
      push @cmds, "$cmd -f sleep 10 $args";
      $cmd = "ssh ${user}localhost -p $iport -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
      $args = '';
      $iport ++;
    }
  }
}
push @cmds, "$cmd $args";

foreach (@cmds) {
  print "$_\n";
  system($_);
}

Pemakaian:

Untuk mengakses HOSTC melalui HOSTA dan HOSTB (pengguna yang sama):

mssh HOSTA HOSTB HOSTC

Untuk mengakses HOSTC melalui HOSTA dan HOSTB dan menggunakan non-default SSH-portnumbers dan pengguna yang berbeda:

mssh user1@HOSTA:1234 user2@HOSTB:1222 user3@HOSTC:78231

Untuk mengakses HOSTC melalui HOSTA dan HOSTB dan menggunakan X-forwarding:

mssh HOSTA HOSTB HOSTC -X

Untuk mengakses port 8080 di HOSTC melalui HOSTA dan HOSTB:

mssh HOSTA HOSTB -L8080:HOSTC:8080

17
2018-01-11 11:02



ini luar biasa - Mala
Saya benar-benar tidak bisa cukup berterima kasih, skrip ini membuat hidup saya lebih mudah setiap hari. Satu-satunya hal yang saya ubah adalah menambahkan int (rand (1000)) ke iport, untuk memungkinkan beberapa instance berjalan pada saat yang bersamaan. Saya pasti berhutang bir kepada Anda. - Mala
Ini bekerja sangat baik. Peningkatan lebih lanjut akan menyelesaikan HOSTB, HOSTC dll menggunakan localhost's / etc / hosts dan ~ / .ssh / config - Steve Bennett
Juga saya komentar kedua Mala. Tanpa port acak, jika Anda kemudian mencoba mssh HOSTA HOSTD Anda benar-benar akan berakhir di HOSTB (dan mungkin tidak akan menyadari ..) - Steve Bennett


OpenSSH v7.3 dan seterusnya mendukung -J beralih dan a ProxyJump pilihan, yang memungkinkan satu atau lebih host lompatan yang dipisahkan koma, jadi, Anda cukup melakukan ini sekarang:

ssh -J jumpuser1@jumphost1,jumpuser2@jumphost2,...,jumpuserN@jumphostN user@host

16
2017-08-10 09:11



ssh -J user1 @ host1 -YC4c arcfour, blowfish-cbc user2 @ host2 firefox -no-remote Ini akan mempercepat mendapatkan firefox dari host2 ke localhost. - Jaur


Jawaban ini mirip dengan kynan, karena melibatkan penggunaan ProxyCommand. Tetapi lebih nyaman menggunakan IMO.

Jika Anda menginstal netcat di mesin hop Anda, Anda dapat menambahkan potongan ini ke ~ / .ssh / config Anda:

Host *+*
    ProxyCommand ssh $(echo %h | sed 's/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /') nc $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /')

Kemudian

ssh -D9999 host1+host2 -l username

akan melakukan apa yang Anda minta.

Saya datang ke sini mencari tempat asli di mana saya membaca trik ini. Saya akan memposting tautan saat saya menemukannya.


8
2018-03-13 09:57



Saya percaya ini adalah asal mula dari trik: wiki.gentoo.org/wiki/SSH_jump_host - slm
@slm ya, itu dia! Terima kasih! - silviot


ssh -L 9999:host2:80 -R 9999:localhost:9999 host1

-L 9999: host2: 80

Berarti mengikat ke localhost: 9999 dan paket yang dikirim ke localhost: 9999 meneruskannya ke host2: 80

-R 9999: localhost: 9999

Berarti paket apa pun yang diterima oleh host1: 9999 meneruskannya kembali ke localhost: 9999


4
2018-01-19 02:03



Jawaban yang brilian dan paling sederhana untuk membuat terowongan sehingga Anda dapat mengakses aplikasi di host2 langsung dari localhost: 9999 - dvtoever
Mengikuti jawaban ini, saya mendapatkan channel 3: open failed: administratively prohibited: open failed  pesan eror. - Franck Dernoncourt


Anda harus dapat menggunakan port forwarding untuk mengakses layanan host2 dari localhost. Panduan yang baik berada sini. Kutipan:

Ada dua jenis port forwarding: penerusan lokal dan jarak jauh. Mereka juga disebut terowongan keluar dan masuk, masing-masing. Penerusan port lokal meneruskan lalu lintas yang datang ke port lokal ke port jarak jauh yang ditentukan.

Misalnya, jika Anda mengeluarkan perintah

ssh2 -L 1234:localhost:23 username@host

semua lalu lintas yang datang ke port 1234 pada klien akan diteruskan ke port 23 pada server (host). Perhatikan bahwa localhost akan diselesaikan oleh sshdserver setelah koneksi dibuat. Dalam hal ini localhost karena itu mengacu pada server (host) itu sendiri.

Remote port forwarding melakukan sebaliknya: lalu lintas ke depan datang ke port remote ke port lokal tertentu.

Misalnya, jika Anda mengeluarkan perintah

ssh2 -R 1234:localhost:23 username@host

semua lalu lintas yang datang ke port 1234 pada server (host) akan diteruskan ke port 23 pada klien (localhost).

Di gips Anda, ganti localhost dalam contoh dengan host2 dan host dengan host1.


2
2018-01-16 06:34



menurut artikel itu, koneksi hanya akan diamankan sampai mesin tengah (host1). Apakah ada cara untuk memastikan semuanya tetap aman? - Mala
Saya belum pernah mencoba ini, tetapi jika host1 dan host2 sama-sama server ssh, Anda mungkin dapat mengatur terowongan dari host1 ke host2, kemudian mengatur terowongan dari localhost ke host1 untuk layanan yang sama (mendapatkan lokal dan remote port kanan). Saya tidak tahu apakah itu mungkin dalam satu perintah dari localhost. - fideli


Saya melakukan apa yang saya lakukan berpikir Anda ingin lakukan dengan

ssh -D 9999 -J host1 host2

Saya diminta untuk kedua kata sandi, lalu saya dapat menggunakan localhost: 9999 untuk proxy SOCKS untuk host2. Itu adalah hal terdekat yang dapat saya pikirkan dari contoh yang Anda tunjukkan di tempat pertama.


2
2017-11-21 11:06