Algoritma Pembentukan Koneksi SSH

(Judul awal artikel "Algoritma Operasi Protokol SSH" diubah sesuai dengan rekomendasi Vindicar , Karroplan , dan anggota komunitas habro lainnya)

Saat secara berkala membaca artikel tentang SSH, saya perhatikan bahwa penulisnya terkadang tidak tahu bagaimana protokol ini bekerja. Dalam kebanyakan kasus, mereka terbatas untuk mempertimbangkan topik pembuatan kunci dan menjelaskan opsi-opsi perintah utama. Bahkan administrator sistem yang berpengalaman sering mengambil omong kosong penuh ketika membahas masalah SSH, mengeluarkan opus dalam gaya: data yang dikirimkan dienkripsi dengan kunci SSH publik klien dan didekripsi dengan kunci pribadi, atau: algoritma RSA digunakan untuk mengenkripsi data selama transmisi.

Saya akan mencoba memberikan kejelasan pada pengoperasian protokol SSH, dan pada saat yang sama mempertimbangkan peran algoritma RSA dan kunci otorisasi pengguna ...

gambar

Algoritma protokol SSH dapat dibagi menjadi tiga tingkatan, yang masing-masing terletak di atas yang sebelumnya: transport (membuka saluran aman), otentikasi, koneksi. Demi integritas gambar, saya juga akan menambahkan tingkat pengaturan koneksi jaringan, meskipun secara resmi level ini di bawah SSH.

1. Buat koneksi TCP


Saya tidak akan membahas prinsip tumpukan TCP / IP, karena topik ini didokumentasikan dengan baik di Runet. Jika perlu, Anda dapat dengan mudah menemukan informasi.

Pada titik ini, klien terhubung ke server pada port TCP yang ditentukan dalam opsi Port (default: 22) di file konfigurasi server / etc / ssh / sshd_config.

2. Membuka saluran aman


2.1 Pertukaran Identitas

Setelah koneksi TCP dibuat, klien dan server (selanjutnya disebut sebagai pihak) bertukar versi protokol SSH dan data pendukung lainnya yang diperlukan untuk menentukan kompatibilitas protokol dan untuk memilih algoritma operasi.

2.2 Pilihan algoritma: pertukaran kunci, enkripsi, kompresi, dll.

SSH menggunakan cukup banyak algoritma, beberapa di antaranya digunakan untuk enkripsi, yang kedua untuk pertukaran kunci, yang ketiga untuk kompresi data yang dikirimkan, dll. Pada langkah ini, para pihak saling mengirim daftar algoritma yang didukung, algoritma di bagian atas setiap daftar memiliki prioritas tertinggi. Kemudian, algoritma dalam daftar yang diperoleh dibandingkan dengan algoritma yang tersedia dalam sistem, dan yang pertama cocok di setiap daftar dipilih.

Daftar algoritma pertukaran kunci sisi klien yang tersedia (digunakan untuk mendapatkan kunci sesi) dapat dilihat dengan perintah:

ssh -Q kex 

Daftar algoritma simetris yang tersedia di sistem (digunakan untuk enkripsi saluran):

 ssh -Q cipher 

Daftar jenis kunci untuk otorisasi di klien:

 ssh -Q key-cert 

Diperbarui oleh komentar onix74 :
Semua perintah yang digunakan dalam publikasi ini relevan untuk OpenSSH versi 7.6 dari Ubuntu 18.04 LTS.

2.3. Mendapatkan kunci enkripsi sesi

Proses mendapatkan kunci sesi mungkin berbeda tergantung pada versi algoritma, tetapi secara umum bermuara pada berikut ini:

  • Server mengirimkan kuncinya ke klien (DSA, RSA, dll., Sesuai dengan kesepakatan antara pihak-pihak yang diproduksi dalam klausa 2.2).
  • Jika klien terhubung ke server ini untuk pertama kalinya (seperti yang ditunjukkan oleh kurangnya entri dalam file /home/username/.ssh/known_hosts pada klien), pengguna akan ditanya tentang mempercayai kunci server. Jika koneksi dengan server ini telah dibuat sebelumnya, klien membandingkan kunci yang terkirim dengan kunci yang direkam di /home/username/.ssh/known_hosts. Jika kunci tidak cocok, maka pengguna akan menerima peringatan tentang kemungkinan upaya peretasan. Namun, Anda dapat melewati pemeriksaan ini jika Anda memanggil ssh dengan opsi StrictHostKeyChecking:
     ssh -o StrictHostKeyChecking=no username@servername 
    Juga, jika pengguna perlu menghapus kunci server lama (misalnya, ketika ada kepastian yang tepat bahwa kunci telah diubah pada server), maka perintah yang digunakan:
     ssh-keygen -R servername 

  • Setelah klien telah menentukan kepercayaan pada kunci server, menggunakan salah satu implementasi (versi didefinisikan dalam Bagian 2.2) dari algoritma Diffie-Hellman, klien dan server menghasilkan kunci sesi yang akan digunakan untuk enkripsi saluran simetris.

