Kif aħna f'ZeroTech konnessajna Apple Safari u ċ-ċertifikati tal-klijenti mal-websockets

L-artiklu se jkun utli għal dawk li:

  • jaf x'inhu Client Cert u jifhem għaliex jeħtieġ websockets fuq Safari mobbli;
  • Nixtieq nippubblika servizzi tal-web lil ċirku limitat ta' nies jew lili nnifsi biss;
  • jaħseb li kollox diġà sar minn xi ħadd, u jixtieq jagħmel id-dinja ftit aktar konvenjenti u aktar sigura.

L-istorja tal-websockets bdiet madwar 8 snin ilu. Preċedentement, intużaw metodi fil-forma ta 'talbiet http twal (fil-fatt tweġibiet): il-browser tal-utent bagħat talba lis-server u stennieh biex iwieġeb xi ħaġa, wara r-rispons reġa' qabbad u stenna. Imma mbagħad dehru websockets.

Kif aħna f'ZeroTech konnessajna Apple Safari u ċ-ċertifikati tal-klijenti mal-websockets

Ftit snin ilu, żviluppajna l-implimentazzjoni tagħna stess f'PHP pur, li ma jistax juża talbiet https, peress li dan huwa s-saff tal-link. Ftit ilu, kważi s-servers tal-web kollha tgħallmu talbiet proxy fuq https u jappoġġjaw konnessjoni:upgrade.

Meta ġara dan, il-websockets saru kważi s-servizz default għall-applikazzjonijiet SPA, għax kemm huwa konvenjenti li jiġi pprovdut kontenut lill-utent fuq inizjattiva tas-server (itrażmetti messaġġ minn utent ieħor jew tniżżel verżjoni ġdida ta 'immaġni, dokument, preżentazzjoni li xi ħadd ieħor bħalissa qed jeditja) .

Għalkemm iċ-Ċertifikat tal-Klijent ilu żmien pjuttost twil, xorta jibqa' appoġġjat ħażin, peress li joħloq ħafna problemi meta jipprova jevitah. U (possibilment :slightly_smiling_face: ) hu għalhekk li l-browsers tal-IOS (kollha ħlief Safari) ma jridux jużawha u jitolbuha mill-maħżen taċ-ċertifikati lokali. Iċ-ċertifikati għandhom ħafna vantaġġi meta mqabbla ma 'ċwievet login/pass jew ssh jew jagħlqu l-portijiet meħtieġa permezz ta' firewall. Imma dan mhux dwar dan.

Fuq iOS, il-proċedura għall-installazzjoni ta 'ċertifikat hija pjuttost sempliċi (mhux mingħajr ispeċifiċitajiet), iżda b'mod ġenerali ssir skond l-istruzzjonijiet, li minnhom hemm ħafna fuq l-Internet u li huma disponibbli biss għall-browser Safari. Sfortunatament, Safari ma jafx kif juża Client Сert għal sockets tal-web, iżda hemm ħafna struzzjonijiet fuq l-Internet dwar kif jinħoloq ċertifikat bħal dan, iżda fil-prattika dan ma jistax jintlaħaq.

Kif aħna f'ZeroTech konnessajna Apple Safari u ċ-ċertifikati tal-klijenti mal-websockets

Biex nifhmu l-websockets, użajna l-pjan li ġej: problema/ipoteżi/soluzzjoni.

Problema: m'hemm l-ebda appoġġ għall-web sockets meta talbiet proxy għal riżorsi li huma protetti minn ċertifikat tal-klijent fuq il-browser mobbli Safari għal IOS u applikazzjonijiet oħra li ppermettew l-appoġġ taċ-ċertifikat.

Ipotesi:

  1. Huwa possibbli li tiġi kkonfigurata eċċezzjoni bħal din biex tuża ċertifikati (jaf li mhux se jkun hemm) għal websockets ta 'riżorsi proxy interni/esterni.
  2. Għall-websockets, tista 'tagħmel konnessjoni unika, sigura u difiżibbli billi tuża sessjonijiet temporanji li huma ġġenerati waqt talba tal-browser normali (mhux websocket).
  3. Sessjonijiet temporanji jistgħu jiġu implimentati bl-użu ta' server web proxy wieħed (moduli u funzjonijiet integrati biss).
  4. It-tokens tas-sessjoni temporanji diġà ġew implimentati bħala moduli Apache lesti.
  5. It-tokens tas-sessjoni temporanju jistgħu jiġu implimentati billi tiddisinja loġikament l-istruttura tal-interazzjoni.

Stat viżibbli wara l-implimentazzjoni.

Għan tax-xogħol: il-ġestjoni tas-servizzi u l-infrastruttura għandha tkun aċċessibbli minn mowbajl fuq IOS mingħajr programmi addizzjonali (bħal VPN), unifikata u sigura.

Għan addizzjonali: iffrankar ta' ħin u riżorsi/traffiku tat-telefon (xi servizzi mingħajr sockets tal-web jiġġeneraw talbiet mhux meħtieġa) bi twassil aktar mgħaġġel tal-kontenut fuq l-Internet mobbli.

Kif tiċċekkja?

1. Paġni tal-ftuħ:

— например, 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. Jew fil-console tal-iżviluppatur:

Kif aħna f'ZeroTech konnessajna Apple Safari u ċ-ċertifikati tal-klijenti mal-websockets

Ittestjar tal-ipoteżi:

1. Huwa possibbli li tiġi kkonfigurata eċċezzjoni bħal din biex tuża ċertifikati (jaf li mhux se jkun hemm) għal web sockets ta 'riżorsi proxy interni/esterni.

Hawnhekk instabu 2 soluzzjonijiet:

a) Fil-livell

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

