← شروع آموزش

WIUNIX ACADEMY

آموزش نصب وردپرس با Nginx و کش FastCGI در اوبونتو و دبیان

صفحهٔ 3 از 4؛ مراحل قبلی و پیش‌نیازها را پیش از ادامه مرور کن.

آموزش متناسب با محیط تو

کجا اجرا می‌کنی؟

سیستم‌عامل و نسخه را انتخاب کن تا مراحل، دستورها و راه‌حل‌ها برای همان محیط نمایش داده شوند.

Ubuntu 24.04 LTSبررسی‌شده با مستندات رسمی ·

آموزش متناسب با مقادیر تو

تنظیمات این آموزش

مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر می‌کنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری می‌شوند و به سرور یا لینک اشتراک‌گذاری فرستاده نمی‌شوند. پیش از اجرا، DNS، گواهی‌ها و سیاست شبکهٔ واقعی را بررسی کن.

ویرایش 4 مقدار این آموزش

نگه‌داری نقطهٔ بازگشت تنظیمات

نسخهٔ خصوصی root ساختار مسیرها را نگه می‌دارد و پیش از ویرایشگر هر دو فایل را مقایسه می‌کند. نشانی چاپ‌شده را ثبت کنید؛ این پشتیبان تنظیمات است، نه دیتابیس و بارگذاری‌ها.

Bash

ترمینال Bash سرور وردپرس، حساب مدیر دارای sudo.

sudo sh -eu <<'SAVE'
umask 077
install -d -m 0700 /root/academy-backups
backup=$(mktemp -d /root/academy-backups/wp-nginx-XXXXXXXX)
cp -a --parents /etc/nginx/sites-available/wordpress /etc/nginx/conf.d/wordpress-cache.conf "$backup/"
cmp /etc/nginx/sites-available/wordpress "$backup/etc/nginx/sites-available/wordpress"
cmp /etc/nginx/conf.d/wordpress-cache.conf "$backup/etc/nginx/conf.d/wordpress-cache.conf"
printf 'Verified pre-cache configuration: %s\n' "$backup"
SAVE
sudo nano /etc/nginx/sites-available/wordpress
از کجا بدانم درست انجام شد؟

بررسی موفق است؛ در صورت خطا، پیش از ادامه علت را برطرف کنید.

18

قدم بعدی

فعال‌سازی کش عمومیِ بررسی‌شده

در location موجود PHP فقط خط خاموش‌بودن کش را عوض کنید. هر دو کنترل bypass و no-cache و محدودیت IP آزمایش باقی بمانند. رفتار پیش‌فرض Nginx برای Set-Cookie، کنترل‌های خصوصی Cache-Control، Vary و X-Accel-Expires حفظ شود. برای گرفتن HIT هدرها را نادیده نگیرید و کوکی را پنهان نکنید. پاسخ عمومی ۲۰۰ در نبود زمان اعتبار بالادست، TTL شصت‌ثانیه‌ای دارد؛ هدر بالادست می‌تواند اولویت داشته باشد. افزونهٔ شخصی‌سازِ فاقد کوکی یا هدر درست با یک هدر کش امن نمی‌شود؛ چنین URLی را مجاز نکنید.

Nginx · /etc/nginx/sites-available/wordpress (existing PHP location)

محتوای فایل؛ در فایل مشخص‌شده ذخیره شود، نه در پوسته.

# In the PHP location, replace ONLY the existing cache-off line:
fastcgi_cache WORDPRESS;
از کجا بدانم درست انجام شد؟

بررسی موفق است؛ در صورت خطا، پیش از ادامه علت را برطرف کنید.

19

قدم بعدی

اعتبارسنجی پیش از reload

شکست آزمون مانع reload می‌شود. reload موفق اعتبار تنظیمات را نشان می‌دهد؛ حریم خصوصی را با بدنه بسنجید.

Bash

ترمینال Bash سرور وردپرس، حساب مدیر دارای sudo.

(
set -euo pipefail
sudo nginx -t
sudo systemctl reload nginx
systemctl is-active nginx
)
از کجا بدانم درست انجام شد؟

بررسی موفق است؛ در صورت خطا، پیش از ادامه علت را برطرف کنید.

20

قدم بعدی

آزمون مستقل MISS و HIT مهمان

در staging بلافاصله پس از نسل تازهٔ کلید و پیش از گرم‌شدن برگه اجرا کنید. انتظار MISS سپس HIT و بدنه‌های عمومی برابر است. اگر از قبل گرم شده، با پنل نگه‌داری نسل استفاده‌نشده بگذارید و یک بار تکرار کنید؛ فایل کش فعال را حذف نکنید. curl باید از مبدأ مجاز بیاید.

Bash

کلاینت مجاز staging، Bash/curl؛ فایل کوکی خصوصی و محلی همان سیستم است.

