Automatyzacja instalacji WordPress z NGINX Unit i Ubuntu

Automatyzacja instalacji WordPress z NGINX Unit i Ubuntu

Istnieje wiele materiałów dotyczących instalacji WordPressa, wyszukiwanie w Google pod hasłem „instalacja WordPressa” zwraca około pół miliona wyników. Niemniej jednak, w rzeczywistości jest bardzo mało przydatnych przewodników, które pozwalają na zainstalowanie i skonfigurowanie WordPressa oraz jego podstawowego systemu operacyjnego w sposób zapewniający długoterminowe wsparcie. Być może odpowiednie ustawienia mocno zależą od konkretnych potrzeb lub też zbyt szczegółowy opis sprawia, że artykuł staje się trudny do przeczytania.

W tym artykule postaramy się zebrać najlepsze z dwóch podejść, dostarczając skrypt bash do automatycznej instalacji WordPressa na Ubuntu, a także przejdziemy przez nie, wyjaśniając, co robi każdy jego kawałek oraz na jakie kompromisy poszliśmy przy jego tworzeniu. Jeśli jesteś doświadczonym użytkownikiem — możesz pominąć tekst artykułu i po prostu zabrać skrypt do modyfikacji i wykorzystania w twoich środowiskach. Na wynik skryptu otrzymujemy dostosowaną instalację WordPressa z wsparciem dla Lets Encrypt, działającą na NGINX Unit i nadającą się do komercyjnego zastosowania.

Opracowana architektura dla wdrożenia WordPressa z użyciem NGINX Unit jest opisana w starszym artykule, teraz dodatkowo skonfigurujemy rzeczy, które nie były tam omówione (jak i w wielu innych przewodnikach):

  • WordPress CLI
  • Let’s Encrypt i certyfikaty TLS/SSL
  • Automatyczne aktualizacje certyfikatów
  • Caching NGINX
  • Kompresja NGINX
  • Wsparcie dla HTTPS i HTTP/2
  • Automatyzacja procesu

W artykule opisano instalację na jednym serwerze, na którym będą jednocześnie umieszczone serwer statyczny, serwer PHP i baza danych. Instalacja z wsparciem dla wielu wirtualnych hostów i usług — to potencjalny temat na przyszłość. Chcesz, abyśmy napisali o czymś, czego nie ma w tych artykułach — pisz w komentarzach.

Wymagania

  • Serwer-kontener (LXC lub LXD), maszyna wirtualna lub zwykły serwer fizyczny, z co najmniej 512 MB pamięci RAM i zainstalowanym Ubuntu 18.04 lub nowszym.
  • Dostępne z internetu porty 80 i 443
  • Nazwa domeny powiązana z publicznym adresem IP tego serwera
  • Dostęp z uprawnieniami root (sudo).

Przegląd architektury

Architektura jest taka sama, jak opisana wcześniej, trzywarstwowa aplikacja webowa. Składa się z skryptów PHP, wykonywanych na interpreterze PHP, oraz statycznych plików, przetwarzanych przez serwer WWW.

Automatyzacja instalacji WordPress z NGINX Unit i Ubuntu

Ogólne zasady

  • Wiele poleceń konfiguracyjnych w skrypcie jest owiniętych w warunki (if) dla idempotencji: skrypt można uruchamiać wielokrotnie bez ryzyka zmiany ustawień, które są już skonfigurowane.
  • Skrypt stara się instalować oprogramowanie z repozytoriów, aby można było stosować aktualizacje systemu poleceniem (apt upgrade dla Ubuntu).
  • Polecenia starają się określić, że są uruchamiane w kontenerze, aby odpowiednio dostosować swoje ustawienia.
  • Aby ustawić liczbę uruchamianych procesów/wątków w konfiguracji, skrypt próbuje zgadnąć automatyczne parametry konfiguracji do pracy w kontenerach, maszynach wirtualnych oraz na "stalowych" serwerach.
  • Przy opisywaniu ustawień zawsze myślimy przede wszystkim o automatyzacji, która, mamy nadzieję, stanie się podstawą do budowy własnej infrastruktury jako kodu.
  • Wszystkie polecenia są uruchamiane jako użytkownik root, ponieważ zmieniają podstawowe ustawienia systemu, ale sam WordPress działa jako zwykły użytkownik.

