Automatizziamo l'installazione di WordPress con NGINX Unit e Ubuntu

Automatizziamo l'installazione di WordPress con NGINX Unit e Ubuntu

Ci sono molti materiali sull'installazione di WordPress; una ricerca su Google con le parole chiave "installazione WordPress" Restituisce circa mezzo milione di risultati. Tuttavia, tra questi, ci sono effettivamente molto poche guide utili che permettano di installare e configurare WordPress e il sistema operativo sottostante in modo da garantirne il supporto per un lungo periodo. È possibile che le impostazioni adeguate dipendano fortemente dalle esigenze specifiche o che ciò sia dovuto al fatto che spiegazioni dettagliate rendono l'articolo difficile da leggere.

In questo articolo cercheremo di raccogliere il meglio di entrambi gli approcci, fornendo uno script bash per l'installazione automatica di WordPress su Ubuntu, e lo esamineremo, spiegando cosa fa ogni sua parte, oltre ai compromessi che abbiamo dovuto affrontare durante la sua realizzazione. Se sei un utente esperto, puoi saltare il testo dell'articolo e semplicemente prendere lo script da modificare e utilizzare nei tuoi ambienti. Alla fine, lo script genera un'installazione di WordPress personalizzabile con supporto per Lets Encrypt, funzionante su NGINX Unit e adatta per applicazioni industriali.

L'architettura progettata per il deployment di WordPress utilizzando NGINX Unit è descritta in un articolo precedente, in questo momento ci occuperemo anche di configurare ulteriormente aspetti che non erano stati trattati (come in molte altre guide):

  • WordPress CLI
  • Lets Encrypt e certificati TLSSSL
  • Aggiornamento automatico dei certificati
  • Caching NGINX
  • Compressione NGINX
  • Supporto HTTPS e HTTP/2
  • Automazione del processo

L'articolo tratterà l'installazione su un singolo server, dove verranno collocati contemporaneamente un server per il trattamento della statica, un server per il trattamento PHP, e un database. L'installazione con supporto per più host virtuali e servizi è un potenziale argomento per il futuro. Vuoi che scriviamo su qualcosa che non è presente in questi articoli? Scrivici nei commenti.

Requisiti

  • Server-containers (LXC o LXD), macchina virtuale, o un semplice server fisico, con almeno 512MB di RAM e Ubuntu 18.04 o versioni più recenti installato.
  • Porte 80 e 443 accessibili da Internet
  • Nome di dominio associato all'indirizzo IP pubblico di questo server
  • Accesso con diritti di root (sudo).

Panoramica dell'architettura

L'architettura è la stessa di quella descritta in precedenza, un'applicazione web a tre livelli. È composta da script PHP eseguiti su un gestore PHP e file statici gestiti dal server web.

Automatizziamo l'installazione di WordPress con NGINX Unit e Ubuntu

Principi generali

  • Molti comandi per la configurazione nello script sono racchiusi in condizioni (if) per l'idempotenza: lo script può essere eseguito più volte senza rischi di modificare le impostazioni già pronte.
  • Lo script cerca di installare software dai repository, in modo da poter applicare gli aggiornamenti di sistema con un solo comando (apt upgrade per Ubuntu).
  • I comandi cercano di determinare se vengono eseguiti in un contenitore per modificare le proprie impostazioni di conseguenza.
  • Per impostare il numero di processi/threads da avviare nelle impostazioni, lo script tenta di indovinare i parametri di configurazione automatica per funzionare in contenitori, macchine virtuali, e server "fisici".
  • Quando descriviamo le impostazioni, pensiamo sempre prima di tutto all'automazione, che speriamo diventi la base per creare la propria infrastruttura come codice.
  • Tutti i comandi vengono eseguiti dall'utente root, poiché modificano le impostazioni di sistema principali, ma WordPress stesso viene eseguito da un normale utente.

Impostazione delle variabili d'ambiente

Impostare le seguenti variabili d'ambiente prima di eseguire lo script:

  • WORDPRESS_DB_PASSWORD — password per il database di WordPress
  • WORDPRESS_ADMIN_USER — nome amministratore di WordPress
  • WORDPRESS_ADMIN_PASSWORD — password dell'amministratore di WordPress
  • WORDPRESS_ADMIN_EMAIL — email dell'amministratore di WordPress
  • WORDPRESS_URL — URL completo del sito WordPress, a partire da https://.
  • LETS_ENCRYPT_STAGING — di default vuota, ma impostando il valore a 1, utilizzerai i server di staging di Let's Encrypt, necessari per richiedere frequentemente i certificati durante il testing delle tue impostazioni, altrimenti Let's Encrypt potrebbe temporaneamente bloccare il tuo indirizzo IP a causa dell'elevato numero di richieste.