(
set -euo pipefail
umask 077
work=$(mktemp -d)
base=https://blog.example.com
for n in 1 2; do
  code=$(curl -sS --connect-timeout 5 --max-time 20 -H 'Cookie:' -H 'Authorization:' -D "$work/$n.h" -o "$work/$n.html" -w '%{http_code}' "$base/sample-page/")
  [ "$code" = 200 ]
  grep -i '^X-WP-Cache:' "$work/$n.h"
done
grep -Eiq '^X-WP-Cache: MISS[[:space:]]*$' "$work/1.h"
grep -Eiq '^X-WP-Cache: HIT[[:space:]]*$' "$work/2.h"
cmp "$work/1.html" "$work/2.html"
grep -F 'PUBLIC_CACHE_MARKER' "$work/2.html"
if grep -Fq 'CACHE_USER_A' "$work/2.html"; then
  echo 'Unexpected cached/private content or status' >&2; exit 1
else
  rc=$?; [ "$rc" = 1 ] || exit "$rc"
fi
printf 'Retained anonymous evidence: %s\n' "$work"
)
از کجا بدانم درست انجام شد؟

دو پاسخ ۲۰۰، ابتدا MISS سپس HIT و بدنهٔ عمومی برابر بدون نشانگر کاربر.

21

قدم بعدی

آزمون نشست واقعی و جداسازی کاربران

با ابزار نشست مورداعتماد خود، دو ورود واقعی staging را خصوصی در فایل کوکی با فرمت Netscape صادر کنید. آزمون در Bash/curl سیستم مجاز است و مسیر فایل‌ها محلیِ همان کلاینت است. کوکی ورود ساختگی اثبات احراز هویت نیست. نوار ابزار و نام نمایشی باید شناخت هر حساب توسط وردپرس را نشان دهد؛ BYPASS تنها کافی نیست. بدنه‌ها خصوصی بمانند. کوکی‌های ساختگی رمز نوشته، سبد و افزونه فقط سیاست Nginx را می‌سنجند و آزمون ورود یا خرید واقعی نیستند.

Bash

سیستم مجاز، Bash/curl و فایل کوکی خصوصی نشست‌های واقعی staging.

(
set -euo pipefail
umask 077
work=$(mktemp -d)
base=https://blog.example.com
# Use an EXISTING private Netscape-format jar exported from your staging login.
# It must be root/user readable only. Never paste cookies into source or logs.
jar=$HOME/wp-staging-user-a.cookies
[ -s "$jar" ]
chmod 0600 "$jar"
for n in 1 2; do
  code=$(curl -sS --connect-timeout 5 --max-time 20 -b "$jar" -D "$work/a$n.h" -o "$work/a$n.html" -w '%{http_code}' "$base/sample-page/")
  [ "$code" = 200 ]
  grep -Eiq '^X-WP-Cache: BYPASS[[:space:]]*$' "$work/a$n.h"
  grep -F 'id="wpadminbar"' "$work/a$n.html"
  grep -F 'CACHE_USER_A' "$work/a$n.html"
  if grep -Fq 'CACHE_USER_B' "$work/a$n.html"; then
    echo 'Unexpected cached/private content or status' >&2; exit 1
  else
    rc=$?; [ "$rc" = 1 ] || exit "$rc"
  fi
done
code=$(curl -sS --connect-timeout 5 --max-time 20 -H 'Cookie:' -D "$work/public.h" -o "$work/public.html" -w '%{http_code}' "$base/sample-page/")
[ "$code" = 200 ]
grep -F 'PUBLIC_CACHE_MARKER' "$work/public.html"
if grep -Fq 'CACHE_USER_A' "$work/public.html"; then
  echo 'Unexpected cached/private content or status' >&2; exit 1
else
  rc=$?; [ "$rc" = 1 ] || exit "$rc"
fi
for cookie in 'wp-postpass_demo=test' 'woocommerce_items_in_cart=1' 'plugin_session=test'; do
  code=$(curl -sS --connect-timeout 5 --max-time 20 -b "$cookie" -D "$work/bypass.h" -o "$work/bypass.html" -w '%{http_code}' "$base/sample-page/")
  [ "$code" = 200 ]
  grep -Eiq '^X-WP-Cache: BYPASS[[:space:]]*$' "$work/bypass.h"
done
jar_b=$HOME/wp-staging-user-b.cookies
[ -s "$jar_b" ]
chmod 0600 "$jar_b"
code=$(curl -sS --connect-timeout 5 --max-time 20 -b "$jar_b" -D "$work/b.h" -o "$work/b.html" -w '%{http_code}' "$base/sample-page/")
[ "$code" = 200 ]
grep -Eiq '^X-WP-Cache: BYPASS[[:space:]]*$' "$work/b.h"
grep -F 'CACHE_USER_B' "$work/b.html"
if grep -Fq 'CACHE_USER_A' "$work/b.html"; then
  echo 'Unexpected cached/private content or status' >&2; exit 1
else
  rc=$?; [ "$rc" = 1 ] || exit "$rc"
fi
code=$(curl -sS --connect-timeout 5 --max-time 20 -H 'Cookie:' -D "$work/public-after-b.h" -o "$work/public.html" -w '%{http_code}' "$base/sample-page/")
[ "$code" = 200 ]
grep -F PUBLIC_CACHE_MARKER "$work/public.html"
if grep -Fq CACHE_USER_A "$work/public.html"; then
  echo 'Unexpected cached/private content or status' >&2; exit 1
else
  rc=$?; [ "$rc" = 1 ] || exit "$rc"
fi
if grep -Fq 'CACHE_USER_B' "$work/public.html"; then
  echo 'Unexpected cached/private content or status' >&2; exit 1
else
  rc=$?; [ "$rc" = 1 ] || exit "$rc"
fi
printf 'Private evidence retained at %s; inspect locally, do not publish cookies/bodies.\n' "$work"
)
از کجا بدانم درست انجام شد؟

