6 poin oleh GN⁺ 2024-09-20 | 1 komentar | Bagikan ke WhatsApp
  • SSH tunneling membawa trafik TCP melalui koneksi SSH yang aman, sehingga berguna untuk membuka jalur terbatas secara aman seperti enkripsi protokol lama, akses panel manajemen, atau koneksi ke server di balik NAT
  • Di sisi server, AllowTcpForwarding yes diperlukan, dan untuk membuka port pada antarmuka selain loopback diperlukan konfigurasi GatewayPorts yes serta restart server SSH
  • ssh -J, ssh -L, ssh -R, ssh -D masing-masing menangani jump host, local forwarding, remote forwarding, dan dynamic forwarding berbasis SOCKS5
  • Untuk menjaga tunnel tetap berjalan di latar belakang, gunakan ssh -fN, dan deteksi putusnya koneksi dapat diatur dengan pengaturan heartbeat seperti ClientAliveInterval dan ClientAliveCountMax
  • SSH tunneling tidak mendukung UDP secara langsung dan dapat mengalami masalah latensi serta throughput pada TCP-over-TCP, sehingga lebih dekat sebagai alat untuk membuka jalur TCP tertentu daripada pengganti VPN

Situasi untuk menggunakan SSH tunneling

  • SSH tunneling dan port forwarding meneruskan trafik TCP melalui koneksi SSH dari klien ke server, atau dari server ke klien
  • Port TCP dan soket UNIX dapat digunakan, tetapi contoh berfokus pada port TCP
  • Pola penggunaan utamanya terbagi menjadi keamanan, pemecahan masalah, dan konektivitas
    • Keamanan
      • Mengenkripsi koneksi tidak aman atau protokol lama seperti FTP
      • Mengakses panel manajemen web melalui tunnel SSH berbasis autentikasi kunci publik
      • Hanya perlu membuka port 22 tanpa mengekspos port tambahan seperti 80/443
    • Pemecahan masalah
      • Melewati firewall atau filter konten
      • Memilih jalur jaringan yang berbeda
    • Konektivitas
      • Mengakses server yang berada di balik NAT
      • Masuk dari internet ke server internal melalui jump host
      • Mengekspos port lokal ke internet

Pengaturan yang perlu dicek sebelum port forwarding

  • Opsi pada contoh dapat dikombinasikan sesuai lingkungan
  • Jika bind_address tidak ditentukan, nilai default-nya adalah localhost
  • Pengguna lokal dan remote masing-masing memerlukan izin untuk membuka port pada mesinnya
    • Port 0-1024 memerlukan hak root kecuali ada konfigurasi khusus
    • Port lainnya dapat dikonfigurasi oleh pengguna biasa
    • Firewall klien dan jaringan juga harus dibuka sesuai jalur forwarding
  • Di server SSH, port forwarding harus diaktifkan
    • AllowTcpForwarding yes
    • Sering kali sudah aktif secara default, tetapi konfigurasi server tetap perlu dicek
  • Untuk meneruskan port ke antarmuka selain 127.0.0.1, aktifkan GatewayPorts di server SSH
    • GatewayPorts yes
    • Setelah itu, layanan server SSH perlu direstart

SSH jump host dan tunnel bertingkat

  • ssh -J digunakan untuk terhubung secara transparan ke host remote melalui satu atau lebih host perantara
ssh -J user@REMOTE-MACHINE:22 -p 22 user@10.99.99.1
  • Jika menggunakan port default 22, penulisan port dapat dihilangkan
  • Jika REMOTE-MACHINE digunakan sebagai jump host, koneksi akan terlihat seperti berikut
[user@REMOTE-MACHINE]$ ss | grep -i ssh
tcp ESTAB 0 0 167.135.173.108:ssh 192.160.140.207:45960
tcp ESTAB 0 0 10.99.99.2:49770 10.99.99.1:ssh
  • Peran alamat pada contoh adalah sebagai berikut
    • 167.135.173.108: IP publik REMOTE-MACHINE
    • 192.160.140.207: IP publik LOCAL-MACHINE
    • 10.99.99.2: IP internal REMOTE-MACHINE
    • 10.99.99.1: IP internal REMOTE-WEBAPP
  • Saat menggunakan beberapa jump host, pisahkan dengan koma
