Lalu lintas UDP melalui terowongan SSH

66

Judulnya cukup meringkasnya. Saya ingin mengirim lalu lintas UDP melalui terowongan SSH. Secara khusus, saya harus dapat mengirim paket UDP melalui terowongan dan membuat server dapat mengirimnya kembali kepada saya di sisi lain. Saya tahu cara melakukannya untuk koneksi TCP. Apakah ini mungkin dengan UDP?

astaga
sumber

Jawaban:

36

Panduan kecil ini memberi tahu Anda cara mengirim lalu lintas UDP melalui SSH menggunakan alat yang standar (ssh, nc, mkfifo) dengan sebagian besar sistem operasi mirip UNIX.

Melakukan tunneling UDP melalui koneksi SSH

Langkah demi langkah Buka port forward TCP dengan koneksi SSH Anda

Pada mesin lokal Anda (lokal), sambungkan ke mesin yang jauh (server) oleh SSH, dengan opsi -L tambahan sehingga SSH dengan TCP port-forward:

local# ssh -L 6667:localhost:6667 server.foo.com

Ini akan memungkinkan koneksi TCP pada nomor port 6667 dari mesin lokal Anda untuk diteruskan ke nomor port 6667 di server.foo.com melalui saluran aman. Atur TCP ke UDP maju di server

Di server, kami membuka pendengar pada port TCP 6667 yang akan meneruskan data ke port UDP 53 dari IP yang ditentukan. Jika Anda ingin melakukan penerusan DNS seperti saya, Anda dapat mengambil IP server nama pertama yang akan Anda temukan di /etc/resolv.conf. Tapi pertama-tama, kita perlu membuat fifo. Fifo diperlukan untuk memiliki komunikasi dua arah antara dua saluran. Pipa shell sederhana hanya akan mengkomunikasikan input standar proses ke 'kiri untuk input kanan proses'.

server# mkfifo /tmp/fifo
server# nc -l -p 6667 < /tmp/fifo | nc -u 192.168.1.1 53 > /tmp/fifo

Ini akan memungkinkan lalu lintas TCP pada port server 6667 untuk diteruskan ke lalu lintas UDP pada port 192.168.1.1 di port 53, dan tanggapan untuk kembali. Siapkan UDP ke TCP ke depan pada mesin Anda

Sekarang, kita perlu melakukan kebalikan dari apa yang dilakukan di atas pada mesin lokal. Anda memerlukan akses khusus untuk mengikat port UDP 53.

local# mkfifo /tmp/fifo
local# sudo nc -l -u -p 53 < /tmp/fifo | nc localhost 6667 > /tmp/fifo

Ini akan memungkinkan lalu lintas UDP pada port mesin lokal 53 untuk diteruskan ke lalu lintas TCP pada port mesin lokal 6667. Nikmati server DNS lokal Anda :)

Seperti yang mungkin sudah Anda duga sekarang, ketika permintaan DNS akan dilakukan pada mesin lokal, misalnya pada port UDP lokal 53, itu akan diteruskan ke port TCP lokal 6667, kemudian ke port TCP server 6667, kemudian ke server DNS server , Port UDP 53 dari 192.168.1.1. Untuk menikmati layanan DNS di mesin lokal Anda, masukkan baris berikut sebagai server nama pertama di /etc/resolv.conf Anda:

nameserver 127.0.0.1
John T
sumber
28
Solusi ini tidak aman. Aliran TCP tidak dijamin untuk mempertahankan batas-batas pesan, sehingga datagram UDP tunggal dapat dibagi menjadi beberapa bagian, melanggar protokol apa pun.
Juho Östman
2
Bisa juga menyenangkan untuk menggunakan port 1153 bukannya 6667 (dari man SSH example), yang digunakan oleh IRC.
phil pirozhkov
1
@ JuhoÖstman Terima kasih telah menunjukkan jebakan ini. Menyadari masalah ... apakah Anda menjalankan solusi ACCOs? apakah pesan yang cukup kecil akan menjadi cara untuk membuatnya berfungsi?
humanityANDpeace
4
Solusinya adalah dengan menambahkan panjang ke setiap paket sebelum dikirim melalui aliran TCP, dan merekonstruksi paket asli dari itu. Akan mudah untuk menulis skrip C untuk melakukan itu, tetapi saya tidak yakin apakah ada solusi yang tersedia. Dalam praktiknya, TCP biasanya menjaga batas-batas pesan dalam kasus ini, tetapi kegagalan aneh dapat terjadi kapan saja.
Juho Östman
Saya menghadapi masalah lain dengan ini: pipa dan fifo buffered sehingga batas bingkai hilang. Begitu banyak frame UDP dapat digabungkan menjadi satu frame TCP.
Julio Guerra
26

Contoh ini (saya pikir jawaban John menunjukkan hal yang sama di tempat yang berbeda), menjelaskan cara mengakses layanan UDP / DNS mesin lain melalui koneksi TCP / SSH.

Kami akan meneruskan lalu lintas UDP / 53 lokal ke TCP, lalu lintas TCP dengan mekanisme port-forwarding SSH ke mesin lain, kemudian TCP ke UDP / 53 di ujung lainnya.
Biasanya, Anda bisa melakukannya dengan openvpn.
Tapi di sini, kita akan melakukannya dengan alat yang lebih sederhana, hanya openssh dan netcat.

Di akhir halaman itu, ada komentar lain dengan referensi ke ' socat',
Akses UDP / DNS yang sama dibuat dengan,

