ProHoster > Blog > Rianachd > Mar a cheangail sinn aig ZeroTech Apple Safari agus teisteanasan teachdaiche le websockets
Mar a cheangail sinn aig ZeroTech Apple Safari agus teisteanasan teachdaiche le websockets
Bidh an artaigil feumail dhaibhsan a tha:
tha fios aige dè a th’ ann an Client Cert agus tuigidh e carson a tha feum aige air websockets air Safari gluasadach;
Bu mhath leam seirbheisean lìn fhoillseachadh do chearcall cuibhrichte de dhaoine no dìreach dhomh fhìn;
den bheachd gu bheil a h-uile càil air a dhèanamh le cuideigin mar-thà, agus bu mhath leis an saoghal a dhèanamh beagan nas goireasaiche agus nas sàbhailte.
Thòisich eachdraidh websockets mu 8 bliadhna air ais. Roimhe sin, chaidh dòighean a chleachdadh ann an cruth iarrtasan http fada (freagairtean dha-rìribh): chuir brabhsair an neach-cleachdaidh iarrtas chun an fhrithealaiche agus dh'fhuirich e gus rudeigin a fhreagairt, às deidh an fhreagairt cheangail e a-rithist agus feitheamh. Ach an uairsin nochd websockets.
O chionn beagan bhliadhnaichean, leasaich sinn ar buileachadh fhèin ann am PHP fìor, nach urrainn iarrtasan https a chleachdadh, leis gur e seo an ìre ceangail. O chionn ghoirid, dh’ ionnsaich cha mhòr a h-uile seirbheisiche lìn iarrtasan neach-ionaid thairis air https agus ceangal taic: ùrachadh.
Nuair a thachair seo, thàinig websockets gu bhith cha mhòr mar an t-seirbheis àbhaisteach airson tagraidhean SPA, oir cho goireasach ‘s a tha e susbaint a thoirt don neach-cleachdaidh air iomairt an fhrithealaiche (cuir teachdaireachd bho neach-cleachdaidh eile no luchdaich sìos dreach ùr de dh’ ìomhaigh, sgrìobhainn, taisbeanadh gu bheil cuideigin eile a’ deasachadh an-dràsta).
Ged a tha Teisteanas Cliant air a bhith timcheall airson ùine mhòr, tha e fhathast le droch thaic, leis gu bheil e a’ cruthachadh tòrr dhuilgheadasan nuair a thathar a’ feuchainn ri faighinn seachad air. Agus ('s dòcha :slightly_smiling_face : ) 's e sin as coireach nach eil brobhsairean IOS (uile ach Safari) airson a chleachdadh agus iarraidh bhon stòr teisteanais ionadail. Tha mòran bhuannachdan aig teisteanasan an taca ri iuchraichean logadh a-steach / pas no ssh no dùnadh na puirt riatanach tro bhalla-teine. Ach chan ann mu dheidhinn a tha seo.
Air iOS, tha an dòigh-obrach airson teisteanas a chuir a-steach gu math sìmplidh (chan ann às aonais mion-fhiosrachadh), ach san fharsaingeachd tha e air a dhèanamh a rèir an stiùiridh, agus tha tòrr dhiubh sin air an eadar-lìn agus nach eil rim faighinn ach airson brabhsair Safari. Gu mì-fhortanach, chan eil fios aig Safari mar a chleachdas tu Client Сert airson socaidean lìn, ach tha mòran stiùiridhean air an eadar-lìn air mar a chruthaicheas tu teisteanas mar seo, ach ann an cleachdadh chan eil seo comasach.
Airson websockets a thuigsinn, chleachd sinn am plana a leanas: duilgheadas/beachd-bharail/fuasgladh.
Problem: chan eil taic ann airson socaidean lìn nuair a thathar a’ proxying iarrtasan gu goireasan a tha air an dìon le teisteanas teachdaiche air brobhsair gluasadach Safari airson IOS agus tagraidhean eile a tha air taic teisteanais a chomasachadh.
Beachd-bharail:
Tha e comasach a leithid de eisgeachd a rèiteachadh gus teisteanasan a chleachdadh (le fios nach bi gin ann) gu socaidean lìn de ghoireasan taobh a-staigh / taobh a-muigh.
Airson websockets, faodaidh tu ceangal sònraichte, tèarainte is dìon a dhèanamh a’ cleachdadh seiseanan sealach a thèid a chruthachadh tro iarrtas brobhsair àbhaisteach (neo-websocket).
Faodar seiseanan sealach a chuir an gnìomh le bhith a’ cleachdadh aon fhrithealaiche lìn proxy (modalan agus gnìomhan togte a-mhàin).
Chaidh comharran seisean sealach a chuir an gnìomh mar mhodalan deiseil Apache.
Faodar comharran seisean sealach a chuir an gnìomh le bhith a’ dealbhadh structar an eadar-obrachaidh gu loidsigeach.
Staid faicsinneach às deidh buileachadh.
Amas: bu chòir riaghladh sheirbheisean agus bun-structair a bhith ruigsinneach bho fhòn-làimhe air IOS gun phrògraman a bharrachd (leithid VPN), aonaichte agus tèarainte.
Amas a bharrachd: sàbhaladh ùine agus goireasan/trafaic fòn (bidh cuid de sheirbheisean às aonais socaidean lìn a’ gineadh iarrtasan neo-riatanach) le lìbhrigeadh susbaint nas luaithe air an eadar-lìn gluasadach.
Mar a nì thu sgrùdadh?
1. Duilleagan fosglaidh:
— например, 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. No ann an consol an leasaiche:
Deuchainn beachd-bharail:
1. Tha e comasach a leithid de eisgeachd a rèiteachadh gus teisteanasan a chleachdadh (le fios nach bi gin ann) gu socaidean lìn de ghoireasan a-staigh/a-muigh.
Bidh dearbhadh teisteanais a’ tachairt às deidh iarrtas chun ghoireas proxied, is e sin, crathadh làimhe às deidh iarrtas. Tha seo a’ ciallachadh gun luchdaich an neach-ionaid an toiseach agus an uairsin gearradh dheth an t-iarrtas chun t-seirbheis dìonta. Tha seo dona, ach chan eil e riatanach;
Anns a 'phròtacal http2. Tha e fhathast ann an dreach, agus chan eil fios aig luchd-saothrachaidh brobhsairean mar a chuireas iad an gnìomh e #info mu dheidhinn crathadh làimhe post tls1.3 http2 (chan eil e ag obair a-nis) Cuir an gnìomh RFC 8740 "A’ cleachdadh TLS 1.3 le HTTP/2";
Chan eil e soilleir ciamar a thèid an giollachd seo aonachadh.
b) Aig ìre bhunaiteach, ceadaich ssl gun teisteanas.
SSLVerifyClient need => SSLVerifyClient roghainneil, ach lughdaichidh seo ìre tèarainteachd an fhrithealaiche progsaidh, oir bidh ceangal mar seo air a ghiullachd às aonais teisteanas. Ach, faodaidh tu tuilleadh diùltadh ruigsinneachd air seirbheisean proxied leis an stiùireadh a leanas:
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>
A’ gabhail a-steach an cead a th’ aig sealbhadair an teisteanais mu thràth, ach le teisteanas a dhìth, bha agam ri sealbhadair teisteanais nach robh ann a chur ris ann an cruth aon de na caochladairean a bha rim faighinn SSl_PROTOCOL (an àite SSL_CLIENT_S_DN_CN), barrachd mion-fhiosrachaidh anns na sgrìobhainnean:
2. Airson websockets, faodaidh tu ceangal sònraichte, tèarainte agus dìonta a dhèanamh a 'cleachdadh seiseanan sealach a thèid a chruthachadh rè iarrtas brabhsair àbhaisteach (neo-websocket).
Stèidhichte air eòlas roimhe, feumaidh tu earrann a bharrachd a chur ris an rèiteachadh gus comharran sealach ullachadh airson ceanglaichean socaid lìn rè iarrtas cunbhalach (neo-lìn).
#подготовка передача себе С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>
Sheall deuchainnean gu bheil e ag obair. Tha e comasach briosgaidean a ghluasad thugad fhèin tro bhrobhsair an neach-cleachdaidh.
3. Faodar seiseanan sealach a chuir an gnìomh le bhith a’ cleachdadh aon fhrithealaiche lìn progsaidh (dìreach modalan agus gnìomhan togte).
Mar a fhuair sinn a-mach na bu thràithe, tha tòrr de phrìomh fheartan aig Apache a leigeas leat togalaichean cumhach a chruthachadh. Ach, feumaidh sinn dòighean gus ar fiosrachadh a dhìon fhad ‘s a tha e ann am brabhsair an neach-cleachdaidh, gus am bi sinn a’ stèidheachadh dè a stòradh agus carson, agus dè na gnìomhan togte a chleachdas sinn:
Feumaidh sinn tòcan nach gabh a chòdachadh gu furasta.
Feumaidh sinn tòcan anns a bheil obsolescence air a thogail a-steach dha agus an comas sgrùdadh a dhèanamh air seann aois air an fhrithealaiche.
Feumaidh sinn tòcan a bhios co-cheangailte ri sealbhadair an teisteanais.
Feumaidh seo gnìomh hashing, salann, agus ceann-latha gus an comharra a aois. Stèidhichte air na sgrìobhainnean Abairtean ann am frithealaiche HTTP Apache tha e uile a-mach às a' bhogsa sha1 agus %{TIME} againn.
B’ e an toradh an dealbhadh seo:
#нет сертификата, и обращение к 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>
Chaidh an amas a choileanadh, ach tha duilgheadasan ann le dìth seirbheis (faodaidh tu Cookie bliadhna a dh'aois a chleachdadh), a tha a 'ciallachadh gu bheil na comharran, ged a tha iad sàbhailte airson an cleachdadh a-staigh, mì-shàbhailte airson cleachdadh gnìomhachais (mòr).
4. Tha comharran seisean sealach air an cur an gnìomh mar mhodalan deiseil Apache.
Bha aon dhuilgheadas mòr fhathast bhon ath-aithris roimhe - an neo-chomas smachd a chumail air aois comharran.
Tha sinn a’ coimhead airson modal deiseil a nì seo, a rèir nam faclan: apache token json two factor auth
Tha, tha modalan deiseil ann, ach tha iad uile ceangailte ri gnìomhan sònraichte agus tha artifacts aca ann an cruth seisean a thòiseachadh agus briosgaidean a bharrachd. Is e sin, chan ann airson greis.
Thug e còig uairean a thìde dhuinn a rannsachadh, rud nach tug sin toradh cruaidh.
5. Faodar comharran seisean sealach a chur an gnìomh le bhith a 'dealbhadh structar eadar-obrachaidh gu loidsigeach.
Tha modalan deiseil ro iom-fhillte, oir chan fheum sinn ach gnìomh no dhà.
Le bhith ga ràdh, is e an duilgheadas leis a’ cheann-latha nach eil gnìomhan togte Apache a’ ceadachadh ceann-latha a ghineadh bhon àm ri teachd, agus chan eil cur-ris / toirt air falbh matamataigeach anns na gnìomhan togte nuair a thathar a’ sgrùdadh airson seanachas.
Is e sin, chan urrainn dhut sgrìobhadh:
(%{env:zt-cert-date} + 30) > %{DATE}
Chan urrainn dhut ach dà àireamh a choimeas.
Fhad ‘s a bha mi a’ lorg dòigh-obrach airson duilgheadas Safari, lorg mi artaigil inntinneach: A’ dèanamh cinnteach à HomeAssistant le teisteanasan teachdaiche (ag obair le Safari/iOS)
Tha e a ’toirt cunntas air eisimpleir de chòd ann an Lua airson Nginx, agus a tha, mar a thionndaidh e a-mach, gu mòr ag ath-aithris loidsig a’ phàirt sin den rèiteachadh a tha sinn air a chuir an gnìomh mar-thà, ach a-mhàin cleachdadh an dòigh sailleadh hmac airson hashing ( cha deach seo a lorg ann an Apache).
Dh’fhàs e soilleir gur e cànan le loidsig shoilleir a th’ ann an Lua, agus tha e comasach rudeigin sìmplidh a dhèanamh dha Apache:
Lorg sinn dòigh air caochladairean env a shuidheachadh ann am faidhle beag Lua gus ceann-latha a shuidheachadh bhon àm ri teachd gus coimeas a dhèanamh ris an fhear a th’ ann an-dràsta.
Seo cò ris a tha sgriobt Lua sìmplidh coltach:
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
Agus seo mar a tha e uile ag obair gu h-iomlan, le bhith a’ dèanamh an fheum as fheàrr den àireamh de bhriosgaidean agus a’ cuir an àite an tòcan nuair a thig leth na h-ùine mus tig an t-seann bhriosgaid (token) gu crìch:
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
Leis nach tèid LuaHookAccessChecker a chuir an gnìomh ach às deidh sgrùdaidhean ruigsinneachd stèidhichte air an fhiosrachadh seo bho Nginx.
San fharsaingeachd, chan eil e gu diofar dè an òrdugh a tha na stiùiridhean air an sgrìobhadh ann an rèiteachadh Apache (is dòcha cuideachd Nginx), oir aig a ’cheann thall thèid a h-uile càil a sheòrsachadh a rèir òrdugh an iarrtais bhon neach-cleachdaidh, a tha a rèir an sgeama airson giullachd Lua sgriobtaichean.
Crìochnachadh:
Staid faicsinneach às deidh a bhuileachadh (amas):
tha riaghladh sheirbheisean agus bun-structair ri fhaighinn bho fhòn-làimhe air IOS gun phrògraman a bharrachd (VPN), aonaichte agus tèarainte.
Chaidh an amas a choileanadh, bidh socaidean lìn ag obair agus tha ìre tèarainteachd aca nach eil nas lugha na teisteanas.