Se sei un amministratore di server, probabilmente hai un server web a tua scelta come Apache o Nginx. Apache è un noto web server dagli anni '90. Nginx è stato sviluppato per la prima volta nel 2004 e ha rapidamente guadagnato popolarità grazie al suo ingombro di memoria leggero e all'elevata velocità di elaborazione per i file HTML statici.
Sia Apache che Nginx supportano l'hosting virtuale, il che significa che puoi ospitare più siti Web o applicazioni Web sullo stesso server. Tuttavia, si verificheranno situazioni in cui è in esecuzione un server Web esistente, ma una particolare applicazione Web richiede l'utilizzo di un server Web diverso. La porta 80 o 443 dell'indirizzo IP pubblico può essere utilizzata da un solo processo. Se Apache sta usando la porta, Nginx non può usarla (o associarla). Allora cosa puoi fare?
Puoi configurare Nginx come proxy inverso per Apache, in modo che Nginx possa reindirizzare le richieste HTTP ad Apache. Nella mia esperienza, ho scoperto che questo non è sempre il modo migliore perché una volta ha causato strani problemi che non riesco a risolvere. Preferisco invece usare HAProxy come proxy inverso sia per Nginx che per Apache . HAProxy è un server proxy e bilanciamento del carico ad alta disponibilità gratuito e open source per applicazioni basate su TCP e HTTP.
Esegui Apache, Nginx e HAProxy sullo stesso server
Ecco come funziona.
- Nginx ascolta su 127.0.0.1:80 e 127.0.0.1:443
- Apache è in ascolto su 127.0.0.2:80 e 127.0.0.2:443
- HAProxy è in ascolto sulle porte 80 e 443 dell'indirizzo IP pubblico. Reindirizza la richiesta HTTP sulla porta 80 alla porta 443. Quando una richiesta arriva sulla porta 443, sceglierà tra il back-end Nginx e Apache analizzando l'intestazione SNI (indicazione del nome del server) nella richiesta HTTPS.
In realtà, anche Cloudflare (un provider CDN) utilizza l'intestazione SNI per determinare come instradare le richieste HTTPS ai server di origine.
Fase 1:ferma Nginx e Apache
Per interrompere Nginx su Debian, Ubuntu e CentOS, esegui
sudo systemctl stop nginx
Per fermare Apache su Debian/Ubuntu, esegui
sudo systemctl stop apache2
Per fermare Apache su CentOS, esegui
sudo systemctl stop httpd
Fase 2:cambia la porta di ascolto in Nginx
Dobbiamo fare in modo che Nginx ascolti su 127.0.0.1:80. Apri i tuoi file di configurazione Nginx in /etc/nginx/conf.d/
o /etc/nginx/sites-enabled/
e trova la riga seguente.
ascolta 80;
Cambialo in
ascolta 127.0.0.1:80;
Se https è abilitato sul blocco del server Nginx, trova anche
ascolta 443 ssl;
E cambialo in
ascolta 127.0.0.1:443 ssl;
Il file di configurazione principale di Nginx /etc/nginx/nginx.conf
potrebbe includere un host virtuale predefinito in ascolto sulla porta 80 o 443, quindi potrebbe essere necessario modificare anche questo file.
Riavvia Nginx per rendere effettive le modifiche.
sudo systemctl riavvia nginx
Fase 3:cambia la porta di ascolto in Apache
Dobbiamo fare in modo che Apache sia in ascolto su 127.0.0.2:80.
Debian/Ubuntu
Su Debian e Ubuntu, modifica /etc/apache2/ports.conf
file.
sudo nano /etc/apache2/ports.conf
Cambia
Ascolta 80Ascolta 443
A
Ascolta 127.0.0.2:80Ascolta 127.0.0.2:443
Salva e chiudi il file. Vai anche su /etc/apache2/sites-enabled/
directory, modificare i file dell'host virtuale. Cambia
A
Se sono presenti host virtuali SSL, cambia anche
A
Riavvia Apache.
sudo systemctl riavvia apache2
CentOS
Su CentOS, modifica il /etc/httpd/conf/httpd.conf
file.
sudo nano /etc/httpd/conf/httpd.conf
Trova
Ascolta 80
Cambialo in
Ascolta 127.0.0.2:80
Salva e chiudi il file. Quindi vai su /etc/httpd/conf.d/
directory, modificare i file dell'host virtuale. Cambia
A
Se sono presenti host virtuali SSL, cambia anche
A
Nel /etc/httpd/conf.d/ssl.conf
file, c'è
Ascolta 443 https
Cambialo in:
Ascolta 127.0.0.2:443 https
Salva e chiudi il file. Riavvia Apache per rendere effettive le modifiche.
sudo systemctl riavvia httpd
Fase 4:Configura HAProxy
Installa HAProxy sulla tua distribuzione.
Debian/Ubuntu
sudo apt install haproxy
CentOS
sudo dnf install haproxy
Modifica il file di configurazione HAProxy.
sudo nano /etc/haproxy/haproxy.cfg
Aggiungi il seguente frammento di codice alla fine del file, che farà ascoltare HAPorxy sulla porta 80 dell'indirizzo IP pubblico e reindirizzare le richieste HTTP sulla porta 80 alla porta 443. Sostituisci 12.34.56.78 con l'indirizzo IP pubblico del tuo server.
frontend http bind 12.34.56.78:80 modalità http schema di reindirizzamento https codice 301
Ora dobbiamo anche aggiungere un front-end HTTPS.
frontend https bind 12.34.56.78:443 modalità tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 }
Quindi definisci i back-end Nginx e Apache. Il check
Il parametro indica a HAProxy di eseguire controlli di integrità sul back-end inviando un pacchetto TCP.
backend nginx modalità tcp opzione ssl-hello-chk server nginx 127.0.0.1:443 checkbackend apache modalità tcp opzione ssl-hello-chk server apache 127.0.0.2:443 controllo
Puoi definire un back-end predefinito con:
default_backend nginx
Useremo l'intestazione SNI nella richiesta HTTPS per reindirizzare al back-end corretto. Ad esempio, se Nginx sta servendo domain1.com
e Apache sta servendo domain2.com
, quindi aggiungi le due righe seguenti. Puoi anche utilizzare i sottodomini, purché siano diversi.
usa_backend nginx if { req_ssl_sni -i domain1.com }usa_backend apache if { req_ssl_sni -i domain2.com }
Nota che il default_backend
e use_backend
le direttive dovrebbero essere poste sopra le definizioni di back-end.
frontend http bind 12.34.56.78:80 modalità http schema di reindirizzamento https codice 301frontend https bind 12.34.56.78:443 modalità tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } default_backend nginx use_backend nginx if { req_ssl_sni -i domain1.com } use_backend apache if { req_ssl_sni -i domain2.com } backend nginx mode tcp opzione ssl-hello-chk server nginx 127.0.0.1:443 checkbackend apache mode tcp opzione ssl-hello-chk server apache 127.0.0.2 :443 verifica
Nella configurazione sopra, abbiamo utilizzato la funzione SNI (Server Name Indication) in TLS per differenziare il traffico HTTPS.
- Quando domain1.com è nel client TLS Hello, HAProxy reindirizza il traffico a
nginx
backend. - Quando domain2.com è nel client TLS Hello, HAProxy reindirizza il traffico a
apache
backend.
Se il client non specifica il nome del server in TLS Client Hello, HAproxy utilizzerà il backend predefinito (nginx).
Salva e chiudi il file. Quindi riavvia HAproxy.
sudo systemctl restart haproxy
Ora Apache, Nginx e HAProxy possono essere eseguiti sullo stesso server.
Come inoltrare l'indirizzo IP del cliente al backend
Per impostazione predefinita, Apache e Nginx possono vedere solo l'indirizzo IP di HAProxy. Per ottenere il vero indirizzo IP del client, assicurati di aver aggiunto il send-proxy-v2
opzione nella definizione del back-end di HAProxy come di seguito.
backend modalità nginx opzione tcp server ssl-hello-chk nginx 127.0.0.1:443 send-proxy-v2 checkbackend apache modalità tcp opzione ssl-hello-chk server apache 127.0.0.2:443 send-proxy-v2 controlla
Abbiamo anche bisogno di aggiungere alcune configurazioni in Nginx e Apache per farlo funzionare, altrimenti il tuo sito web sarà inaccessibile.
Nginx
Aggiungi proxy_protocol
in Nginx listen
direttiva come di seguito.
ascolta 127.0.0.2:443 ssl http2 proxy_protocol;
Quindi aggiungi le seguenti due direttive in Nginx http { }
bloccare in /etc/nginx/nginx.conf
file.
set_real_ip_from 127.0.0.1;protocollo_proxy_ip_header reale;
Salva e chiudi il file. Quindi ricarica Nginx.
sudo systemctl ricarica nginx
Nota :Se il tuo sito web viene eseguito dietro Cloudflare CDN, dovresti cambiare real_ip_header proxy_protocol;
a real_ip_header CF-Connecting-IP;
per mostrare il vero indirizzo IP del cliente. Puoi anche aggiungere questo real_ip_header
direttiva al singolo file di blocco del server per sovrascrivere la configurazione globale in /etc/nginx/nginx.conf
file.
Infine, riavvia HAProxy.
sudo systemctl restart haproxy
Apache
Se usi Apache su Debian/Ubuntu, devi abilitare il ip remoto modulo. (Questo modulo è abilitato su CentOS per impostazione predefinita.)
sudo a2enmod ip remoto
Quindi aggiungi le seguenti 3 righe nel file di configurazione dell'host virtuale Apache.
RemoteIPProxyProtocol OnRemoteIPHeader X-Forwarded-ForRemoteIPTrustedProxy 127.0.0.1
Così.
ServerName www.example.com RemoteIPProxyProtocol su RemoteIPHeader X-Forwarded-For RemoteIPTrustedProxy 127.0.0.1
Salva e chiudi il file. Quindi dobbiamo anche cambiare il combined
formato di registro. Modifica il file di configurazione principale di Apache.
sudo nano /etc/apache2/apache2.conf
o
sudo nano /etc/httpd/conf/httpd.conf
Trova la riga seguente.
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combinato
Sostituiscilo con:
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combinato
Salva e chiudi il file. Quindi riavvia Apache per rendere effettive le modifiche.
sudo systemctl riavvia apache2
o
sudo systemctl riavvia httpd
Nota che il RemoteIPProxyProtocol On
la direttiva è disponibile solo in Apache 2.4.31 e versioni successive. Per controllare la tua versione di Apache, esegui
sudo apache2 -v
o
sudo httpd -v
Ubuntu 18.04 viene fornito con Apache 2.4.29. Se la tua versione di Apache non soddisfa questo requisito, dovresti rimuovere send-proxy-v2
nella definizione del back-end HAProxy. CentOS 8 viene fornito con Apache 2.4.37.
Infine, riavvia HAProxy.
sudo systemctl restart haproxy
Come aggiungere nuovi host virtuali
Se disponi di server Web Apache e Nginx, ti servono solo due backend:uno per Apache e uno per Nginx.
Quando è necessario aggiungere un altro dominio (o sottodominio), non è necessario aggiungere un nuovo back-end in HAProxy. Invece, dovresti creare un nuovo host virtuale per il nuovo dominio (o sottodominio) in Apache o Nginx, quindi utilizzare use_backend
direttiva in HAProxy per reindirizzare il traffico al backend corretto.
frontend http bind 12.34.56.78:80 modalità http schema di reindirizzamento https codice 301frontend https bind 12.34.56.78:443 modalità tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } default_backend nginx use_backend nginx if { req_ssl_sni -i domain1.com } use_backend nginx if { req_ssl_sni -i sub.domain1.com } use_backend apache if { req_ssl_sni -i domain2.com } use_backend apache if { req_ssl_sni -i sub.domain2.com } backend nginx mode tcp option ssl -hello-chk server nginx 127.0.0.1:443 checkbackend apache modalità tcp opzione ssl-hello-chk server apache 127.0.0.2:443 check
Consiglio di usare apache
e nginx
come i nomi di back-end come nel codice sopra, così sai quale server web sta ospitando quale applicazione.
Ottenere il nuovo certificato SSL Let's Encrypt
Sfida http-01
Innanzitutto, devi capire come utilizzare Certbot apache e nginx Authenticator per ottenere il certificato TLS.
- Abilita correttamente HTTPS su Apache con Let's Encrypt su Ubuntu
- Abilita correttamente HTTPS su Nginx con Let's Encrypt su Ubuntu
Certbot apache e nginx autenticatore usano http-01
challenge, che funziona sulla porta TCP 80. Poiché HAProxy utilizza la porta TCP 80, quindi Certbot http-01
la sfida rischia di fallire. Tuttavia, puoi farlo funzionare con il seguente metodo.
- Abilita l'host SSL in Apache o Nginx con un certificato autofirmato o un certificato per un altro dominio.
- Quindi usa Certbot apache e nginx autenticatore come al solito.
Questo metodo funziona perché Certbot http-01
challenge può essere reindirizzato dalla porta TCP 80 alla porta TCP 443 e Certbot accetta certificati non validi sulla porta 443.
sfida dns-01
Puoi anche usare il certbot dns-01
challenge, che funziona creando un record TXT temporaneo per il tuo dominio per certificare che sei effettivamente il proprietario di questo dominio, in modo che possa bypassare la porta TCP 80 e la porta TCP 443. Lo svantaggio di questo metodo è che non tutti i registrar di domini sono supportati.
Innanzitutto, è necessario installare il plug-in DNS Certbot. Sono diversi plugin DNS disponibili nel repository del software Debian e Ubuntu, che puoi trovare con
apt search python3-certbot-dns
Uscita:
python3-certbot-dns-cloudflare/bionic,bionic 0.23.0-1 plug-in DNS allCloudflare per Certbotpython3-certbot-dns-digitalocean/bionic,bionic 0.23.0-1 plug-in DNS allDigitalOcean per Certbotpython3-certbot-dns-dnsimple /bionic,bionic 0.23.0-1 allDNSemplice plug-in DNS per Certbotpython3-certbot-dns-google/bionic,bionic 0.23.0-1 allGoogle Plugin DNS per Certbotpython3-certbot-dns-rfc2136/bionic,bionic 0.23.0-1 allRFC 2136 Plugin DNS per Certbotpython3-certbot-dns-route53/bionic,bionic 0.23.0-1 allRoute53 Plugin DNS per Certbot
Su CentOS 8, puoi trovare i plug-in DNS di Certbot dal repository EPEL. Tieni presente che devi installare Certbot dal repository CentOS predefinito.
sudo dnf install certbot
Trova i plugin DNS dal repository EPEL.
sudo dnf install epel-releasednf cerca certbot-dns
Uscita:
python3-certbot-dns-ovh.noarch :plugin OVH DNS Authenticator per Certbotpython3-certbot-dns-nsone.noarch :plugin NS1 DNS Authenticator per Certbotpython3-certbot-dns-gehirn.noarch :Gehirn Infrastructure Service plugin DNS Authenticator per Certbotpython3-certbot-dns-google.noarch :plug-in autenticatore DNS di Google Cloud per Certbotpython3-certbot-dns-linode.noarch :plug-in autenticatore DNS Linode per Certbotpython3-certbot-dns-luadns.noarch :plug-in autenticatore LuaDNS per Certbotpython3-certbot-dns -rfc2136.noarch:plug-in di autenticazione DNS RFC 2136 per Certbotpython3-certbot-dns-route53.noarch:plug-in di autenticazione DNS Route53 per Certbotpython3-certbot-dns-cloudxns.noarch:plug-in di autenticazione DNS CloudXNS per Certbotpython3-certbot-dns-dnsimple.noarch :Plugin DNS Authenticator DNSimple per Certbotpython3-certbot-dns-cloudflare.noarch :Plugin Authenticator DNS Cloudflare per Certbotpython3-certbot-dns-cloudflare.noarch :Plugin Authenticator DNS Cloudflare per Certbotpyt hon3-certbot-dns-dnsmadeeasy.noarch :plug-in DNS Made Easy per autenticatore DNS per Certbotpython3-certbot-dns-sakuracloud.noarch :plug-in Sakura Cloud DNS Authenticator per Certbot
Installa uno di questi plugin in base al servizio di hosting DNS che stai utilizzando. Sto usando Cloudflare, quindi userò Cloudflare come esempio. Esegui il comando seguente per installare python3-certbot-dns-cloudflare
pacchetto su Debian/Ubuntu.
sudo apt install python3-certbot-dns-cloudflare
Quindi crea un file di configurazione per Cloudflare.
sudo nano /etc/letsencrypt/cloudflare.ini
Dobbiamo aggiungere l'indirizzo email del nostro account Cloudflare e la chiave API in questo file.
# Credenziali API Cloudflare utilizzate da Certbotdns_cloudflare_email =[email protected]dns_cloudflare_api_key =0123456789abcdef0123456789abcdef01234567
Puoi trovare la tua chiave API Cloudflare su https://dash.cloudflare.com/profile
. Tieni presente che il plug-in Certbot Cloudflare non supporta attualmente i "token API" di Cloudflare, quindi assicurati di utilizzare la "Chiave API globale" per l'autenticazione.
Salva e chiudi il file. La chiave API ignora l'autenticazione a due fattori di Cloudflare, quindi dovresti consentire solo all'utente root di leggere questo file.
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
Ora esegui certbot.
sudo certbot --agree-tos -a dns-cloudflare -i nginx --redirect --hsts --staple-ocsp --email [email protetta] -d www.tuo-dominio.com,tuo-dominio. com
Nel comando precedente, abbiamo specificato che utilizzeremo dns-cloudflare
come autenticatore per ottenere un nuovo certificato TLS e utilizzare nginx
plug-in per creare il blocco del server HTTPS. Se usi Apache, sostituisci nginx
con apache
.
Questo comando ti chiederà di inserire il percorso del .ini
file, quindi inserisci /etc/letsencrypt/cloudflare.ini
e premere il tasto Invio.
Dopo che il certificato SSL è stato ottenuto e installato nel file di configurazione del server web. Devi farlo ascoltare su 127.0.0.1:443 o 127.0.0.2:443. Ad esempio, se usi Nginx, trova
ascolta 443 ssl
E cambialo in
ascolta 127.0.0.1:443 ssl http2
Inoltre, cambia la porta 80 in
ascolta 127.0.0.1:80;
Salva e chiudi il file. Quindi riavvia il tuo server web.
Errori comuni
1 Nome di dominio errato
Se hai più host virtuali Nginx su un server e quando digiti un nome di dominio, il browser Web ti porta a un altro nome di dominio ospitato sullo stesso server, potrebbe essere che uno dei tuoi nomi di file host virtuali Nginx non finisca con il .conf
estensione del nome file, quindi Nginx non ha caricato questo host virtuale. Potrebbe anche essere che tu abbia impostato il record AAAA per il nome di dominio, ma non hai configurato Nginx per servire il nome di dominio in IPv6.
Quanto sopra si applica anche al server web Apache.
2 Violazione del protocollo di rete
Se imposti il send-proxy-v2
header in HAProxy, ma non ha abilitato proxy_protocol
in Nginx o Apache, il tuo sito web visualizzerà il seguente errore.
Il sito ha riscontrato una violazione del protocollo di rete che non può essere riparata.
Ricordarsi di riavviare Nginx/Apache dopo aver apportato modifiche al file di configurazione.
3 PR_CONNECT_RESET_ERROR
Se abiliti proxy_protocol
in Nginx o Apache, ma non ha impostato il send-proxy-v2
header in HAProxy, il tuo sito web visualizzerà questo errore.
E troverai il seguente messaggio di errore nel registro degli errori di Nginx o Apache.
intestazione interrotta durante la lettura del protocollo PROXY
Ricordarsi di riavviare Nginx/Apache dopo aver apportato modifiche al file di configurazione.
Tieni inoltre presente che se abiliti il proxy protocol
in un file host virtuale Apache/Nginx, quindi è anche abilitato in modo implicito per tutti gli altri host virtuali. E non ho trovato un modo per disabilitare proxy_protocol
per il singolo host virtuale. Poiché stai eseguendo Apache e Nginx sullo stesso server, una soluzione alternativa è che abiliti solo il protocollo proxy in Nginx e non lo abiliti in Apache. Se un host virtuale non ha bisogno di ottenere l'indirizzo IP reale del client, configuralo per utilizzare Apache.
Aggiorna :Mi è venuto in mente che puoi configurare un nuovo host virtuale Apache/Nginx su un altro indirizzo di loopback come 127.0.0.4. In questo modo, il nuovo host virtuale non abiliterà il protocollo proxy.
4 PR_END_OF_FILE_ERROR
Se hai abilitato il protocollo proxy in Apache/Nginx, ma provi ad accedere direttamente all'host virtuale (bypassando HAProxy), vedrai il seguente errore.
PR_END_OF_FILE_ERROR
5 SSL_ERROR_SYSCALL
Se usi il comando curl:
curl -I https://example.com
E riscontri il seguente errore
curl:(35) OpenSSL SSL_connect:SSL_ERROR_SYSCALL in connessione a example.com:443
Probabilmente è perché non hai impostato la definizione di back-end per questo dominio.