Sisi server: socat tcp4-listen:5353,reuseaddr,fork UDP:nameserver:53
Sisi klien:socat udp4-listen:53,reuseaddr,fork tcp:localhost:5353

Lihat contoh socat untuk informasi lebih lanjut.

nik
sumber
3
Yang ini tampaknya jauh lebih berguna bagi saya daripada jawaban yang diterima. Saya membutuhkan pengalihan searah aliran video (TS / UDP) ssh orig_strm_src socat udp4-listen:4003,reuseaddr,fork STDOUT| socat STDIN udp-sendto:localhost:4003
searah
FWIW, saya telah menulis panduan yang lebih rinci di halaman rumah saya yang menjelaskan cara mengatur socat atas SSH untuk penerusan UDP. Ini menggunakan SNMP sebagai contoh.
Peter V. Mørch
20

SSH (setidaknya OpenSSH) memiliki dukungan untuk VPN sederhana. Menggunakan opsi -watau Tunneldi sshklien, Anda dapat membuat tunperangkat di kedua ujungnya, yang dapat digunakan untuk meneruskan segala jenis lalu lintas IP. (Lihat juga Tunneldi halaman manual ssh_config(5).) Perhatikan bahwa ini membutuhkan OpenSSH (dan mungkin root privilege) di kedua ujungnya.

grawity
sumber
Ini membutuhkan hak akses root pada mesin jarak jauh bahkan untuk tunneling UDP port yang tidak diprivatisasi dan PermitRootLogin diatur ke tidak 'tidak'. Sangat buruk.
phil pirozhkov
@grawity Terima kasih telah menunjukkan opsi ini, yang meskipun ditunjukkan oleh philpirozhkov, login root yang diperlukan. Saya ingin tahu apakah ada cara untuk mengelabui agar tidak membutuhkan root?
humanityANDpeace
4
@humanityANDpeace: Anda dapat membuat perangkat tun / tap dan membuatnya milik pengguna tertentu, menggunakan ip tuntap add.
grawity
Hai kegembiraan. Saya suka solusi Anda tetapi tidak bisa membuatnya bekerja. Saya membuat tunperangkat sebagai berikut: sudo ip tuntap add mode tuntetapi ketika pernah menggunakan -wopsi seperti ini: ssh $Server -w $portSaya mengerti Tunnel device open failed. Could not request tunnel forwarding.Apa yang saya lakukan salah?
Lucas Aimaretto
16

Atau Anda bisa menggunakan ssf (yang dirancang untuk menangani use case ini), dengan perintah sederhana:


Sisi klien:

#>./ssfc -U 53:192.168.1.1:53 server.foo.com

Perintah ini mengalihkan port lokal 53 (dns) ke port 192.168.1.1 port 53, melalui terowongan aman antara localhost dan server.foo.com.


Anda memerlukan server ssf (bukan - atau di sebelah - server ssh Anda):

#>./ssfs

By the way, baik sisi klien dan server ssf bekerja pada Windows / Linux / Mac. Ini adalah aplikasi userland, jadi Anda tidak perlu tun / ketuk atau VPN.

Untuk mengarahkan ulang port 53, Anda akan memerlukan hak administratif - terlepas dari alat yang Anda gunakan.

Untuk info lebih lanjut, detail, gunakan case, atau unduh: https://securesocketfunneling.github.io/ssf/

ssf-pengembang
sumber
Harap berhati-hati menjawab dengan, "ini produk saya", ini adalah spam batas. Saya sarankan membaca dan mengikuti pedoman dari pusat bantuan .
heavyd
7
Paling-paling, ini adalah plug yang tidak tahu malu. Bagaimanapun solusinya mungkin sesuai dengan permintaan Anda. Omong-omong, SSF adalah OpenSource dan nirlaba.
ssf-developer
11
@heavyd: Jika dia memposting banyak skrip hack, itu bisa diterima, tetapi karena dia membuat alat open-source yang matang, bukan? Ini menjawab pertanyaan asli dengan sempurna.
Synthead
Saya harus mengakui bahwa ini adalah alat yang saya cari, walaupun itu adalah plug yang tidak tahu malu.
therealrootuser
9

Saya tidak dapat mulai ncbekerja untuk SNMP, karena klien SNMP terus memilih port UDP sumber baru, dan beberapa dapat aktif sekaligus.

Sebagai gantinya, saya telah menulis sebuah posting yang menjelaskan bagaimana melakukannya dengan socatdalam posting blog ini , menggunakan SNMP sebagai contoh. Intinya, menggunakan dua terminal, dimulai dengan tinjauan umum:

gambaran

Terminal satu:

client$ ssh -L 10000:localhost:10000 server
server$ socat -T10 TCP4-LISTEN:10000,fork UDP4:switch:161

Ini menciptakan penerusan SSH port TCP 10000 dan menjalankan socat di server. Perhatikan bagaimana alamat IP switch disebutkan dalam baris perintah socat sebagai "switch".

Terminal dua:

client$ sudo socat UDP4-LISTEN:161,fork TCP4:localhost:10000

Itu mengatur socat pada klien. Itu harus dilakukan.

Peter V. Mørch
sumber
ini bekerja untuk saya :)
Paul Fenney
4

VPN adalah solusi yang lebih baik jika Anda memiliki akses ke port UDP.

Jika Anda hanya memiliki akses ke port TCP SSH, maka terowongan SSH sama baiknya dengan VPN, setidaknya untuk ping dan backtracking paket.

Michael
sumber