Ustawianie zmiennych środowiskowych

Ustaw następujące zmienne środowiskowe przed uruchomieniem skryptu:

  • WORDPRESS_DB_PASSWORD — hasło do bazy danych WordPress
  • WORDPRESS_ADMIN_USER — nazwa administratora WordPress
  • WORDPRESS_ADMIN_PASSWORD — hasło administratora WordPress
  • WORDPRESS_ADMIN_EMAIL — email administratora WordPress
  • WORDPRESS_URL — pełny adres URL strony WordPress, zaczynając od https://.
  • LETS_ENCRYPT_STAGING — domyślnie pusty, ale ustawiając wartość na 1, użyjesz staging serwerów Let’s Encrypt, które są potrzebne do częstego żądania certyfikatów podczas testowania konfiguracji, w przeciwnym razie Let’s Encrypt może tymczasowo zablokować Twój adres IP z powodu dużej liczby żądań.

Skrypt sprawdza, że te związane z WordPress zmienne są ustawione, i kończy działanie, jeśli tak nie jest.
Linie skryptu 572-576 sprawdzają wartość LETS_ENCRYPT_STAGING.

Ustawianie pochodnych zmiennych środowiskowych

Skrypt w liniach 55-61 ustawia następujące zmienne środowiskowe, albo na pewną wartość stałą, albo z użyciem wartości uzyskanej z zmiennych ustawionych w poprzedniej sekcji:

  • DEBIAN_FRONTEND="noninteractive" — informuje aplikacje, że są uruchamiane w skrypcie i nie ma możliwości interakcji z użytkownikiem.
  • WORDPRESS_CLI_VERSION="2.4.0" — wersja aplikacji WordPress CLI.
  • WORDPRESS_CLI_MD5= "dedd5a662b80cda66e9e25d44c23b25c" — suma kontrolna pliku wykonywalnego WordPress CLI 2.4.0 (wersja jest określona w zmiennej WORDPRESS_CLI_VERSION). Skrypt na 162. linii wykorzystuje tę wartość do sprawdzenia, czy pobrany został poprawny plik WordPress CLI.
  • UPLOAD_MAX_FILESIZE="16M" — maksymalny rozmiar pliku, który można przesłać do WordPressa. Ustawienie to jest używane w kilku miejscach, więc łatwiej jest ustawić je w jednym miejscu.
  • TLS_HOSTNAME= "$(echo ${WORDPRESS_URL} | cut -d'\/' -f3)" — nazwa hosta systemu, wydobywana z zmiennej WORDPRESS_URL. Jest używana do uzyskania odpowiednich certyfikatów TLS/SSL od Let’s Encrypt, a także do wewnętrznej weryfikacji WordPressa.
  • NGINX_CONF_DIR="\/etc\/nginx" — ścieżka do katalogu z ustawieniami NGINX, w tym do głównego pliku nginx.conf.
  • CERT_DIR="\/etc\/letsencrypt\/live\/${TLS_HOSTNAME}" — ścieżka do certyfikatów Let’s Encrypt dla witryny WordPress, uzyskiwana z zmiennej TLS_HOSTNAME.

Przypisanie nazwy hosta do serwera WordPress

Skrypt ustawia nazwę hosta serwera, aby wartość odpowiadała nazwie domeny witryny. Nie jest to konieczne, ale ułatwia wysyłanie wiadomości e-mail przez SMTP podczas konfiguracji jednego serwera, co jest ustawiane przez skrypt.

kod skryptu

# 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

Dodanie nazwy hosta do \/etc\/.hosts

Uzupełnienie WP‑Cron jest używane do uruchamiania zadań cyklicznych, wymaga, aby WordPress mógł uzyskać dostęp do samego siebie przez HTTP. Aby upewnić się, że WP-Cron działa poprawnie we wszystkich środowiskach, skrypt dodaje linię do pliku /etc/hosts, dzięki czemu WordPress może uzyskać dostęp do samego siebie przez interfejs loopback:

