ProHoster > Blogi > Haldamine > Kuidas me ZeroTechis Apple Safari ja kliendi sertifikaadid veebipesadega ühendasime
Kuidas me ZeroTechis Apple Safari ja kliendi sertifikaadid veebipesadega ühendasime
Artikkel on kasulik neile, kes:
teab, mis on Client Cert ja mõistab, miks see vajab mobiilses Safaris veebipesasid;
Soovin avaldada veebiteenuseid piiratud ringile inimestele või ainult endale;
arvab, et kõik on kellegi poolt juba tehtud, ja tahaks maailma natuke mugavamaks ja turvalisemaks muuta.
Websockettide ajalugu algas umbes 8 aastat tagasi. Varem kasutati meetodeid pikkade http-päringute (tegelikult vastuste) kujul: kasutaja brauser saatis serverile päringu ja ootas, kuni see midagi vastab, pärast vastust ühendus uuesti ja ootas. Siis aga ilmusid veebipesad.
Mõned aastad tagasi töötasime välja oma juurutuse puhtas PHP-s, mis ei saa kasutada https-päringuid, kuna see on lingikiht. Mitte kaua aega tagasi õppisid peaaegu kõik veebiserverid puhverserveri taotlusi läbi https ja toetama ühendus:uuendust.
Kui see juhtus, muutusid websocketid SPA-rakenduste jaoks peaaegu vaiketeenuseks, sest kui mugav on serveri initsiatiivil kasutajale sisu pakkuda (teise kasutaja sõnumi edastamine või pildi, dokumendi, esitluse uue versiooni allalaadimine mida keegi teine parasjagu toimetab) .
Kuigi Client Certificate on olnud kasutusel juba mõnda aega, on see endiselt halvasti toetatud, kuna see tekitab palju probleeme, kui proovite sellest mööda minna. Ja (võib-olla :slightly_smiling_face: ) sellepärast ei taha IOS-i brauserid (kõik peale Safari) seda kasutada ja taotlevad seda kohalikust sertifikaadihoidlast. Sertifikaatidel on palju eeliseid võrreldes sisselogimise/passi või ssh-võtmetega või vajalike portide sulgemisega läbi tulemüüri. Kuid see pole see, millest see jutt käib.
IOS-is on sertifikaadi installimise protseduur üsna lihtne (mitte ilma spetsiifikata), kuid üldiselt toimub see juhiste järgi, mida Internetis on palju ja mis on saadaval ainult Safari brauseri jaoks. Kahjuks ei oska Safari Client Сert veebipesade jaoks kasutada, kuid Internetis on palju juhiseid, kuidas sellist sertifikaati luua, kuid praktikas on see kättesaamatu.
Probleem: IOS-i ja muude serditoe lubanud rakenduste jaoks Safari mobiilibrauseris kliendisertifikaadiga kaitstud ressurssidele päringute puhverserveri puhul veebipesade tugi puudub.
Hüpoteesid:
Sellist erandit on võimalik konfigureerida kasutama sertifikaate (teades, et neid ei tule) sisemiste/väliste puhverserveri ressursside veebisocketite jaoks.
Veebipistikupesade jaoks saate luua unikaalse, turvalise ja kaitstud ühenduse, kasutades ajutisi seansse, mis genereeritakse tavalise (mitte-websocket) brauseri päringu ajal.
Ajutisi seansse saab realiseerida ühe puhverserveri abil (ainult sisseehitatud moodulid ja funktsioonid).
Ajutised seansimärgid on juba kasutusele võetud valmis Apache moodulitena.
Ajutisi seansimärke saab rakendada interaktsioonistruktuuri loogilise kujundamise teel.
Nähtav olek pärast rakendamist.
Eesmärk: teenuste ja infrastruktuuri haldamine peaks olema IOS-i mobiiltelefonilt juurdepääsetav ilma lisaprogrammideta (nt VPN), ühtne ja turvaline.
Lisaeesmärk: säästa aega ja ressursse/telefoniliiklust (mõned ilma veebipistikupesadeta teenused tekitavad tarbetuid päringuid) sisu kiirema edastamisega mobiilses Internetis.
Kuidas kontrollida?
1. Avalehed:
— например, 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. Või arendajakonsoolis:
Hüpoteesi testimine:
1. Sellist erandit on võimalik seadistada sertifikaatide kasutamiseks (teades, et neid ei tule) sisemiste/väliste puhverserveri ressursside veebipesadele.
Sertifikaadi kinnitamine toimub pärast päringu esitamist puhverserverile, st pärast päringujärgset käepigistust. See tähendab, et puhverserver laadib esmalt ja katkestab seejärel kaitstud teenuse päringu. See on halb, kuid mitte kriitiline;
http2 protokollis. See on endiselt mustand ja brauseritootjad ei tea, kuidas seda rakendada #info tls1.3 kohta http2 postita käepigistuse (praegu ei tööta) Rakendage RFC 8740 "TLS 1.3 kasutamine HTTP/2-ga";
Ei ole selge, kuidas seda töötlemist ühtlustada.
b) Põhitasemel lubage ssl ilma sertifikaadita.
SSLVerifyClient nõuavad => SSLVerifyClient valikuline, kuid see vähendab puhverserveri turvataset, kuna sellist ühendust töödeldakse ilma sertifikaadita. Juurdepääsu puhverserveri teenustele saate siiski keelata järgmise direktiiviga:
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>
Võttes arvesse sertifikaadi omaniku olemasolevat volitust, kuid puuduva sertifikaadiga, pidin lisama olematu sertifikaadi omaniku ühe saadaoleva muutuja SSl_PROTOCOL kujul (SSL_CLIENT_S_DN_CN asemel), täpsemalt dokumentatsioonis:
2. Veebipistikupesade puhul saate luua unikaalse, turvalise ja kaitstud ühenduse, kasutades ajutisi seansse, mis genereeritakse tavalise (mitte-websocket) brauseri päringu ajal.
Varasema kogemuse põhjal tuleb konfiguratsiooni lisada täiendav sektsioon, et tavalise (mitteveebipesa) päringu ajal veebipesa ühenduste jaoks ette valmistada ajutised märgid.
#подготовка передача себе С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>
Testimine näitas, et see töötab. Kasutaja brauseri kaudu on võimalik küpsiseid endale üle kanda.
3. Ajutisi seansse saab realiseerida ühe puhverserveri abil (ainult sisseehitatud moodulid ja funktsioonid).
Nagu varem teada saime, on Apache'il üsna palju põhifunktsioone, mis võimaldavad teil luua tingimuslikke konstruktsioone. Siiski vajame vahendeid oma teabe kaitsmiseks, kui see on kasutaja brauseris, nii et me määrame, mida ja miks salvestada ning milliseid sisseehitatud funktsioone kasutame:
Vajame märgi, mida ei saa kergesti dekodeerida.
Vajame luba, millel on sisseehitatud vananemine ja mis võimaldab serveris vananemist kontrollida.
Vajame sertifikaati, mis seotakse sertifikaadi omanikuga.
Selleks on vaja märgi vanandamiseks räsifunktsiooni, soola ja kuupäeva. Dokumentatsiooni põhjal Avaldised Apache HTTP serveris meil on see kõik karbist väljas sha1 ja %{TIME}.
Tulemuseks oli selline disain:
#нет сертификата, и обращение к 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>
Eesmärk on saavutatud, kuid probleeme on serveri vananemisega (võite kasutada aasta vanust küpsist), mis tähendab, et tokenid on küll sisekasutuseks ohutud, kuid tööstuslikuks (massiks) kasutamiseks ohtlikud.
4. Ajutised seansimärgid on juba rakendatud valmis Apache moodulitena.
Eelmisest iteratsioonist jäi alles üks oluline probleem – võimetus kontrollida märgi vananemist.
Otsime valmis moodulit, mis teeb seda sõnadega: apache token json kahefaktoriline auth
Jah, on olemas valmismoodulid, kuid need kõik on seotud konkreetsete toimingutega ja sisaldavad artefakte seansi alustamise ja täiendavate küpsiste kujul. See tähendab, et mitte mõnda aega.
Otsimiseks kulus meil viis tundi, mis aga konkreetset tulemust ei andnud.
5. Ajutisi seansimärke saab realiseerida interaktsioonide struktuuri loogiliselt kujundades.
Valmis moodulid on liiga keerulised, sest vajame vaid paari funktsiooni.
Sellegipoolest on kuupäeva probleemiks see, et Apache sisseehitatud funktsioonid ei võimalda tulevikust kuupäeva genereerida ja sisseehitatud funktsioonides pole vananemise kontrollimisel matemaatilist liitmist/lahutamist.
See tähendab, et te ei saa kirjutada:
(%{env:zt-cert-date} + 30) > %{DATE}
Võrrelda saab ainult kahte numbrit.
Safari probleemile lahendust otsides leidsin huvitava artikli: HomeAssistanti kaitsmine kliendi sertifikaatidega (töötab Safari/iOS-iga)
See kirjeldab Nginxi jaoks mõeldud Lua koodi näidet ja mis, nagu selgus, kordab suurel määral konfiguratsiooni selle osa loogikat, mille oleme juba rakendanud, välja arvatud hmac soolamismeetodi kasutamine räsimiseks ( seda Apache'is ei leitud).
Selgus, et Lua on selge loogikaga keel ja Apache jaoks on võimalik teha midagi lihtsat:
Üldiselt pole vahet, millises järjekorras Apache (ilmselt ka Nginxi) konfiguratsioonis juhised on kirjutatud, kuna lõpuks sorteeritakse kõik vastavalt kasutaja päringu järjekorrale, mis vastab töötlemise skeemile. Lua skriptid.
Lõpetamine:
Nähtav olek pärast rakendamist (eesmärk):
teenuste ja infrastruktuuri haldamine on IOS-i mobiiltelefonilt saadaval ilma lisaprogrammideta (VPN), ühtne ja turvaline.
Eesmärk on saavutatud, veebipistikupesad töötavad ja nende turvalisuse tase ei ole madalam kui sertifikaat.