使用 NGINX Unit 和 Ubuntu 自動安裝 WordPress

使用 NGINX Unit 和 Ubuntu 自動安裝 WordPress

有很多關於安裝 WordPress 的材料;Google 搜索“WordPress install”將返回大約 XNUMX 萬個結果。 然而,實際上很少有有用的指南可以幫助您安裝和配置 WordPress 以及底層操作系統,以便它們能夠得到長期支持。 也許正確的設置很大程度上取決於特定的需求,或者這是因為詳細的解釋使文章難以閱讀。

在本文中,我們將嘗試通過提供一個bash 腳本來在Ubuntu 上自動安裝WordPress,從而將兩個世界的優點結合在一起,並且我們將逐步介紹它,解釋每個部分的作用以及我們在設計時所做的權衡它。 如果您是高級用戶,可以跳過文章正文,直接閱讀 拿劇本 用於在您的環境中進行修改和使用。 該腳本的輸出是一個自定義 WordPress 安裝,支持 Lets Encrypt,在 NGINX Unit 上運行,適合生產使用。

使用 NGINX 單元部署 WordPress 的開發架構在 舊文章,我們現在還將進一步配置其中未涵蓋的內容(如許多其他教程中一樣):

  • WordPress命令行
  • 讓我們加密和 TLSSSL 證書
  • 自動更新證書
  • NGINX 緩存
  • NGINX 壓縮
  • HTTPS 和 HTTP/2 支持
  • 過程自動化

本文將描述在一台服務器上的安裝,該服務器將同時託管靜態處理服務器、PHP 處理服務器和數據庫。 支持多個虛擬主機和服務的安裝是未來的一個潛在主題。 如果您希望我們寫一些這些文章中沒有的內容,請在評論中寫下。

需求

  • 服務器容器(LXCLXD)、虛擬機或至少具有 512MB RAM 且安裝了 Ubuntu 18.04 或更高版本的常規 Iron 服務器。
  • 可訪問 Internet 的端口 80 和 443
  • 與該服務器的公共IP地址關聯的域名
  • 使用 root 權限 (sudo) 進行訪問。

架構概述

架構與描述的相同 ,一個三層 Web 應用程序。 它由在 PHP 引擎上執行的 PHP 腳本和由 Web 服務器處理的靜態文件組成。

使用 NGINX Unit 和 Ubuntu 自動安裝 WordPress

一般原則

  • 腳本中的許多配置命令都包含在冪等性的 if 條件中:腳本可以多次運行,而不會存在更改已準備就緒的設置的風險。
  • 該腳本嘗試從存儲庫安裝軟件,因此您可以通過一個命令應用系統更新(apt upgrade 對於 Ubuntu)。
  • 命令嘗試檢測它們是否在容器中運行,以便可以相應地更改其設置。
  • 為了在設置中設置要啟動的線程進程數,該腳本嘗試猜測在容器、虛擬機和硬件服務器中工作的自動設置。
  • 在描述設置時,我們總是首先考慮自動化,我們希望自動化將成為創建您自己的基礎設施即代碼的基礎。
  • 所有命令均以用戶身份運行 ,因為他們更改了基本系統設置,但直接以普通用戶身份運行 WordPress。

設置環境變量

運行腳本之前設置以下環境變量:

  • WORDPRESS_DB_PASSWORD - WordPress數據庫密碼
  • WORDPRESS_ADMIN_USER - WordPress 管理員名稱
  • WORDPRESS_ADMIN_PASSWORD - WordPress 管理員密碼
  • WORDPRESS_ADMIN_EMAIL - WordPress 管理員電子郵件
  • WORDPRESS_URL 是 WordPress 網站的完整 URL,從 https://.
  • LETS_ENCRYPT_STAGING — 默認為空,但通過將該值設置為1,您將使用Let's Encrypt 的臨時服務器,這對於測試您的設置時頻繁請求證書是必要的,否則Let's Encrypt 可能會因大量請求而暫時阻止您的IP 地址。

該腳本會檢查這些與 WordPress 相關的變量是否已設置,如果沒有則退出。
腳本第 572-576 行檢查值 LETS_ENCRYPT_STAGING.

設置派生環境變量