kod skryptu

# 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

Instalacja niezbędnych narzędzi do kolejnych kroków

Reszta skryptu wymaga kilku programów i zakłada, że repozytoria są aktualne. Aktualizujemy listę repozytoriów, po czym instalujemy potrzebne narzędzia:

kod skryptu

# 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

Dodanie repozytoriów NGINX Unit i NGINX

Skrypt instaluje NGINX Unit i NGINX z otwartym kodem źródłowym z oficjalnych repozytoriów NGINX, aby upewnić się, że używane są wersje z najnowszymi aktualizacjami zabezpieczeń i poprawkami błędów.

Skrypt dodaje repozytorium NGINX Unit, a następnie repozytorium NGINX, dodając klucz repozytoriów i pliki konfiguracyjne apt, określające dostęp do repozytoriów przez internet.

Rzeczywista instalacja NGINX Unit i NGINX odbywa się w następnym rozdziale. Najpierw dodajemy repozytoria, aby uniknąć wielokrotnego aktualizowania metadanych, co przyspiesza instalację.

kod skryptu

# 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

Instalacja NGINX, NGINX Unit, PHP MariaDB, Certbot (Let’s Encrypt) oraz ich zależności

Gdy wszystkie repozytoria zostaną dodane, aktualizujemy metadane i instalujemy aplikacje. Pakiety instalowane przez skrypt zawierają również zalecane rozszerzenia PHP przy uruchamianiu WordPress.org.

kod skryptu

echo " Aktualizacja metadanych repozytoriów"
apt-get -qq update

# Instalacja PHP z zależnościami i NGINX Unit
echo " Instalacja PHP, NGINX Unit, NGINX, Certbot i 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

Konfiguracja PHP do użycia z NGINX Unit i WordPress

Skrypt tworzy plik konfiguracyjny w katalogu conf.d. Tutaj ustawia się maksymalny rozmiar przesyłanych plików dla PHP, włącza wyjście błędów PHP do STDERR, aby były rejestrowane w dzienniku NGINX Unit, a także restartuje NGINX Unit.

kod skryptu

# 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

Ustawienia bazy danych MariaDB dla WordPress

Wybraliśmy MariaDB zamiast MySQL, ponieważ ma większą aktywność w społeczności, a także może, na domyślnej konfiguracji, (być prostsza: aby zainstalować MySQL, trzeba dodać kolejne repozytorium, przyp. tłumacza).

Skrypt tworzy nową bazę danych oraz generuje dane umożliwiające dostęp do WordPress przez interfejs loopback:

kod skryptu

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

Instalacja narzędzia WordPress CLI

Na tym etapie skrypt instaluje program WP-CLI. Dzięki niemu można instalować i zarządzać ustawieniami WordPress bez ręcznej edycji plików, aktualizacji bazy danych lub logowania się do panelu administracyjnego. Umożliwia także instalację motywów i wtyczek oraz aktualizację WordPress.

kod skryptu

if [ ! -f /usr/local/bin/wp ]; then
  # Instalacja narzędzia WordPress CLI
  echo " Instalacja narzędzia 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

Instalacja i konfiguracja WordPress

Skrypt instaluje najnowszą wersję WordPress w katalogu /var/www/wordpress, oraz zmienia ustawienia:

  • Połączenie z bazą danych działa przez unix domain socket zamiast TCP na loopback, aby zmniejszyć ruch TCP.
  • WordPress dodaje prefiks https:// do URL, jeśli klienci łączą się z NGINX przez protokół HTTPS, a także przekazuje zdalną nazwę hosta (jak udostępnia to NGINX) do PHP. Używamy kawałka kodu, aby to skonfigurować.
  • WordPress potrzebuje HTTPS do logowania.
  • Struktura URL domyślnie opiera się na zasobach.
  • Ustawiane są prawidłowe uprawnienia w systemie plików dla katalogu WordPress.

kod skryptu

