نصب خودکار وردپرس با واحد NGINX و Ubuntu

نصب خودکار وردپرس با واحد NGINX و Ubuntu

مطالب زیادی در مورد نصب وردپرس وجود دارد؛ جستجوی Google برای "WordPress install" حدود نیم میلیون نتیجه را به دست خواهد آورد. با این حال، در واقع راهنماهای مفید بسیار کمی وجود دارد که می تواند به شما در نصب و پیکربندی وردپرس و سیستم عامل زیرین کمک کند تا بتوانند در مدت زمان طولانی پشتیبانی شوند. شاید تنظیمات صحیح به شدت به نیازهای خاص شما بستگی داشته باشد، یا ممکن است به این دلیل باشد که توضیحات مفصل خواندن مقاله را دشوار می کند.

در این مقاله، سعی می کنیم با ارائه یک اسکریپت bash برای نصب خودکار وردپرس در اوبونتو، بهترین های هر دو دنیا را گرد هم آوریم، و آن را بررسی می کنیم و توضیح می دهیم که هر قطعه چه کاری انجام می دهد و مبادلاتی که در طراحی انجام دادیم. آی تی. اگر کاربر با تجربه ای هستید، می توانید از متن مقاله صرف نظر کنید و فقط فیلمنامه را بگیرید برای اصلاح و استفاده در محیط های خود. خروجی اسکریپت یک نصب سفارشی وردپرس با پشتیبانی از Lets Encrypt است که روی واحد NGINX اجرا می شود و برای استفاده صنعتی مناسب است.

معماری توسعه یافته برای استقرار وردپرس با استفاده از واحد NGINX در شرح داده شده است مقاله قدیمی تر، اکنون مواردی را که در آنجا پوشش داده نشده اند را نیز پیکربندی خواهیم کرد (مانند بسیاری از آموزش های دیگر):

  • وردپرس CLI
  • بیایید گواهینامه ها و TLSSSL را رمزگذاری کنیم
  • تمدید خودکار گواهینامه
  • NGINX Caching
  • فشرده سازی NGINX
  • پشتیبانی از HTTPS و HTTP/2
  • خودکارسازی فرایند

در این مقاله نصب بر روی یک سرور توضیح داده خواهد شد که به طور همزمان میزبان یک سرور پردازش ایستا، یک سرور پردازش PHP و یک پایگاه داده است. نصب با پشتیبانی از چندین میزبان مجازی و سرویس یک موضوع بالقوه برای آینده است. اگر می خواهید در مورد چیزی بنویسیم که در این مقالات نیست، در نظرات بنویسید.

مقررات

  • ظرف سرور (LXC یا LXD، یک ماشین مجازی یا یک سرور سخت افزاری معمولی با حداقل 512 مگابایت رم و اوبونتو 18.04 یا جدیدتر نصب شده است.
  • پورت های 80 و 443 قابل دسترسی به اینترنت
  • نام دامنه مرتبط با آدرس IP عمومی این سرور
  • دسترسی با حقوق ریشه (sudo).

نمای کلی معماری

معماری همان است که توضیح داده شد زودتر، یک برنامه وب سه لایه. این شامل اسکریپت های PHP اجرا شده بر روی موتور PHP و فایل های ثابت پردازش شده توسط وب سرور است.

نصب خودکار وردپرس با واحد NGINX و Ubuntu

اصول عمومی

  • بسیاری از دستورات پیکربندی در یک اسکریپت در صورت شرایط ناتوانی در آن قرار می گیرند: اسکریپت را می توان چندین بار بدون خطر تغییر تنظیماتی که از قبل آماده هستند اجرا کرد.
  • اسکریپت سعی می کند نرم افزار را از مخازن نصب کند، بنابراین می توانید به روز رسانی های سیستم را در یک دستور اعمال کنید (apt upgrade برای اوبونتو).
  • تیم ها سعی می کنند تشخیص دهند که در یک کانتینر در حال اجرا هستند تا بتوانند تنظیمات خود را مطابق با آن تغییر دهند.
  • به منظور تنظیم تعداد فرآیندهای رشته ای که باید در تنظیمات راه اندازی شوند، اسکریپت سعی می کند تنظیمات خودکار برای کار در کانتینرها، ماشین های مجازی و سرورهای سخت افزاری را حدس بزند.
  • هنگام توصیف تنظیمات، ما همیشه ابتدا به اتوماسیون فکر می کنیم، که امیدواریم مبنایی برای ایجاد زیرساخت خود به عنوان کد باشد.
  • تمامی دستورات از سوی کاربر اجرا می شود ریشه، زیرا تنظیمات اولیه سیستم را تغییر می دهند، اما خود وردپرس به عنوان یک کاربر معمولی اجرا می شود.

تنظیم متغیرهای محیطی

قبل از اجرای اسکریپت متغیرهای محیطی زیر را تنظیم کنید:

  • WORDPRESS_DB_PASSWORD - رمز عبور پایگاه داده وردپرس
  • WORDPRESS_ADMIN_USER - نام کاربری مدیریت وردپرس
  • WORDPRESS_ADMIN_PASSWORD - رمز عبور مدیریت وردپرس
  • WORDPRESS_ADMIN_EMAIL - ایمیل مدیریت وردپرس
  • WORDPRESS_URL – آدرس کامل سایت وردپرس، با شروع https://.
  • LETS_ENCRYPT_STAGING — به طور پیش‌فرض خالی است، اما با تنظیم مقدار روی 1، از سرورهای مرحله‌ای Let's Encrypt استفاده خواهید کرد، که برای درخواست مکرر گواهی هنگام آزمایش تنظیمات ضروری هستند، در غیر این صورت Let's Encrypt ممکن است به دلیل تعداد زیاد درخواست‌ها، آدرس IP شما را به طور موقت مسدود کند.

اسکریپت بررسی می کند که این متغیرهای مربوط به وردپرس تنظیم شده باشند و اگر تنظیم نشده باشند خارج می شود.
خطوط اسکریپت 572-576 مقدار را بررسی می کنند LETS_ENCRYPT_STAGING.

تنظیم متغیرهای محیطی مشتق شده

اسکریپت در خطوط 55-61 متغیرهای محیطی زیر را به مقداری کدگذاری شده یا با استفاده از مقداری مشتق شده از متغیرهای تنظیم شده در بخش قبل تنظیم می کند:

  • DEBIAN_FRONTEND="noninteractive" - به برنامه ها می گوید که در یک اسکریپت در حال اجرا هستند و امکان تعامل با کاربر وجود ندارد.
  • WORDPRESS_CLI_VERSION="2.4.0" - نسخه CLI وردپرس برنامه.
  • WORDPRESS_CLI_MD5= "dedd5a662b80cda66e9e25d44c23b25c" - جمع چک فایل اجرایی WordPress CLI 2.4.0 (نسخه در متغیر نشان داده شده است WORDPRESS_CLI_VERSION). اسکریپت خط 162 از این مقدار برای تأیید اینکه فایل CLI وردپرس صحیح دانلود شده است استفاده می کند.
  • UPLOAD_MAX_FILESIZE="16M" - حداکثر اندازه فایلی که می توان در وردپرس آپلود کرد. این تنظیم در چندین مکان استفاده می شود، بنابراین تنظیم آن در یک مکان آسان تر است.
  • TLS_HOSTNAME= "$(echo ${WORDPRESS_URL} | cut -d'/' -f3)" - نام میزبان سیستم، استخراج شده از متغیر WORDPRESS_URL. برای دریافت گواهی‌های TLS/SSL مناسب از Let's Encrypt و همچنین برای تأیید داخلی وردپرس استفاده می‌شود.
  • NGINX_CONF_DIR="/etc/nginx" - مسیر دایرکتوری با تنظیمات NGINX، از جمله فایل اصلی nginx.conf.
  • CERT_DIR="/etc/letsencrypt/live/${TLS_HOSTNAME}" — مسیر مجوزهای Let's Encrypt برای سایت وردپرس که از متغیر بدست آمده است TLS_HOSTNAME.

اختصاص نام هاست به سرور وردپرس

اسکریپت نام میزبان سرور را طوری تنظیم می کند که مقدار با نام دامنه سایت مطابقت داشته باشد. این ضروری نیست، اما ارسال نامه های خروجی از طریق 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 برای اجرای وظایف دوره ای استفاده می شود، به وردپرس نیاز دارد که بتواند از طریق HTTP به خود دسترسی داشته باشد. برای اطمینان از اینکه WP-Cron در همه محیط ها به درستی کار می کند، اسکریپت یک خط به فایل اضافه می کند / غیره / میزبانبه طوری که وردپرس بتواند از طریق رابط 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 منبع باز را از مخازن رسمی NGINX نصب می‌کند تا اطمینان حاصل کند که نسخه‌هایی با آخرین به‌روزرسانی‌های امنیتی و رفع اشکال استفاده می‌شوند.

اسکریپت مخزن واحد NGINX و سپس مخزن NGINX را اضافه می کند و کلید مخازن و فایل های تنظیمات را اضافه می کند. apt، تعریف دسترسی به مخازن از طریق اینترنت.

نصب واقعی واحد NGINX و 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) و وابستگی های آنها

پس از اضافه شدن تمام مخازن، ابرداده ها را به روز می کنیم و برنامه ها را نصب می کنیم. بسته های نصب شده توسط اسکریپت همچنین شامل پسوندهای PHP هستند که هنگام اجرای WordPress.org توصیه می شود

کد اسکریپت

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 و وردپرس

اسکریپت یک فایل تنظیمات در دایرکتوری ایجاد می کند 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

تنظیم تنظیمات پایگاه داده MariaDB برای وردپرس

ما MariaDB را به MySQL انتخاب کردیم زیرا فعالیت های جامعه بیشتری دارد و همچنین می تواند به طور پیش فرض عملکرد بهتری را ارائه می دهد (احتمالاً همه چیز در اینجا ساده تر است: برای نصب MySQL، باید یک مخزن دیگر اضافه کنید، تقریبا مترجم).

این اسکریپت یک پایگاه داده جدید ایجاد می کند و اعتبار دسترسی وردپرس را از طریق رابط loopback ایجاد می کند:

کد اسکریپت

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

نصب برنامه وردپرس CLI

در این مرحله اسکریپت برنامه را نصب می کند WP-CLI. با آن می توانید تنظیمات وردپرس را بدون نیاز به ویرایش دستی فایل ها، به روز رسانی پایگاه داده یا ورود به کنترل پنل نصب و مدیریت کنید. همچنین می توان از آن برای نصب تم ها و افزونه ها و به روز رسانی وردپرس استفاده کرد.

کد اسکریپت

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

نصب و پیکربندی وردپرس

این اسکریپت آخرین نسخه وردپرس را در دایرکتوری نصب می کند /var/www/wordpressو همچنین تنظیمات را تغییر می دهد:

  • اتصال پایگاه داده روی یک سوکت دامنه یونیکس به جای TCP در حلقه بک کار می کند تا ترافیک TCP را کاهش دهد.
  • وردپرس یک پیشوند اضافه می کند https:// در صورتی که کلاینت ها از طریق HTTPS به NGINX متصل شوند، به URL و همچنین نام میزبان راه دور (همانطور که توسط NGINX ارائه شده است) را به PHP ارسال می کند. ما از یک کد برای تنظیم آن استفاده می کنیم.
  • وردپرس برای ورود به سیستم نیاز به HTTPS دارد
  • ساختار URL به صورت بی صدا مبتنی بر منابع است
  • مجوزهای سیستم فایل صحیح برای دایرکتوری وردپرس تنظیم شده است.

کد اسکریپت

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 و مدیریت مسیرهای وردپرس، جداسازی فضای نام فرآیندهای PHP و بهینه سازی تنظیمات عملکرد پیکربندی می کند. سه ویژگی وجود دارد که ارزش توجه به آنها وجود دارد:

  • پشتیبانی از فضای نام براساس شرایط، بر اساس بررسی اینکه اسکریپت در ظرف اجرا می شود، تعیین می شود. این امر ضروری است زیرا اکثر تنظیمات کانتینر از اجرای تودرتوی کانتینرها پشتیبانی نمی کنند.
  • اگر از فضای نام پشتیبانی وجود داشته باشد، فضای نام غیرفعال می شود شبکه. این برای اجازه دادن به وردپرس برای اتصال همزمان به نقاط پایانی و در دسترس بودن در اینترنت ضروری است.
  • حداکثر تعداد فرآیندها به شرح زیر تعیین می شود: (حافظه موجود برای اجرای MariaDB و NGINX Uniy)/(محدودیت RAM در PHP + 5)
    این مقدار در تنظیمات واحد NGINX تنظیم شده است.

