SSH publik melalui relai gagal pada dua batas yang tidak terkait, dan memperbaiki yang satu biasanya mengungkap yang lain. Tepi mengembalikan respons HTTP alih-alih membawa aliran, atau relai menambahkan header di depan yang tidak pernah setuju dibaca oleh backend. Tiga kondisi menentukan mana yang Anda lihat: ke mana catatan publik sebenarnya menunjuk, apa yang dikirim blok aliran ke hulu, dan nama mana yang diverifikasi klien SSH. Kerjakan dalam urutan itu.

Dua batas, dua gejala

Kegagalan di tepi tampak seperti halaman status HTTP yang tiba di tempat banner SSH seharusnya berada. Koneksi selesai di tingkat TCP dan byte pertama adalah teks milik server web. Itu ketidakcocokan protokol, bukan paket hilang. Itu juga memberi tahu Anda bahwa tepi sengaja melayani hal lain untuk nama itu.

Kegagalan di hulu terlihat berbeda. Koneksi mencapai sshd, sshd membaca byte yang bukan pertukaran identifikasi yang diharapkannya, dan sesi mati atau menggantung tanpa pernah menawarkan kunci.

Keduanya mudah tertukar karena keduanya menghasilkan klien yang terhubung lalu gagal. Respons protokol pertama yang Anda terima adalah yang membedakannya, karena itu ia masuk ke tiket.

Header PROXY adalah pesan, bukan sakelar

Di modul aliran, proxy_protocol on memerintahkan NGINX menulis header protokol PROXY ke arah hulu sebelum muatan. Itu tidak mengaktifkan proksi TCP, dan tidak ada hubungannya dengan enkripsi SSH. Itu adalah catatan yang ditujukan kepada penerima. Jika penerima tidak dapat membacanya, ia menjadi serpihan di awal aliran.

Layanan penerima harus mengonsumsi header itu dengan sengaja. sshd normal mengharapkan pertukaran identifikasi SSH sebagai byte pertama pada koneksi, jadi pembukaan tak terduga merusak jabat tangan dengan cara yang tampak seperti server rusak.

stream {
    server {
        listen 2222;
        proxy_pass 10.77.0.20:22;
    }
}

Fragmen itu adalah keseluruhan relai yang berfungsi untuk backend yang dapat dijangkau melalui VPN. Tidak ada direktif PROXY yang muncul karena penerima tidak berbicara protokol itu, dan ketiadaan itu adalah keputusan, bukan kelalaian.

Pisahkan juga kedua arah. Menyetel proxy_protocol pada baris listen berarti NGINX mengharapkan kliennya sendiri mengirim header lebih dulu; mengaktifkannya untuk klien SSH biasa menghasilkan persis kebalikan dari masalah yang biasanya dicoba dipecahkan orang.

Apa yang sebenarnya dicapai nama host publik

Halaman HTTP 400 dalam sesi SSH adalah bukti tentang tepi. Sesuatu di jalur berbicara HTTP, dan tidak ada pekerjaan kunci atau akun di backend yang akan mengubahnya. Berhenti mengubah backend sampai tepi dibereskan.

Catatan terproksikan biasa Cloudflare membawa lalu lintas HTTP dan HTTPS yang didukungnya pada port yang ditentukan. Mengaktifkan proksi untuk nama host tidak membuat relai TCP umum, dan memindahkan SSH ke port 443 tidak membuatnya menjadi HTTPS.

Ada dua arah yang bisa dikerjakan. Catatan khusus DNS dapat menunjuk ke relai TCP Anda sendiri, yang menaruh keputusan paparan di tangan Anda. Sebagai alternatif, gunakan produk yang secara eksplisit mendokumentasikan pengangkutan SSH, dengan konfigurasi asal, klien, dan aksesnya sendiri.

Apa pun yang Anda pilih, relai tetap membutuhkan rute VPN ke backend, koneksi yang diizinkan, dan jalur kembali. Rute itu bukan opsional karena sisi publik berfungsi.

Jaga identitas SSH stabil melalui alias

Pengguna biasanya ingin terus mengetik nama host yang ada. Alias konfigurasi SSH dapat melakukannya tanpa mengubah apa pun pada relai, dan menjaga perubahan tetap di sisi klien tempat ia seharusnya.

Host git.example.com
    HostName ssh-entry.example.net
    Port 2222
    User git
    HostKeyAlias git.example.com

Tanpa HostKeyAlias, OpenSSH mencari kunci host dengan nama yang menjadi tujuannya, sehingga entri berpindah dan setiap pengguna melihat peringatan kunci berubah saat pertama kali digunakan. Menyetel alias menjaga entri known-hosts tetap stabil sementara koneksi tetap menuju relai.

Alias ini hanya berlaku untuk remote berbasis SSH. URL Git HTTPS tidak mengonsultasikannya, dan URL remote tipikal harus cocok dengan transport yang benar-benar Anda sediakan.

Yang tidak boleh Anda lakukan adalah menonaktifkan verifikasi kunci host agar peringatan hilang. Itu menghapus perlindungan yang tidak pernah diminta disentuh oleh perbaikan penerusan, dan mengubah gangguan kosmetik menjadi paparan nyata.

Verifikasi setiap lompatan secara terpisah

Uji pendengar publik sendirian, lalu koneksi relai ke backend dari host relai, dan baru setelah itu klien dari ujung ke ujung. Masing-masing dari ketiga uji itu menyingkirkan lapisan yang berbeda. Melewatkan satu berarti dua hasil yang tersisa tidak dapat ditafsirkan. Tiga pengamatan, tiga tempat kegagalan bisa hidup.

Simpan alamat tujuan, port, dan byte protokol pertama bersama setiap hasil. Trio itu membedakan kesalahan tepi dari masalah perutean VPN dan dari kegagalan autentikasi SSH, dan itulah perbedaan antara perbaikan dan dugaan.

Akhirnya, dokumentasikan paparan yang dimaksudkan. Relai TCP yang membawa SSH ke backend pribadi adalah pembukaan yang disengaja di perimeter publik, dan ia layak mendapat tinjauan yang sama seperti layanan masuk lainnya.

Artikel terkait