if [ ! -d /var/www/wordpress ]; then
  # Utwórz katalogi WordPress
  mkdir -p /var/www/wordpress
  chown -R www-data:www-data /var/www

  # Pobierz WordPress za pomocą WordPress CLI
  echo " Instalowanie 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}""

  # Ten fragment jest wstrzykiwany do pliku wp-config.php, gdy jest tworzony;
  # informuje WordPressa, że jesteśmy za odwrotnym proxy, a tym samym
  # pozwala mu generować linki używając HTTPS
  cat > /tmp/wp_forwarded_for.php << 'EOM'
/* Włącz HTTPS 'on', jeśli HTTP_X_FORWARDED_PROTO odpowiada '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

  # Utwórz konfigurację 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

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

  # Ustaw strukturę permalinków na sensowny domyślny, która nie jest w interfejsie użytkownika
  su -s /bin/sh -p -c "wp --path=/var/www/wordpress option update permalink_structure '/%year%/%monthnum%/%postname%/'" www-data

  # Usuń plik próbny, ponieważ jest zbędny i może stanowić problem z bezpieczeństwem
  rm /var/www/wordpress/wp-config-sample.php

  # Upewnij się, że uprawnienia WordPress są poprawne
  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

Konfiguracja NGINX Unit

Skrypt konfiguruje NGINX Unit do uruchamiania PHP i obsługi ścieżek WordPress, izolując przestrzeń nazw procesów PHP i optymalizując ustawienia wydajności. Oto trzy funkcje, na które warto zwrócić uwagę:

  • Wsparcie dla przestrzeni nazw określane jest na podstawie warunku, który opiera się na sprawdzaniu uruchomienia skryptu w kontenerze. Jest to konieczne, ponieważ większość ustawień kontenerów nie wspiera zagnieżdżonego uruchamiania kontenerów.
  • Jeśli jest wsparcie dla przestrzeni nazw, przestrzeń nazw jest dezaktywowana. network. Jest to konieczne, aby umożliwić WordPressowi jednoczesne połączenie się z punktami końcowymi i być dostępnym w Internecie.
  • Maksymalna liczba procesów jest określona w następujący sposób: (Dostępna pamięć dla uruchomionych MariaDB i NGINX Uniy)/(limit pamięci operacyjnej w PHP + 5)
    Ta wartość jest ustawiana w ustawieniach NGINX Unit.

Ta wartość oznacza również, że zawsze musi być co najmniej dwa uruchomione procesy PHP, co jest istotne, ponieważ WordPress wykonuje wiele asynchronicznych zapytań do samego siebie, a bez dodatkowych procesów uruchomienie, na przykład, WP-Cron, się nie powiedzie. Możesz chcieć zwiększyć lub zmniejszyć te ograniczenia w oparciu o swoje lokalne ustawienia, ponieważ ustawienia stworzone tutaj są konserwatywne. Na większości systemów produkcyjnych ustawienia mieszczą się między 10 a 100.

kod skryptu

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 " Obliczono maksymalną liczbę procesów PHP jako ${MAX_PHP_PROCESSES}. Może być konieczne dostosowanie tej wartości z powodu wariacji w Twojej konfiguracji. Nie jest niczym niezwykłym widzieć wartości między 10-100 w konfiguracjach produkcyjnych."

echo " Konfiguracja NGINX Unit do użycia z PHP i 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

Konfiguracja NGINX

Konfiguracja podstawowych parametrów NGINX

Skrypt tworzy katalog dla pamięci podręcznej NGINX, a następnie tworzy główny plik konfiguracyjny nginx.conf. Zwróć uwagę na liczbę procesów przetwarzających oraz ustawienie maksymalnego rozmiaru pliku do załadowania. Istnieje również wiersz, w którym podłączany jest plik konfiguracyjny kompresji, określony w następnym rozdziale, a następnie następują ustawienia buforowania.

kod skryptu

# 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

Konfiguracja kompresji NGINX

Kompresja treści w locie przed wysłaniem jej do klientów to doskonały sposób na poprawę wydajności strony, ale tylko jeśli kompresja jest prawidłowo skonfigurowana. Ta sekcja skryptu opiera się na ustawieniach. stąd.

kod skryptu

cat > ${NGINX_CONF_DIR}/gzip_compression.conf << 'EOM'
# Kredyt: https://github.com/h5bp/server-configs-nginx/
# ----------------------------------------------------------------------
# | Kompresja                                                        |
# ----------------------------------------------------------------------
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
# Włącz kompresję gzip.
# Domyślnie: wyłączona
gzip on;
# Poziom kompresji (1-9).
# 5 to idealny kompromis między rozmiarem a użyciem CPU, oferując około 75%
# redukcji dla większości plików ASCII (niemal identyczny do poziomu 9).
# Domyślnie: 1
gzip_comp_level 6;
# Nie kompresuj niczego, co już jest małe i mało prawdopodobne, aby się jeszcze skurczyło
# (domyślnie to 20 bajtów, co jest złe, ponieważ zazwyczaj prowadzi do większych
# plików po kompresji gzip).
# Domyślnie: 20
gzip_min_length 256;
# Kompresuj dane nawet dla klientów, którzy łączą się z nami przez proxy,
# zidentyfikowanych przez nagłówek "Via" (wymagane dla CloudFront).
# Domyślnie: wyłączona
gzip_proxied any;
# Powiedz proxy, aby pamiętało zarówno wersję skompresowaną, jak i zwykłą zasobu
# za każdym razem, gdy nagłówek możliwości Accept-Encoding klienta się zmienia;
# Zapobiega to problemowi, w którym klient, który nie obsługuje gzip (co jest niezwykle rzadkie
# dzisiaj), wyświetli niezrozumiały tekst, jeśli jego proxy przekaże mu wersję skompresowaną.
# Domyślnie: wyłączona
gzip_vary on;
# Kompresuj wszystkie wyjścia oznaczone jednym z poniższych typów MIME.
# `text/html` jest zawsze kompresowane przez moduł gzip.
# Domyślnie: 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

Konfiguracja NGINX dla WordPress

Następnie skrypt tworzy plik konfiguracyjny dla WordPressa. default.conf w katalogu conf.d. Tutaj są ustawienia:

  • Aktywacja certyfikatów TLS otrzymanych od Let’s Encrypt za pośrednictwem Certbota (jego konfiguracja będzie w następnym rozdziale).
  • Konfiguracja parametrów bezpieczeństwa TLS, oparta na zaleceniach od Let’s Encrypt.
  • Włączenie buforowania pomijanych żądań na 1 godzinę domyślnie.
  • Wyłączenie rejestrowania dostępu oraz rejestrowania błędów, jeśli plik nie został znaleziony, dla dwóch ogólnych plików: favicon.ico i robots.txt.
  • Zabronienie dostępu do ukrytych plików i niektórych plików. .php, aby zapobiec nielegalnemu dostępowi lub niezamierzonemu uruchomieniu
  • Wyłączenie logowania dostępu dla statycznych plików i czcionek
  • Ustawienie nagłówka Access-Control-Allow-Origin dla plików czcionek
  • Dodanie routingu dla index.php i innych statycznych plików.

kod skryptu

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 używane przez Certbota dla 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/;
    # Konfiguracja 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;
    # Aktywność proxy cache
    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;
    }
    
    # Zabroń wszystkie próby uzyskania dostępu do ukrytych plików, takich jak .htaccess, .htpasswd,
    # .DS_Store (Mac)
    # Zachowaj logowanie żądań do przetworzenia później (lub do przesłania do narzędzi zapory,
    # takich jak fail2ban)
    location ~ /\. {
        deny all;
    }
    # Zabroń dostępu do jakichkolwiek plików z rozszerzeniem .php w katalogu uploads;
    # działa w instalacjach w podkatalogu i również w sieci multi-site.
    # Zachowaj logowanie żądań do przetworzenia później (lub do przesłania do narzędzi zapory,
    # takich jak fail2ban).
    location ~* /(?:uploads|files)/.*.php$ {
        deny all;
    }
    # WordPress: zabroń dostępu do plików PHP w wp-content i wp-includes
    location ~* ^/(?:wp-content|wp-includes)/.*.php$ {
        deny all;
    }
    # Zabroń publicznego dostępu do wp-config.php
    location ~* wp-config.php {
        deny all;
    }
    # Nie loguj dostępu do statycznych zasobów, mediów
    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

Konfiguracja Certbota dla certyfikatów od Let’s Encrypt i automatyczne odnawianie

Certbot to darmowe narzędzie od Electronic Frontier Foundation (EFF), które pozwala uzyskiwać i automatycznie odnawiać certyfikaty TLS od Let’s Encrypt. Skrypt wykonuje następujące czynności, które prowadzą do konfiguracji Certbota do obsługi certyfikatów od Let’s Encrypt w NGINX:

  • Zatrzymuje NGINX
  • Pobiera zalecane parametry TLS
  • Uruchamia Certbota, aby uzyskać certyfikaty dla witryny
  • Ponownie uruchamia NGINX, aby używać certyfikatów
  • Konfiguruje codzienne uruchamianie Certbota o 3:24 w nocy, aby sprawdzić potrzebę odnowienia certyfikatów, a także, w razie potrzeby, pobranie nowych certyfikatów i ponowne uruchomienie NGINX.

kod skryptu

echo " Zatrzymywanie NGINX w celu skonfigurowania 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 " Pobieranie zalecanych parametrów TLS"
  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 "Nie można pobrać najnowszego options-ssl-nginx.conf"
fi

if [ ! -f ${NGINX_CONF_DIR}/ssl-dhparams.pem ]; then
  echo " Pobieranie zalecanych parametrów DH TLS"
  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 "Nie można pobrać najnowszego ssl-dhparams.pem"
fi

# Jeśli tls_certs_init.sh nie zostało wcześniej uruchomione, usuń samopodpisane certyfikaty
if [ ! -d "/etc/letsencrypt/accounts" ]; then
  echo " Usuwanie samopodpisanych certyfikatów"
  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 " Generowanie certyfikatów z Let's Encrypt"
  certbot certonly --standalone 
         -m "${WORDPRESS_ADMIN_EMAIL}" 
         ${CERTBOT_STAGING_FLAG} 
         --agree-tos --force-renewal --non-interactive 
         -d "${TLS_HOSTNAME}"
fi

echo " Uruchamianie NGINX w celu użycia nowej konfiguracji"
service nginx start

# Zapisz crontab dla okresowego odnawiania certyfikatów Let's Encrypt
if [ "$(crontab -l | grep -m1 'certbot renew')" == "" ]; then
  echo " Dodawanie certbota do crontab w celu automatycznego odnawiania Let's Encrypt"
  (crontab -l 2>/dev/null; echo "24 3 * * * certbot renew --nginx --post-hook 'service nginx reload'") | crontab -
fi

Dodatkowa konfiguracja Twojej strony

Powyżej opisaliśmy, jak nasz skrypt konfiguruje NGINX i NGINX Unit do obsługi gotowej do produkcji strony z włączonym TLS/SSL. Możesz także, w zależności od swoich potrzeb, dodać w przyszłości:

  • Wsparcie Brotli, poprawione kompresowanie w locie przez HTTPS
  • ModSecurity z regułami dla WordPressa, aby zapobiec automatycznym atakom na Twoją stronę
  • Kopie zapasowe dla WordPressa, które Ci odpowiada
  • Ochrona z pomocą AppArmor (na Ubuntu)
  • Postfix lub msmtp, aby WordPress mógł wysyłać e-maile
  • Testy twojej strony, abyś wiedział, ile ruchu może ona wytrzymać

Aby uzyskać jeszcze lepszą wydajność strony, zalecamy aktualizację do NGINX Plus, naszego komercyjnego produktu klasy korporacyjnej opartego na NGINX z otwartym kodem źródłowym. Jego subskrybenci otrzymają dynamicznie ładowany moduł Brotli oraz (za dodatkową opłatą) NGINX ModSecurity WAF. Oferujemy również NGINX App Protect, moduł WAF dla NGINX Plus oparty na technologii wiodącej w branży bezpieczeństwa od F5.

N.B. W sprawie wsparcia wysokonakładowej strony możesz skontaktować się z ekspertami Southbridge. Zapewnimy szybką i niezawodną pracę twojej strony lub usługi pod dowolnym obciążeniem.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster