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.

Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sijil pelanggan dengan soket web

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.

Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sijil pelanggan dengan soket web

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:

  1. Adalah mungkin untuk mengkonfigurasi pengecualian sedemikian untuk menggunakan sijil (mengetahui bahawa tidak akan ada) kepada soket web sumber proksi dalaman/luaran.
  2. 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).
  3. Sesi sementara boleh dilaksanakan menggunakan satu pelayan web proksi (modul dan fungsi terbina dalam sahaja).
  4. Token sesi sementara telah pun dilaksanakan sebagai modul Apache siap sedia.
  5. 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.

Bagaimana untuk menyemak?

1. Muka surat pembukaan:

β€” Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, https://teamcity.yourdomain.com Π² мобильном Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ Safari (доступСн Ρ‚Π°ΠΊΠΆΠ΅ Π² дСсктопной вСрсии) β€” Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π²Π΅Π±-сокСтам.
β€” Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, https://teamcity.yourdomain.com/admin/admin.html?item=diagnostics&tab=webS…— ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ping/pong.
β€” Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, https://rancher.yourdomain.com/p/c-84bnv:p-vkszd/workload/deployment:danidb:ph…-> viewlogs β€” ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π»ΠΎΠ³ΠΈ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°.

2. Atau dalam konsol pembangun:

Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sijil pelanggan dengan soket web

Ujian hipotesis:

1. Adalah mungkin untuk mengkonfigurasi pengecualian sedemikian untuk menggunakan sijil (mengetahui bahawa tidak akan ada) kepada soket web sumber proksi dalaman/luaran.

2 penyelesaian ditemui di sini:

a) Di peringkat

<Location sock*> SSLVerifyClient optional </Location>
<Location /> SSLVerifyClient require </Location>

menukar tahap akses.

Kaedah ini mempunyai nuansa berikut:

  • 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"

Maklumat lebih terperinci boleh didapati dalam artikel tentang ssl: Pengesahan Sijil Pelanggan Pelayan Apache

Kedua-dua pilihan telah diuji, pilihan "b" telah dipilih untuk fleksibiliti dan keserasian dengan protokol http2.

Untuk melengkapkan pengesahan hipotesis ini, ia mengambil banyak percubaan dengan konfigurasi; reka bentuk berikut telah diuji:

jika = memerlukan = tulis semula

Hasilnya ialah reka bentuk asas berikut:

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:

Modul Apache mod_ssl

Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sijil pelanggan dengan soket web

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).

#ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° сСбС Π‘ookie Ρ‡Π΅Ρ€Π΅Π· ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€
<If "%{SSL:SSL_CLIENT_VERIFY} = 'SUCCESS'">
<If "%{HTTP:Upgrade} != 'websocket'">
Header set Set-Cookie "websocket-allowed=true; path=/; Max-Age=100"
</If>
</If>

#ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Cookie для установлСния Π²Π΅Π±-сокСт соСдинСния
<source lang="javascript">
<If "%{SSL:SSL_CLIENT_VERIFY} != 'SUCCESS'">
<If "%{HTTP:Upgrade} = 'websocket'">
#check for exists cookie

#get and check
SetEnvIf Cookie "websocket-allowed=(.*)" env-var-name=$1

#or rewrite rule
RewriteCond %{HTTP_COOKIE} !^.*mycookie.*$

#or if
<If "%{HTTP_COOKIE} =~ /(^|; )cookie-names*=s*some-val(;|$)/ >
</If

</If>
</If>

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}.

Hasilnya ialah reka bentuk ini:

#Π½Π΅Ρ‚ сСртификата, ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ websocket
<If "%{SSL:SSL_CLIENT_VERIFY} != 'SUCCESS'">
<If "%{HTTP:Upgrade} = 'websocket'">
    SetEnvIf Cookie "zt-cert-sha1=([^;]+)" zt-cert-sha1=$1
    SetEnvIf Cookie "zt-cert-uid=([^;]+)" zt-cert-uid=$1
    SetEnvIf Cookie "zt-cert-date=([^;]+)" zt-cert-date=$1

#Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΌΠΈ Π² env-Π°Ρ… Π² этот ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, Π±ΠΎΠ»Π΅Π΅ ΠΎΠ½ΠΈ Π½ΠΈΠ³Π΄Π΅ Π½Π΅ доступны для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ (ΠΏΠΎ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΌΠΎΠΆΠ½ΠΎ, Π½ΠΎ Π½Π΅ вмСстС, Π΄Π° ΠΈ Π΅Ρ‰Ρ‘ с Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ)
    <RequireAll>
        Require expr %{sha1:salt1%{env:zt-cert-date}salt3%{env:zt-cert-uid}salt2} == %{env:zt-cert-sha1}
        Require expr %{env:zt-cert-sha1} =~ /^.{40}$/
    </RequireAll>
</If>
</If>

