ProHoster > Blog > Pentadbiran > Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sijil pelanggan dengan soket web
Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sijil pelanggan dengan soket web
Artikel itu akan berguna kepada mereka yang:
mengetahui apa itu Sijil Pelanggan dan memahami mengapa ia memerlukan soket web pada Safari mudah alih;
Saya ingin menerbitkan perkhidmatan web kepada kalangan orang yang terhad atau hanya untuk diri saya sendiri;
berfikir bahawa segala-galanya telah dilakukan oleh seseorang, dan ingin menjadikan dunia lebih mudah dan selamat.
Sejarah websocket bermula kira-kira 8 tahun yang lalu. Sebelum ini, kaedah digunakan dalam bentuk permintaan http yang panjang (sebenarnya respons): penyemak imbas pengguna menghantar permintaan kepada pelayan dan menunggu untuk menjawab sesuatu, selepas respons ia disambungkan semula dan menunggu. Tetapi kemudian websocket muncul.
Beberapa tahun yang lalu, kami membangunkan pelaksanaan kami sendiri dalam PHP tulen, yang tidak boleh menggunakan permintaan https, kerana ini adalah lapisan pautan. Tidak lama dahulu, hampir semua pelayan web mempelajari permintaan proksi melalui https dan menyokong connection:upgrade.
Apabila ini berlaku, soket web hampir menjadi perkhidmatan lalai untuk aplikasi SPA, kerana betapa mudahnya untuk menyediakan kandungan kepada pengguna atas inisiatif pelayan (menghantar mesej daripada pengguna lain atau memuat turun versi baharu imej, dokumen, pembentangan bahawa orang lain sedang mengedit) .
Walaupun Sijil Pelanggan telah wujud untuk sekian lama, ia masih kekal kurang disokong, kerana ia menimbulkan banyak masalah apabila cuba memintasnya. Dan (mungkin :slightly_smiling_face: ) itulah sebabnya pelayar IOS (semua kecuali Safari) tidak mahu menggunakannya dan memintanya daripada kedai sijil tempatan. Sijil mempunyai banyak kelebihan berbanding dengan kekunci log masuk/lulus atau ssh atau menutup port yang diperlukan melalui tembok api. Tetapi bukan itu yang dimaksudkan.
Pada iOS, prosedur untuk memasang sijil agak mudah (bukan tanpa spesifik), tetapi secara umum ia dilakukan mengikut arahan, yang terdapat banyak di Internet dan yang hanya tersedia untuk penyemak imbas Safari. Malangnya, Safari tidak tahu cara menggunakan Client Π‘ert untuk soket web, tetapi terdapat banyak arahan di Internet tentang cara membuat sijil sedemikian, tetapi dalam amalan ini tidak dapat dicapai.
Untuk memahami soket web, kami menggunakan pelan berikut: masalah/hipotesis/penyelesaian.
Masalah: tiada sokongan untuk soket web apabila meminta proksi kepada sumber yang dilindungi oleh sijil klien pada penyemak imbas mudah alih Safari untuk IOS dan aplikasi lain yang telah mendayakan sokongan sijil.
Hipotesis:
Adalah mungkin untuk mengkonfigurasi pengecualian sedemikian untuk menggunakan sijil (mengetahui bahawa tidak akan ada) kepada soket web sumber proksi dalaman/luaran.
Untuk soket web, anda boleh membuat sambungan yang unik, selamat dan boleh dipertahankan menggunakan sesi sementara yang dijana semasa permintaan penyemak imbas biasa (bukan soket web).
Sesi sementara boleh dilaksanakan menggunakan satu pelayan web proksi (modul dan fungsi terbina dalam sahaja).
Token sesi sementara telah pun dilaksanakan sebagai modul Apache siap sedia.
Token sesi sementara boleh dilaksanakan dengan mereka bentuk struktur interaksi secara logik.
Keadaan yang boleh dilihat selepas pelaksanaan.
Matlamat kerja: pengurusan perkhidmatan dan infrastruktur harus boleh diakses daripada telefon mudah alih pada IOS tanpa program tambahan (seperti VPN), bersatu dan selamat.
Matlamat tambahan: menjimatkan masa dan sumber/trafik telefon (sesetengah perkhidmatan tanpa soket web menjana permintaan yang tidak perlu) dengan penghantaran kandungan yang lebih pantas pada Internet mudah alih.
1. Adalah mungkin untuk mengkonfigurasi pengecualian sedemikian untuk menggunakan sijil (mengetahui bahawa tidak akan ada) kepada soket web sumber proksi dalaman/luaran.
Pengesahan sijil berlaku selepas permintaan kepada sumber yang diproksikan, iaitu, pasca permintaan berjabat tangan. Ini bermakna proksi akan memuatkan dahulu dan kemudian memotong permintaan kepada perkhidmatan yang dilindungi. Ini buruk, tetapi tidak kritikal;
Dalam protokol http2. Ia masih dalam draf, dan pengeluar penyemak imbas tidak tahu cara melaksanakannya #info tentang tls1.3 http2 pasca jabat tangan (tidak berfungsi sekarang) Laksanakan RFC 8740 "Menggunakan TLS 1.3 dengan HTTP/2";
Tidak jelas bagaimana untuk menyatukan pemprosesan ini.
b) Pada peringkat asas, benarkan ssl tanpa sijil.
SSLVerifyClient memerlukan => SSLVerifyClient pilihan, tetapi ini mengurangkan tahap keselamatan pelayan proksi, kerana sambungan sedemikian akan diproses tanpa sijil. Walau bagaimanapun, anda boleh menafikan lagi akses kepada perkhidmatan 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 mengambil kira kebenaran sedia ada oleh pemilik sijil, tetapi dengan sijil yang tiada, saya terpaksa menambah pemilik sijil yang tidak wujud dalam bentuk salah satu pembolehubah yang tersedia SSl_PROTOCOL (bukan SSL_CLIENT_S_DN_CN), butiran lanjut dalam dokumentasi:
2. Untuk soket web, anda boleh membuat sambungan yang unik, selamat dan dilindungi menggunakan sesi sementara yang dijana semasa permintaan penyemak imbas biasa (bukan soket web).
Berdasarkan pengalaman sebelumnya, anda perlu menambah bahagian tambahan pada konfigurasi untuk menyediakan token sementara untuk sambungan soket web semasa permintaan biasa (bukan soket web).
Ujian menunjukkan bahawa ia berfungsi. Adalah mungkin untuk memindahkan Kuki kepada diri sendiri melalui penyemak imbas pengguna.
3. Sesi sementara boleh dilaksanakan menggunakan satu pelayan web proksi (hanya modul dan fungsi terbina dalam).
Seperti yang kami ketahui sebelum ini, Apache mempunyai banyak fungsi teras yang membolehkan anda membuat binaan bersyarat. Walau bagaimanapun, kami memerlukan cara untuk melindungi maklumat kami semasa ia berada dalam penyemak imbas pengguna, jadi kami menetapkan perkara yang perlu disimpan dan sebabnya, dan apakah fungsi terbina dalam yang akan kami gunakan:
Kami memerlukan token yang tidak boleh dinyahkodkan dengan mudah.
Kami memerlukan token yang mempunyai keusangan terbina di dalamnya dan keupayaan untuk menyemak keusangan pada pelayan.
Kami memerlukan token yang akan dikaitkan dengan pemilik sijil.
Ini memerlukan fungsi pencincangan, garam dan tarikh untuk umur token. Berdasarkan dokumentasi Ungkapan dalam Pelayan HTTP Apache kami mempunyai semuanya di luar kotak sha1 dan %{TIME}.
Matlamat telah dicapai, tetapi terdapat masalah dengan keusangan pelayan (anda boleh menggunakan Kuki berusia setahun), yang bermaksud bahawa token, walaupun selamat untuk kegunaan dalaman, tidak selamat untuk kegunaan industri (massa).
4. Token sesi sementara telah pun dilaksanakan sebagai modul Apache siap sedia.
Satu masalah penting kekal daripada lelaran sebelumnya - ketidakupayaan untuk mengawal penuaan token.
Kami sedang mencari modul siap sedia yang melakukan ini, menurut perkataan: Apache token json two factor auth
Ya, terdapat modul siap sedia, tetapi semuanya terikat pada tindakan tertentu dan mempunyai artifak dalam bentuk memulakan sesi dan Kuki tambahan. Maksudnya, bukan untuk seketika.
Kami mengambil masa lima jam untuk mencari, yang tidak memberikan hasil yang konkrit.
5. Token sesi sementara boleh dilaksanakan dengan mereka bentuk struktur interaksi secara logik.
Modul sedia dibuat terlalu kompleks, kerana kita hanya memerlukan beberapa fungsi.
Walaupun begitu, masalah dengan tarikh ialah fungsi terbina dalam Apache tidak membenarkan menjana tarikh dari masa hadapan, dan tiada penambahan/penolakan matematik dalam fungsi terbina dalam semasa menyemak keusangan.
Iaitu, anda tidak boleh menulis:
(%{env:zt-cert-date} + 30) > %{DATE}
Anda hanya boleh membandingkan dua nombor.
Semasa mencari penyelesaian untuk masalah Safari, saya menemui artikel yang menarik: Mengamankan HomeAssistant dengan sijil pelanggan (berfungsi dengan Safari/iOS)
Ia menerangkan contoh kod dalam Lua untuk Nginx, dan yang, ternyata, sangat mengulangi logik bahagian konfigurasi yang telah kami laksanakan, dengan pengecualian penggunaan kaedah pengasinan hmac untuk pencincangan ( ini tidak ditemui dalam Apache).
Ia menjadi jelas bahawa Lua ialah bahasa dengan logik yang jelas, dan adalah mungkin untuk melakukan sesuatu yang mudah untuk Apache:
Kami menemui cara untuk menetapkan pembolehubah env dalam fail Lua kecil untuk menetapkan tarikh dari masa hadapan untuk dibandingkan dengan yang semasa.
Inilah rupa skrip Lua yang mudah:
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 ini adalah cara semuanya berfungsi secara keseluruhan, dengan pengoptimuman bilangan Kuki dan penggantian token apabila separuh masa tiba sebelum Kuki lama (token) tamat tempoh:
Secara umum, tidak kira dalam susunan arahan yang ditulis dalam konfigurasi Apache (mungkin juga Nginx), kerana pada akhirnya semuanya akan disusun berdasarkan susunan permintaan daripada pengguna, yang sepadan dengan skema untuk pemprosesan Skrip Lua.
Selesai:
Keadaan yang boleh dilihat selepas pelaksanaan (matlamat):
pengurusan perkhidmatan dan infrastruktur tersedia daripada telefon mudah alih pada IOS tanpa program tambahan (VPN), bersatu dan selamat.
Matlamat telah dicapai, websocket berfungsi dan mempunyai tahap keselamatan tidak kurang daripada sijil.