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
- Š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
- 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,
- Š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,
- Š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
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,
- Š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)%C2%A0), 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,
- Š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)
--
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%3a3... 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.20... (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):
- 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...
community-list@lists.vpsfree.cz