第 55-61 行的腳本將以下環境變量設置為某個硬編碼值或使用從上一節中設置的變量派生的值:

  • DEBIAN_FRONTEND="noninteractive" — 告訴應用程序它們正在腳本中運行,並且不可能進行用戶交互。
  • WORDPRESS_CLI_VERSION="2.4.0" — 應用程序的 WordPress CLI 版本。
  • WORDPRESS_CLI_MD5= "dedd5a662b80cda66e9e25d44c23b25c" — WordPress CLI 2.4.0 可執行文件的校驗和(版本在變量中指定) WORDPRESS_CLI_VERSION)。 第 162 行的腳本使用此值來檢查是否已下載正確的 WordPress CLI 文件。
  • UPLOAD_MAX_FILESIZE="16M" - WordPress 中可以上傳的最大文件大小。 此設置會在多個地方使用,因此在一個地方設置它會更容易。
  • TLS_HOSTNAME= "$(echo ${WORDPRESS_URL} | cut -d'/' -f3)" - 系統的主機名,從 WORDPRESS_URL 變量檢索。 用於從 Let's Encrypt 獲取適當的 TLS/SSL 證書以及內部 WordPress 驗證。
  • NGINX_CONF_DIR="/etc/nginx" - NGINX 設置的目錄路徑,包括主文件 nginx.conf.
  • CERT_DIR="/etc/letsencrypt/live/${TLS_HOSTNAME}" — WordPress 站點的 Let's Encrypt 證書的路徑,從變量獲取 TLS_HOSTNAME.

為 WordPress 服務器分配主機名

該腳本設置服務器的主機名以匹配站點的域名。 這不是必需的,但在設置單個服務器時,根據腳本的配置,通過 SMTP 發送外發郵件會更方便。

腳本代碼

# 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

將主機名添加到 /etc/hosts

增加 WP-Cron 用於運行定期任務,要求 WordPress 能夠通過 HTTP 訪問自身。 為了確保 WP-Cron 在所有環境下都能正常工作,腳本在文件中添加了一行 / etc / hosts文件這樣WordPress就可以通過loopback接口訪問自身:

腳本代碼

# 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

安裝後續步驟所需的工具

腳本的其餘部分需要一些程序並假設存儲庫是最新的。 我們更新存儲庫列表,然後安裝必要的工具:

腳本代碼

# 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

添加 NGINX 單元和 NGINX 存儲庫

該腳本從官方 NGINX 存儲庫安裝 NGINX Unit 和開源 NGINX,以確保使用帶有最新安全補丁和錯誤修復的版本。

該腳本添加 NGINX Unit 存儲庫,然後添加 NGINX 存儲庫,添加存儲庫密鑰和設置文件 apt,定義通過 Internet 對存儲庫的訪問。

NGINX Unit 和 NGINX 的實際安裝將在下一節中進行。 我們預先添加存儲庫,因此不必多次更新元數據,這使得安裝速度更快。

腳本代碼

# 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