ssh -J user@REMOTE-MACHINE:22,user@ANOTHER-REMOTE-MACHINE:22 -p 22 user@10.99.99.1

Local port forwarding

  • Local port forwarding menggunakan opsi ssh -L
  • Contoh pertama meneruskan 10.10.10.1:8001 pada LOCAL-MACHINE ke localhost:8000 pada REMOTE-MACHINE
ssh -L 10.10.10.1:8001:localhost:8000 user@REMOTE-MACHINE
  • Log akses web server yang hanya bind ke 127.0.0.1 di REMOTE-MACHINE akan terlihat seperti berikut
127.0.0.1 - - [30/Dec/2022 18:05:15] "GET / HTTP/1.1" 200
  • Permintaan ini berasal dari LOCAL-MACHINE
  • Contoh kedua meneruskan 8001 lokal ke 10.99.99.1:8000 melalui REMOTE-MACHINE
ssh -L 8001:10.99.99.1:8000 user@REMOTE-MACHINE
  • Pada log akses web server REMOTE-WEBAPP, permintaan akan tercatat sebagai berasal dari IP internal REMOTE-MACHINE
10.99.99.2 - - [30/Dec/2022 21:28:42] "GET / HTTP/1.1" 200

Remote port forwarding

  • Remote port forwarding menggunakan opsi ssh -R
  • Contohnya meneruskan 8000 pada REMOTE-MACHINE ke localhost:8001 atau 10.10.10.2:8001 di sisi lokal
ssh -R 8000:localhost:8001 user@REMOTE-MACHINE
ssh -R 8000:10.10.10.2:8001 user@REMOTE-MACHINE
  • Dapat juga diatur agar menerima pada antarmuka remote tertentu, yaitu 10.99.99.2:8000
ssh -R 10.99.99.2:8000:10.10.10.2:8001 user@REMOTE-MACHINE
  • Untuk menerima koneksi dari antarmuka selain loopback, GatewayPorts yes harus diaktifkan di server SSH

Dynamic port forwarding dan SOCKS5

  • Saat meneruskan beberapa port, SSH menggunakan protokol SOCKS
  • SOCKS adalah protokol proxy transparan, dan SSH menggunakan versi terbarunya, yaitu SOCKS5
  • Port default server SOCKS5 adalah 1080 seperti didefinisikan dalam RFC 1928
  • Klien harus dikonfigurasi untuk menggunakan proxy SOCKS di lapisan aplikasi atau lapisan OS
  • Contoh ssh -D membuka proxy SOCKS di 10.10.10.1:5555
ssh -D 10.10.10.1:5555 user@REMOTE-MACHINE
  • Pada klien LOCAL, jalur koneksi dapat diuji dengan curl
curl -L -x socks5://10.10.10.1:5555 brrl.net/ip
  • Jika berjalan normal, IP publik REMOTE-MACHINE akan dikembalikan

SSH TUN/TAP tunneling

  • Flag -w dapat digunakan untuk membuat tunnel dua arah
  • Antarmuka harus dibuat terlebih dahulu
  • Ada caveat bahwa metode ini belum diuji
-w local_tun[:remote_tun]

Menjalankan di latar belakang dan menghentikan

  • Untuk menjalankan tunnel di latar belakang secara native, gunakan -fN
    • -f: jalankan di latar belakang
    • -N: tidak membuka shell
ssh -fN -L 8001:127.0.0.1:8000 user@REMOTE-MACHINE
  • Selain itu, screen atau alat lain juga dapat digunakan
  • SSH yang berjalan di latar belakang dapat dihentikan dengan mencari prosesnya lalu mengakhiri berdasarkan PID
