Indice dei contenuti
Qualche settimana fa abbiamo pubblicato un tutorial che spiega come usare Nginx come reverse-proxy (proxy inverso) con funzioni di request buffering e caching usando una tecnica particolare, denominata edge-origin, che prevede l'interazione tra un servizio esposto al web che accetta le request HTTP degli utenti (edge) e le veicola a uno o più server HTTP retrostanti (origin) accessibili soltanto a lui: questa particolare configurazione ha innumerevoli vantaggi in termini di sicurezza e performance, specialmente se viene accompagnata da una configurazione adeguata del reverse proxy che consente di creare una cache statica dei contenuti HTTP più visitati.
I parametri di configurazione descritti nel precedente tutorial erano pensati per siti web generici, ma possono senz'altro essere ottimizzati ulteriormente - dal punto di vista delle prestazioni - per gestire al meglio scenari di caching specifici, a patto di conoscere la tecnologia con cui il server origin serve i propri contenuti. In questo articolo di follow-up vedremo come è possibile perfezionare la configurazione del file nginx.conf per ottimizzare le performance di Nginx nei casi in cui lo si utilizza come reverse-proxy di un tipico sito web abilitato per WordPress.
Inutile dire che il server origin, ovvero quello che serve il sito web su piattaforma WordPress, può essere Linux o Windows e utilizzare qualsiasi webserver (Apache, Nginx, IIS o altro), mentre il server edge, che ospita Nginx e accetta le request dal web, è normalmente una macchina Linux. I due servizi possono persino essere installati sulla stessa macchina Linux, a patto che il server web utilizzato come origin sia configurato per servire le proprie pagine su una porta diversa da quella che sarà esposta al pubblico (es. 8080 in luogo della 80): al tempo stesso, installare tutto su una singola macchina è decisamente sconsigliabile se il sito web genera un gran numero di richieste HTTP, per ovvi motivi di performance.
Http
Ecco le impostazioni ottimizzate per WordPress che possono essere utilizzate all'interno della sezione http del file nginx.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# --------------------------------------------------------------------- # REVERSE PROXY CONFIGURATION for Wordpress, v1.0/2018 # https://www.ryadel.com # --------------------------------------------------------------------- #Enables or disables buffering of responses from the proxied server. proxy_buffering on; #prevent header too large errors proxy_buffers 256 16k; proxy_buffer_size 32k; #set the location of the cached files, zone, name, size (1000 MB) and how long to cache for (600 minutes) proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=edge-cache:10m inactive=600m max_size=1g; proxy_temp_path /var/cache/nginx/tmp; proxy_cache_key $scheme$host$request_uri; # When enabled, only one request at a time will be allowed to populate # a new cache element identified according to the proxy_cache_key directive # by passing a request to a proxied server. # Other requests of the same cache element will either wait for a response to appear in the cache # or the cache lock for this element to be released, up to the time set by the proxy_cache_lock_timeout directive. proxy_cache_lock on; # proxy_cache_revalidate instructs NGINX to use conditional GET requests when refreshing content from the origin servers. # If a client requests an item that is cached but expired as defined by the cache control headers, NGINX includes the # If-Modified-Since field in the header of the GET request it sends to the origin server. # This saves on bandwidth, because the server sends the full item only if it has been modified since the time recorded # in the Last-Modified header attached to the file when NGINX originally cached it. proxy_cache_revalidate on; #proxy_cache_min_uses sets the number of times an item must be requested by clients before NGINX caches it. # This is useful if the cache is constantly filling up, as it ensures that only the most frequently accessed items # are added to the cache. By default proxy_cache_min_uses is set to 1. proxy_cache_min_uses 3; #The updating parameter to the proxy_cache_use_stale directive, combined with enabling the # proxy_cache_background_update directive, instructs NGINX to deliver stale content when clients request an item # that is expired or is in the process of being updated from the origin server. All updates will be done in the background. # The stale file is returned for all requests until the updated file is fully downloaded. proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; proxy_cache_background_update on; #fix 504 gateway timeouts, can go in nginx.conf proxy_connect_timeout 600; proxy_send_timeout 600; proxy_read_timeout 600; send_timeout 600; # Sets caching time for different response codes proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid any 1m; # Sets the HTTP protocol version for proxying (default is 1.0). # Version 1.1 is recommended for use with keepalive connections and NTLM authentication. proxy_http_version 1.1; # Determines whether SSL sessions can be reused when working with the proxied server (default is on). # If the errors “SSL3_GET_FINISHED:digest check failed” appear in the logs, try turning it off. # proxy_ssl_session_reuse on; # --------------------------------------------------------------------- # REVERSE PROXY CONFIGURATION - END # --------------------------------------------------------------------- |
Tutte le opzioni di configurazione utilizzate sono precedute da un commento che spiega in dettaglio il loro funzionamento: nel caso in cui abbiate bisogno di ulteriori informazioni, vi consigliamo di consultare la documentazione ufficiale di Nginx, estremamente chiara ed esaustiva.
Ovviamente, se non volete che il vostro nginx.conf diventi troppo grande e di difficile lettura, potete anche inserire il tutto all'interno di un file separato - con un nome del tipo http.reverseproxy.conf - da creare nella cartella /etc/nginx/ e poi da linkare al file di configurazione principale inserendo la seguente riga all'interno del file nginx.conf:
1 |
include http.reverseproxy.conf; |
Server
Ecco le opzioni di configurazione da inserire all'interno della sezione server del file nginx.conf, subito sotto alle impostazioni listen e server_name che istruiscono Nginx sulle porte e nomi host a cui rispondere:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# --------------------------------------------------------------------- # CACHE CONFIGURATION for Wordpress, v1.0/2018 # https://www.ryadel.com # --------------------------------------------------------------------- # define nginx variables set $do_not_cache 0; set $skip_reason ""; set $bypass 0; # security for bypass so localhost can empty cache if ($remote_addr ~ "^(127.0.0.1)$") { set $bypass $http_secret_header; } # skip caching WordPress cookies if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) { set $do_not_cache 1; set $skip_reason Cookie; } # Don't cache URIs containing the following segments if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|sitemap(_index)?.xml") { set $skip_cache 1; set $skip_reason URI; } # --------------------------------------------------------------------- # CACHE CONFIGURATION for Wordpress - END # --------------------------------------------------------------------- |
Location
Ultime, ma non per importanza, le impostazioni di configurazione per la sezione location:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
location / { # comment out proxy_redirect if get login redirect loop proxy_redirect off; proxy_cache edge-cache; proxy_cache_revalidate on; proxy_ignore_headers Expires Cache-Control; # CACHE CONFIGURATION result proxy_cache_bypass $bypass $do_not_cache; proxy_no_cache $do_not_cache; # httpoxy exploit protection proxy_set_header Proxy ""; # add forwarded for header proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # add the Wordpress hostname to avoid Wordpress canonical redirect proxy_set_header Host $host; # proxy_set_header Host www.giudiziouniversale.com; proxy_set_header Connection ""; # pass requests to the origin backend proxy_pass https://origin; } |
Come si può evincere analizzando i vari comandi e i relativi commenti, ci siamo assicurati che la cache di Nginx venga bypassata in tutti i casi in cui l'utente è autenticato e/o effettua delle request a contenuti che non è opportuno mettere in cache: cookie di autenticazione WP, pagine di amministrazione, e così via: in questo modo le funzionalità di WordPress non saranno compromesse dalla presenza del reverse-proxy.
Riepilogo
Il codice seguente rappresenta un esempio di file nginx.conf completo che è possibile mettere in piedi sommando tutte le impostazioni descritte in questo articolo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# --------------------------------------------------------------------- # NGINX - Proxy-Cache configuration - v1.0/2018 # https://www.ryadel.com/ # --------------------------------------------------------------------- user nginx; worker_processes 2; working_directory /var/www; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include mime.types; default_type application/octet-stream; include http.reverseproxy.conf; # Custom settings for http add_header X-Cache-Status $upstream_cache_status; upstream origin { # gusrv (via INTERNAL firewalld zone) server www.origin-hostname.com; } server { listen 80 default_server; listen [::]:80 default_server; server_name www.edge-hostname.com; # --------------------------------------------------------------------- # CACHE CONFIGURATION for Wordpress, v1.0/2018 # https://www.ryadel.com # --------------------------------------------------------------------- # define nginx variables set $do_not_cache 0; set $skip_reason ""; set $bypass 0; # security for bypass so localhost can empty cache if ($remote_addr ~ "^(127.0.0.1)$") { set $bypass $http_secret_header; } # skip caching WordPress cookies if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) { set $do_not_cache 1; set $skip_reason Cookie; } # Don't cache URIs containing the following segments if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|sitemap(_index)?.xml") { set $skip_cache 1; set $skip_reason URI; } # --------------------------------------------------------------------- # CACHE CONFIGURATION for Wordpress - END # --------------------------------------------------------------------- location / { # comment out proxy_redirect if get login redirect loop proxy_redirect off; proxy_cache edge-cache; proxy_cache_revalidate on; proxy_ignore_headers Expires Cache-Control; # CACHE CONFIGURATION result proxy_cache_bypass $bypass $do_not_cache; proxy_no_cache $do_not_cache; # httpoxy exploit protection proxy_set_header Proxy ""; # add forwarded for header proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # add the Wordpress hostname to avoid Wordpress canonical redirect proxy_set_header Host $host; # proxy_set_header Host www.edge-hostname.com; proxy_set_header Connection ""; # pass requests to the origin backend proxy_pass https://origin; } } } |
Problematiche comuni
La maggior parte dei problemi che possono capitare quando si configura Nginx come reverse proxy sono relativi a una errata configurazione dei permessi di accesso ai file: per questo motivo è opportuno assicurarsi che l'utente nginx - o qualsiasi altro utente indicato dal parametro user all'interno del file nginx.conf - abbia modo di accedere in lettura e scrittura alle cartelle specificate nei parametri working_directory , proxy_cache_path e proxy_temp_path.
Nel caso in cui questo non sia sufficiente a risolvere il problema, è importante dare un'occhiata ai file di log accessi e/o errori generati da Nginx durante l'esecuzione, ovvero /var/log/nginx/access.log e /var/log/nginx/error.log : nella maggior parte dei casi, sarà possibile recuperare tutte le informazioni necessarie per effettuare una ricerca sul web e risolvere la problematica.
Conclusioni
Per il momento è tutto! Spero sinceramente che queste impostazioni potranno essere d'aiuto agli amministratori di sistema che necessitano di ottimizzare la propria configurazione Nginx per gestire al meglio il reverse-proxy dei loro siti WordPress.