Pokud jste správce serveru, pravděpodobně máte webový server podle svého výběru, jako je Apache nebo Nginx. Apache je známý webový server již od 90. let. Nginx byl poprvé vyvinut v roce 2004 a rychle se prosadil díky své nízké kapacitě paměti a vysoké rychlosti zpracování statických HTML souborů.
Apache i Nginx podporují virtuální hosting, což znamená, že můžete hostovat více webových stránek nebo webových aplikací na stejném serveru. Setkáte se však se situacemi, kdy máte spuštěný existující webový server, ale konkrétní webová aplikace vyžaduje použití jiného webového serveru. Port 80 nebo 443 na veřejné IP adrese může používat pouze jeden proces. Pokud Apache používá port, pak jej Nginx nemůže použít (nebo se k němu připojit). Co tedy můžete dělat?
Nginx můžete nakonfigurovat jako reverzní proxy pro Apache, takže Nginx může přesměrovat požadavky HTTP na Apache. Ze své zkušenosti jsem zjistil, že to není vždy nejlepší způsob, protože to kdysi způsobilo podivné problémy, které nemohu vyřešit. Místo toho raději používám HAProxy jako reverzní proxy pro Nginx i Apache . HAProxy je bezplatný open source nástroj pro vyrovnávání zátěže a proxy server pro aplikace založené na TCP a HTTP.
Spusťte Apache, Nginx a HAProxy na stejném serveru
Zde je návod, jak to funguje.
- Nginx poslouchá na 127.0.0.1:80 a 127.0.0.1:443
- Apache naslouchá na 127.0.0.2:80 a 127.0.0.2:443
- HAProxy naslouchá na portu 80 a 443 veřejné IP adresy. Přesměruje požadavek HTTP na portu 80 na port 443. Když požadavek dorazí na port 443, vybere si mezi serverem Nginx a Apache analýzou záhlaví SNI (indikace názvu serveru) v požadavku HTTPS.
Cloudflare (poskytovatel CDN) ve skutečnosti také používá hlavičku SNI k určení, jak směrovat požadavky HTTPS na původní servery.
Krok 1:Zastavte Nginx a Apache
Chcete-li zastavit Nginx na Debianu, Ubuntu a CentOS, spusťte
sudo systemctl stop nginx
Chcete-li zastavit Apache na Debian/Ubuntu, spusťte
sudo systemctl stop apache2
Chcete-li zastavit Apache na CentOS, spusťte
sudo systemctl stop httpd
Krok 2:Změňte port pro poslech v Nginx
Potřebujeme, aby Nginx poslouchal na 127.0.0.1:80. Otevřete konfigurační soubory Nginx v /etc/nginx/conf.d/
nebo /etc/nginx/sites-enabled/
a najděte následující řádek.
poslouchejte 80;
Změňte jej na
poslouchejte 127.0.0.1:80;
Pokud je na bloku serveru Nginx povoleno https, vyhledejte také
poslouchejte 443 ssl;
A změňte jej na
poslouchejte 127.0.0.1:443 ssl;
Hlavní konfigurační soubor Nginx /etc/nginx/nginx.conf
může obsahovat výchozí virtuální hostitel naslouchající na portu 80 nebo 443, takže možná budete muset upravit i tento soubor.
Restartujte Nginx, aby se změny projevily.
sudo systemctl restart nginx
Krok 3:Změňte port pro poslech v Apache
Potřebujeme, aby Apache poslouchal na 127.0.0.2:80.
Debian/Ubuntu
V Debianu a Ubuntu upravte /etc/apache2/ports.conf
soubor.
sudo nano /etc/apache2/ports.conf
Změnit
Listen 80Listen 443
Komu
Poslouchejte 127.0.0.2:80Poslouchejte 127.0.0.2:443
Uložte a zavřete soubor. Přejděte také na /etc/apache2/sites-enabled/
adresář, upravte soubory virtuálního hostitele. Změnit
Komu
Pokud existuje virtuální hostitel SSL, změňte také
Komu
Restartujte Apache.
sudo systemctl restart apache2
CentOS
V systému CentOS upravte /etc/httpd/conf/httpd.conf
soubor.
sudo nano /etc/httpd/conf/httpd.conf
Najít
Poslouchejte 80
Změňte jej na
Poslouchejte 127.0.0.2:80
Uložte a zavřete soubor. Poté přejděte na /etc/httpd/conf.d/
adresář, upravte soubory virtuálního hostitele. Změnit
Komu
Pokud existuje virtuální hostitel SSL, změňte také
Komu
V /etc/httpd/conf.d/ssl.conf
soubor, je
Poslouchejte 443 https
Změňte jej na:
Poslouchejte 127.0.0.2:443 https
Uložte a zavřete soubor. Restartujte Apache, aby se změny projevily.
sudo systemctl restart httpd
Krok 4:Konfigurace HAProxy
Nainstalujte si HAProxy do své distribuce.
Debian/Ubuntu
sudo apt install haproxy
CentOS
instalace sudo dnf haproxy
Upravte konfigurační soubor HAProxy.
sudo nano /etc/haproxy/haproxy.cfg
Přidejte následující fragment kódu na konec souboru, díky kterému bude HAporxy naslouchat na portu 80 veřejné IP adresy a přesměrovat požadavky HTTP na portu 80 na port 443. Nahraďte 12.34.56.78 veřejnou IP adresou vašeho serveru.
frontend http bind 12.34.56.78:80 režim http schéma přesměrování https kód 301
Nyní také potřebujeme přidat rozhraní HTTPS.
frontend https bind 12.34.56.78:443 režim tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 }
Poté definujte zadní konce Nginx a Apache. check
parametr říká HAProxy, aby provedla kontrolu stavu na back-endu odesláním paketu TCP.
možnost backend nginx tcp ssl-hello-chk server nginx 127.0.0.1:443 checkbackend apache mode tcp option ssl-hello-chk server apache 127.0.0.2:443 check
Výchozí back-end můžete definovat pomocí:
default_backend nginx
K přesměrování na správný back-end použijeme hlavičku SNI v požadavku HTTPS. Pokud například Nginx obsluhuje domain1.com
a Apache obsluhuje domain2.com
, pak přidáte následující dva řádky. Můžete také použít subdomény, pokud se liší.
use_backend nginx if { req_ssl_sni -i domain1.com }use_backend apache if { req_ssl_sni -i domain2.com }
Všimněte si, že default_backend
a use_backend
direktivy by měly být umístěny nad definicemi backendu.
frontend http bind 12.34.56.78:80 režim http schéma přesměrování https kód 301frontend https bind 12.34.56.78:443 režim tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_backend_hello_type use if { req_ssl} default_hello_type use 1 req_ssl_sni -i domain1.com } use_backend apache if { req_ssl_sni -i domain2.com }backend nginx mode tcp option ssl-hello-chk server nginx 127.0.0.1:443 checkbackend apache mode tchelp.server tchelp0-s.0 :443 kontrola
Ve výše uvedené konfiguraci jsme použili funkci SNI (Server Name Indication) v TLS k rozlišení provozu HTTPS.
- Když je doména1.com v klientovi TLS Hello, HAProxy přesměruje provoz na
nginx
backend. - Když je domain2.com v TLS Client Hello, HAProxy přesměruje provoz na
apache
backend.
Pokud klient neuvede název serveru v TLS Client Hello, pak HAproxy použije výchozí backend (nginx).
Uložte a zavřete soubor. Poté restartujte HAproxy.
sudo systemctl restart haproxy
Nyní mohou Apache, Nginx a HAProxy běžet na stejném serveru.
Jak předat IP adresu klienta do backendu
Ve výchozím nastavení mohou Apache a Nginx vidět pouze IP adresu HAProxy. Chcete-li získat skutečnou IP adresu klienta, ujistěte se, že jste přidali send-proxy-v2
možnost v definici back-endu HAProxy, jak je uvedeno níže.
možnost backendu nginx tcp ssl-hello-chk server nginx 127.0.0.1:443 send-proxy-v2 checkbackend apache mode tcp option ssl-hello-chk server apache 127.0.0.2:443 send-proxy-v2 zkontrolovat
Potřebujeme také přidat nějakou konfiguraci v Nginx a Apache, aby to fungovalo, jinak bude váš web nepřístupný.
Nginx
Přidejte proxy_protocol
v listen
Nginx směrnice jako níže.
poslouchejte 127.0.0.2:443 ssl http2 proxy_protocol;
Poté přidejte následující dvě direktivy do Nginx http { }
blok v /etc/nginx/nginx.conf
soubor.
set_real_ip_from 127.0.0.1;real_ip_header proxy_protocol;
Uložte a zavřete soubor. Poté znovu načtěte Nginx.
sudo systemctl reload nginx
Poznámka :Pokud váš web běží za Cloudflare CDN, měli byste změnit real_ip_header proxy_protocol;
na real_ip_header CF-Connecting-IP;
za účelem zobrazení skutečné IP adresy klienta. Můžete také přidat tento real_ip_header
direktiva do souboru bloků jednotlivých serverů k přepsání globální konfigurace v /etc/nginx/nginx.conf
soubor.
Nakonec restartujte HAProxy.
sudo systemctl restart haproxy
Apache
Pokud používáte Apache na Debianu/Ubuntu, musíte povolit remoteip modul. (Tento modul je v systému CentOS ve výchozím nastavení povolen.)
sudo a2enmod remoteip
Poté přidejte následující 3 řádky do konfiguračního souboru virtuálního hostitele Apache.
RemoteIPProxyProtocol OnRemoteIPHeader X-Forwarded-ForRemoteIPTrustedProxy 127.0.0.1
Takhle.
ServerName www.example.com RemoteIPProxyProtocol On RemoteIPHeader X-Forwarded-For RemoteIPTrustedProxy 127.0.0.1
Uložte a zavřete soubor. Pak musíme také změnit combined
formát protokolu. Upravte hlavní konfigurační soubor Apache.
sudo nano /etc/apache2/apache2.conf
nebo
sudo nano /etc/httpd/conf/httpd.conf
Najděte následující řádek.
Formát protokolu "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" kombinovaný
Nahraďte jej řetězcem:
Formát protokolu "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" kombinovaný
Uložte a zavřete soubor. Poté restartujte Apache, aby se změny projevily.
sudo systemctl restart apache2
nebo
sudo systemctl restart httpd
Poznámka že RemoteIPProxyProtocol On
direktiva je dostupná pouze v Apache 2.4.31 a novějších. Chcete-li zkontrolovat verzi Apache, spusťte
sudo apache2 -v
nebo
sudo httpd -v
Ubuntu 18.04 se dodává s Apache 2.4.29. Pokud vaše verze Apache tento požadavek nesplňuje, měli byste odstranit send-proxy-v2
v definici back-endu HAProxy. CentOS 8 je dodáván s Apache 2.4.37.
Nakonec restartujte HAProxy.
sudo systemctl restart haproxy
Jak přidat nové virtuální hostitele
Pokud máte webové servery Apache a Nginx, potřebujete pouze dva backendy:jeden pro Apache a jeden pro Nginx.
Když potřebujete přidat další doménu (nebo subdoménu), nemusíte přidávat nový backend v HAProxy. Místo toho byste měli vytvořit nového virtuálního hostitele pro novou doménu (nebo subdoménu) v Apache nebo Nginx a poté použít use_backend
direktiva v HAProxy k přesměrování provozu na správný backend.
frontend http bind 12.34.56.78:80 režim http schéma přesměrování https kód 301frontend https bind 12.34.56.78:443 režim tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_backend_hello_type use if { req_ssl} default_hello_type use 1 req_ssl_sni -i doména1.com } use_backend nginx if { req_ssl_sni -i sub.domain1.com } use_backend apache if { req_ssl_sni -i doména2.com } use_backend apache if { req_ssl_sni -i scng options} sub.domain -hello-chk server nginx 127.0.0.1:443 checkbackend apache mode tcp option ssl-hello-chk server apache 127.0.0.2:443 check
Doporučuji používat apache
a nginx
jako jsou názvy backendu ve výše uvedeném kódu, takže víte, který webový server je hostitelem které aplikace.
Získání nového certifikátu Let's Encrypt SSL
http-01 výzva
Nejprve musíte pochopit, jak používat autentizátor Certbot apache a nginx k získání certifikátu TLS.
- Správně povolte HTTPS na Apache pomocí Let’s Encrypt na Ubuntu
- Správně povolte HTTPS na Nginx pomocí Let's Encrypt na Ubuntu
Autentikátor Certbot apache a nginx používá http-01
challenge, který funguje na TCP portu 80. Protože HAProxy používá TCP port 80, tak Certbot http-01
výzva pravděpodobně neuspěje. Můžete to však zprovoznit pomocí následující metody.
- Povolte hostitele SSL v Apache nebo Nginx pomocí certifikátu s vlastním podpisem nebo certifikátu pro jinou doménu.
- Potom použijte autentizátor Certbot apache a nginx jako obvykle.
Tato metoda funguje, protože Certbot http-01
challenge může být přesměrována z TCP portu 80 na TCP port 443 a Certbot přijímá neplatné certifikáty na portu 443.
výzva dns-01
Můžete také použít certbot dns-01
challenge, která funguje tak, že pro vaši doménu vytvoří dočasný TXT záznam, který potvrdí, že tuto doménu skutečně vlastníte, takže může obejít TCP port 80 a TCP port 443. Nevýhodou této metody je, že ne všichni registrátoři domén jsou podporováni.
Nejprve musíte nainstalovat plugin Certbot DNS. Jedná se o několik zásuvných modulů DNS dostupných v úložišti softwaru Debian a Ubuntu, které můžete najít pomocí
apt search python3-certbot-dns
Výstup:
python3-certbot-dns-cloudflare/bionic,bionic 0.23.0-1 allCloudflare DNS plugin pro Certbotpython3-certbot-dns-digitalocean/bionic,bionic 0.23.0-1 allDigitalOcean DNSple plugin pro Certbotpython3-certn /bionic,bionic 0.23.0-1 allDNSjednoduchý DNS plugin pro Certbotpython3-certbot-dns-google/bionic,bionic 0.23.0-1 allGoogle DNS plugin pro Certbotpython3-certbot-dns-rfc2136/bionic,bionic 0.23.0-1 allR 2136 DNS plugin pro Certbotpython3-certbot-dns-route53/bionic,bionic 0.23.0-1 allRoute53 DNS plugin pro Certbot
Na CentOS 8 najdete pluginy Certbot DNS z úložiště EPEL. Upozorňujeme, že musíte nainstalovat Certbot z výchozího úložiště CentOS.
instalace sudo dnf certbot
Najděte DNS pluginy z úložiště EPEL.
sudo dnf install epel-releasednf hledat certbot-dns
Výstup:
python3-certbot-dns-ovh.noarch :OVH DNS Authenticator plugin pro Certbotpython3-certbot-dns-nsone.noarch :NS1 DNS Authenticator plugin pro Certbotpython3-certbot-dns-gehirn.noarch :Gehirn Authentic plugin DNS Service plugin Certbotpython3-certbot-dns-google.noarch :Zásuvný modul Google Cloud DNS Authenticator pro Certbotpython3-certbot-dns-linode.noarch :Zásuvný modul Linode DNS Authenticator pro Certbotpython3-certbot-dns-luadns.noarch :Luaentic-DNSbotthon3 plugin Certentic-DNS Authns -rfc2136.noarch :Zásuvný modul DNS Authenticator RFC 2136 pro Certbotpython3-certbot-dns-route53.noarch :Route53 Zásuvný modul DNS Authenticator pro Certbotpython3-certbot-dns-cloudxns.noarch :CloudXentic-certbot DNS-simulátor DNStplens. :Plugin DNSimple DNS Authenticator pro Certbotpython3-certbot-dns-cloudflare.noarch :Plugin Cloudflare DNS Authenticator pro Certbotpython3-certbot-dns-cloudflare.noarch :Plugin Cloudflare DNS Authenticator pro Certbotpyt hon3-certbot-dns-dnsmadeeasy.noarch :DNS Made Easy Plugin DNS Authenticator pro Certbotpython3-certbot-dns-sakuracloud.noarch :Sakura Cloud DNS Authenticator plugin pro Certbot
Nainstalujte si jeden z těchto pluginů podle toho, jakou DNS hostingovou službu používáte. Používám Cloudflare, takže jako příklad použiji Cloudflare. Spuštěním následujícího příkazu nainstalujte python3-certbot-dns-cloudflare
balíček na Debian/Ubuntu.
sudo apt install python3-certbot-dns-cloudflare
Poté vytvořte konfigurační soubor pro Cloudflare.
sudo nano /etc/letsencrypt/cloudflare.ini
Do tohoto souboru musíme přidat e-mailovou adresu našeho účtu Cloudflare a klíč API.
# Přihlašovací údaje Cloudflare API používané Certbotdns_cloudflare_email =[email protected]dns_cloudflare_api_key =0123456789abcdef0123456789abcdef01234567
Klíč Cloudflare API najdete na https://dash.cloudflare.com/profile
. Všimněte si, že plugin Certbot Cloudflare v současné době nepodporuje „API Tokeny“ Cloudflare, takže se ujistěte, že k ověření používáte „Global API Key“.
Uložte a zavřete soubor. Klíč API obchází dvoufaktorovou autentizaci Cloudflare, takže byste měli umožnit čtení tohoto souboru pouze uživateli root.
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
Nyní spusťte certbot.
sudo certbot --agree-tos -a dns-cloudflare -i nginx --redirect --hsts --staple-ocsp --email [chráněn e-mailem] -d www.vase-domena.com,vase-domena. com
Ve výše uvedeném příkazu jsme určili, že budeme používat dns-cloudflare
jako ověřovatel pro získání nového certifikátu TLS a použití nginx
plugin pro vytvoření bloku serveru HTTPS. Pokud používáte Apache, nahraďte nginx
s apache
.
Tento příkaz vás požádá o zadání cesty k souboru .ini
zadejte /etc/letsencrypt/cloudflare.ini
a stiskněte klávesu Enter.
Po získání certifikátu SSL a jeho instalaci do konfiguračního souboru webového serveru. Musíte to nechat poslouchat na 127.0.0.1:443 nebo 127.0.0.2:443. Pokud například používáte Nginx, vyhledejte
poslouchejte 443 ssl
A změňte jej na
poslouchejte 127.0.0.1:443 ssl http2
Změňte také port 80 na
poslouchejte 127.0.0.1:80;
Uložte a zavřete soubor. Poté restartujte webový server.
Běžné chyby
1 nesprávný název domény
Pokud máte na serveru více virtuálních hostitelů Nginx a když zadáte jeden název domény, webový prohlížeč vás přenese na jiný název domény hostovaný na stejném serveru, může se stát, že jeden z názvu vašeho virtuálního hostitelského souboru Nginx nekončí pomocí .conf
příponu názvu souboru, takže Nginx nenačetl tento virtuální hostitel. Může se také stát, že jste pro název domény nastavili záznam AAAA, ale nenakonfigurovali jste Nginx tak, aby poskytoval název domény v IPv6.
Výše uvedené platí také pro webový server Apache.
2 Porušení síťového protokolu
Pokud nastavíte send-proxy-v2
záhlaví v HAProxy, ale nepovolil proxy_protocol
v Nginx nebo Apache, pak se na vašem webu zobrazí následující chyba.
Na webu došlo k porušení síťového protokolu, které nelze opravit.
Po provedení změn v konfiguračním souboru nezapomeňte restartovat Nginx/Apache.
3 PR_CONNECT_RESET_ERROR
Pokud povolíte proxy_protocol
v Nginx nebo Apache, ale nenastavili jste send-proxy-v2
záhlaví v HAProxy, pak váš web zobrazí tuto chybu.
zabezpečené připojení se nezdařilo. PR_CONNECT_RESET_ERROR
A v protokolu chyb Nginx nebo Apache najdete následující chybovou zprávu.
rozbité záhlaví při čtení protokolu PROXY
Po provedení změn v konfiguračním souboru nezapomeňte restartovat Nginx/Apache.
Všimněte si také, že pokud povolíte proxy protocol
v jednom souboru virtuálního hostitele Apache/Nginx, pak je to také implicitně povoleno pro všechny ostatní virtuální hostitele. A nenašel jsem způsob, jak deaktivovat proxy_protocol
pro jednotlivé virtuální hostitele. Protože používáte Apache a Nginx na stejném serveru, řešením je, že povolíte protokol proxy pouze v Nginx a nepovolíte jej v Apache. Pokud virtuální hostitel nepotřebuje získat skutečnou IP adresu klienta, nakonfigurujte jej tak, aby používal Apache.
Aktualizovat :Napadlo mě, že můžete nastavit nového virtuálního hostitele Apache/Nginx na jiné adrese zpětné smyčky, jako je 127.0.0.4. Tímto způsobem nový virtuální hostitel nepovolí protokol proxy.
4 PR_END_OF_FILE_ERROR
Pokud jste povolili protokol proxy v Apache/Nginx, ale pokusíte se o přímý přístup k virtuálnímu hostiteli (obejít HAProxy), zobrazí se následující chyba.
PR_END_OF_FILE_ERROR
5 SSL_ERROR_SYSCALL
Pokud použijete příkaz curl:
curl -I https://example.com
A narazíte na následující chybu
curl:(35) OpenSSL SSL_connect:SSL_ERROR_SYSCALL ve spojení s example.com:443
Je to pravděpodobně proto, že jste pro tuto doménu nenastavili definici backendu.