Lo script verifica che queste variabili relative a WordPress siano impostate e termina l'esecuzione se non lo sono.
Le righe dello script 572-576 verificano il valore LETS_ENCRYPT_STAGING.

Impostazione delle variabili d'ambiente derivate

Nelle righe 55-61, lo script imposta le seguenti variabili d'ambiente, a un valore fisso oppure utilizzando un valore ottenuto dalle variabili impostate nella sezione precedente:

  • DEBIAN_FRONTEND="noninteractive" — informa le applicazioni che sono in esecuzione in uno script e non c'è possibilità di interazione con l'utente.
  • WORDPRESS_CLI_VERSION="2.4.0" — versione dell'applicazione WordPress CLI.
  • WORDPRESS_CLI_MD5= "dedd5a662b80cda66e9e25d44c23b25c" — checksum del file eseguibile WordPress CLI 2.4.0 (la versione è indicata nella variabile WORDPRESS_CLI_VERSION). Lo script alla riga 162 utilizza questo valore per verificare che sia stato scaricato il file corretto di WordPress CLI.
  • UPLOAD_MAX_FILESIZE="16M" — dimensione massima del file che può essere caricato in WordPress. Questa impostazione viene utilizzata in vari punti, quindi è più semplice definirla in un unico luogo.
  • TLS_HOSTNAME= "$(echo ${WORDPRESS_URL} | cut -d'\/' -f3)" — hostname del sistema, estratto dalla variabile WORDPRESS_URL. Viene utilizzato per ottenere i certificati TLS/SSL appropriati da Let’s Encrypt, nonché per la verifica interna di WordPress.
  • NGINX_CONF_DIR="\/etc\/nginx" — percorso della directory con le impostazioni NGINX, compreso il file principale nginx.conf.
  • CERT_DIR="\/etc\/letsencrypt\/live\/${TLS_HOSTNAME}" — percorso ai certificati Let’s Encrypt per il sito WordPress, ottenuto dalla variabile TLS_HOSTNAME.

Assegnazione dell'hostname al server WordPress

Lo script imposta l'hostname del server in modo che il valore corrisponda al nome di dominio del sito. Non è obbligatorio, ma è più comodo inviare email in uscita tramite SMTP quando si configura un singolo server, come fa lo script.

codice dello script

# Change the hostname to be the same as the WordPress hostname
if [ ! "$(hostname)" == "${TLS_HOSTNAME}" ]; then
  echo " Changing hostname to ${TLS_HOSTNAME}"
  hostnamectl set-hostname "${TLS_HOSTNAME}"
fi

Aggiunta dell'hostname in \/etc\/hosts

Estensione WP‑Cron viene utilizzato per eseguire attività periodiche, richiede che WordPress possa accedere a se stesso tramite HTTP. Per garantire che WP-Cron funzioni correttamente in tutti gli ambienti, lo script aggiunge una riga al file /etc/hosts, in modo che WordPress possa accedere a se stesso tramite l'interfaccia loopback:

codice dello script

# Add the hostname to /etc/hosts
if [ "$(grep -m1 "${TLS_HOSTNAME}" /etc/hosts)" = "" ]; then
  echo " Adding hostname ${TLS_HOSTNAME} to /etc/hosts so that WordPress can ping itself"
  printf "::1 %sn127.0.0.1 %sn" "${TLS_HOSTNAME}" "${TLS_HOSTNAME}" >> /etc/hosts
fi

Installazione degli strumenti necessari per i passaggi successivi

La parte rimanente dello script richiede alcuni programmi e presuppone che i repository siano aggiornati. Aggiorniamo l'elenco dei repository e poi installiamo gli strumenti necessari:

codice dello script

# Make sure tools needed for install are present
echo " Installing prerequisite tools"
apt-get -qq update
apt-get -qq install -y 
  bc 
  ca-certificates 
  coreutils 
  curl 
  gnupg2 
  lsb-release