user@pleasejustwork:~$ ps -ef | grep ssh
[...]
user 19255 1 0 11:40 ? 00:00:00 ssh -fN -L 8001:127.0.0.1:8000 user@REMOTE-MACHINE
[...]
kill 19255

Menjaga koneksi SSH tetap aktif dan reconnect

  • Ada beberapa cara untuk menjaga koneksi SSH tetap aktif
  • Opsi heartbeat untuk penanganan timeout dapat diatur di klien, server, atau keduanya
  • ClientAliveInterval mengirim permintaan setiap n detik untuk menjaga koneksi tetap hidup
ClientAliveInterval 15
  • ClientAliveCountMax adalah jumlah permintaan heartbeat yang dikirim sebelum koneksi ditutup saat tidak ada respons dari sisi lain
ClientAliveCountMax 3
  • 3 adalah nilai default, dan jika diatur ke 0 maka penutupan koneksi dinonaktifkan
  • Dalam contoh pengaturan ini, koneksi akan terputus setelah sekitar 45 detik jika tidak ada respons
  • Untuk reconnect setelah koneksi terputus, dapat digunakan autossh, skrip, cronjob, dan sebagainya

Batasan dan perhatian keamanan

  • UDP

    • SSH bergantung pada pengiriman yang andal agar dekripsi dapat berjalan dengan benar
    • UDP tidak menyediakan keandalan, sehingga tidak didukung dan tidak direkomendasikan dalam tunnel SSH
    • Ada metode yang membahas UDP over SSH tunneling, tetapi disertai caveat bahwa metode tersebut belum diuji
  • TCP-over-TCP

    • Karena overhead, throughput menurun dan latensi meningkat
    • Pada koneksi dengan packet loss atau latensi tinggi, TCP meltdown dapat terjadi
    • Lihat juga artikel tentang TCP over TCP
    • Saat menggunakan OpenVPN-over-TCP untuk некоторое время, throughput lebih rendah dibanding UDP tetapi tetap berjalan stabil, dan hasilnya sangat bergantung pada konfigurasi
  • Keterbatasan sebagai pengganti VPN

    • SSH tunneling bisa digunakan seperti VPN, tetapi VPN lebih cocok untuk performa yang lebih baik
  • Risiko keamanan

    • Jika fitur ini tidak diperlukan, disarankan untuk menonaktifkannya
    • Penyerang dapat menggunakan SSH tunneling dan port forwarding untuk menghindari firewall serta mekanisme keamanan lain
  • Referensi