Kunci sesi dibuat secara eksklusif untuk masa pakai saluran dan dimusnahkan ketika koneksi ditutup.

3. Otentikasi Klien


Dan hanya sekarang, ketika klien dan server telah membentuk saluran untuk transmisi data terenkripsi, mereka dapat mengotentikasi dengan kata sandi atau kunci.

Secara umum, otentikasi kunci terjadi sebagai berikut:

  • Klien mengirimkan nama pengguna (nama pengguna) ke server dan kunci publiknya.
  • Server memeriksa file /home/username/.ssh/authorized_keys untuk kunci publik yang dikirim oleh klien. Jika kunci publik ditemukan, server menghasilkan nomor acak dan mengenkripsinya dengan kunci publik klien, setelah itu hasilnya dikirim ke klien.
  • Klien mendekripsi pesan dengan kunci privatnya dan mengirimkan hasilnya ke server.
  • Server memeriksa hasil untuk kecocokan dengan nomor yang awalnya dienkripsi dengan kunci publik klien, dan jika cocok, itu menganggap otentikasi berhasil.

4. Tingkat Koneksi


Setelah melakukan semua prosedur di atas, pengguna mendapat kesempatan untuk mengirim perintah ke server atau menyalin file.

Pada level ini, disediakan: perkalian saluran (kemampuan untuk mengoperasikan beberapa saluran ke satu server dengan menggabungkannya menjadi satu saluran), tunneling, dll.

Dari teori ke praktik


Nah, sekarang, saya pikir, para pembaca memiliki pertanyaan yang sepenuhnya logis: mengapa Anda perlu mengetahui semua detail protokol SSH ini, jika untuk pekerjaan sehari-hari ada cukup pengetahuan tentang perintah pembuatan kunci (ssh-keygen), membuka sesi terminal (ssh), transfer file ( scp)?

Sebagai jawaban, kita dapat mengingat topik tentang mengubah port SSH standar ke yang lain, yang terus-menerus menjadi penyebab holivar di Habr ...

Dalam praktik saya sendiri, saya tidak ingat satu server melihat jaringan eksternal yang tidak akan disadap setiap hari di port 22. Dalam situasi di mana SSH bekerja untuk Anda pada port standar (dan tidak dilindungi oleh apa pun), bahkan jika otentikasi dengan kunci dan tidak ada tebakan kata sandi menakutkan, maka karena terus-menerus berbohong permintaan dari klien yang tidak jujur, server masih dipaksa untuk melakukan banyak pekerjaan yang tidak berguna: membuat koneksi TCP, memilih algoritma, menghasilkan kunci sesi, mengirim permintaan otentikasi, menulis file log.

Dalam situasi di mana tidak ada apa-apa pada port ke-22, atau port tersebut dilindungi menggunakan iptables (atau add-on seperti fail2ban), penyerang akan jatuh pada tahap membangun koneksi TCP.

Terlihat paling menarik seperti tabel *
KonfigurasiPeluang PeretasanKerugian akibat banjir **
22 port
otorisasi kata sandi,
tanpa perlindungan
tinggitinggi
22 port
otorisasi kunci,
tanpa perlindungan
rata-rata ***tinggi
22 port
otorisasi kunci,
perlindungan berdasarkan pembatasan upaya otorisasi yang gagal
rendahsedang ****
Port non-standar,
otorisasi kata sandi,
tanpa perlindungan
tinggirendah
Port non-standar,
otorisasi kunci,
tanpa perlindungan
rata-rata ***rendah
Port non-standar,
otorisasi kunci,
perlindungan berdasarkan pembatasan upaya otorisasi yang gagal
rendahrendah

* - nilai parameter (tinggi, sedang, rendah) bersifat relatif dan hanya berfungsi untuk membandingkan indikator.
** - ini berarti konsumsi sumber daya server (prosesor, disk, saluran jaringan, dll.) untuk memproses longsoran permintaan yang biasanya masuk ke port 22.
*** - meretas jika kunci RSA digunakan untuk otorisasi sangat sulit, tetapi upaya otorisasi dalam jumlah tak terbatas memungkinkan hal ini.
**** - jumlah upaya otorisasi terbatas, tetapi server masih harus memprosesnya dari sejumlah besar penyusup.

Bahan tambahan


Source: https://habr.com/ru/post/id425637/


All Articles