Aggiunta dei repository NGINX Unit e NGINX

Lo script installa NGINX Unit e NGINX open source dai repository ufficiali di NGINX, per assicurarsi che vengano utilizzate versioni con le ultime aggiornamenti di sicurezza e correzioni di bug.

Lo script aggiunge il repository NGINX Unit e poi il repository NGINX, aggiungendo la chiave dei repository e i file di configurazione apt, che definiscono l'accesso ai repository tramite internet.

L'installazione reale di NGINX Unit e NGINX avviene nella sezione successiva. Aggiungiamo preventivamente i repository per non dover aggiornare più volte i metadati, rendendo così l'installazione più veloce.

codice dello script

# Install the NGINX Unit repository
if [ ! -f /etc/apt/sources.list.d/unit.list ]; then
  echo " Installing NGINX Unit repository"
  curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
  echo "deb https://packages.nginx.org/unit/ubuntu/ $(lsb_release -cs) unit" > /etc/apt/sources.list.d/unit.list
fi

# Install the NGINX repository
if [ ! -f /etc/apt/sources.list.d/nginx.list ]; then
  echo " Installing NGINX repository"
  curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
  echo "deb https://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" > /etc/apt/sources.list.d/nginx.list
fi

Installazione di NGINX, NGINX Unit, PHP MariaDB, Certbot (Let’s Encrypt) e delle loro dipendenze.

Una volta aggiunti tutti i repository, aggiorniamo i metadati e installiamo le applicazioni. I pacchetti installati dallo script includono anche le estensioni PHP raccomandate per l'esecuzione di WordPress.org.

codice dello script

echo " Aggiornamento dei metadati del repository"
apt-get -qq update

# Installa PHP con dipendenze e NGINX Unit
echo " Installazione di PHP, NGINX Unit, NGINX, Certbot e MariaDB"
apt-get -qq install -y --no-install-recommends 
  certbot 
  python3-certbot-nginx 
  php-cli 
  php-common 
  php-bcmath 
  php-curl 
  php-gd 
  php-imagick 
  php-mbstring 
  php-mysql 
  php-opcache 
  php-xml 
  php-zip 
  ghostscript 
  nginx 
  unit 
  unit-php 
  mariadb-server

Configurazione di PHP per l'uso con NGINX Unit e WordPress.

Lo script crea un file di configurazione nella directory conf.d. Qui viene impostata la dimensione massima dei file caricati per PHP, viene attivata l'uscita degli errori PHP in STDERR, in modo che vengano registrati nel log di NGINX Unit, e viene riavviato NGINX Unit.

codice dello script

# Find the major and minor PHP version so that we can write to its conf.d directory
PHP_MAJOR_MINOR_VERSION="$(php -v | head -n1 | cut -d' ' -f2 | cut -d'.' -f1,2)"

if [ ! -f "/etc/php/${PHP_MAJOR_MINOR_VERSION}/embed/conf.d/30-wordpress-overrides.ini" ]; then
  echo " Configuring PHP for use with NGINX Unit and WordPress"
  # Add PHP configuration overrides
  cat > "/etc/php/${PHP_MAJOR_MINOR_VERSION}/embed/conf.d/30-wordpress-overrides.ini" << EOM
; Set a larger maximum upload size so that WordPress can handle
; bigger media files.
upload_max_filesize=${UPLOAD_MAX_FILESIZE}
post_max_size=${UPLOAD_MAX_FILESIZE}
; Write error log to STDERR so that error messages show up in the NGINX Unit log
error_log=/dev/stderr
EOM
fi

# Restart NGINX Unit because we have reconfigured PHP
echo " Restarting NGINX Unit"
service unit restart

Impostazione delle configurazioni del database MariaDB per WordPress.

Abbiamo scelto MariaDB invece di MySQL poiché ha una comunità più attiva; inoltre, potrebbe offrire prestazioni più elevate per impostazione predefinita. (probabilmente qui è tutto più semplice: per installare MySQL, bisogna aggiungere un ulteriore repository, nota del traduttore).

Lo script crea un nuovo database e genera le credenziali per accedere a WordPress tramite l'interfaccia loopback:

codice dello script

# Set up the WordPress database
echo " Configuring MariaDB for WordPress"
mysqladmin create wordpress || echo "Ignoring above error because database may already exist"
mysql -e "GRANT ALL PRIVILEGES ON wordpress.* TO "wordpress"@"localhost" IDENTIFIED BY "$WORDPRESS_DB_PASSWORD"; FLUSH PRIVILEGES;"

Installazione di WordPress CLI.

In questo passaggio lo script installa il programma WP-CLI. Con esso puoi installare e gestire le impostazioni di WordPress senza dover modificare manualmente i file, aggiornare il database o accedere al pannello di controllo. Inoltre, consente di installare temi e plugin e di eseguire l'aggiornamento di WordPress.

codice dello script

if [ ! -f /usr/local/bin/wp ]; then
  # Installa il WordPress CLI
  echo " Installazione dello strumento WordPress CLI"
  curl --retry 6 -Ls "https://github.com/wp-cli/wp-cli/releases/download/v${WORDPRESS_CLI_VERSION}/wp-cli-${WORDPRESS_CLI_VERSION}.phar" > /usr/local/bin/wp
  echo "$WORDPRESS_CLI_MD5 /usr/local/bin/wp" | md5sum -c -
  chmod +x /usr/local/bin/wp
fi

Installazione e configurazione di WordPress.

Lo script installa l'ultima versione di WordPress nella directory /var/www/wordpress, e modifica le impostazioni:

  • La connessione al database avviene tramite socket di dominio unix anziché TCP su loopback, per ridurre il traffico TCP.
  • WordPress aggiunge un prefisso. https:// al URL, se i client si connettono a NGINX tramite il protocollo HTTPS e inviano anche l'hostname remoto (come fornito da NGINX) a PHP. Utilizziamo un frammento di codice per configurarlo.
  • WordPress richiede HTTPS per il login
  • La struttura dell'URL di default si basa sulle risorse
  • Vengono impostati i diritti corretti sul file system per la directory di WordPress.

codice dello script

if [ ! -d /var/www/wordpress ]; then
  # Crea le directory di WordPress
  mkdir -p /var/www/wordpress
  chown -R www-data:www-data /var/www

  # Scarica WordPress utilizzando la WordPress CLI
  echo " Installazione di WordPress"
  su -s /bin/sh -c 'wp --path=/var/www/wordpress core download' www-data

  WP_CONFIG_CREATE_CMD="wp --path=/var/www/wordpress config create --extra-php --dbname=wordpress --dbuser=wordpress --dbhost="localhost:/var/run/mysqld/mysqld.sock" --dbpass="${WORDPRESS_DB_PASSWORD}""

  # Questo frammento viene iniettato nel file wp-config.php quando viene creato;
  # informa WordPress che siamo dietro a un proxy inverso e, come tale,
  # ci consente di generare link utilizzando HTTPS
  cat > /tmp/wp_forwarded_for.php << 'EOM'
/* Attiva HTTPS se HTTP_X_FORWARDED_PROTO corrisponde a 'https' */
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
    $_SERVER['HTTPS'] = 'on';
}
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
EOM

  # Crea la configurazione di WordPress
  su -s /bin/sh -p -c "cat /tmp/wp_forwarded_for.php | ${WP_CONFIG_CREATE_CMD}" www-data
  rm /tmp/wp_forwarded_for.php
  su -s /bin/sh -p -c "wp --path=/var/www/wordpress config set 'FORCE_SSL_ADMIN' 'true'" www-data

  # Installa WordPress
  WP_SITE_INSTALL_CMD="wp --path=/var/www/wordpress core install --url="${WORDPRESS_URL}" --title="${WORDPRESS_SITE_TITLE}" --admin_user="${WORDPRESS_ADMIN_USER}" --admin_password="${WORDPRESS_ADMIN_PASSWORD}" --admin_email="${WORDPRESS_ADMIN_EMAIL}" --skip-email"
  su -s /bin/sh -p -c "${WP_SITE_INSTALL_CMD}" www-data

  # Imposta la struttura del permalink su un valore predefinito ragionevole che non è nell'interfaccia utente
  su -s /bin/sh -p -c "wp --path=/var/www/wordpress option update permalink_structure '/%year%/%monthnum%/%postname%/'" www-data

  # Rimuovi il file di esempio perché è superfluo e potrebbe essere un problema di sicurezza
  rm /var/www/wordpress/wp-config-sample.php

  # Assicurati che i permessi di WordPress siano corretti
  find /var/www/wordpress -type d -exec chmod g+s {} ;
  chmod g+w /var/www/wordpress/wp-content
  chmod -R g+w /var/www/wordpress/wp-content/themes
  chmod -R g+w /var/www/wordpress/wp-content/plugins
fi

Configurazione di NGINX Unit

Lo script configura NGINX Unit per eseguire PHP e gestire i percorsi di WordPress, isolando lo spazio dei nomi dei processi PHP e ottimizzando le impostazioni delle prestazioni. Ci sono tre funzioni a cui prestare attenzione:

  • Il supporto degli spazi dei nomi è definito da una condizione, basata sulla verifica dell'esecuzione dello script in un container. Questo è necessario poiché la maggior parte delle impostazioni dei container non supporta l'esecuzione nidificata di container.
  • Se è supportato lo spazio dei nomi, viene disabilitato lo spazio dei nomi network. Questo è necessario per consentire a WordPress di connettersi contemporaneamente agli endpoint e di essere accessibile in Internet.
  • Il numero massimo di processi è determinato nel seguente modo: (Memoria disponibile per i processi MariaDB e NGINX Uniy) / (limite di memoria RAM in PHP + 5)
    Questo valore è impostato nelle configurazioni di NGINX Unit.

Questo valore implica anche che ci sono sempre almeno due processi PHP in esecuzione, il che è importante poiché WordPress effettua molti richieste asincrone a se stesso e senza processi aggiuntivi, ad esempio, l'esecuzione di WP-Cron non funzionerà. Potresti voler aumentare o diminuire questi limiti in base alle tue configurazioni locali, poiché le impostazioni create qui sono conservative. Nella maggior parte dei sistemi di produzione, le impostazioni si trovano tra 10 e 100.

codice dello script

if [ "${container:-unknown}" != "lxc" ] && [ "$(grep -m1 -a container=lxc /proc/1/environ | tr -d ' ')" == "" ]; then
  NAMESPACES='"namespaces": {
        "cgroup": true,
        "credential": true,
        "mount": true,
        "network": false,
        "pid": true,
        "uname": true
    }'
else
  NAMESPACES='"namespaces": {}'
fi

PHP_MEM_LIMIT="$(grep 'memory_limit' /etc/php/7.4/embed/php.ini | tr -d ' ' | cut -f2 -d= | numfmt --from=iec)"
AVAIL_MEM="$(grep MemAvailable /proc/meminfo | tr -d ' kB' | cut -f2 -d: | numfmt --from-unit=K)"
MAX_PHP_PROCESSES="$(echo "${AVAIL_MEM}/${PHP_MEM_LIMIT}+5" | bc)"
echo " Calcolato il numero massimo di processi PHP come ${MAX_PHP_PROCESSES}. Potresti voler ottimizzare questo valore a causa delle variazioni nella tua configurazione. Non è insolito vedere valori tra 10-100 nelle configurazioni di produzione."

echo " Configurando NGINX Unit per utilizzare PHP e WordPress"
cat > /tmp/wordpress.json << EOM
{
  "settings": {
    "http": {
      "header_read_timeout": 30,
      "body_read_timeout": 30,
      "send_timeout": 30,
      "idle_timeout": 180,
      "max_body_size": $(numfmt --from=iec ${UPLOAD_MAX_FILESIZE})
    }
  },
  "listeners": {
    "127.0.0.1:8080": {
      "pass": "routes/wordpress"
    }
  },
  "routes": {
    "wordpress": [
      {
        "match": {
          "uri": [
            "*.php",
            "*.php/*",
            "/wp-admin/"
          ]
        },
        "action": {
          "pass": "applications/wordpress/direct"
        }
      },
      {
        "action": {
          "share": "/var/www/wordpress",
          "fallback": {
            "pass": "applications/wordpress/index"
          }
        }
      }
    ]
  },
  "applications": {
    "wordpress": {
      "type": "php",
      "user": "www-data",
      "group": "www-data",
      "processes": {
        "max": ${MAX_PHP_PROCESSES},
        "spare": 1
      },
      "isolation": {
        ${NAMESPACES}
      },
      "targets": {
        "direct": {
          "root": "/var/www/wordpress/"
        },
        "index": {
          "root": "/var/www/wordpress/",
          "script": "index.php"
        }
      }
    }
  }
}
EOM

curl -X PUT --data-binary @/tmp/wordpress.json --unix-socket /run/control.unit.sock http://localhost/config

Configurazione di NGINX

Configurazione dei parametri principali di NGINX

Lo script crea una directory per la cache di NGINX e poi crea il file di configurazione principale nginx.conf. Fai attenzione al numero di processi elaboratori e all'impostazione delle dimensioni massime del file per il caricamento. C'è anche una riga per collegare il file di configurazione della compressione, definito nella sezione successiva, seguita dalle impostazioni di caching.

codice dello script

# Make directory for NGINX cache
mkdir -p /var/cache/nginx/proxy

echo " Configuring NGINX"
cat > ${NGINX_CONF_DIR}/nginx.conf << EOM
user nginx;
worker_processes auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       ${NGINX_CONF_DIR}/mime.types;
    default_type  application/octet-stream;
    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;
    client_max_body_size ${UPLOAD_MAX_FILESIZE};
    keepalive_timeout  65;
    # gzip settings
    include ${NGINX_CONF_DIR}/gzip_compression.conf;
    # Cache settings
    proxy_cache_path /var/cache/nginx/proxy
        levels=1:2
        keys_zone=wp_cache:10m
        max_size=10g
        inactive=60m
        use_temp_path=off;
    include ${NGINX_CONF_DIR}/conf.d/*.conf;
}
EOM

Configurazione della compressione NGINX

La compressione del contenuto al volo prima di inviarlo ai clienti è un ottimo modo per migliorare le prestazioni del sito web, ma solo se la compressione è configurata correttamente. Questa sezione dello script si basa sulle impostazioni da qui.

codice dello script

cat > ${NGINX_CONF_DIR}\/gzip_compression.conf << 'EOM'
# Credito: https://github.com/h5bp/server-configs-nginx/
# ----------------------------------------------------------------------
# | Compressione                                                      |
# ----------------------------------------------------------------------
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
# Abilita la compressione gzip.
# Impostazione predefinita: off
gzip on;
# Livello di compressione (1-9).
# 5 è un compromesso perfetto tra dimensione e utilizzo della CPU, offrendo circa il 75%
# di riduzione per la maggior parte dei file ASCII (quasi identico al livello 9).
# Impostazione predefinita: 1
gzip_comp_level 6;
# Non comprimere nulla che sia già piccolo e poco probabile che si riduca molto, se non del tutto
# (l'impostazione predefinita è 20 byte, il che è negativo poiché di solito porta a file più grandi
# dopo la compressione gzip).
# Impostazione predefinita: 20
gzip_min_length 256;
# Comprimi i dati anche per i clienti che si connettono a noi tramite proxy,
# identificati dall'intestazione "Via" (richiesta per CloudFront).
# Impostazione predefinita: off
gzip_proxied any;
# Indica ai proxy di memorizzare nella cache sia la versione gzippata sia quella normale di una risorsa
# ogni volta che l'intestazione delle capacità di Accept-Encoding del cliente varia;
# Evita il problema in cui un cliente non compatibile con gzip (che è estremamente raro
# oggi) visualizzerebbe del testo confuso se il loro proxy fornisse la versione gzippata.
# Impostazione predefinita: off
gzip_vary on;
# Comprimi tutto l'output etichettato con uno dei seguenti tipi MIME.
# `text/html` è sempre compresso dal modulo gzip.
# Impostazione predefinita: text/html
gzip_types
  application/atom+xml
  application/geo+json
  application/javascript
  application/x-javascript
  application/json
  application/ld+json
  application/manifest+json
  application/rdf+xml
  application/rss+xml
  application/vnd.ms-fontobject
  application/wasm
  application/x-web-app-manifest+json
  application/xhtml+xml
  application/xml
  font/eot
  font/otf
  font/ttf
  image/bmp
  image/svg+xml
  text/cache-manifest
  text/calendar
  text/css
  text/javascript
  text/markdown
  text/plain
  text/xml
  text/vcard
  text/vnd.rim.location.xloc
  text/vtt
  text/x-component
  text/x-cross-domain-policy;
EOM

Configurazione NGINX per WordPress

Lo script crea quindi un file di configurazione per WordPress default.conf nella directory conf.d. Qui vengono configurati:

  • Attivazione dei certificati TLS ricevuti da Let’s Encrypt tramite Certbot (la sua configurazione sarà nella sezione successiva)
  • Impostazione delle opzioni di sicurezza TLS, basata sulle raccomandazioni di Let’s Encrypt
  • Attivazione della memorizzazione nella cache delle richieste saltate per 1 ora per impostazione predefinita
  • Disattivazione della registrazione degli accessi e della registrazione degli errori, se il file non viene trovato, per due file richiesti comuni: favicon.ico e robots.txt
  • Divieto di accesso a file nascosti e ad alcuni file .php, per prevenire accessi non autorizzati o avvii involontari
  • Disabilitazione del logging degli accessi per risorse statiche e file di font
  • Impostazione dell'intestazione Access-Control-Allow-Origin per i file di font
  • Aggiunta di routing per index.php e altre risorse statiche.

codice dello script

cat > ${NGINX_CONF_DIR}/conf.d/default.conf << EOM
upstream unit_php_upstream {
    server 127.0.0.1:8080;
    keepalive 32;
}
server {
    listen 80;
    listen [::]:80;
    # ACME-challenge usato da Certbot per Let's Encrypt
    location ^~ \/.well-known\/acme-challenge\/ {
      root \/var\/www\/certbot;
    }
    location \/ {
      return 301 https:\/${TLS_HOSTNAME}$request_uri;
    }
}
server {
    listen      443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ${TLS_HOSTNAME};
    root        \/var\/www\/wordpress\/;
    # Configurazione Let's Encrypt
    ssl_certificate         ${CERT_DIR}\/fullchain.pem;
    ssl_certificate_key     ${CERT_DIR}\/privkey.pem;
    ssl_trusted_certificate ${CERT_DIR}\/chain.pem;
    include ${NGINX_CONF_DIR}\/options-ssl-nginx.conf;
    ssl_dhparam ${NGINX_CONF_DIR}\/ssl-dhparams.pem;
    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    # Cache proxy
    proxy_cache wp_cache;
    proxy_cache_valid 200 302 1h;
    proxy_cache_valid 404 1m;
    proxy_cache_revalidate on;
    proxy_cache_background_update on;
    proxy_cache_lock on;
    proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
    location = \/favicon.ico {
        log_not_found off;
        access_log off;
    }
    location = \/robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # Negare tutti i tentativi di accesso a file nascosti come .htaccess, .htpasswd,
    # .DS_Store (Mac)
    # Continuare a registrare le richieste per elaborarle in seguito (o per inviarle a utility firewall
    # come fail2ban)
    location ~ \/. {
        deny all;
    }
    # Negare l'accesso a eventuali file con un'estensione .php nella directory uploads;
    # funziona anche in installazioni in sottodirectory e in reti multi-sito.
    # Continuare a registrare le richieste per elaborarle in seguito (o per inviarle a utility firewall
    # come fail2ban).
    location ~* \/(?:uploads|files)\/.*.php$ {
        deny all;
    }
    # WordPress: negare l'accesso ai file PHP in wp-content, wp-includes
    location ~* ^\/(?:wp-content|wp-includes)\/.*.php$ {
        deny all;
    }
    # Negare l'accesso pubblico a wp-config.php
    location ~* wp-config.php {
        deny all;
    }
    # Non registrare accessi per risorse statiche, media
    location ~* .(?:css(.map)?|js(.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
        access_log off;
    }
    location ~* .(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
        add_header Access-Control-Allow-Origin "*";
        access_log off;
    }
    location \/ {
        try_files $uri @index_php;
    }
    location @index_php {
        proxy_socket_keepalive on;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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 $scheme;
        proxy_set_header Host $host;
        proxy_pass       http:\/\/unit_php_upstream;
    }
    location ~* .php$ {
        proxy_socket_keepalive on;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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 $scheme;
        proxy_set_header Host $host;
        try_files        $uri =404;
        proxy_pass       http:\/\/unit_php_upstream;
    }
}
EOM

Impostazione di Certbot per i certificati di Let’s Encrypt e il loro rinnovo automatico

Certbot — strumento gratuito della Electronic Frontier Foundation (EFF) che permette di ottenere e aggiornare automaticamente i certificati TLS da Let’s Encrypt. Lo script esegue le seguenti azioni, portando all'impostazione di Certbot per la gestione dei certificati di Let’s Encrypt in NGINX:

  • Ferma NGINX
  • Scarica i parametri TLS consigliati
  • Avvia Certbot per ottenere certificati per il sito
  • Riavvia NGINX per utilizzare i certificati
  • Imposta l'esecuzione giornaliera di Certbot alle 3:24 di notte per verificare la necessità di aggiornare i certificati e, se necessario, scaricare nuovi certificati e riavviare NGINX.

codice dello script

echo " Fermando NGINX per impostare Let's Encrypt"
service nginx stop

mkdir -p /var/www/certbot
chown www-data:www-data /var/www/certbot
chmod g+s /var/www/certbot

if [ ! -f ${NGINX_CONF_DIR}/options-ssl-nginx.conf ]; then
  echo " Scaricando i parametri TLS consigliati"
  curl --retry 6 -Ls -z "Tue, 14 Apr 2020 16:36:07 GMT" 
    -o "${NGINX_CONF_DIR}/options-ssl-nginx.conf" 
    "https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf" 
    || echo "Impossibile scaricare l'ultima options-ssl-nginx.conf"
fi

if [ ! -f ${NGINX_CONF_DIR}/ssl-dhparams.pem ]; then
  echo " Scaricando i parametri TLS DH consigliati"
  curl --retry 6 -Ls -z "Tue, 14 Apr 2020 16:49:18 GMT" 
    -o "${NGINX_CONF_DIR}/ssl-dhparams.pem" 
    "https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem" 
    || echo "Impossibile scaricare l'ultima ssl-dhparams.pem"
fi

# Se tls_certs_init.sh non è stato eseguito prima, rimuovere i certificati autofirmati
if [ ! -d "/etc/letsencrypt/accounts" ]; then
  echo " Rimuovendo i certificati autofirmati"
  rm -rf "${CERT_DIR}"
fi

if [ "" = "${LETS_ENCRYPT_STAGING:-}" ] || [ "0" = "${LETS_ENCRYPT_STAGING}" ]; then
  CERTBOT_STAGING_FLAG=""
else
  CERTBOT_STAGING_FLAG="--staging"
fi

if [ ! -f "${CERT_DIR}/fullchain.pem" ]; then
  echo " Generando certificati con Let's Encrypt"
  certbot certonly --standalone 
         -m "${WORDPRESS_ADMIN_EMAIL}" 
         ${CERTBOT_STAGING_FLAG} 
         --agree-tos --force-renewal --non-interactive 
         -d "${TLS_HOSTNAME}"
fi

echo " Avviando NGINX per utilizzare la nuova configurazione"
service nginx start

# Scrivi crontab per il rinnovo periodico dei certificati Let's Encrypt
if [ "$(crontab -l | grep -m1 'certbot renew')" == "" ]; then
  echo " Aggiungendo certbot al crontab per il rinnovo automatico di Let's Encrypt"
  (crontab -l 2>/dev/null; echo "24 3 * * * certbot renew --nginx --post-hook 'service nginx reload'") | crontab -
fi

Ulteriore configurazione del tuo sito

Abbiamo descritto sopra come il nostro script configura NGINX e NGINX Unit per servire un sito pronto per la produzione con TLS SSL abilitato. Puoi anche, a seconda delle tue necessità, aggiungere in futuro:

  • Supporto Brotli, una compressione migliore al volo tramite HTTPS
  • ModSecurity con con regole per WordPress, per prevenire attacchi automatici al tuo sito
  • Backup per WordPress, adatto a te
  • Protezione utilizzando AppArmor (su Ubuntu)
  • Postfix o msmtp, affinché WordPress possa inviare email
  • Controlli del tuo sito per capire quanta traffico può sostenere

Per una performance ancora migliore del sito, ti consigliamo di aggiornarti a NGINX Plus, il nostro prodotto commerciale di livello enterprise, basato su NGINX con codice sorgente aperto. I suoi abbonati riceveranno un modulo Brotli caricato dinamicamente, oltre a (a pagamento) NGINX ModSecurity WAF. Offriamo anche NGINX App Protect, un modulo WAF per NGINX Plus, basato su tecnologia leader nel settore della sicurezza di F5.

N.B. Per supporto su un sito ad alto traffico, puoi rivolgerti agli esperti Southbridge. Garantiamo il funzionamento veloce e affidabile del tuo sito o servizio sotto qualsiasi carico.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS - ProHoster