安裝 NGINX、NGINX Unit、PHP MariaDB、Certbot (Let's Encrypt) 及其依賴項

添加所有存儲庫後,我們將更新元數據並安裝應用程序。 該腳本安裝的軟件包還包括運行 WordPress.org 時推薦的 PHP 擴展

腳本代碼

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

設置 PHP 以與 NGINX Unit 和 WordPress 一起使用

該腳本在目錄中創建一個設置文件 conf.d。 這設置了 PHP 上傳的最大文件大小,打開 PHP 錯誤輸出到 STDERR,以便將它們寫入 NGINX 單元日誌,並重新啟動 NGINX 單元。

腳本代碼

# 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

指定 WordPress 的 MariaDB 數據庫設置

我們選擇 MariaDB 而不是 MySQL,因為它有更多的社區活動,並且也可能 默認情況下提供更好的性能 (也許,這裡一切都更簡單:要安裝 MySQL,您需要添加另一個存儲庫,大約。 譯者)。

該腳本創建一個新的數據庫並創建通過環回接口訪問 WordPress 的憑據:

腳本代碼

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

安裝 WordPress CLI 程序

這一步,腳本安裝程序 WP-CLI。 有了它,您可以安裝和管理 WordPress 設置,而無需手動編輯文件、更新數據庫或進入控制面板。 它還可用於安裝主題和附加組件以及更新 WordPress。

腳本代碼

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

安裝和配置 WordPress

該腳本在目錄中安裝最新版本的 WordPress /var/www/wordpress並且還更改設置:

  • 數據庫連接通過 unix 域套接字而不是環回 TCP 進行工作,以減少 TCP 流量。
  • WordPress 添加前綴 https:// 如果客戶端通過 HTTPS 連接到 NGINX,則發送到 URL,並將遠程主機名(由 NGINX 提供)發送到 PHP。 我們使用一段代碼來設置它。
  • WordPress 需要 HTTPS 才能登錄
  • 默認 URL 結構基於資源
  • 為 WordPress 目錄設置了正確的文件系統權限。

腳本代碼

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

設置 NGINX 單元

該腳本配置 NGINX 單元來運行 PHP 並處理 WordPress 路徑,隔離 PHP 進程命名空間並優化性能設置。 這裡需要注意三個功能:

  • 命名空間支持由條件確定,基於檢查腳本是否在容器中運行。 這是必要的,因為大多數容器設置不支持容器的嵌套運行。
  • 如果支持命名空間,則禁用命名空間 網絡。 這是為了允許 WordPress 連接到兩個端點並同時在網絡上可用。
  • 最大進程數定義如下: (運行 MariaDB 和 NGINX Uniy 的可用內存)/(PHP 中的 RAM 限制 + 5)
    該值在 NGINX 單元設置中設置。

該值還意味著始終至少有兩個 PHP 進程在運行,這很重要,因為 WordPress 會向自身發出大量異步請求,並且如果沒有其他進程運行,例如 WP-Cron 將崩潰。 您可能需要根據本地設置增加或減少這些限制,因為此處創建的設置是保守的。 在大多數生產系統上,設置在 10 到 100 之間。

腳本代碼

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

設置 NGINX

配置基本 NGINX 設置

該腳本為 NGINX 緩存創建一個目錄,然後創建主配置文件 nginx.conf。 注意handler進程的數量以及上傳最大文件大小的設置。 還有一行包含下一節中定義的壓縮設置文件,後面是緩存設置。

腳本代碼

# 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

設置 NGINX 壓縮

在將內容髮送到客戶端之前對其進行動態壓縮是提高站點性能的好方法,但前提是壓縮配置正確。 這部分腳本基於設置 .

腳本代碼

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

為 WordPress 設置 NGINX

接下來,該腳本為 WordPress 創建一個配置文件 默認配置文件 在目錄中 conf.d。 它在這裡配置:

  • 激活通過 Certbot 從 Let's Encrypt 收到的 TLS 證書(設置將在下一節中進行)
  • 根據 Let's Encrypt 的建議配置 TLS 安全設置
  • 默認啟用緩存跳過請求 1 小時
  • 對於兩個常見請求的文件:favicon.ico 和 robots.txt,禁用訪問日誌記錄以及未找到文件時的錯誤日誌記錄
  • 防止訪問隱藏文件和某些文件 。PHP防止非法訪問或無意啟動
  • 禁用靜態文件和字體文件的訪問日誌記錄
  • 設置標題 訪問控制允許來源 對於字體文件
  • 添加index.php 和其他靜態信息的路由。

腳本代碼

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

為 Let's Encrypt 的證書設置 Certbot 並自動更新它們

Certbot 是來自電子前沿基金會 (EFF) 的免費工具,可讓您從 Let's Encrypt 獲取並自動續訂 TLS 證書。 該腳本執行以下步驟來配置 Certbot 以在 NGINX 中處理來自 Let's Encrypt 的證書:

  • 停止 NGINX
  • 下載推薦的 TLS 設置
  • 運行 Certbot 以獲取站點的證書
  • 重新啟動 NGINX 以使用證書
  • 將 Certbot 配置為每天凌晨 3:24 運行以檢查證書續訂,並在必要時下載新證書並重新啟動 NGINX。

腳本代碼

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

對您的網站進行額外的定制

我們上面討論了我們的腳本如何配置 NGINX 和 NGINX Unit 來為啟用了 TLSSSL 的生產就緒網站提供服務。 您還可以根據您的需要,在將來添加:

  • 支持 Brotli,改進了 HTTPS 上的即時壓縮
  • ModSecurity的 с WordPress 規則防止對您網站的自動攻擊
  • 備用 適用於 WordPress,適合您
  • 保護 在...的幫助下 AppArmor的 (在Ubuntu上)
  • Postfix 或 msmtp 以便 WordPress 可以發送郵件
  • 檢查您的網站,了解它可以處理多少流量

為了獲得更好的網站性能,我們建議升級到 NGINX Plus,我們基於開源NGINX的企業級商業產品。 其訂閱者將收到動態加載的 Brotli 模塊,以及(需額外付費) NGINX ModSecurity WAF。 我們還提供 NGINX 應用程序保護,基於 F5 業界領先的安全技術的 NGINX Plus 的 WAF 模塊。

注: 如需支持高負載站點,您可以聯繫專家 南橋。 我們將確保您的網站或服務在任何負載下快速可靠地運行。

來源: www.habr.com