Automatisering av WordPress-installasjon med NGINX Unit og Ubuntu

Automatisering av WordPress-installasjon med NGINX Unit og Ubuntu

Det er mange veiledninger om hvordan du installerer WordPress, et Google-søk etter "WordPress install" vil gi omtrent en halv million resultater. Imidlertid er det faktisk svært få gode guider blant dem, ifølge hvilke du kan installere og konfigurere WordPress og det underliggende operativsystemet slik at de er i stand til å støtte over lang tid. Kanskje de riktige innstillingene er svært avhengig av spesifikke behov, eller dette skyldes det faktum at en detaljert forklaring gjør artikkelen vanskelig å lese.

I denne artikkelen vil vi prøve å kombinere det beste fra begge verdener ved å gi et bash-skript for å automatisk installere WordPress på Ubuntu, samt gå gjennom det, forklare hva hvert stykke gjør, samt kompromissene vi gjorde med å utvikle det . Hvis du er en avansert bruker, kan du hoppe over teksten i artikkelen og bare ta manuset for modifikasjon og bruk i dine miljøer. Utgangen av skriptet er en tilpasset WordPress-installasjon med Lets Encrypt-støtte, kjører på NGINX Unit og egnet for produksjonsbruk.

Den utviklede arkitekturen for å distribuere WordPress ved å bruke NGINX-enheten er beskrevet i eldre artikkel, nå vil vi også konfigurere ting som ikke ble dekket der (som i mange andre opplæringsprogrammer):

  • WordPress CLI
  • La oss kryptere og TLSSSL-sertifikater
  • Automatisk fornyelse av sertifikater
  • NGINX-bufring
  • NGINX-komprimering
  • HTTPS og HTTP/2-støtte
  • Prosessautomatisering

Artikkelen vil beskrive installasjonen på én server, som samtidig vil være vert for en statisk prosesseringsserver, en PHP-behandlingsserver og en database. En installasjon som støtter flere virtuelle verter og tjenester er et potensielt tema for fremtiden. Hvis du vil at vi skal skrive om noe som ikke står i disse artiklene, skriv i kommentarfeltet.

Krav

  • Container server (LXC eller LXD), en virtuell maskin eller en vanlig jernserver med minst 512 MB RAM og Ubuntu 18.04 eller nyere installert.
  • Internett-tilgjengelige porter 80 og 443
  • Domenenavn knyttet til den offentlige ip-adressen til denne serveren
  • Rottilgang (sudo).

Arkitektur oversikt

Arkitekturen er den samme som beskrevet tidligere, en tre-lags nettapplikasjon. Den består av PHP-skript som kjører på PHP-motoren og statiske filer som behandles av webserveren.

Automatisering av WordPress-installasjon med NGINX Unit og Ubuntu

Generelle prinsipper

  • Mange konfigurasjonskommandoer i et skript er pakket inn i betingelser for idempotens: skriptet kan kjøres flere ganger uten risiko for å endre innstillinger som allerede er på plass.
  • Skriptet prøver å installere programvare fra depoter, slik at du kan bruke systemoppdateringer i én kommando (apt upgrade for Ubuntu).
  • Kommandoer prøver å oppdage at de kjører i en beholder, slik at de kan endre innstillingene tilsvarende.
  • For å angi antall trådprosesser som skal starte i innstillingene, prøver skriptet å gjette de automatiske innstillingene for arbeid i containere, virtuelle maskiner og maskinvareservere.
  • Når vi beskriver innstillinger, tenker vi alltid først og fremst på automatisering, som vi håper vil bli grunnlaget for å lage din egen infrastruktur som kode.
  • Alle kommandoer kjøres som bruker root, fordi de endrer de grunnleggende systeminnstillingene, men WordPress kjører direkte som en vanlig bruker.

Stille inn miljøvariabler

Angi følgende miljøvariabler før du kjører skriptet:

  • WORDPRESS_DB_PASSWORD - WordPress-databasepassord
  • WORDPRESS_ADMIN_USER - WordPress administratornavn
  • WORDPRESS_ADMIN_PASSWORD - WordPress admin passord
  • WORDPRESS_ADMIN_EMAIL - WordPress admin e-post
  • WORDPRESS_URL er den fullstendige URL-en til WordPress-nettstedet, fra kl https://.
  • LETS_ENCRYPT_STAGING - tom som standard, men ved å sette verdien til 1, vil du bruke Let's Encrypt staging-servere, som er nødvendige for ofte å be om sertifikater når du tester innstillingene dine, ellers kan Let's Encrypt midlertidig blokkere ip-adressen din på grunn av et stort antall forespørsler .