tibdel il-livell ta' aċċess.

Dan il-metodu għandu l-sfumaturi li ġejjin:

  • Il-verifika taċ-ċertifikat isseħħ wara talba lir-riżorsa prokurata, jiġifieri, wara t-talba għal handshake. Dan ifisser li l-proxy l-ewwel jgħabbi u mbagħad jaqta’ t-talba lis-servizz protett. Dan huwa ħażin, iżda mhux kritiku;
  • Fil-protokoll http2. Għadu fl-abbozz, u l-manifatturi tal-brawżers ma jafux kif jimplimentawha #info dwar tls1.3 http2 post handshake (mhux qed jaħdem issa) Implimenta RFC 8740 "L-użu ta' TLS 1.3 b'HTTP/2";
  • Mhux ċar kif tgħaqqad dan l-ipproċessar.

b) Fuq livell bażiku, ħalli ssl mingħajr ċertifikat.

SSLVerifyClient require => SSLVerifyClient fakultattiv, iżda dan inaqqas il-livell ta' sigurtà tas-server proxy, peress li konnessjoni bħal din tiġi pproċessata mingħajr ċertifikat. Madankollu, tista' tkompli tiċħad l-aċċess għal servizzi prokurati bid-direttiva li ġejja:

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"

Informazzjoni aktar dettaljata tista 'tinstab fl-artiklu dwar ssl: Awtentikazzjoni taċ-Ċertifikat tal-Klijent tal-Apache Server

Iż-żewġ għażliet ġew ittestjati, l-għażla "b" ntgħażlet għall-versatilità u l-kompatibilità tagħha mal-protokoll http2.

Biex tlesti l-verifika ta 'din l-ipoteżi, ħadu ħafna esperimenti bil-konfigurazzjoni; id-disinji li ġejjin ġew ittestjati:

jekk = jeħtieġu = jikteb mill-ġdid

Ir-riżultat huwa d-disinn bażiku li ġej:

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>

B'kont meħud tal-awtorizzazzjoni eżistenti mis-sid taċ-ċertifikat, iżda b'ċertifikat nieqes, kelli nżid sid ta 'ċertifikat ineżistenti fil-forma ta' waħda mill-varjabbli disponibbli SSl_PROTOCOL (minflok SSL_CLIENT_S_DN_CN), aktar dettalji fid-dokumentazzjoni:

Modulu Apache mod_ssl

Kif aħna f'ZeroTech konnessajna Apple Safari u ċ-ċertifikati tal-klijenti mal-websockets

2. Għal websockets, tista 'tagħmel konnessjoni unika, sigura u protetta billi tuża sessjonijiet temporanji li huma ġġenerati waqt talba tal-browser normali (mhux websocket).

Ibbażat fuq esperjenza preċedenti, għandek bżonn iżżid sezzjoni addizzjonali mal-konfigurazzjoni sabiex tipprepara tokens temporanji għal konnessjonijiet ta 'socket tal-web waqt talba regolari (mhux socket tal-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>

L-ittestjar wera li jaħdem. Huwa possibbli li tittrasferixxi Cookies lilek innifsek permezz tal-browser tal-utent.

3. Sessjonijiet temporanji jistgħu jiġu implimentati bl-użu ta' server web prokura wieħed (moduli u funzjonijiet integrati biss).

Kif sirna nafu qabel, Apache għandu ħafna funzjonalità ewlenija li tippermettilek toħloq kostruzzjonijiet kondizzjonali. Madankollu, neħtieġu mezzi biex nipproteġu l-informazzjoni tagħna waqt li tkun fil-browser tal-utent, għalhekk nistabbilixxu x’naħżen u għaliex, u liema funzjonijiet inkorporati se nużaw:

  • Għandna bżonn token li ma jistax jiġi dekodifikat faċilment.
  • Għandna bżonn token li għandu l-obsolexxenza mibni fih u l-abbiltà li tivverifika l-obsolexxenza fuq is-server.
  • Għandna bżonn token li se jkun assoċjat mas-sid taċ-ċertifikat.

