ProHoster > Blog > Pangangasiwa > Paano namin sa ZeroTech ikinonekta ang Apple Safari at mga certificate ng kliyente gamit ang mga websocket
Paano namin sa ZeroTech ikinonekta ang Apple Safari at mga certificate ng kliyente gamit ang mga websocket
Ang artikulo ay magiging kapaki-pakinabang sa mga taong:
alam kung ano ang Client Cert at nauunawaan kung bakit kailangan nito ng mga websocket sa mobile Safari;
Gusto kong mag-publish ng mga serbisyo sa web sa isang limitadong lupon ng mga tao o sa aking sarili lamang;
iniisip na ang lahat ay nagawa na ng isang tao, at nais na gawing mas maginhawa at mas ligtas ang mundo.
Ang kasaysayan ng mga websocket ay nagsimula mga 8 taon na ang nakakaraan. Noong nakaraan, ang mga pamamaraan ay ginamit sa anyo ng mga mahabang kahilingan sa http (talagang mga tugon): nagpadala ang browser ng gumagamit ng isang kahilingan sa server at naghintay na sumagot ito ng isang bagay, pagkatapos ng tugon ay kumonekta muli ito at naghintay. Ngunit pagkatapos ay lumitaw ang mga websocket.
Ilang taon na ang nakalipas, bumuo kami ng sarili naming pagpapatupad sa purong PHP, na hindi maaaring gumamit ng mga kahilingan sa https, dahil ito ang layer ng link. Hindi pa nagtagal, halos lahat ng web server ay natutong mag-proxy ng mga kahilingan sa https at suportahan ang connection:upgrade.
Nang mangyari ito, halos naging default na serbisyo ang mga websocket para sa mga application ng SPA, dahil gaano kaginhawang magbigay ng nilalaman sa user sa inisyatiba ng server (magpadala ng mensahe mula sa ibang user o mag-download ng bagong bersyon ng isang imahe, dokumento, presentasyon na kasalukuyang ini-edit ng ibang tao) .
Bagama't medyo matagal na ang Client Certificate, nananatili pa rin itong hindi gaanong suportado, dahil lumilikha ito ng maraming problema kapag sinusubukang i-bypass ito. At (posibleng :slightly_smiling_face: ) kaya ang mga browser ng IOS (lahat maliban sa Safari) ay ayaw itong gamitin at hilingin ito mula sa lokal na tindahan ng sertipiko. Ang mga sertipiko ay may maraming mga pakinabang kumpara sa pag-login/pass o ssh key o pagsasara ng mga kinakailangang port sa pamamagitan ng isang firewall. Ngunit hindi iyon ang tungkol dito.
Sa iOS, ang pamamaraan para sa pag-install ng isang sertipiko ay medyo simple (hindi walang mga detalye), ngunit sa pangkalahatan ito ay ginagawa ayon sa mga tagubilin, kung saan marami sa Internet at kung saan ay magagamit lamang para sa Safari browser. Sa kasamaang palad, hindi alam ng Safari kung paano gamitin ang Client Π‘ert para sa mga web socket, ngunit maraming mga tagubilin sa Internet kung paano lumikha ng naturang sertipiko, ngunit sa pagsasanay ito ay hindi matamo.
Upang maunawaan ang mga websocket, ginamit namin ang sumusunod na plano: problema/hypothesis/solusyon.
Problema: walang suporta para sa mga web socket kapag nag-proxy ng mga kahilingan sa mga mapagkukunan na protektado ng isang client certificate sa Safari mobile browser para sa IOS at iba pang mga application na pinagana ang suporta sa certificate.
Hypotheses:
Posibleng i-configure ang naturang pagbubukod upang gumamit ng mga sertipiko (alam na wala) sa mga websocket ng panloob/panlabas na mga mapagkukunang proxied.
Para sa mga websocket, maaari kang gumawa ng natatangi, secure at mapagtatanggol na koneksyon gamit ang mga pansamantalang session na nabuo sa panahon ng isang normal (hindi websocket) na kahilingan sa browser.
Maaaring ipatupad ang mga pansamantalang session gamit ang isang proxy web server (mga built-in na module at function lang).
Naipatupad na ang mga pansamantalang session token bilang mga nakahanda nang Apache module.
Maaaring ipatupad ang mga pansamantalang session token sa pamamagitan ng lohikal na pagdidisenyo ng istruktura ng pakikipag-ugnayan.
Nakikitang estado pagkatapos ng pagpapatupad.
Layunin: ang pamamahala ng mga serbisyo at imprastraktura ay dapat ma-access mula sa isang mobile phone sa IOS nang walang karagdagang mga programa (tulad ng VPN), pinag-isa at secure.
Karagdagang layunin: makatipid ng oras at mga mapagkukunan/trapiko ng telepono (ilang mga serbisyo na walang mga web socket ay bumubuo ng mga hindi kinakailangang kahilingan) na may mas mabilis na paghahatid ng nilalaman sa mobile Internet.
1. Posibleng i-configure ang naturang exception para gumamit ng mga certificate (alam na wala) sa mga web socket ng internal/external na proxied na mapagkukunan.
Ang pamamaraang ito ay may mga sumusunod na nuances:
Nagaganap ang pag-verify ng certificate pagkatapos ng isang kahilingan sa na-proxy na mapagkukunan, iyon ay, post request handshake. Ibig sabihin, maglo-load muna ang proxy at pagkatapos ay puputulin ang kahilingan sa protektadong serbisyo. Ito ay masama, ngunit hindi kritikal;
Sa http2 protocol. Nasa draft pa rin ito, at hindi alam ng mga manufacturer ng browser kung paano ito ipatupad #info tungkol sa tls1.3 http2 post handshake (hindi gumagana ngayon) Ipatupad ang RFC 8740 "Paggamit ng TLS 1.3 na may HTTP/2";
Hindi malinaw kung paano pag-isahin ang pagpoprosesong ito.
b) Sa isang pangunahing antas, payagan ang ssl nang walang sertipiko.
Kinakailangan ng SSLVerifyClient => SSLVerifyClient opsyonal, ngunit binabawasan nito ang antas ng seguridad ng proxy server, dahil ang naturang koneksyon ay ipoproseso nang walang sertipiko. Gayunpaman, maaari mong higit pang tanggihan ang pag-access sa mga proxied na serbisyo gamit ang sumusunod na direktiba:
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"
Ang parehong mga pagpipilian ay sinubukan, ang opsyon na "b" ay pinili para sa kanyang kagalingan sa maraming bagay at pagiging tugma sa protocol ng http2.
Upang makumpleto ang pag-verify ng hypothesis na ito, tumagal ng maraming mga eksperimento sa pagsasaayos; ang mga sumusunod na disenyo ay sinubukan:
Ang resulta ay ang sumusunod na pangunahing disenyo:
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>
Isinasaalang-alang ang umiiral na awtorisasyon ng may-ari ng certificate, ngunit may nawawalang certificate, kinailangan kong magdagdag ng hindi umiiral na may-ari ng certificate sa anyo ng isa sa mga available na variable na SSl_PROTOCOL (sa halip na SSL_CLIENT_S_DN_CN), higit pang mga detalye sa dokumentasyon:
2. Para sa mga websocket, maaari kang gumawa ng natatangi, secure at protektadong koneksyon gamit ang mga pansamantalang session na nabuo sa panahon ng isang normal (hindi websocket) na kahilingan sa browser.
Batay sa nakaraang karanasan, kailangan mong magdagdag ng karagdagang seksyon sa configuration upang makapaghanda ng mga pansamantalang token para sa mga koneksyon sa web socket sa panahon ng isang regular na kahilingan (hindi web socket).
Ang pagsubok ay nagpakita na ito ay gumagana. Posibleng ilipat ang Cookies sa iyong sarili sa pamamagitan ng browser ng user.
3. Maaaring ipatupad ang mga pansamantalang session gamit ang isang proxy web server (mga built-in na module at function lamang).
Tulad ng nalaman namin kanina, ang Apache ay may napakaraming pangunahing pag-andar na nagbibigay-daan sa iyo upang lumikha ng mga kondisyong konstruksyon. Gayunpaman, kailangan namin ng paraan upang maprotektahan ang aming impormasyon habang ito ay nasa browser ng user, kaya itinatag namin kung ano ang iimbak at bakit, at kung anong mga built-in na function ang gagamitin namin:
Kailangan natin ng token na hindi madaling ma-decode.
Kailangan namin ng token na may laos na nakapaloob dito at ang kakayahang suriin ang pagkaluma sa server.
Kailangan namin ng token na iuugnay sa may-ari ng certificate.
Nangangailangan ito ng function ng hashing, asin, at petsa ng edad ng token. Batay sa dokumentasyon Mga expression sa Apache HTTP Server mayroon kaming lahat ng ito sa labas ng kahon sha1 at %{TIME}.
Naabot na ang layunin, ngunit may mga problema sa pagiging luma ng server (maaari kang gumamit ng isang taong gulang na Cookie), na nangangahulugang ang mga token, bagama't ligtas para sa panloob na paggamit, ay hindi ligtas para sa pang-industriya (mass) na paggamit.
4. Naipatupad na ang mga temporary session token bilang mga nakahanda nang Apache modules.
Isang makabuluhang problema ang nananatili mula sa nakaraang pag-ulit - ang kawalan ng kakayahang kontrolin ang pagtanda ng token.
Naghahanap kami ng isang handa na module na gumagawa nito, ayon sa mga salita: apache token json two factor auth
Oo, may mga nakahanda nang module, ngunit lahat sila ay nakatali sa mga partikular na aksyon at may mga artifact sa anyo ng pagsisimula ng isang session at karagdagang Cookies. Ibig sabihin, hindi saglit.
Inabot kami ng limang oras sa paghahanap, na hindi nagbigay ng konkretong resulta.
5. Maaaring ipatupad ang mga pansamantalang session token sa pamamagitan ng lohikal na pagdidisenyo ng istruktura ng mga pakikipag-ugnayan.
Masyadong kumplikado ang mga ready-made na module, dahil kailangan lang namin ng ilang function.
Iyon ay sinabi, ang problema sa petsa ay hindi pinapayagan ng mga built-in na function ng Apache ang pagbuo ng petsa mula sa hinaharap, at walang mathematical na pagdaragdag/pagbabawas sa mga built-in na function kapag sinusuri ang pagkaluma.
Iyon ay, hindi ka maaaring sumulat:
(%{env:zt-cert-date} + 30) > %{DATE}
Dalawang numero lang ang maihahambing mo.
Habang naghahanap ng isang solusyon para sa problema sa Safari, nakakita ako ng isang kawili-wiling artikulo: Pag-secure ng HomeAssistant gamit ang mga certificate ng kliyente (gumagana sa Safari/iOS)
Inilalarawan nito ang isang halimbawa ng code sa Lua para sa Nginx, at kung saan, tulad ng nangyari, inuulit ang lohika ng bahaging iyon ng pagsasaayos na naipatupad na namin, maliban sa paggamit ng hmac salting method para sa pag-hash ( hindi ito natagpuan sa Apache).
Naging malinaw na ang Lua ay isang wika na may malinaw na lohika, at posible na gumawa ng isang bagay na simple para sa Apache:
Nakakita kami ng paraan upang magtakda ng mga variable ng env sa isang maliit na file ng Lua upang magtakda ng petsa mula sa hinaharap upang ihambing sa kasalukuyan.
Ito ang hitsura ng isang simpleng script ng Lua:
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
At ito ay kung paano gumagana ang lahat sa kabuuan, na may pag-optimize ng bilang ng Cookies at pagpapalit ng token kapag dumating ang kalahati ng oras bago mag-expire ang lumang Cookie (token):
Sa pangkalahatan, hindi mahalaga kung anong pagkakasunud-sunod ang mga direktiba ay nakasulat sa Apache (marahil din ng Nginx) na pagsasaayos, dahil sa huli ang lahat ay pag-uuri-uriin batay sa pagkakasunud-sunod ng kahilingan mula sa gumagamit, na tumutugma sa pamamaraan para sa pagproseso. Mga script ng Lua.
Pagkumpleto:
Nakikitang estado pagkatapos ng pagpapatupad (layunin):
Ang pamamahala ng mga serbisyo at imprastraktura ay makukuha mula sa isang mobile phone sa IOS nang walang karagdagang mga programa (VPN), pinag-isa at secure.
Ang layunin ay nakamit, ang mga web socket ay gumagana at may antas ng seguridad na hindi bababa sa isang sertipiko.