Skriptet sjekker at disse WordPress-relaterte variablene er satt og avsluttes hvis ikke.
Skriptlinje 572-576 kontrollerer verdien LETS_ENCRYPT_STAGING.

Sette avledede miljøvariabler

Skriptet på linjene 55-61 setter følgende miljøvariabler, enten til en hardkodet verdi eller ved å bruke en verdi hentet fra variablene satt i forrige seksjon:

  • DEBIAN_FRONTEND="noninteractive" - Forteller applikasjoner at de kjører i et skript og at det ikke er mulighet for brukerinteraksjon.
  • WORDPRESS_CLI_VERSION="2.4.0" er versjonen av WordPress CLI-applikasjonen.
  • WORDPRESS_CLI_MD5= "dedd5a662b80cda66e9e25d44c23b25c" — sjekksum for WordPress CLI 2.4.0 kjørbare fil (versjonen er spesifisert i variabelen WORDPRESS_CLI_VERSION). Skriptet på linje 162 bruker denne verdien for å sjekke at den riktige WordPress CLI-filen er lastet ned.
  • UPLOAD_MAX_FILESIZE="16M" - den maksimale filstørrelsen som kan lastes opp i WordPress. Denne innstillingen brukes flere steder, så det er lettere å sette den på ett sted.
  • TLS_HOSTNAME= "$(echo ${WORDPRESS_URL} | cut -d'/' -f3)" - vertsnavnet til systemet, hentet fra WORDPRESS_URL-variabelen. Brukes til å skaffe passende TLS/SSL-sertifikater fra Let's Encrypt samt intern WordPress-verifisering.
  • NGINX_CONF_DIR="/etc/nginx" - bane til katalogen med NGINX-innstillinger, inkludert hovedfilen nginx.conf.
  • CERT_DIR="/etc/letsencrypt/live/${TLS_HOSTNAME}" — banen til Let's Encrypt-sertifikatene for WordPress-nettstedet, hentet fra variabelen TLS_HOSTNAME.

Tilordne et vertsnavn til en WordPress-server

Skriptet setter serverens vertsnavn til å samsvare med nettstedets domenenavn. Dette er ikke nødvendig, men det er mer praktisk å sende utgående e-post via SMTP når du setter opp en enkelt server, som konfigurert av skriptet.

skriptkode

# 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

Legger til vertsnavn til /etc/hosts

Tillegg WP-Cron brukes til å kjøre periodiske oppgaver, krever at WordPress skal kunne få tilgang til seg selv via HTTP. For å sikre at WP-Cron fungerer riktig i alle miljøer, legger skriptet til en linje i filen / Etc / hostsslik at WordPress kan få tilgang til seg selv via loopback-grensesnittet:

skriptkode

# 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

Installere verktøyene som kreves for de neste trinnene

Resten av skriptet trenger noen programmer og forutsetter at depotene er oppdatert. Vi oppdaterer listen over depoter, hvoretter vi installerer de nødvendige verktøyene:

skriptkode

# 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

Legger til NGINX Unit og NGINX Repositories

Skriptet installerer NGINX Unit og åpen kildekode NGINX fra de offisielle NGINX-repositoriene for å sikre at versjonene med de nyeste sikkerhetsoppdateringene og feilrettingene brukes.

Skriptet legger til NGINX Unit-depotet og deretter NGINX-depotet, og legger til depotnøkkelen og konfigurasjonsfilene apt, definerer tilgang til depoter via Internett.

Selve installasjonen av NGINX Unit og NGINX skjer i neste avsnitt. Vi legger til depotene på forhånd slik at vi ikke trenger å oppdatere metadataene flere ganger, noe som gjør installasjonen raskere.

skriptkode

# 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

Installere NGINX, NGINX Unit, PHP MariaDB, Certbot (La oss kryptere) og deres avhengigheter

Når alle depotene er lagt til, oppdater metadataene og installer applikasjonene. Pakkene som er installert av skriptet inkluderer også PHP-utvidelsene som anbefales når du kjører WordPress.org

skriptkode

echo " Updating repository metadata"
apt-get -qq update

# Install PHP with dependencies and NGINX Unit
echo " Installing PHP, NGINX Unit, NGINX, Certbot, and 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

Sette opp PHP for bruk med NGINX Unit og WordPress

Skriptet oppretter en innstillingsfil i katalogen konf. d. Dette angir maksimal filstørrelse for PHP-opplastinger, slår på PHP-feilutgang til STDERR slik at de blir skrevet til NGINX-enhetsloggen, og starter NGINX-enheten på nytt.

skriptkode

# 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

Spesifisere MariaDB-databaseinnstillinger for WordPress

Vi har valgt MariaDB fremfor MySQL ettersom det har mer fellesskapsaktivitet og sannsynligvis også har det gir bedre ytelse som standard (sannsynligvis er alt enklere her: for å installere MySQL, må du legge til et annet depot, ca. oversetter).

Skriptet oppretter en ny database og oppretter legitimasjon for å få tilgang til WordPress via loopback-grensesnittet:

skriptkode

# 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;"

Installere WordPress CLI-programmet

På dette trinnet installerer skriptet programmet WP-CLI. Med den kan du installere og administrere WordPress-innstillinger uten å måtte redigere filer manuelt, oppdatere databasen eller gå inn i kontrollpanelet. Den kan også brukes til å installere temaer og tillegg og oppdatere WordPress.

skriptkode

if [ ! -f /usr/local/bin/wp ]; then
  # Install the WordPress CLI
  echo " Installing the WordPress CLI tool"
  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

Installere og konfigurere WordPress

Skriptet installerer den nyeste versjonen av WordPress i en katalog /var/www/wordpressog endrer også innstillingene:

  • Databasetilkoblingen fungerer over unix domene socket i stedet for TCP på loopback for å kutte ned på TCP trafikk.
  • WordPress legger til et prefiks https:// til URL-en hvis klienter kobler til NGINX over HTTPS, og sender også det eksterne vertsnavnet (som gitt av NGINX) til PHP. Vi bruker et stykke kode for å sette opp dette.
  • WordPress trenger HTTPS for pålogging
  • Standard URL-struktur er basert på ressurser
  • Angir de riktige tillatelsene på filsystemet for WordPress-katalogen.

skriptkode

if [ ! -d /var/www/wordpress ]; then
  # Create WordPress directories
  mkdir -p /var/www/wordpress
  chown -R www-data:www-data /var/www

  # Download WordPress using the WordPress CLI
  echo " Installing 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}""

  # This snippet is injected into the wp-config.php file when it is created;
  # it informs WordPress that we are behind a reverse proxy and as such
  # allows it to generate links using HTTPS
  cat > /tmp/wp_forwarded_for.php << 'EOM'