حساب‌های A و B با BYPASS فقط هویت خود را می‌بینند و پاسخ مهمان بعدی هیچ‌کدام را ندارد.

22

قدم بعدی

کنترل پارامترها و مسیرهای پویا

پیش‌نمایش ممکن است به ورود هدایت شود. statusهای محدود رفتار ورود و دسترسی را می‌پذیرند، اما BYPASS لازم است و 5xx یا شکست ارتباط رد می‌شود. بدنه نیز باید متعلق به همان مسیر باشد. هر query string از جمله UTM به‌جای حذف پنهانی، bypass می‌شود.

Bash

کلاینت مجاز staging، Bash/curl؛ فایل کوکی خصوصی و محلی همان سیستم است.

(
set -euo pipefail
work=$(mktemp -d)
n=0
for target in '/sample-page/?preview=true' '/sample-page/?utm_source=qa' '/wp-login.php' '/wp-json/'; do
  n=$((n + 1))
  code=$(curl -sS --connect-timeout 5 --max-time 20 -D "$work/$n.h" -o "$work/$n.body" -w '%{http_code}' "https://blog.example.com$target")
  case "$code" in 200|301|302|401|403|404) ;; *) echo "Unexpected status $code" >&2; exit 1;; esac
  grep -Eiq '^X-WP-Cache: BYPASS[[:space:]]*$' "$work/$n.h"
  printf '%s -> %s, BYPASS\n' "$target" "$code"
done
)
از کجا بدانم درست انجام شد؟

بررسی موفق است؛ در صورت خطا، پیش از ادامه علت را برطرف کنید.

23

قدم بعدی

تفکیک کلید صفحات بازنویسی‌شده و روش درخواست

کلید شامل scheme، روش، دامنهٔ کنترل‌شده، URI اصلی و نسل است. بازنویسی پیوند یکتا نباید کلید همهٔ صفحات را index.php کند. فقط GET مجاز است؛ HEAD نیز عمداً bypass می‌شود تا پاسخِ بدون بدنه کلید GET را پر نکند. POST خالیِ مهمان به برگهٔ عمومی آزمایش اقدام فرم ندارد و باید bypass شود. Nginx برای POST از موتور کش عبور نمی‌کند؛ بنابراین هدر ممکن است به‌جای BYPASS غایب باشد، اما پاسخ کش‌شدهٔ HIT یا STALE مجاز نیست.

Bash

کلاینت مجاز staging، Bash/curl؛ فایل کوکی خصوصی و محلی همان سیستم است.

(
set -euo pipefail
work=$(mktemp -d)
code=$(curl -sS --connect-timeout 5 --max-time 20 -D "$work/home.h" -o "$work/home.html" -w '%{http_code}' https://blog.example.com/)
[ "$code" = 200 ]
grep -F PUBLIC_HOME_MARKER "$work/home.html"
if grep -Fq PUBLIC_CACHE_MARKER "$work/home.html"; then
  echo 'Unexpected cached/private content or status' >&2; exit 1
else
  rc=$?; [ "$rc" = 1 ] || exit "$rc"
fi
code=$(curl -sS --connect-timeout 5 --max-time 20 -X POST -d '' -D "$work/post.h" -o "$work/post.html" -w '%{http_code}' https://blog.example.com/sample-page/)
[ "$code" = 200 ]
if grep -Eiq '^X-WP-Cache: (HIT|STALE|UPDATING|REVALIDATED)[[:space:]]*$' "$work/post.h"; then
  echo 'Unexpected cached/private content or status' >&2; exit 1
else
  rc=$?; [ "$rc" = 1 ] || exit "$rc"
fi
grep -F PUBLIC_CACHE_MARKER "$work/post.html"
curl -sS --head --connect-timeout 5 --max-time 20 https://blog.example.com/sample-page/
)
از کجا بدانم درست انجام شد؟

کلید دو صفحه متفاوت است؛ POST بدنهٔ عمومی درست دارد و از کش نیست؛ HEAD بدون بدنه bypass می‌شود.

همهٔ آموزش‌های آکادمی ↗