این مقدار همچنین نشان می‌دهد که همیشه حداقل دو پردازش PHP در حال اجرا هستند، که مهم است زیرا وردپرس درخواست‌های ناهمزمان زیادی را برای خود ارسال می‌کند و بدون اجرای فرآیندهای اضافی، به عنوان مثال، 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. به تعداد پردازش های کنترل کننده و حداکثر تنظیم اندازه فایل برای دانلود توجه کنید. همچنین یک خط وجود دارد که فایل تنظیمات فشرده سازی که در قسمت بعدی تعریف شده است، روی آن وصل شده و به دنبال آن تنظیمات کش قرار می گیرند.

کد اسکریپت

# 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

راه اندازی NGINX برای وردپرس

سپس اسکریپت یک فایل پیکربندی برای وردپرس ایجاد می کند default.conf در کاتالوگ conf.d. در اینجا پیکربندی شده است:

  • فعال سازی گواهی های TLS دریافت شده از Let's Encrypt از طریق Certbot (پیکربندی آن در بخش بعدی خواهد بود)
  • تنظیمات امنیتی TLS را بر اساس توصیه‌های Let's Encrypt پیکربندی کنید
  • به طور پیش‌فرض، ذخیره درخواست نادیده گرفته شده را برای ۱ ساعت فعال کنید
  • غیرفعال کردن گزارش دسترسی و همچنین ثبت خطا در صورت یافت نشدن فایل، برای دو فایل درخواستی رایج: favicon.ico و robots.txt
  • دسترسی به فایل های مخفی و برخی فایل ها را ممنوع کنید پی اچ پیبرای جلوگیری از دسترسی غیرقانونی یا راه اندازی ناخواسته
  • غیرفعال کردن گزارش دسترسی برای فایل های استاتیک و فونت
  • تنظیم عنوان Access-Control-Allow-Origin برای فایل های فونت
  • اضافه کردن مسیریابی برای 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

پیکربندی Certbot برای Let's Encrypt گواهی ها و تمدید خودکار آنها

Certbot یک ابزار رایگان از Electronic Frontier Foundation (EFF) است که به شما امکان می دهد گواهینامه های TLS را از Let's Encrypt دریافت کرده و به طور خودکار تمدید کنید. اسکریپت مراحل زیر را برای پیکربندی Certbot انجام می‌دهد تا گواهی‌های Let's Encrypt در NGINX را پردازش کند:

  • 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 را پیکربندی می‌کند تا یک وب‌سایت آماده تولید با فعال TLSSSL را ارائه کند، صحبت کردیم. همچنین می توانید بسته به نیاز خود، در آینده اضافه کنید:

  • حمایت کردن برتلی، فشرده سازی در حین پرواز را از طریق HTTPS بهبود بخشید
  • امنیت مد с قوانین برای وردپرسبرای جلوگیری از حملات خودکار به سایت شما
  • پشتیبان گیری برای وردپرس، برای شما مناسب است
  • حفاظت با کمک AppArmor (در اوبونتو)
  • Postfix یا msmtp تا وردپرس بتواند نامه ارسال کند
  • سایت خود را بررسی کنید تا متوجه شوید که چقدر ترافیک می تواند تحمل کند

برای عملکرد بهتر سایت، توصیه می‌کنیم آن را ارتقا دهید NGINX Plus، محصول تجاری ما در سطح سازمانی مبتنی بر منبع باز NGINX. مشترکین آن یک ماژول Brotli بارگذاری شده پویا و همچنین (با هزینه اضافی) دریافت خواهند کرد. NGINX ModSecurity WAF. ما نیز ارائه می دهیم NGINX App Protectیک ماژول WAF برای NGINX Plus بر اساس فناوری امنیتی پیشرو در صنعت F5.

NB برای پشتیبانی از یک وب سایت پر بار، می توانید با متخصصان تماس بگیرید Southbridge. ما عملکرد سریع و مطمئن وب سایت یا خدمات شما را تحت هر باری تضمین خواهیم کرد.

منبع: www.habr.com