Ahoj, přes týden jsem se snažil nastudovat nasazení Nginx jako proxy a vrtá mi hlavou několik věcí. Chtěl jsem proto poprosit o radu zkušenější, abych něco "nezkonil" hned na začátku :-) 1) Spojení mezi proxy a backendem V jiném vlákně tady proběhla diskuze ohledně "vnitřních" IP adres. Na KB jsem se dočetl, že se o ně musí žádat a můžou se měnit. Mají pro spojení mezi proxy a backendem vnitřní adresy nějaký význam, například z hlediska bezpečnosti nebo rychlosti? Můj plán byl dělat spojení mezi stroji pomocí přidělených IPv6 adres. 2) Šifrování mezi proxy a backendem Myslím, že v tom samém vlákně Snajpa psal něco ve smyslu, že na síti mezi VPS je těžké odposlechnout provoz (myslím, že se tam řešili privátní vlany nebo tak něco). Úplně se v tomhle neorientuji a proto jsem se chtěl zeptat, zda byste v našem prostředí považovali za bezpečné, kdybych SSL spojení ukončoval na proxy a mezi proxy a backendem posílal jen klasické HTTP? Na webu Nginxu jsem našel, že je možné mezi proxy a backendem rozjet také SSL spojení, ale nevím, zda to není overkill. 3) SSH tunel na proxy Aktuálně mám na serveru jednu stránku, pro kterou Nginx poslouchá na 127.0.0.1 a klienti se k ní propojují pomocí SSH tunelu a port forwardingu. V případě nasazení jako "proxy - backend" bych na proxy opět udělal server poslouchající na 127.0.0.1 a předávající požadavky na proxy. Bude stačit, když na backendu pro tuto stránku nastavím omezení přístupu jen z IP adresy proxy? Nebo bych to měl ošetřit ještě nějak dál? Předem díky za pomoc! Všechny zdraví Honza -- Jan B. Kolář Zažeň nudu Hodolanská 17, 779 00 Olomouc tel: +420 605 800 859 e-mail: janbivoj.kolar@zazen-nudu.cz www.zazen-nudu.cz
2) Šifrování mezi proxy a backendem
Myslím, že v tom samém vlákně Snajpa psal něco ve smyslu, že na síti mezi VPS je těžké odposlechnout provoz (myslím, že se tam řešili privátní vlany nebo tak něco). Úplně se v tomhle neorientuji a proto jsem se chtěl zeptat, zda byste v našem prostředí považovali za bezpečné, kdybych SSL spojení ukončoval na proxy a mezi proxy a backendem posílal jen klasické HTTP? Na webu Nginxu jsem našel, že je možné mezi proxy a backendem rozjet také SSL spojení, ale nevím, zda to není overkill.
Žádné VLAN - jestli si to dobře pamatuju, tak mezi každou VPS a jejím hostitelem existuje jedna dvoučlenná síť, takže není možné odposlouchávání na síti ze strany jiné VPS (což nic neříká o možnostech odposlouchávání na fyzické síti mezi hostiteli, ale to už je něco jiného, na to byste se z té VPS musel prohákovat ven do hostitele, nebo se nějak dostat k síťovým prvků mezi hostiteli.) Ohledně SSL mezi proxy a backendem je jedna věc ke zvážení: jestli všechny weby, které provozujete, budou schopny detekovat SSL spojení i na HTTP. Mluvím o funkci "přesměrování na HTTPS", kde aplikace zjišťuje, jestli je příchozí spojení šifrované, z informací od svého webserveru - který vždy uvidí HTTP. Toto se řeší například tím, že proxy do požadavku předávaného backendu přidá hlavičku (třeba) X-Forwarded-Proto, ale pokud ji aplikace nebude umět použít, tak se všechny požadavky zacyklí do přesměrování na https
3) SSH tunel na proxy
Aktuálně mám na serveru jednu stránku, pro kterou Nginx poslouchá na 127.0.0.1 a klienti se k ní propojují pomocí SSH tunelu a port forwardingu. V případě nasazení jako "proxy - backend" bych na proxy opět udělal server poslouchající na 127.0.0.1 a předávající požadavky na proxy. Bude stačit, když na backendu pro tuto stránku nastavím omezení přístupu jen z IP adresy proxy? Nebo bych to měl ošetřit ještě nějak dál?
Záleží na tom, jak paranoidní budete :-) Tím serverem poslouchajícím na proxy na 127.0.0.1 může být SSH klient, který bude mít vytvořený tunel na backend server a předávat spojení na jeho 127.0.0.1
Ahoj,
2) Šifrování mezi proxy a backendem
Myslím, že v tom samém vlákně Snajpa psal něco ve smyslu, že na síti mezi VPS je těžké odposlechnout provoz (myslím, že se tam řešili privátní vlany nebo tak něco). Úplně se v tomhle neorientuji a proto jsem se chtěl zeptat, zda byste v našem prostředí považovali za bezpečné, kdybych SSL spojení ukončoval na proxy a mezi proxy a backendem posílal jen klasické HTTP? Na webu Nginxu jsem našel, že je možné mezi proxy a backendem rozjet také SSL spojení, ale nevím, zda to není overkill.
tady jen doplním, že pokud nechceš, Nginx _nemusí_ vystupovat v roli TLS termination proxy. Jinak řečeno Nginx umí celý ten stream vzít a podle SNI hlavičky předat dále na konkrétní stroj. Konfiguruje se to pak ve "stream" direktivě, nikoli "http". Výhoda je mj. i ta, že takto můžeš obsloužit nikoli jen HTTPS, ale cokoli, co lze do TLS zabalit. A jinak Nginx umí také proxy protocol převzatý z HAProxy, takže i tímto způsobem umí předat TLS stream dále (včetně informace o source IP). Reverse proxy != TLS termination proxy, záleží čistě na Tobě, kde chceš TLS ukončit. Argumentů pro různé varianty je hodně. Radek Zajíc tady dal dříve odkaz na pěknou a srozumitelnou přednášku z Mythic Beasts, tuším i tam to zmiňovali, jak to mají vyřešené. Petr
Ahoj, díky moc Petrovi a Jirkovi za reakce. Asi jsem měl napsat, že ta TLS terminace na proxy se mi líbí a chtěl bych to tak zkusit nasadit :-) Šlo mi hlavně o to, jestli mi v našem VPS prostředí neunikají nějaká vážnější bezpečností rizika, na která bych si měl dát pozor. Díky za upozornění ohledně aplikací a jejich případné nefunkčnosti za proxy. Už jsem na to narazil v jednom článku a můj plán je přesouvat jeden web po druhém, abych to mohl otestovat a případně odladit. Ještě jsem se s Vámi chtěl podělit o jeden odkaz s informacemi a ukázkami nastavení Nginxu. Přijde mi to celkem solidně zpracované, tak se to třeba bude někomu hodit: https://github.com/trimstray/nginx-admins-handbook Zdraví Honza Dne 13. 06. 20 v 14:24 Petr Kutalek napsal(a):
Ahoj,
2) Šifrování mezi proxy a backendem
Myslím, že v tom samém vlákně Snajpa psal něco ve smyslu, že na síti mezi VPS je těžké odposlechnout provoz (myslím, že se tam řešili privátní vlany nebo tak něco). Úplně se v tomhle neorientuji a proto jsem se chtěl zeptat, zda byste v našem prostředí považovali za bezpečné, kdybych SSL spojení ukončoval na proxy a mezi proxy a backendem posílal jen klasické HTTP? Na webu Nginxu jsem našel, že je možné mezi proxy a backendem rozjet také SSL spojení, ale nevím, zda to není overkill.
tady jen doplním, že pokud nechceš, Nginx _nemusí_ vystupovat v roli TLS termination proxy. Jinak řečeno Nginx umí celý ten stream vzít a podle SNI hlavičky předat dále na konkrétní stroj. Konfiguruje se to pak ve "stream" direktivě, nikoli "http". Výhoda je mj. i ta, že takto můžeš obsloužit nikoli jen HTTPS, ale cokoli, co lze do TLS zabalit.
A jinak Nginx umí také proxy protocol převzatý z HAProxy, takže i tímto způsobem umí předat TLS stream dále (včetně informace o source IP). Reverse proxy != TLS termination proxy, záleží čistě na Tobě, kde chceš TLS ukončit. Argumentů pro různé varianty je hodně.
Radek Zajíc tady dal dříve odkaz na pěknou a srozumitelnou přednášku z Mythic Beasts, tuším i tam to zmiňovali, jak to mají vyřešené.
Petr _______________________________________________ Community-list mailing list Community-list@lists.vpsfree.cz http://lists.vpsfree.cz/listinfo/community-list
-- Jan B. Kolář Zažeň nudu Hodolanská 17, 779 00 Olomouc tel: +420 605 800 859 e-mail: janbivoj.kolar@zazen-nudu.cz www.zazen-nudu.cz
Jen protože to dnes je bezpečné, neznamená že že to zítra někdo nedokáže zneužít. Netřeba implementovat celý NIST zero-trust ( https://csrc.nist.gov/publications/detail/sp/800-207/draft ), ale třeba doručení HTTPS až na webserver vs ukončení na proxy, nic nestojí. Jindra On Sun, Jun 14, 2020, at 15:19, Jan B. Kolář wrote:
Ahoj,
díky moc Petrovi a Jirkovi za reakce. Asi jsem měl napsat, že ta TLS terminace na proxy se mi líbí a chtěl bych to tak zkusit nasadit :-) Šlo mi hlavně o to, jestli mi v našem VPS prostředí neunikají nějaká vážnější bezpečností rizika, na která bych si měl dát pozor.
Díky za upozornění ohledně aplikací a jejich případné nefunkčnosti za proxy. Už jsem na to narazil v jednom článku a můj plán je přesouvat jeden web po druhém, abych to mohl otestovat a případně odladit.
Ještě jsem se s Vámi chtěl podělit o jeden odkaz s informacemi a ukázkami nastavení Nginxu. Přijde mi to celkem solidně zpracované, tak se to třeba bude někomu hodit:
https://github.com/trimstray/nginx-admins-handbook
Zdraví
Honza
Dne 13. 06. 20 v 14:24 Petr Kutalek napsal(a):
Ahoj,
2) Šifrování mezi proxy a backendem
Myslím, že v tom samém vlákně Snajpa psal něco ve smyslu, že na síti mezi VPS je těžké odposlechnout provoz (myslím, že se tam řešili privátní vlany nebo tak něco). Úplně se v tomhle neorientuji a proto jsem se chtěl zeptat, zda byste v našem prostředí považovali za bezpečné, kdybych SSL spojení ukončoval na proxy a mezi proxy a backendem posílal jen klasické HTTP? Na webu Nginxu jsem našel, že je možné mezi proxy a backendem rozjet také SSL spojení, ale nevím, zda to není overkill.
tady jen doplním, že pokud nechceš, Nginx _nemusí_ vystupovat v roli TLS termination proxy. Jinak řečeno Nginx umí celý ten stream vzít a podle SNI hlavičky předat dále na konkrétní stroj. Konfiguruje se to pak ve "stream" direktivě, nikoli "http". Výhoda je mj. i ta, že takto můžeš obsloužit nikoli jen HTTPS, ale cokoli, co lze do TLS zabalit.
A jinak Nginx umí také proxy protocol převzatý z HAProxy, takže i tímto způsobem umí předat TLS stream dále (včetně informace o source IP). Reverse proxy != TLS termination proxy, záleží čistě na Tobě, kde chceš TLS ukončit. Argumentů pro různé varianty je hodně.
Radek Zajíc tady dal dříve odkaz na pěknou a srozumitelnou přednášku z Mythic Beasts, tuším i tam to zmiňovali, jak to mají vyřešené.
Petr _______________________________________________ Community-list mailing list Community-list@lists.vpsfree.cz http://lists.vpsfree.cz/listinfo/community-list
-- Jan B. Kolář
Zažeň nudu Hodolanská 17, 779 00 Olomouc tel: +420 605 800 859 e-mail: janbivoj.kolar@zazen-nudu.cz www.zazen-nudu.cz
_______________________________________________ Community-list mailing list Community-list@lists.vpsfree.cz http://lists.vpsfree.cz/listinfo/community-list
Jak se to vezme. Znamena to slozitejsi distribuci certifikatu a udrzovani in -sync (proxy je jedna az dve, webserveru muzou byt desitky), webserver se zbytecne zatezuje vypoctem sifer, slozitejsi aplikaci, chyba na webu muze zpristupnit private key. Oba pristupy maji svoje pro i proti a musi se zvazit vzdycky co je pro danou aplikaci vhodne. Ja osobne HTTPS terminuju na balanceru na HAProxy a pak dal uz jedu po vnitrni VLANe nesifrovane. Ondra Flidr ---------- Původní e-mail ---------- Od: Jindřich Sadílek <jindrich.sadilek@gmail.com> Komu: community-list@lists.vpsfree.cz Datum: 14. 6. 2020 16:45:39 Předmět: Re: [vpsFree.cz: community-list] Nginx proxy, SSH " Jen protože to dnes je bezpečné, neznamená že že to zítra někdo nedokáže zneužít. Netřeba implementovat celý NIST zero-trust ( https://csrc.nist.gov/ publications/detail/sp/800-207/draft (https://csrc.nist.gov/publications/detail/sp/800-207/draft) ), ale třeba doručení HTTPS až na webserver vs ukončení na proxy, nic nestojí. Jindra On Sun, Jun 14, 2020, at 15:19, Jan B. Kolář wrote: " Ahoj, díky moc Petrovi a Jirkovi za reakce. Asi jsem měl napsat, že ta TLS terminace na proxy se mi líbí a chtěl bych to tak zkusit nasadit :-) Šlo mi hlavně o to, jestli mi v našem VPS prostředí neunikají nějaká vážnější bezpečností rizika, na která bych si měl dát pozor. Díky za upozornění ohledně aplikací a jejich případné nefunkčnosti za proxy. Už jsem na to narazil v jednom článku a můj plán je přesouvat jeden web po druhém, abych to mohl otestovat a případně odladit. Ještě jsem se s Vámi chtěl podělit o jeden odkaz s informacemi a ukázkami nastavení Nginxu. Přijde mi to celkem solidně zpracované, tak se to třeba bude někomu hodit: https://github.com/trimstray/nginx-admins-handbook (https://github.com/trimstray/nginx-admins-handbook) Zdraví Honza Dne 13. 06. 20 v 14:24 Petr Kutalek napsal(a):
Ahoj,
2) Šifrování mezi proxy a backendem
Myslím, že v tom samém vlákně Snajpa psal něco ve smyslu, že na síti
mezi VPS je těžké odposlechnout provoz (myslím, že se tam řešili
privátní vlany nebo tak něco). Úplně se v tomhle neorientuji a proto
jsem se chtěl zeptat, zda byste v našem prostředí považovali za
bezpečné, kdybych SSL spojení ukončoval na proxy a mezi proxy a
backendem posílal jen klasické HTTP? Na webu Nginxu jsem našel, že je
možné mezi proxy a backendem rozjet také SSL spojení, ale nevím, zda
to není overkill.
tady jen doplním, že pokud nechceš, Nginx _nemusí_ vystupovat v roli
TLS termination proxy. Jinak řečeno Nginx umí celý ten stream vzít a
podle SNI hlavičky předat dále na konkrétní stroj. Konfiguruje se to
pak ve "stream" direktivě, nikoli "http". Výhoda je mj. i ta, že takto
můžeš obsloužit nikoli jen HTTPS, ale cokoli, co lze do TLS zabalit.
A jinak Nginx umí také proxy protocol převzatý z HAProxy, takže i
tímto způsobem umí předat TLS stream dále (včetně informace o source
IP). Reverse proxy != TLS termination proxy, záleží čistě na Tobě, kde
chceš TLS ukončit. Argumentů pro různé varianty je hodně.
Radek Zajíc tady dal dříve odkaz na pěknou a srozumitelnou přednášku z
Mythic Beasts, tuším i tam to zmiňovali, jak to mají vyřešené.
Petr
_______________________________________________
Community-list mailing list
Community-list@lists.vpsfree.cz(mailto:Community-list@lists.vpsfree.cz)
http://lists.vpsfree.cz/listinfo/community-list (http://lists.vpsfree.cz/listinfo/community-list)
-- Jan B. Kolář Zažeň nudu Hodolanská 17, 779 00 Olomouc tel: +420 605 800 859 e-mail: janbivoj.kolar@zazen-nudu.cz(mailto:janbivoj.kolar@zazen-nudu.cz) www.zazen-nudu.cz(http://www.zazen-nudu.cz) _______________________________________________ Community-list mailing list Community-list@lists.vpsfree.cz(mailto:Community-list@lists.vpsfree.cz) http://lists.vpsfree.cz/listinfo/community-list (http://lists.vpsfree.cz/listinfo/community-list) " _______________________________________________ Community-list mailing list Community-list@lists.vpsfree.cz http://lists.vpsfree.cz/listinfo/community-list "
TL;DR něco k nastavení Nginx Ahoj, když se tady poslední dobou probírá dost Nginx, tak jsem si říkal, že zkusím napsat nějaké poznámky, které jsem jinde uceleně nenašel, k věcem, co mi přišly špatné. Snad to někomu pomůže. Přeci jen je prima, pokud ty služby máme nastaveny správně. Omlouvám se všem, pro které to byly sovy v Aténách. Předně musím říct, že já mám Nginx nesmírně rád; myslím si, že Igor Sysojev odvedl výbornou práci a trošku mu závidím. Již jsem nějaký ten Nginx nastavil (včetně vlastních modulů), takže vím, co mne také na něm hněvá. 1) tip: dejte si pozor na to, že Nginx v upstreamu nepoužívá při HTTPS SNI. `proxy_ssl_server_name on`, defaultně je to off; 2) Nginx neumí ještě ani v roce 2020 volbu ekvivalentní `strict-sni` v HAProxy, bug je na to veden 8 let a z vývojářů je cítit lehká arogance a nepochopení stavu věci [https://trac.nginx.org/nginx/ticket/195]. Někteří to řeší tak, že dávají HAProxy před Nginx, což je IMO overkill. Pokud mi na HTTPS přistupuje klient a neuvede SNI pole v TLS, Nginx použije defaultně první TLS certifikát, který má v konfiguraci uvedený. Mi se to nelíbí a nedává mi to smysl. Je radost se podívat, jak mají weby vedené u Cloudflare ve Qualys SSL reportu pouze jeden certifikát. (Tady je vidět rozdíl: nějaký náhodný Cloudflare hostovaný web: https://www.ssllabs.com/ssltest/analyze.html?d=oops.ml&s=2606%3a4700%3a3037%... a tady se omlouvám Janovi, že jsem vzal jeho web, ale nic jiného mne nenapadlo: https://www.ssllabs.com/ssltest/analyze.html?d=www.zazen-nudu.cz&s=37.205.10... (certificate 2 pro No SNI)) Z vlastních zkušeností mohu říci, že bez SNI a s chybným SNI, mám výhradně závadný provoz z Ruska a Číny a takový, kde si jakýsi člen vpsFree, co měl "mé" IPv4 a IPv6 adresy předemnou, zapomenul zrušit záznamy v DNS u svých klientů. Možnost je snadno opatchovat Nginx, nebo trochu zneužít nastavení TLS. Pokud nepoužijeme TLSv1.3, nýbrž pouze TLSv1.2(!), je možné Nginx jako první TLS http/server nastavit tak, že bude podporovat pouze aNULL cipher suite (tj. bez autentizace, takže nebude nabízet certifikát pro Server Hello) a takovéto spojení budeme zavírat bez odpovědi: ``` $ less /etc/nginx/nginx.conf http { ssl_protocols TLSv1.2; # we do not want TLSv1.3 because of "strict sni" workaround ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256"; ssl_ecdh_curve "prime256v1"; # aka "strict sni" workaround # https://trac.nginx.org/nginx/ticket/195 server { listen *:443 ssl http2; listen [::]:443 ssl http2; server_name --; ssl_ciphers "ADH-AES128-SHA256"; # aNULL cipher, no authentication, no cert :) ssl_stapling off; ssl_certificate certs/dummy.pem; # it could be sneak-oil etc. ssl_certificate_key certs/dummy.key; return 444; # non-standard code that closes the connection } server { listen *:443 ssl http2; listen [::]:443 ssl http2; server_name example.com; root /srv/http/example.com; index index.txt index.html; ssl_certificate certs/example.com.pem; ssl_certificate_key certs/example.com.key; // … } server { listen *:443 ssl http2; listen [::]:443 ssl http2; server_name sample.cz; root /srv/http/sample.cz; index index.txt index.html; ssl_certificate certs/sample.cz.pem; ssl_certificate_key certs/sample.cz.key; // … } } ``` OK, funguje to pěkně, funguje to dokonce správně, ale s použitím TLSv1.3 to padá. Ovšem zdá se, že to vývojáři nakonec řešit budou. :) (Dalo by se to asi i řešit přes iptables, https://github.com/Lochnair/xt_tls, ale do toho jsem se pouštět nechtěl.) 3) Nginx chybně pracuje s OCSP Must-Staple certifikáty: Pokud máte v certifikátu "OCSP Must-Staple" assertion (OID 1.3.6.1.5.5.7.1.24), což tedy doporučuji, podporuje je i Let's Encrypt, Nginx jako první odpověď po restartu OCSP nepošle(!), teprve si jej získá a bude jej již běžně posílat až s druhou a další odpovědí. Ovšem to není košér, protože první odpověď je bez OCSP, ovšem s cert. příznakem Must-Staple. Vyřešil jsem to tak, že jsem si na nginx.service v systemd (protože jej mám rád) nabindoval druhou service (spouštěnou/zastavenou automaticky spolu s nginx), která mi provede první dotazy přes s_client v openssl: ``` $ less /etc/systemd/system/nginx-ocspfix.service [Unit] Description=nginx OCSP fix Wants=network-online.target After=network-online.target BindsTo=nginx.service After=nginx.service [Service] Type=oneshot User=nobody Group=nobody ExecStart=/usr/local/bin/nginx-ocspfix.sh RemainAfterExit=true [Install] WantedBy=nginx.service ``` a ``` $ less /usr/local/bin/nginx-ocspfix.sh #!/bin/bash for c in /etc/nginx/certs/*.pem; do domains=$(openssl x509 -noout -text -in $c | grep DNS: | perl -l -0777 -ne '@names=/\bDNS:([^\s,]+)/g; print join("\n", sort @names);' | sort -u) for d in $domains; do openssl s_client -connect 127.0.0.1:443 -servername $d -status < /dev/null > /dev/null 2> /dev/null done done ``` 4) Pikoška – malé tiskací "P", které mne stálo hromadu času, ale spolu s Googlem jsem to dohromady dal (vize přílohu): Ve své konfiguraci preferuji své pořadí cipher suites (AES-GCM), ovšem s tím, že umožňuji využít CHACHA20-POLY1305, pokud klient preferuje ji, protože je energeticky méně náročná, typicky nemá-li klient v CPU akcelerované AES-GCM (AES-NI instrukce pro AES a PCLMULQDQ pro Galois Field operace v x86), jedná se většinou o nějaké Androidy. Nginx to nastavit umožňuje s novým openssl, ovšem je mu trošku pomoci s konfigurací. Opět využívám systemd – v proměnných prostředí mu předávám vlastní konfiguraci openssl.conf: ```$ less /etc/nginx/openssl.conf openssl_conf = default_conf [default_conf] ssl_conf = ssl_sect [ssl_sect] system_default = system_default_sect [system_default_sect] Options = ServerPreference,PrioritizeChaCha ``` a ``` $ less /etc/systemd/system/nginx.service.d/override.conf [Unit] Wants=network-online.target After=network-online.target [Service] Environment=OPENSSL_CONF=/etc/nginx/openssl.conf ``` A jde to! :) 5) QUIC (HTTP/3) netřeba ani vzpomínat, Cloudflare dokonce připravilo patche a nic… OK, dost stesku nad Nginx, přeji všem pěkně nastavený Nginx, ať už dělá proxy nebo servíruje obsah! :) Petr
Dne 14. 06. 20 v 22:56 Petr Kutalek napsal(a):
5) QUIC (HTTP/3) netřeba ani vzpomínat, Cloudflare dokonce připravilo patche a nic…
Paráda, díky za super rozbor a zajímavé tipy. Jen doplním, že Nginx už má experimentální podporu QUIC a HTTP/3. Viz: https://www.root.cz/zpravicky/nginx-ma-experimentalni-podporu-pro-quic-a-htt... -- Petr Krčmář vpsFree.cz
participants (6)
-
Jan B. Kolář -
Jindřich Sadílek -
Jirka Bourek -
Ondrej.Flidr -
Petr Krcmar -
Petr Kutalek