Dan jeħtieġ funzjoni ta 'hashing, melħ, u data biex tixjieħ it-token. Ibbażat fuq id-dokumentazzjoni Espressjonijiet f'Apache HTTP Server għandna dan kollu barra mill-kaxxa sha1 u %{TIME}.

Ir-riżultat kien dan id-disinn:

#нет сертификата, и обращение к 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>

L-għan intlaħaq, iżda hemm problemi bl-obsolexxenza tas-server (tista 'tuża Cookie ta' sena), li jfisser li t-tokens, għalkemm sikuri għall-użu intern, mhumiex sikuri għall-użu industrijali (massa).

Kif aħna f'ZeroTech konnessajna Apple Safari u ċ-ċertifikati tal-klijenti mal-websockets

4. It-tokens tas-sessjoni temporanju diġà ġew implimentati bħala moduli Apache lesti.

Problema waħda sinifikanti baqgħet mill-iterazzjoni preċedenti - l-inkapaċità li tikkontrolla t-tixjiħ tat-token.

Qegħdin infittxu modulu lest li jagħmel dan, skont il-kliem: apache token json two factor auth

Iva, hemm moduli lesti, iżda kollha huma marbuta ma 'azzjonijiet speċifiċi u għandhom artifacts fil-forma ta' bidu ta 'sessjoni u Cookies addizzjonali. Jiġifieri mhux għal xi żmien.
Domna ħames sigħat biex infittxu, li ma tatx riżultat konkret.

5. It-tokens tas-sessjoni temporanju jistgħu jiġu implimentati billi tiddisinja loġikament l-istruttura tal-interazzjonijiet.

Moduli lesti huma kumplessi wisq, għaliex għandna bżonn biss ftit funzjonijiet.

Dan ingħad, il-problema bid-data hija li l-funzjonijiet integrati ta 'Apache ma jippermettux li tiġġenera data mill-futur, u m'hemm l-ebda żieda/tnaqqis matematiku fil-funzjonijiet integrati meta tiċċekkja għal obsolexxenza.

Jiġifieri ma tistax tikteb:

(%{env:zt-cert-date} + 30) > %{DATE}

Tista 'tqabbel biss żewġ numri.

Waqt li kont qed infittex soluzzjoni għall-problema tas-Safari, sibt artiklu interessanti: L-iżgurar ta' HomeAssistant b'ċertifikati tal-klijent (jaħdem ma' Safari/iOS)
Jiddeskrivi eżempju ta 'kodiċi fil-Lua għal Nginx, u li, kif irriżulta, jirrepeti ħafna l-loġika ta' dik il-parti tal-konfigurazzjoni li diġà implimentajna, bl-eċċezzjoni tal-użu tal-metodu tat-tmelliħ hmac għall-hashing ( dan ma nstabx f'Apache).

Deher ċar li Lua hija lingwa b'loġika ċara, u huwa possibbli li tagħmel xi ħaġa sempliċi għal Apache:

Wara li studja d-differenza ma 'Nginx u Apache:

U funzjonijiet disponibbli mill-manifattur tal-lingwa Lua:
22.1 – Data u Ħin

Sibna mod kif nissettjaw varjabbli env f'fajl Lua żgħir sabiex nissettjaw data mill-futur biex tqabbel ma 'dak attwali.

Hekk tidher skript Lua sempliċi:

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

U dan huwa kif jaħdem kollu b'kollox, bl-ottimizzazzjoni tan-numru ta 'Cookies u sostituzzjoni tat-token meta nofs iż-żmien jasal qabel ma jiskadi l-Cookie (token) l-antik:

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 

Minħabba li LuaHookAccessChecker se jiġi attivat biss wara kontrolli ta 'aċċess ibbażati fuq din l-informazzjoni minn Nginx.

Kif aħna f'ZeroTech konnessajna Apple Safari u ċ-ċertifikati tal-klijenti mal-websockets

Link għas-sors immaġni.

Ħaġ'oħra.

B'mod ġenerali, ma jimpurtax f'liema ordni d-direttivi huma miktuba fil-konfigurazzjoni Apache (probabbilment ukoll Nginx), peress li fl-aħħar kollox se jiġi magħżul abbażi tal-ordni tat-talba mill-utent, li tikkorrispondi mal-iskema għall-ipproċessar. Lua skripts.

Tlestija:

Stat viżibbli wara l-implimentazzjoni (għan):
ġestjoni tas-servizzi u l-infrastruttura hija disponibbli minn telefon ċellulari fuq IOS mingħajr programmi addizzjonali (VPN), unifikata u sigura.

L-għan intlaħaq, is-sockets tal-web jaħdmu u għandhom livell ta 'sigurtà mhux inqas minn ċertifikat.

Kif aħna f'ZeroTech konnessajna Apple Safari u ċ-ċertifikati tal-klijenti mal-websockets

Sors: www.habr.com

Żid kumment