Nginx tip & tricks: differenze tra le versioni

Da Webmobili Wiki.
Nessun oggetto della modifica
 
(52 versioni intermedie di 2 utenti non mostrate)
Riga 1: Riga 1:
Varnish Cache server non supporta SSL perché lo sviluppatore non ha voglia di includerlo (fonte [https://varnish-cache.org/docs/4.1/phk/ssl.html non ha voglia]).<br/>
== Forward dell'IP reale del client ==
Per la natura dell'infrastruttura server, l'IP reale del client viene perso dopo la chiamata a Nginx.<br/>
Il giro è<br/>
<code>Client -> Nginx -> IIS</code><br/>
di conseguenza ad IIS arriva come client IP quello di Nginx e la geolocalizzazione va a puttane<br/>
Per sistemare il problema il dato dev'essere passato tramite le varie request all'interno di un header specializzato: '''X-FORWARDED-FOR'''.<br/>


Per ovviare al problema è necessario installare '''nginx''' , un web-server/reverse-proxy in grado di catturare la chiamata https e redirigerla a Varnish.<br/><br/>
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''.
 
<syntaxhighlight lang="bash">
== Procedura per installazione ==
#...
Sulla macchina che ha già VARNISH, <u>installare nginx</u>
location / {
<syntaxhighlight>
  proxy_pass http://127.0.0.1:80;
sudo apt-get install nginx
  # Set di un header X-Real-IP che serve a varnish
</syntaxhighlight >
  proxy_set_header X-Real-IP  $remote_addr;
L'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.<br/><br/>
  # 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;
Per prima cosa dobbiamo <u>generare un certificato autofirmato</u>
  proxy_set_header X-Forwarded-Proto https;
<syntaxhighlight>
  proxy_set_header X-Forwarded-Port 443;
sudo mkdir /etc/nginx/ssl
  proxy_set_header Host $host;
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
}
</syntaxhighlight >
#...
Alla domanda sul ''common name'' è necessario scrivere il nome della macchina sul dominio (lo stesso di a <code>/etc/hostname</code>). Il certificato generato vale solo 10 anni, cambiare il parametro days a piacimento<br/><br/>
</syntaxhighlight>


== Brotli compression ==
La compressione '''brotli''' che sostituisce ''gzip'' quando possibile è stata approfondita qua<br/>
[[Nginx modulo Brotli (text compression)]]


Ora apriamo la configurazione di nginx e lo <u>istruiamo per rispondere alle richieste https</u>
== Leggere i LOG del web-server ==
<syntaxhighlight>
Purtroppo i log non potranno più essere letti comodamente dall'IIS di Windows perché davanti a lui c'è '''nginx'''.<br/>
sudo nano /etc/nginx/sites-enabled/default
Il consiglio è quello di creare uno share in Samba come questo
</syntaxhighlight >
Il seguente è la configurazione del server di test BRUNOPROXY,
il valore di <code>server_name</code> deve corrispondere con il ''common name'' che è stato dato al certificato.
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
# Default server configuration
[NginxLogs]
#
  comment = Cartella di condivisione dei log di nginx
server {
  read only = yes
# listen 80 default_server;
  locking = no
# listen [::]:80 default_server;
  path = /var/log/nginx
 
  guest ok = no
# 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 BRUNOPROXY;
ssl_certificate /etc/nginx/ssl/brunoproxy.crt;
ssl_certificate_key /etc/nginx/ssl/brunoproxy.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;
}
}
</syntaxhighlight>
</syntaxhighlight>
Ora tutte le richieste HTTPS passano da nginx che a sua volta le rigira a Varnish sulla porta 80 (riga <code>proxy_pass <nowiki>http://127.0.0.1:80</nowiki></code>). Vengono servite col certificato autofirmato che non deve essere usato in ambiente di produzione.<br/><br/>
e di rendere il proprio utente facente parte del gruppo ''adm'' affinché abbia i permessi di lettura.
 
Facciamo un <u>restart di ngix</u>
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo service nginx start
  sudo adduser nomeutente adm
</syntaxhighlight>
</syntaxhighlight>
e per testare andare su <code><nowiki>https://IPPUBBLICO</nowiki></code>.
In caso di Varnish che punta a Windows si arriverà all'IIS. Non è necessario configurare IIS con SSL, possono essere tutti normali websites.<br/><br/>


== Aggiungere domini certificati ==
== LOG configurazione avanzata ==
Per aggiungere un VirtualHost con certificato autentico aggiungere un file dentro alla cartella <code>/etc/nginx/sites-available</code> con la configurazione personalizzata che utilizzi i certificati giusti.
Avendo diversi siti su Nginx bisogna dividere i log nelle cartelle<br/>
Per renderlo disponibile creare un symlink dentro alla cartella <code>/etc/nginx/sites-enabled</code> e restartare nginx.<br/><br/>
es.
 
<syntaxhighlight>
Esempio pratico:
/media/discodati/logs/nomesito1.com
* Copiare i file del certificato (crt e key) nella cartella <code>/etc/nginx/ssl/</code>.
/media/discodati/logs/nomesito2.it
N.B. Se si dispone del file .cer basta rinominare l'estensione in .crt<br/><br/>
/media/discodati/logs/immagini.sito2.com
 
</syntaxhighlight>
* Creare il virtual host
assicurandosi di mettere i permessi adatti<br/>
es.
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo touch /etc/nginx/sites-available/nomesito.com
sudo chown www-data:adm /media/discodati/logs -R
sudo nano /etc/nginx/sites-available/nomesito.com
sudo chmod 775 /media/discodati/logs -R
</syntaxhighlight>
</syntaxhighlight><br/>


e scriverci dentro qualcosa come
E di conseguenza configurare i singoli virtual host con la cartella giusta
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
server {
server {
listen 443;
 
ssl on;
        # ...
ssl_certificate /etc/nginx/ssl/nomesito.com_ssl_certificate.crt;
ssl_certificate_key /etc/nginx/ssl/nomesito.com_ssl_certificate.key;
server_name nomesito.com;
server_name nomesito.com;


location / {
        error_log /media/discodati/nomesito.com/error.log;
proxy_pass http://127.0.0.1:80;
        access_log /media/discodati/nomesito.com/access.log;
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;
}
}
}
</syntaxhighlight><br/>
</syntaxhighlight><br/>


* Pubblicare il virtual host su nginx
A questo punto tutti i log verranno riversati nei 2 file <code>error.log</code> e <code>access.log</code>.<br/>
Per fare in modo che vengano '''divisi''' e '''compressi''' (una volta che diventano vecchi) automaticamente è necessario configurare '''LOGROTATE'''.
<syntaxhighlight lang="bash">
sudo nano /etc/logrotate.d/nginx
</syntaxhighlight>
e modificare come da esempio
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo ls -s /etc/nginx/sites-available/nomesito.com /etc/nginx/sites-enabled
/var/log/nginx/*.log /media/discodati/logs/*/*.log {
sudo service nginx restart
su www-data adm
</syntaxhighlight><br/><br/>
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
}
</syntaxhighlight>
Per forzare il logrotate usare
<syntaxhighlight lang="bash">
sudo logrotate -f /etc/logrotate.d/nginx
</syntaxhighlight>


== 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 <code>http</code> arriva al <code>''Varnish''</code>
# <code>''Varnish''</code> la dirotta verso la macchina Win con <code>''IIS''</code>
# <code>''IIS''</code> dal suo rewriter trasforma la richiesta in <code>https</code>
# Il giro ricomincia passando questa volta da <code>''Nginx''</code>
# Da qui si torna a <code>''Varnish''</code>, il quale non sapendo gestire una richiesta <code>https</code>, dirotta una normale richiesta <code>http</code> alla macchina Win con <code>''IIS''</code>
# <code>''IIS''</code> dal suo rewriter trasforma la richiesta in <code>https</code> e sitorna al punto '''4'''. generando un <u>loop infinito</u>


[[Category:IT]]
[[Category:IT]]
[[Category:Linux]]
[[Category:Linux]]

Versione attuale delle 15:35, 15 feb 2024

Forward dell'IP reale del client

[modifica]

Per la natura dell'infrastruttura server, l'IP reale del client viene perso dopo la chiamata a Nginx.
Il giro è
Client -> Nginx -> IIS
di conseguenza ad IIS arriva come client IP quello di Nginx 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.

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;
}
#...

Brotli compression

[modifica]

La compressione brotli che sostituisce gzip quando possibile è stata approfondita qua
Nginx modulo Brotli (text compression)

Leggere i LOG del web-server

[modifica]

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

[modifica]

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.com

assicurandosi 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