#Π΅ΡΡ‚ΡŒ сСртификат, Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ Π½Π΅ websocket
<If "%{SSL:SSL_CLIENT_VERIFY} = 'SUCCESS'">
<If "%{HTTP:Upgrade} != 'websocket'">
    SetEnvIf Cookie "zt-cert-sha1=([^;]+)" HAVE_zt-cert-sha1=$1

    SetEnv zt_cert "path=/; HttpOnly;Secure;SameSite=Strict"
#НовыС ΠΊΡƒΠΊΠΈ ставятся, Ссли старых Π½Π΅Ρ‚
    Header add Set-Cookie "expr=zt-cert-sha1=%{sha1:salt1%{TIME}salt3%{SSL_CLIENT_S_DN_CN}salt2};%{env:zt_cert}" env=!HAVE_zt-cert-sha1
    Header add Set-Cookie "expr=zt-cert-uid=%{SSL_CLIENT_S_DN_CN};%{env:zt_cert}" env=!HAVE_zt-cert-sha1
    Header add Set-Cookie "expr=zt-cert-date=%{TIME};%{env:zt_cert}" env=!HAVE_zt-cert-sha1
</If>
</If>

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).

Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sijil pelanggan dengan soket web

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:

Setelah mengkaji perbezaan dengan Nginx dan Apache:

Dan fungsi yang tersedia daripada pengeluar bahasa Lua:
22.1 – Tarikh dan Masa

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:

SSLVerifyClient optional

#LuaScope thread
#generate event variables zt-cert-date-next
LuaHookAccessChecker /usr/local/etc/apache24/sslincludes/websocket_token.lua handler early

#Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅ΠΌ Π±Π΅Π· сСртификата Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π΅Ρ‰Ρ‘, ΠΊΡ€ΠΎΠΌΠ΅ webscoket
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 certauth
<If "%{SSL:SSL_CLIENT_VERIFY} != 'SUCCESS'">
<If "%{HTTP:Upgrade} = 'websocket'">
    SetEnvIf Cookie "zt-cert=([^,;]+),([^,;]+),[^,;]+,([^,;]+)" zt-cert-sha1=$1 zt-cert-date=$2 zt-cert-uid=$3

    <RequireAll>
        Require expr %{sha1:salt1%{env:zt-cert-date}salt3%{env:zt-cert-uid}salt2} == %{env:zt-cert-sha1}
        Require expr %{env:zt-cert-sha1} =~ /^.{40}$/
        Require expr %{env:zt-cert-date} -ge %{env:zt-cert-date-now}
    </RequireAll>
   
    #Π·Π°ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΏΠΎ Π²Π»Π°Π΄Π΅Π»ΡŒΡ†Ρƒ сСртификата Π½Π° Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΏΠΎ Π½ΠΎΠΌΠ΅Ρ€Ρƒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°
    SSLUserName SSl_PROTOCOL
    SSLOptions -FakeBasicAuth
</If>
</If>

<If "%{SSL:SSL_CLIENT_VERIFY} = 'SUCCESS'">
<If "%{HTTP:Upgrade} != 'websocket'">
    SetEnvIf Cookie "zt-cert=([^,;]+),[^,;]+,([^,;]+)" HAVE_zt-cert-sha1=$1 HAVE_zt-cert-date-halfnow=$2
    SetEnvIfExpr "env('HAVE_zt-cert-date-halfnow') -ge %{TIME} && env('HAVE_zt-cert-sha1')=~/.{40}/" HAVE_zt-cert-sha1-found=1

    Define zt-cert "path=/;Max-Age=%{env:zt-cert-timeout};HttpOnly;Secure;SameSite=Strict"
    Define dates_user "%{env:zt-cert-date-next},%{env:zt-cert-date-halfnext},%{SSL_CLIENT_S_DN_CN}"
    Header set Set-Cookie "expr=zt-cert=%{sha1:salt1%{env:zt-cert-date-next}sal3%{SSL_CLIENT_S_DN_CN}salt2},${dates_user};${zt-cert}" env=!HAVE_zt-cert-sha1-found
</If>
</If>

SetEnvIfExpr "env('HAVE_zt-cert-date-halfnow') -ge %{TIME} && env('HAVE_zt-cert-sha1')=~/.{40}/" HAVE_zt-cert-sha1-found=1
Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚,

Π° Ρ‚Π°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚
SetEnvIfExpr "env('HAVE_zt-cert-date-halfnow') -ge  env('zt-cert-date-now') && env('HAVE_zt-cert-sha1')=~/.{40}/" HAVE_zt-cert-sha1-found=1 

Kerana LuaHookAccessChecker hanya akan diaktifkan selepas semakan akses berdasarkan maklumat ini daripada Nginx.

Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sijil pelanggan dengan soket web

Pautan ke sumber Imej.

Satu lagi perkara.

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.

Bagaimana kami di ZeroTech menghubungkan Apple Safari dan sijil pelanggan dengan soket web

Sumber: www.habr.com

Tambah komen