Nginx tip & tricks
Varnish Cache server non supporta SSL perché lo sviluppatore non ha voglia di includerlo (fonte non ha voglia).
Per ovviare al problema è necessario installare nginx , un web-server/reverse-proxy in grado di catturare la chiamata https e redirigerla a Varnish.
Procedura per installazione
Sulla macchina che ha già VARNISH, installare nginx
sudo apt-get install nginxL'installazione andrà a buon fine ma verrà mostrato un errore, nginx non riesce a partire perché Varnish è già attivo sulla porta 80. È necessario configurarlo in modo che accolga solo le richieste https.
Per prima cosa dobbiamo generare un certificato autofirmato
sudo mkdir /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crtAlla domanda sul common name è necessario scrivere il nome della macchina sul dominio (lo stesso di a /etc/hostname). Il certificato generato vale solo 10 anni, cambiare il parametro days a piacimento
Per quanto riguarda la configurazione generale di Nginx conviene aggiungere 3 parametri che aumentano il tempo di timeout delle pagine quando sono sotto reverse-proxy dentro alla sezione http { ... } di /etc/nginx/nginx.conf
##
# Reverse-Proxy Settings
##
proxy_connect_timeout 900;
proxy_send_timeout 900;
proxy_read_timeout 900;
send_timeout 900;
Ora apriamo la configurazione di nginx e lo istruiamo per rispondere alle richieste https
sudo nano /etc/nginx/sites-enabled/defaultIl seguente è la configurazione del server di test BRUNOPROXY,
il valore di server_name deve corrispondere con il common name che è stato dato al certificato.
# Default server configuration
#
server {
# listen 80 default_server;
# listen [::]:80 default_server;
# SSL configuration
#
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
#root /var/www/html;
# Add index.php to the list if you are using PHP
# index index.html index.htm index.nginx-debian.html;
server_name POCAHONTAS;
ssl_certificate /etc/nginx/ssl/pocahontas.crt;
ssl_certificate_key /etc/nginx/ssl/pocahontas.key;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
}
}
Ora tutte le richieste HTTPS passano da nginx che a sua volta le rigira a Varnish sulla porta 80 (riga proxy_pass http://127.0.0.1:80). Vengono servite col certificato autofirmato che non deve essere usato in ambiente di produzione.
Facciamo un restart di ngix
sudo service nginx start
e per testare andare su https://IPPUBBLICO.
In caso di Varnish che punta a Windows si arriverà all'IIS. Non è necessario configurare IIS con SSL, possono essere tutti normali websites.
Aggiungere domini certificati
Per creare un VirtualHost con certificato autentico aggiungere un file dentro alla cartella /etc/nginx/sites-available con la configurazione personalizzata che utilizzi i certificati giusti.
Per renderlo disponibile creare un symlink dentro alla cartella /etc/nginx/sites-enabled e restartare nginx.
Esempio pratico:
- Copiare i file del certificato (crt e key) + il certificato intermedio nella cartella
/etc/nginx/ssl/. N.B. Se si dispone del file .cer basta rinominare l'estensione in .crt - Unire certificato e certificato intermedio in un unico file con il comando
cat nomesito.com_ssl_certificate.crt nomesito.com_ssl_certificate_intermediate.crt >> nomesito.com_ssl_certificate_bundle.crt
Ricordarsi di mettere in /etc/nginx/ssl/ i tre file
nomesito.com_ssl_certificate.crtnomesito.com_private_key.keynomesito.com_ssl_certificate_bundle.crt
Per il momento su MULAN c'è solo designbest.com .
wm4pr.com è settato ma non usato. In uso in Test su POCAHONTAS.
- Creare il virtual host
sudo touch /etc/nginx/sites-available/nomesito.com
sudo nano /etc/nginx/sites-available/nomesito.com
e scriverci dentro qualcosa come
server {
listen 443;
ssl on;
ssl_certificate /etc/nginx/ssl/nomesito.com_ssl_certificate_bundle.crt;
ssl_certificate_key /etc/nginx/ssl/nomesito.com_ssl_certificate.key;
server_name nomesito.com;
location / {
proxy_pass http://127.0.0.1:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
}
}
- Pubblicare il virtual host su nginx
sudo ln -s /etc/nginx/sites-available/nomesito.com /etc/nginx/sites-enabled
sudo service nginx restart
Verificare la validità del certificato su siti come questo: SSL Certificate Checker
Forward dell'IP reale del client
Per la natura dell'infrastruttura server, l'IP reale del client viene perso dopo la chiamata a Nginx.
Il giro è
Client -> Nginx -> Varnish -> IIS
di conseguenza ad IIS arriva come client IP quello del Varnish e la geolocalizzazione va a puttane
Per sistemare il problema il dato dev'essere passato tramite le varie request all'interno di un header specializzato: X-FORWARDED-FOR.
Forward di Nginx
Essendo il primo punto di passaggio è l'unico che possiede il reale client-IP. Nella configurazione vista del paragrafo precedente si vede l'assegnazione del client-IP nel req header X-FORWARDED-FOR.
#...
location / {
proxy_pass http://127.0.0.1:80;
# Set di un header X-Real-IP che serve a varnish
proxy_set_header X-Real-IP $remote_addr;
# Set dell'header X-Forwarded-For per conservare il real IP tramite le varie request che portano ad IIS
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
}
#...
Forward di Varnish
Nel file di configurazione /etc/varnish/default.vcl piazzare queste righe
sub vcl_recv {
# Setta l'IP reale del client e lo forwarda
set req.http.X-Actual-IP = regsub(req.http.X-Forwarded-For, "[, ].*$", "");
set req.http.X-Forwarded-For = req.http.X-Actual-IP;
#...
Redirect http to https
Per colpa della configurazione del routing il redirect verso https non può essere fatto a livello applicativo.
Infatti succederebbe la seguente cosa:
- La chiamata
httparriva alVarnish Varnishla dirotta verso la macchina Win conIISIISdal suo rewriter trasforma la richiesta inhttps- Il giro ricomincia passando questa volta da
Nginx - Da qui si torna a
Varnish, il quale non sapendo gestire una richiestahttps, dirotta una normale richiestahttpalla macchina Win conIIS IISdal suo rewriter trasforma la richiesta inhttpse sitorna al punto 4. generando un loop infinito
SOLUZIONE:
La gestione del redirect verso HTTPS dev'essere affidata a Varnish.
Dentro al file /etc/varnish/default.vlc aggiungere queste 2 parti di codice
sub vcl_recv {
# ...
# Gestione redirect Https
if(req.http.X-Forwarded-Proto !~ "(?i)https") {
set req.http.location = "https://" + req.http.host + req.url;
return (synth(750, "Permanently moved"));
}
# altri contenuti
}
sub vcl_synth {
# ... altri contenuti
else if(resp.status == 750) {
set resp.http.Location = "https://" + req.http.host + req.url;
set resp.status = 301;
return (deliver);
}
}
In questo modo si evita il loop infinito. IMPORTANTE ricordarsi che dev'essere Varnish ad occuparsi del redirect https, mai l'applicativo.
Ringrazio Stephen Reese per le info di questa guida.
Leggere i LOG del web-server
Purtroppo i log non potranno più essere letti comodamente dall'IIS di Windows perché davanti a lui c'è nginx.
Il consiglio è quello di creare uno share in Samba come questo
[NginxLogs]
comment = Cartella di condivisione dei log di nginx
read only = yes
locking = no
path = /var/log/nginx
guest ok = no
e di rendere il proprio utente facente parte del gruppo adm affinché abbia i permessi di lettura.
sudo adduser nomeutente adm
LOG configurazione avanzata
Avendo diversi siti su Nginx bisogna dividere i log nelle cartelle
es.
/media/discodati/logs/nomesito1.com
/media/discodati/logs/nomesito2.it
/media/discodati/logs/immagini.sito2.comassicurandosi di mettere i permessi adatti
es.
sudo chown www-data:adm /media/discodati/logs -R
sudo chmod 775 /media/discodati/logs -R
E di conseguenza configurare i singoli virtual host con la cartella giusta
server {
# ...
server_name nomesito.com;
error_log /media/discodati/nomesito.com/error.log;
access_log /media/discodati/nomesito.com/access.log;
# ...
}
A questo punto tutti i log verranno riversati nei 2 file error.log e access.log.
Per fare in modo che vengano divisi e compressi (una volta che diventano vecchi) automaticamente è necessario configurare LOGROTATE.
sudo nano /etc/logrotate.d/nginx
e modificare come da esempio
/var/log/nginx/*.log /media/discodati/logs/*/*.log {
su www-data adm
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
Per forzare il logrotate usare
sudo logrotate -f /etc/logrotate.d/nginx
