ProHoster > blog > administrasi > Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sertifikat klien dengan soket web
Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sertifikat klien dengan soket web
Artikel ini akan bermanfaat bagi mereka yang:
mengetahui apa itu Sertifikat Klien dan memahami mengapa ia memerlukan soket web di Safari seluler;
Saya ingin mempublikasikan layanan web ke kalangan terbatas atau hanya untuk diri saya sendiri;
berpikir bahwa semuanya telah dilakukan oleh seseorang, dan ingin membuat dunia menjadi lebih nyaman dan aman.
Sejarah websockets dimulai sekitar 8 tahun yang lalu. Sebelumnya, metode yang digunakan dalam bentuk permintaan http panjang (sebenarnya respons): browser pengguna mengirim permintaan ke server dan menunggu untuk menjawab sesuatu, setelah respons terhubung kembali dan menunggu. Tapi kemudian soket web muncul.
Beberapa tahun yang lalu, kami mengembangkan implementasi kami sendiri dalam PHP murni, yang tidak dapat menggunakan permintaan https, karena ini adalah lapisan tautan. Belum lama ini, hampir semua server web mempelajari permintaan proxy melalui https dan mendukung koneksi: peningkatan.
Ketika ini terjadi, websockets hampir menjadi layanan default untuk aplikasi SPA, karena betapa nyamannya menyediakan konten kepada pengguna atas inisiatif server (mengirimkan pesan dari pengguna lain atau mengunduh versi baru dari gambar, dokumen, presentasi yang sedang diedit orang lain).
Meskipun Sertifikat Klien telah ada selama beberapa waktu, namun dukungannya masih kurang, karena menimbulkan banyak masalah saat mencoba melewatinya. Dan (mungkin :slightly_smiling_face: ) itulah sebabnya browser iOS (semua kecuali Safari) tidak ingin menggunakannya dan memintanya dari toko sertifikat lokal. Sertifikat memiliki banyak keunggulan dibandingkan dengan kunci login/pass atau ssh atau menutup port yang diperlukan melalui firewall. Tapi masalahnya bukan itu.
Di iOS, prosedur pemasangan sertifikat cukup sederhana (bukan tanpa spesifik), tetapi secara umum dilakukan sesuai petunjuk, yang banyak terdapat di Internet dan hanya tersedia untuk browser Safari. Sayangnya, Safari tidak mengetahui cara menggunakan Sertifikat Klien untuk soket web, tetapi ada banyak instruksi di Internet tentang cara membuat sertifikat semacam itu, tetapi dalam praktiknya hal ini tidak mungkin tercapai.
Untuk memahami websockets, kami menggunakan rencana berikut: masalah/hipotesis/solusi.
Masalah: tidak ada dukungan untuk soket web saat memproksi permintaan ke sumber daya yang dilindungi oleh sertifikat klien di browser seluler Safari untuk iOS dan aplikasi lain yang telah mengaktifkan dukungan sertifikat.
Hipotesis:
Dimungkinkan untuk mengonfigurasi pengecualian seperti itu untuk menggunakan sertifikat (mengetahui bahwa tidak akan ada sertifikat) ke soket web sumber daya proksi internal/eksternal.
Untuk websockets, Anda dapat membuat koneksi yang unik, aman, dan dapat dipertahankan menggunakan sesi sementara yang dihasilkan selama permintaan browser normal (non-websocket).
Sesi sementara dapat diimplementasikan menggunakan satu server web proxy (hanya modul dan fungsi bawaan).
Token sesi sementara telah diimplementasikan sebagai modul Apache siap pakai.
Token sesi sementara dapat diimplementasikan dengan merancang struktur interaksi secara logis.
Keadaan terlihat setelah implementasi.
Objektif: pengelolaan layanan dan infrastruktur harus dapat diakses dari ponsel di iOS tanpa program tambahan (seperti VPN), terpadu dan aman.
Tujuan tambahan: menghemat waktu dan sumber daya/lalu lintas telepon (beberapa layanan tanpa soket web menghasilkan permintaan yang tidak perlu) dengan pengiriman konten yang lebih cepat di Internet seluler.
1. Dimungkinkan untuk mengonfigurasi pengecualian tersebut untuk menggunakan sertifikat (mengetahui bahwa tidak akan ada sertifikat) ke soket web sumber daya proksi internal/eksternal.
Verifikasi sertifikat terjadi setelah permintaan ke sumber daya yang diproksi, yaitu jabat tangan pasca permintaan. Ini berarti proxy akan memuat terlebih dahulu dan kemudian memotong permintaan ke layanan yang dilindungi. Ini buruk, tapi tidak kritis;
Dalam protokol http2. Ini masih dalam rancangan, dan produsen browser tidak tahu bagaimana menerapkannya #info tentang tls1.3 http2 post handshake (tidak berfungsi sekarang) Menerapkan RFC 8740 "Menggunakan TLS 1.3 dengan HTTP/2";
Tidak jelas bagaimana menyatukan proses ini.
b) Pada tingkat dasar, izinkan SSL tanpa sertifikat.
SSLVerifyClient memerlukan => SSLVerifyClient opsional, tetapi ini mengurangi tingkat keamanan server proxy, karena koneksi tersebut akan diproses tanpa sertifikat. Namun, Anda dapat menolak akses lebih lanjut ke layanan proksi dengan arahan berikut:
RewriteEngine on
RewriteCond %{SSL:SSL_CLIENT_VERIFY} !=SUCCESS
RewriteRule .? - [F]
ErrorDocument 403 "You need a client side certificate issued by CAcert to access this site"
SSLVerifyClient optional
RewriteEngine on
RewriteCond %{SSL:SSL_CLIENT_VERIFY} !=SUCCESS
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule .? - [F]
#ErrorDocument 403 "You need a client side certificate issued by CAcert to access this site"
#websocket for safari without cert auth
<If "%{SSL:SSL_CLIENT_VERIFY} != 'SUCCESS'">
<If "%{HTTP:Upgrade} = 'websocket'">
...
#Π·Π°ΠΌΠ΅ΡΠ°Π΅ΠΌ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎ Π²Π»Π°Π΄Π΅Π»ΡΡΡ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°ΡΠ° Π½Π° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎ Π½ΠΎΠΌΠ΅ΡΡ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π°
SSLUserName SSl_PROTOCOL
</If>
</If>
Dengan mempertimbangkan otorisasi yang ada oleh pemilik sertifikat, tetapi dengan sertifikat yang hilang, saya harus menambahkan pemilik sertifikat yang tidak ada dalam bentuk salah satu variabel yang tersedia SSl_PROTOCOL (bukan SSL_CLIENT_S_DN_CN), lebih detailnya di dokumentasi:
2. Untuk websockets, Anda dapat membuat koneksi unik, aman dan terlindungi menggunakan sesi sementara yang dihasilkan selama permintaan browser normal (non-websocket).
Berdasarkan pengalaman sebelumnya, Anda perlu menambahkan bagian tambahan ke konfigurasi untuk menyiapkan token sementara untuk koneksi soket web selama permintaan reguler (soket non-web).
Pengujian menunjukkan bahwa itu berhasil. Dimungkinkan untuk mentransfer Cookie ke diri Anda sendiri melalui browser pengguna.
3. Sesi sementara dapat diimplementasikan menggunakan satu server web proxy (hanya modul dan fungsi bawaan).
Seperti yang kita ketahui sebelumnya, Apache memiliki cukup banyak fungsi inti yang memungkinkan Anda membuat konstruksi bersyarat. Namun, kami memerlukan cara untuk melindungi informasi kami saat berada di browser pengguna, jadi kami menentukan apa yang harus disimpan dan alasannya, serta fungsi bawaan apa yang akan kami gunakan:
Kami memerlukan token yang tidak dapat dengan mudah diterjemahkan.
Kami memerlukan token yang memiliki keusangan di dalamnya dan kemampuan untuk memeriksa keusangan di server.
Kita memerlukan token yang akan dikaitkan dengan pemilik sertifikat.
Ini memerlukan fungsi hashing, garam, dan tanggal untuk menentukan umur token. Berdasarkan dokumentasi Ekspresi di Apache HTTP Server kami memiliki semuanya di luar kotak sha1 dan %{TIME}.
Tujuannya telah tercapai, tetapi ada masalah dengan keusangan server (Anda dapat menggunakan Cookie yang berumur satu tahun), yang berarti bahwa token tersebut, meskipun aman untuk penggunaan internal, tidak aman untuk penggunaan industri (massal).
4. Token sesi sementara telah diimplementasikan sebagai modul Apache siap pakai.
Satu masalah signifikan yang tersisa dari iterasi sebelumnya adalah ketidakmampuan untuk mengontrol penuaan token.
Kami mencari modul siap pakai yang melakukan ini, sesuai dengan kata-kata: apache token json two factor auth
Ya, ada modul yang sudah jadi, tetapi semuanya terkait dengan tindakan tertentu dan memiliki artefak dalam bentuk memulai sesi dan Cookie tambahan. Artinya, tidak untuk sementara waktu.
Kami membutuhkan waktu lima jam untuk mencari, tetapi tidak memberikan hasil yang nyata.
5. Token sesi sementara dapat diimplementasikan dengan merancang struktur interaksi secara logis.
Modul yang sudah jadi terlalu rumit, karena kita hanya memerlukan beberapa fungsi.
Meskipun demikian, masalah tanggal adalah fungsi bawaan Apache tidak memungkinkan pembuatan tanggal dari masa depan, dan tidak ada penambahan/pengurangan matematis pada fungsi bawaan saat memeriksa keusangan.
Artinya, Anda tidak dapat menulis:
(%{env:zt-cert-date} + 30) > %{DATE}
Anda hanya dapat membandingkan dua angka.
Saat mencari solusi untuk masalah Safari, saya menemukan artikel menarik: Mengamankan HomeAssistant dengan sertifikat klien (berfungsi dengan Safari/iOS)
Ini menjelaskan contoh kode di Lua untuk Nginx, dan ternyata, sangat mengulangi logika bagian konfigurasi yang telah kita terapkan, dengan pengecualian penggunaan metode pengasinan hmac untuk hashing ( ini tidak ditemukan di Apache).
Menjadi jelas bahwa Lua adalah bahasa dengan logika yang jelas, dan dimungkinkan untuk melakukan sesuatu yang sederhana untuk Apache:
Kami menemukan cara untuk menyetel variabel env dalam file Lua kecil untuk menyetel tanggal dari masa depan untuk dibandingkan dengan tanggal saat ini.
Ini adalah tampilan skrip Lua yang sederhana:
require 'apache2'
function handler(r)
local fmt = '%Y%m%d%H%M%S'
local timeout = 3600 -- 1 hour
r.notes['zt-cert-timeout'] = timeout
r.notes['zt-cert-date-next'] = os.date(fmt,os.time()+timeout)
r.notes['zt-cert-date-halfnext'] = os.date(fmt,os.time()+ (timeout/2))
r.notes['zt-cert-date-now'] = os.date(fmt,os.time())
return apache2.OK
end
Dan beginilah cara kerjanya secara total, dengan optimalisasi jumlah Cookies dan penggantian token ketika separuh waktunya tiba sebelum Cookie (token) lama habis masa berlakunya:
Secara umum, tidak masalah dalam urutan apa arahan ditulis dalam konfigurasi Apache (mungkin juga Nginx), karena pada akhirnya semuanya akan diurutkan berdasarkan urutan permintaan dari pengguna, yang sesuai dengan skema pemrosesan. skrip Lua.
Penyelesaian:
Keadaan yang terlihat setelah implementasi (tujuan):
pengelolaan layanan dan infrastruktur tersedia dari ponsel di iOS tanpa program tambahan (VPN), terpadu dan aman.
Tujuannya telah tercapai, soket web berfungsi dan memiliki tingkat keamanan tidak kurang dari sertifikat.