Port forwarding menjadikan koneksi SSH sebagai terowongan (tunnel) bagi koneksi TCP lain, sehingga layanan yang tidak diekspos ke jaringan tetap dapat dijangkau dari mesin lokal. Topik ini membahas pembuatan tunnel lokal dengan opsi -L, arah sebaliknya dengan -R, proxy dinamis dengan -D, beserta kesalahan yang lazim ditemui ketika tunnel tidak berjalan.
Konsep tunnel SSH#
Selain sesi terminal, koneksi SSH dapat mengangkut koneksi TCP lain di dalam kanal terenkripsinya. Pada tunnel lokal (local forwarding), klien ssh membuka port di mesin lokal, dan setiap koneksi yang masuk ke port itu diteruskan melalui tunnel menuju tujuan yang dijangkau dari sisi server. Tujuannya tidak harus mesin server itu sendiri, melainkan apa pun yang dapat dijangkau dari server, termasuk layanan pada jaringan privat di belakangnya.
Kegunaan khasnya adalah menjangkau layanan yang sengaja tidak dibuka ke publik. Aplikasi web di server misalnya dapat dikonfigurasi untuk hanya mendengarkan pada localhost:3000, sehingga tidak bisa dibuka dari luar, tetapi tetap bisa dijelajahi dari mesin lokal melalui tunnel. Diagram berikut mengikuti perjalanan satu permintaan pada susunan semacam itu.
Cakupan tunnel ini sebatas port-port yang dideklarasikan pada opsi, sehingga tunnel bukan pengganti VPN yang meneruskan seluruh lalu lintas jaringan. Kelebihannya justru pada keterbatasan itu, karena port yang dibuka hanya sedikit, seluruhnya tercatat jelas pada perintahnya, dan hilang begitu proses ssh-nya diakhiri.
Membuat tunnel dengan -L#
Bentuk opsi -L adalah -L port-lokal:tujuan:port-tujuan, dan perintah lengkapnya ditulis seperti berikut.
# tidak-dijalankan
# klien ssh tidak terpasang di sandbox, sehingga tunnel dicoba pada mesin dengan OpenSSH
# membuka localhost:8080 di mesin lokal menuju localhost:3000 di sisi server
ssh -L 8080:localhost:3000 [email protected] -NAngka 8080 adalah port yang dibuka di mesin lokal, sedangkan localhost:3000 dinilai dari sisi server, sehingga yang dimaksud adalah port 3000 pada server itu sendiri. Opsi -N menyatakan bahwa sesi ini tidak menjalankan perintah jarak jauh apa pun, sehingga tidak ada prompt terminal yang terbuka dan tunnel berhenti segera setelah Ctrl-C ditekan. Selama proses ssh itu berjalan, browser yang membuka http://localhost:8080 sebenarnya sedang terhubung ke aplikasi di server.
# tidak-dijalankan
# dijalankan pada terminal lain selama sesi tunnel masih terbuka
curl -I http://localhost:8080Klien mengikat port lokal pada 127.0.0.1 secara default, sehingga tunnel hanya dapat dipakai dari mesin yang sama. Menuliskan bind address secara eksplisit seperti -L 0.0.0.0:8080:localhost:3000 membuka tunnel bagi mesin lain di jaringan, dan keputusan semacam itu harus disertai kesadaran bahwa semua orang di jaringan tersebut ikut mendapat jalan masuk. Opsi -f menempatkan proses ssh ke latar belakang setelah autentikasi, sehingga tunnel dapat berjalan tanpa menempati terminal.
Satu koneksi boleh membawa beberapa tunnel sekaligus dengan menuliskan opsi -L berulang, misalnya untuk membuka aplikasi web dan basis data dalam satu login.
# tidak-dijalankan
# dua tunnel pada satu koneksi: aplikasi web dan basis data
ssh -L 8080:localhost:3000 -L 5433:localhost:5432 [email protected] -NSetiap port lokal yang dibuka tunduk pada aturan bind address yang sama, dan seluruhnya berhenti bersamaan ketika proses ssh diakhiri.
Arah sebaliknya dan proxy dinamis#
Opsi -R membalik arah, yaitu klien meminta server membuka port, dan koneksi yang masuk ke port tersebut diteruskan menuju tujuan di sisi klien. Bentuk ini dipakai untuk memperlihatkan layanan mesin lokal kepada server, misalnya ketika aplikasi yang sedang dikembangkan perlu dijangkau oleh layanan webhook yang hanya menjangkau server. Secara default, port yang dibuka -R di sisi server terikat pada 127.0.0.1 server itu sendiri, sehingga hanya dapat diakses dari server tersebut. Membukanya bagi pihak lain menuntut opsi GatewayPorts pada sshd. Opsi -D membuka proxy SOCKS lokal yang merutekan koneksi sesuai permintaan aplikasi, bukan menuju satu tujuan tetap. Opsi -N dan -f bekerja dengan cara yang sama pada ketiganya, sehingga pola penggunaan dan pengakhirannya tidak perlu dipelajari ulang.
| Opsi | Port dibuka di | Tujuan dinilai dari | Kegunaan khas |
|---|---|---|---|
-L | mesin lokal | sisi server | menjangkau layanan yang tidak diekspos |
-R | server | sisi klien | memperlihatkan layanan lokal ke server |
-D | mesin lokal | sesuai permintaan aplikasi | proxy SOCKS untuk banyak tujuan |
# tidak-dijalankan
# memperlihatkan localhost:8000 mesin lokal sebagai localhost:9000 di server
ssh -R 9000:localhost:8000 [email protected] -N
# membuka proxy SOCKS pada port 1080 mesin lokal
ssh -D 1080 [email protected] -NKesalahan umum#
- Memilih port lokal yang sudah dipakai. Klien melaporkan
bind [127.0.0.1]:8080: Address already in usedan tunnel tidak terbentuk, sehingga solusinya adalah memilih port lain atau menghentikan proses yang memakainya. - Mengira
localhostpada-L 8080:localhost:3000berarti mesin lokal. Bagian tujuan selalu dinilai dari sisi server, sehingga layanan yang dituju harus benar-benar berjalan di server. - Mengira tunnel tetap hidup setelah sesi ditutup. Tunnel berjalan selama proses ssh-nya berjalan, dan
-fhanya memindahkannya ke latar belakang, bukan memisahkannya dari sesi. - Menyalahkan firewall ketika halaman tidak terbuka. Apabila port lokal sudah terbuka tetapi halaman gagal dimuat, periksa dahulu apakah layanan di server memang berjalan dan mendengarkan pada port yang dituju.
- Kehilangan jejak proses tunnel latar belakang. Proses yang diluncurkan dengan
-ftidak meninggalkan jendela terminal, sehingga pencariannya memakaipgrep -af 'ssh -L'dan pengakhirannya memakaikillatas PID yang ditemukan.
Ringkasan#
ssh -L 8080:localhost:3000 server -Nmeneruskan koneksi lokal menuju tujuan yang dinilai dari sisi server, di dalam satu kanal terenkripsi.- Tujuan tunnel boleh berupa mesin lain yang dijangkau server, dan bind address default
127.0.0.1menjaga tunnel tetap lokal. - Opsi
-Rmembalik arah untuk memperlihatkan layanan lokal ke server, sedangkan-Dmembuka proxy SOCKS. - Tunnel berhenti ketika proses ssh-nya dihentikan, dan opsi
-fmemindahkannya ke latar belakang.
Referensi#
- ssh(1) — OpenBSD — Opsi -L, -R, -D, -N, dan -f beserta format penentuan tujuan.
- OpenSSH manual — OpenSSH — Halaman manual resmi proyek OpenSSH untuk klien dan server.