1 komentar

 
GN⁺ 2024-09-20
Komentar Hacker News
  • Pada 2024, daripada menulis perintah SSH yang panjang secara langsung, lebih baik mengatur LocalForward, RemoteForward, dan ProxyJump di ~/.ssh/config
    Ini sangat menghemat waktu saat mengakses server jarak jauh yang harus melewati beberapa koneksi SSH perantara dengan ssh, scp, atau rsync
    Misalnya, cukup rangkai jump-host-1, jump-host-2, jump-host-3 dengan ProxyJump, lalu masuk ke target-server menggunakan alias
    LocalForward 0.0.0.0:8080 0.0.0.0:80 meneruskan port 80 di remote ke 8080 lokal, sedangkan RemoteForward 0.0.0.0:9022 0.0.0.0:22 meneruskan permintaan SSH yang masuk ke 9022 di remote ke port 22 lokal
    Untuk LocalForward dan RemoteForward, sisi kiri adalah server tujuan dan sisi kanan adalah lokal; ada juga tip untuk memakai 0.0.0.0 alih-alih localhost atau 127.0.0.1

    • Berbagi tip ssh_config: untuk di dalam rumah atau VPN self-hosted, konfigurasi yang berguna adalah SSH langsung ke tiap perangkat, sedangkan saat di luar otomatis dialihkan melalui jump host
      Dengan Match host *.example.org exec "getent ahosts router.example.org | grep -q ^10.0.0.1", misalnya, deteksi dulu apakah sedang di rumah/VPN dari alamat router, lalu dengan arp bisa dibuat agar memakai ProxyJump jump.example.org jika alamat MAC tidak sesuai nilai yang diharapkan
      Urutan penting: deteksi jaringan VPN/rumah harus dilakukan lebih dulu, lalu terapkan jump host ketika berada di luar
    • Kadang pekerjaan hanya sekali pakai, jadi tidak selalu ingin sampai membuat file konfigurasi
      Jika membuat VPS jangka pendek untuk dipakai sebagai proksi SOCKS lewat SSH demi melewati pembatasan wilayah, atau harus sekali masuk ke server yang biasanya tidak diakses untuk sementara membantu tim lain, opsi command-line rasanya lebih baik
    • Memakai 0.0.0.0 bisa berbahaya
      Itu bisa membuka port di semua antarmuka jaringan, dan terutama jika server remote tidak punya firewall, Anda bisa saja mengekspos sesuatu ke seluruh internet
      Untuk tunneling atau port forwarding yang sering dipakai, file konfigurasi memang bagus, tetapi untuk tugas sekali pakai atau jarang dilakukan, opsi command-line rasanya lebih baik
    • Penasaran bagaimana orang mengelola konfigurasi SSH seperti ini jika ingin menstandarkannya dan menyebarkannya ke beberapa mesin lokal
      Mencari solusi mirip GitOps yang cocok untuk satu pengguna/banyak mesin, tanpa perlu selalu menyalakan server terpisah, dan bisa mengambil konfigurasi dari tempat seperti GitHub
    • Karena tidak selalu ingin shell terbuka, saya membuat fungsi bash/fish dasar agar hanya perlu mengingat argumen seminimal mungkin
      Kalau lupa, tinggal lihat definisi fungsi yang sudah didokumentasikan
  • Di lingkungan perusahaan absurd tempat saya bekerja, SSH tunneling itu wajib
    Karena birokrasi, mendapatkan hak akses, membuka port, atau memperoleh pengecualian firewall/VPN kadang butuh berminggu-minggu
    Artikel ini menyebut -D, tetapi tidak cukup menjelaskan kekuatannya
    Jika menjalankan ssh -D 8888 someserver lalu mengatur proksi SOCKS browser ke localhost:8888, seluruh trafik browser akan dirutekan lewat someserver
    Firefox masih sangat berguna karena pengaturan ini bisa dilakukan tanpa mengubah default sistem

    • Pada pertengahan 2000-an, cara itu hampir menjadi standar ketika browsing web dari luar rumah
      Namun setelah masuk perusahaan, karena daftar izin IP, saya bahkan tidak bisa membuat koneksi SSH ke server sembarang di internet; saking tersiksanya, saya sempat mencari cara membuat tunnel HTTP dan memasukkan server yang saya kendalikan ke daftar izin, tetapi akhirnya pindah kerja
    • Melewati jaringan perusahaan bukan ide bagus
      Pembatasan seperti itu ada alasannya, dan upaya bypass bisa terlihat sebagai kurangnya keahlian serta pengabaian terhadap prosedur dan keamanan organisasi
      Jika mendapatkan akses butuh berminggu-minggu atau berbulan-bulan, ya harus menunggu; Anda tentu tidak ingin bertanggung jawab karena membuka backdoor ke informasi rahasia atau melemahkan keamanan
  • Peretasan SSH tunneling paling kotor yang pernah saya lakukan pukul 3 pagi adalah pekerjaan menghubungkan tiga data center
    Tiga fasilitas di area metropolitan yang sama terhubung ke jaringan backbone internet, tetapi karena kebijakan routing yang aneh, A hanya bisa terhubung ke B, dan hanya B yang bisa terhubung ke C
    Pada akhirnya, untuk memindahkan data A ke C lewat B, saya harus mencampuradukkan rsync + tunnel SSH + key + trik routing; setelah beberapa kali memperbaiki perintah yang seperti mantra, melihat semuanya bergerak sekaligus terasa seperti sihir
    Sekarang rasanya sangat jelas bagaimana melakukannya, tetapi sebagai pemula saat itu, itu pencapaian besar, dan saya masih ingat sensasi ketika memastikan sinkronisasi selesai

    • Dengan ~/.ssh/config dan ProxyJump, pada dasarnya Anda bisa melompat melalui berapa pun tahap seperti A, B, C, D, E
  • Detail visualisasinya bagus
    Khusus untuk networking, saya berharap ada jauh lebih banyak alat yang merepresentasikan trafik secara visual, terutama pada koneksi level yang lebih rendah

  • Jika server Linux atau perangkat IoT berada di balik firewall dan tidak punya IP statis, tetapi Anda ingin mengaksesnya lewat SSH, Anda bisa memakai layanan tunneling seperti https://sshreach.me

  • Saya sudah cukup banyak memakai tunneling selama beberapa tahun, tetapi tidak tahu opsi -J
    Daripada menghabiskan 30 menit mengatur setiap kali butuh tunnel beberapa bulan sekali, saya berharap ada alat visual untuk menyusun tunnel

  • Ada penjelasan bahwa TCP-over-TCP menambah overhead sehingga menurunkan throughput dan meningkatkan latensi, serta dapat menyebabkan TCP meltdown pada koneksi dengan latensi tinggi seperti ketika terjadi packet loss atau jaringan satelit
    Namun, pada tunnel SSH, hal ini sebenarnya tidak menjadi masalah selama tidak memakai TAP/TUN
    Sebab SSH membongkar stream TCP lalu meneruskannya
    Meski begitu, saat memakai beberapa channel, performa bisa turun karena head-of-line blocking

  • Sekitar 15 tahun lalu, saya belajar tunnel SSH untuk melewati firewall jaringan kampus, dan harus mengganti port default ke 443
    Sejak itu, saya terus memakainya untuk jauh lebih banyak keperluan daripada sekadar melewati firewall

    • Saya penasaran, selain melewati firewall atau mengekspos layanan lokal ke luar jaringan, untuk penggunaan apa saja Anda merasa ini berguna/menarik?
  • Jika mencoba sshuttle, tunneling menjadi jauh lebih praktis
    Dengan penggunaan seperti sshuttle -r user@host 10.0.0.0/8, rentang 10/8 akan otomatis ditunnelkan, dan pada dasarnya bekerja seperti VPN di atas SSH

  • Saya penasaran apakah SSH sendiri punya fitur redirect
    Misalnya, ketika A hendak SSH ke B, B memberi tahu agar terhubung ke C, lalu A secara transparan terhubung langsung ke C, dan B tidak lagi berada di jalur data utama

    • Sepertinya hal serupa bisa dilakukan dengan IP virtual
      Firewall/router saya tidak meneruskan DHCP option 67 dengan benar dan selalu mengirim alamatnya sendiri, jadi saya harus mengatur IP virtual/aturan agar traffic boot PXE pada port tersebut, ketika menuju IP router, diroutingkan ke server boot PXE yang sebenarnya
    • Jika A tidak tahu bahwa target sebenarnya adalah C, ini bisa menyesatkan
      Jika tidak demikian, gunakan saja fitur jump: ssh -J B C
      Jika B tidak perlu berada di jalur dan C bisa dihubungi langsung, cukup hubungi C secara langsung; jika itu tidak bisa, bagaimanapun B harus masuk sebagai hop
    • B bisa saja melakukan port forwarding ke C, yaitu merutekan paket, tetapi tampaknya tidak ada fitur setara seperti redirect permanen pada HTTP
      Jika masalahnya dijelaskan lebih lanjut, mungkin ada solusi yang lebih cocok
      Untuk host yang sampai tingkat tertentu bersifat embedded, DNS bisa dibuat mengambil peran “routing”, tetapi dalam kasus ini verifikasi sidik jari host key harus ditangani sendiri