/* Turn HTTPS 'on' if HTTP_X_FORWARDED_PROTO matches '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

  # Create WordPress configuration
  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

  # Install 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

  # Set permalink structure to a sensible default that isn't in the UI
  su -s /bin/sh -p -c "wp --path=/var/www/wordpress option update permalink_structure '/%year%/%monthnum%/%postname%/'" www-data

  # Remove sample file because it is cruft and could be a security problem
  rm /var/www/wordpress/wp-config-sample.php

  # Ensure that WordPress permissions are correct
  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

Sette opp NGINX-enhet

Skriptet konfigurerer NGINX-enheten til å kjøre PHP og behandle WordPress-baner, isolere PHP-prosessens navneområde og optimalisere ytelsesinnstillingene. Det er tre funksjoner å se etter her:

  • Støtte for navneområder bestemmes av betingelse, basert på å sjekke at skriptet kjører i en beholder. Dette er nødvendig fordi de fleste containeroppsett ikke støtter nestet lansering av containere.
  • Hvis det er støtte for navneområder, deaktiver navneområdet nettverk. Dette er for å la WordPress koble til begge endepunktene og være tilgjengelig på nettet samtidig.
  • Maksimalt antall prosesser er definert som følger: (Tilgjengelig minne for å kjøre MariaDB og NGINX Uniy)/(RAM-grense i PHP + 5)
    Denne verdien angis i NGINX Unit-innstillingene.

Denne verdien innebærer også at det alltid er minst to PHP-prosesser som kjører, noe som er viktig fordi WordPress gjør mange asynkrone forespørsler til seg selv, og uten ytterligere prosesser vil kjøring av f.eks WP-Cron gå i stykker. Det kan være lurt å øke eller redusere disse grensene basert på dine lokale innstillinger, fordi innstillingene som er opprettet her er konservative. På de fleste produksjonssystemer er innstillingene mellom 10 og 100.

skriptkode

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 " Calculated the maximum number of PHP processes as ${MAX_PHP_PROCESSES}. You may want to tune this value due to variations in your configuration. It is not unusual to see values between 10-100 in production configurations."

echo " Configuring NGINX Unit to use PHP and 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

Sette opp NGINX

Konfigurere grunnleggende NGINX-innstillinger

Skriptet oppretter en katalog for NGINX-cachen og lager deretter hovedkonfigurasjonsfilen nginx.conf. Vær oppmerksom på antall behandlerprosesser og innstillingen av maksimal filstørrelse for opplasting. Det er også en linje som inkluderer komprimeringsinnstillingsfilen definert i neste seksjon, etterfulgt av caching-innstillingene.

skriptkode

# 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

Sette opp NGINX-komprimering

Å komprimere innhold på farten før du sender det til klienter er en fin måte å forbedre nettstedets ytelse på, men bare hvis komprimeringen er riktig konfigurert. Denne delen av skriptet er basert på innstillinger derav.

skriptkode

cat > ${NGINX_CONF_DIR}/gzip_compression.conf << 'EOM'
# Credit: https://github.com/h5bp/server-configs-nginx/
# ----------------------------------------------------------------------
# | Compression                                                        |
# ----------------------------------------------------------------------
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
# Enable gzip compression.
# Default: off
gzip on;
# Compression level (1-9).
# 5 is a perfect compromise between size and CPU usage, offering about 75%
# reduction for most ASCII files (almost identical to level 9).
# Default: 1
gzip_comp_level 6;
# Don't compress anything that's already small and unlikely to shrink much if at
# all (the default is 20 bytes, which is bad as that usually leads to larger
# files after gzipping).
# Default: 20
gzip_min_length 256;
# Compress data even for clients that are connecting to us via proxies,
# identified by the "Via" header (required for CloudFront).
# Default: off
gzip_proxied any;
# Tell proxies to cache both the gzipped and regular version of a resource
# whenever the client's Accept-Encoding capabilities header varies;
# Avoids the issue where a non-gzip capable client (which is extremely rare
# today) would display gibberish if their proxy gave them the gzipped version.
# Default: off
gzip_vary on;
# Compress all output labeled with one of the following MIME-types.
# `text/html` is always compressed by gzip module.
# Default: 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

Sette opp NGINX for WordPress

Deretter oppretter skriptet en konfigurasjonsfil for WordPress default.conf i katalogen konf. d. Den er konfigurert her:

  • Aktivering av TLS-sertifikater mottatt fra Let's Encrypt via Certbot (oppsett vil være i neste seksjon)
  • Konfigurere TLS-sikkerhetsinnstillinger basert på anbefalinger fra Let's Encrypt
  • Aktiver caching hoppe forespørsler i 1 time som standard
  • Deaktiver tilgangslogging, samt feillogging hvis filen ikke ble funnet, for to vanlige forespurte filer: favicon.ico og robots.txt
  • Hindre tilgang til skjulte filer og enkelte filer . Phpfor å forhindre ulovlig tilgang eller utilsiktet start
  • Deaktiver tilgangslogging for statiske filer og fontfiler
  • Header-innstilling Tilgangskontroll-Tillat-opprinnelse for fontfiler
  • Legger til ruting for index.php og annen statikk.

skriptkode

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 used by Certbot for 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/;
    # Let's Encrypt configuration
    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;
    # Proxy caching
    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;
    }

    # Deny all attempts to access hidden files such as .htaccess, .htpasswd,
    # .DS_Store (Mac)
    # Keep logging the requests to parse later (or to pass to firewall utilities
    # such as fail2ban)
    location ~ /. {
        deny all;
    }
    # Deny access to any files with a .php extension in the uploads directory;
    # works in subdirectory installs and also in multi-site network.
    # Keep logging the requests to parse later (or to pass to firewall utilities
    # such as fail2ban).
    location ~* /(?:uploads|files)/.*.php$ {
        deny all;
    }
    # WordPress: deny access to wp-content, wp-includes PHP files
    location ~* ^/(?:wp-content|wp-includes)/.*.php$ {
        deny all;
    }
    # Deny public access to wp-config.php
    location ~* wp-config.php {
        deny all;
    }
    # Do not log access for static assets, 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

Sette opp Certbot for sertifikater fra Let's Encrypt og automatisk fornye dem

certbot er et gratis verktøy fra Electronic Frontier Foundation (EFF) som lar deg få og automatisk fornye TLS-sertifikater fra Let's Encrypt. Skriptet gjør følgende for å konfigurere Certbot til å behandle sertifikater fra Let's Encrypt in NGINX:

  • Stopper NGINX
  • Laster ned anbefalte TLS-innstillinger
  • Kjører Certbot for å få sertifikater for nettstedet
  • Starter NGINX på nytt for å bruke sertifikater
  • Konfigurerer Certbot til å kjøre daglig klokken 3:24 for å sjekke om sertifikater må fornyes, og om nødvendig last ned nye sertifikater og start NGINX på nytt.

skriptkode

echo " Stopping NGINX in order to set up 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 " Downloading recommended TLS parameters"
  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 "Couldn't download latest options-ssl-nginx.conf"
fi

if [ ! -f ${NGINX_CONF_DIR}/ssl-dhparams.pem ]; then
  echo " Downloading recommended TLS DH parameters"
  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 "Couldn't download latest ssl-dhparams.pem"
fi

# If tls_certs_init.sh hasn't been run before, remove the self-signed certs
if [ ! -d "/etc/letsencrypt/accounts" ]; then
  echo " Removing self-signed certificates"
  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 " Generating certificates with Let's Encrypt"
  certbot certonly --standalone 
         -m "${WORDPRESS_ADMIN_EMAIL}" 
         ${CERTBOT_STAGING_FLAG} 
         --agree-tos --force-renewal --non-interactive 
         -d "${TLS_HOSTNAME}"
fi

echo " Starting NGINX in order to use new configuration"
service nginx start

# Write crontab for periodic Let's Encrypt cert renewal
if [ "$(crontab -l | grep -m1 'certbot renew')" == "" ]; then
  echo " Adding certbot to crontab for automatic Let's Encrypt renewal"
  (crontab -l 2>/dev/null; echo "24 3 * * * certbot renew --nginx --post-hook 'service nginx reload'") | crontab -
fi

Ytterligere tilpasning av nettstedet ditt

Vi snakket ovenfor om hvordan skriptet vårt konfigurerer NGINX og NGINX Unit for å betjene et produksjonsklart nettsted med TLSSSL aktivert. Du kan også, avhengig av dine behov, legge til i fremtiden:

  • Brukerstøtte Brotli, forbedret on-the-fly komprimering over HTTPS
  • ModSecurity с regler for wordpressfor å forhindre automatiserte angrep på nettstedet ditt
  • backup for WordPress som passer deg
  • Beskyttelse via AppArmor (på Ubuntu)
  • Postfix eller msmtp slik at WordPress kan sende e-post
  • Sjekker nettstedet ditt slik at du forstår hvor mye trafikk det kan håndtere

For enda bedre nettstedytelse anbefaler vi å oppgradere til NGINX Plus, vårt kommersielle, enterprise-grade produkt basert på åpen kildekode NGINX. Abonnentene vil motta en dynamisk lastet Brotli-modul, samt (mot en ekstra avgift) NGINX ModSecurity WAF. Vi tilbyr også NGINX App Protect, en WAF-modul for NGINX Plus basert på bransjeledende sikkerhetsteknologi fra F5.

NB For støtte til et høyt belastet nettsted, kan du kontakte ekspertene Southbridge. Vi vil sikre rask og pålitelig drift av nettstedet eller tjenesten din under enhver belastning.

Kilde: www.habr.com