آپاچی در ۵۰ شب؛ از میزبان مجازی تا WordPress و ممیزی CIS
در این دوره یک وبسرور چندسایتی میسازیم: سایت ثابت، برنامهٔ پشت پراکسی، مسیر
WebSocket، WordPress و ورودی مدیریتی محدود. از نصب apache2 در Debian/Ubuntu و
httpd در AlmaLinux/Rocky Linux شروع میکنیم و به کنترل دسترسی، بهرهبرداری و
ممیزی پیکربندی میرسیم. هر تغییر باید دلیل، آزمون مثبت، آزمون منفی و راه برگشت داشته باشد.
این یک دورهٔ تألیفی مستقل است. هدف آن آموزش عملی Apache HTTP Server 2.4 و ساخت گزارش ممیزی بر اساس نسخهٔ منتخب CIS Benchmark است؛ مدرک رسمی CIS یا تضمین انطباق بدون اجرای ممیزی ارائه نمیکند. شمارهٔ کنترلها و profile از PDF رسمی همان نسخه برداشت میشوند؛ متن کامل Benchmark در سایت بازنشر نمیشود.
روش مطالعه و پیشنیازها#
کار با shell، sudo، مجوز فایل، systemd و مفاهیم IP، DNS و TCP را بلد باش. اصطلاحهای تازه در درس مربوط توضیح داده میشوند. هر «شب» یک واحد مطالعه و تمرین است؛ حدود ۶۰ تا ۹۰ دقیقه نقطهٔ شروع مناسبی است و تمرینهای WordPress، TLS و ممیزی ممکن است بیشتر زمان بخواهند. هر ۵۰ درس اکنون در دسترس است؛ تاریخ آنها برنامهٔ انتشار آینده نیست.
در دفترچه سه وضعیت «مطالعهشده»، «اجراشده» و «تأییدشده» را جدا ثبت کن. خروجیهای مورد انتظار در متن، نتیجهٔ اجرای واقعی همهٔ سیستمعاملها توسط نویسنده نیستند. ساخت سایت و پیوندها بررسی میشوند؛ آزمایش سرویس، شبکه و امنیت باید در VM خودت انجام شود.
نسخههای مبنا و تفاوت توزیعها#
| محیط | Apache و PHP مبنا | نقش |
|---|---|---|
| Debian 13 | بستهٔ apache2، PHP 8.4 مخزن توزیع | شاخهٔ Debian، FPM و Cloneهای legacy |
| Ubuntu Server 24.04 LTS | بستهٔ apache2، PHP 8.3 | شاخهٔ Ubuntu، FPM و تمرین ACME |
| AlmaLinux 9 بهروز | بستهٔ httpd، stream موجود php:8.3 | شاخهٔ RHEL با SELinux |
| Rocky Linux 9 بهروز | بستهٔ httpd، stream موجود php:8.3 | شاخهٔ RHEL با SELinux |
شمارهٔ دقیق بسته، revision و stream واقعاً موجود را در شروع ثبت کن. نمونههای DNF برای VM تمیز با stream اعلامشدهاند؛ روی نصب موجود reset و تعویض stream انجام نده. برای Debian 12، Ubuntu 22.04 یا خانوادهٔ RHEL 10 باید نسخهٔ PHP، مسیرها و روش بستهبندی را با مستندات همان release تطبیق بدهی؛ اینها محیط مبنای فرمانها نیستند.
در Alma/Rocky 9 مسیر اصلی PHP از FPM استفاده میکند. تمرینهای mod_php و
PHP-CGI در Cloneهای Debian/Ubuntu انجام میشوند؛ نصب Apache، TLS، proxy،
WordPress/FPM و hardening برای هر دو خانواده در متن آمدهاند.
قرارداد آزمایشگاه#
برای VM وب از دو vCPU، حدود ۲ تا ۴ GiB حافظه و دیسک با فضای کافی برای backup شروع کن؛ ظرفیت production باید اندازهگیری شود. همهٔ تمرینها نیاز به اجرای همزمان همهٔ backendها ندارند. دو کلاینت مستقل برای تست مجاز و غیرمجاز لازماند.
| ماشین | IPv4 روی شبکهٔ Host-only | IPv6 اختیاری | کاربرد |
|---|---|---|---|
debian-web یا ubuntu-web | 192.168.56.10/24 | fd50:80::10/64 | وبسرور شاخهٔ Debian |
alma-web یا rocky-web | 192.168.56.30/24 | fd50:80::30/64 | وبسرور شاخهٔ RHEL |
client-allowed | 192.168.56.20/24 | fd50:80::20/64 | درخواست مجاز و محل CA lab |
client-denied | 192.168.56.21/24 | fd50:80::21/64 | درخواست منفی واقعی |
edge، Clone اختیاری | 192.168.56.40/24 | در تمرین پایه لازم نیست | اعتماد به پراکسی در شب ۲۳ |
میتوان هر توزیع را نوبتی یا در Clone دارای IP مستقل اجرا کرد. دو VM روشن با IP یکسان ایجاد نکن. کارت Host-only از LAN واقعی جدا باشد؛ کارت NAT جدا فقط برای بستهها و آمادهسازی dependency استفاده میشود. کنسول Hypervisor و Snapshot پیش از تغییر فایروال، MPM، handler، policy یا دیتابیس لازماند.
IPv6 اختیاری را روی همان کارت Host-only، بدون RA یا route عمومی، با آدرس جدول
تنظیم کن. نام interface را از ip -br address بگیر؛ برای افزودن موقت آدرس روی
VM وب، ابتدا LAB_IF را به نام واقعی کارت و آدرس را به ردیف خودت تبدیل کن:
sudo ip -6 addr add fd50:80::10/64 dev "$LAB_IF"
پس از reboot این تنظیم موقت ممکن است از بین برود؛ برای ماندگاری از مدیر شبکهٔ توزیع استفاده کن. آدرسهای خصوصی نمونه نباید با شبکهٔ واقعی میزبان تداخل داشته باشند.
| نام سرویس | نقش |
|---|---|
www.example.test | محتوای ثابت و تمرینهای پایه |
docs.example.test | سایت دوم آزمایشگاهی |
app.example.test | proxy برنامه، WebSocket و SSE |
wp.example.test | WordPress |
admin.example.test | mTLS و ورودی مدیریتی |
backend.example.test | هویت TLS backend محلی |
دامنهٔ .test محلی است و از CA عمومی گواهی نمیگیرد. برای curl از --resolve
و برای مرورگر/کلاینت WebSocket از /etc/hosts استفاده کن. فقط نامهای سرویس
همان شاخه را به IP وبسرور فعال نگاشت کن. backend.example.test در شب ۲۶ روی
خود وبسرور به loopback نگاشت میشود، نه در کلاینت عمومی.
در بیشتر نمونهها IP .10 نوشته شده؛ هنگام تمرین Alma/Rocky آن را به .30
تبدیل کن. برای IPv6 نمونهٔ resolve به شکل www.example.test:443:[fd50:80::10]
است. آزمون IP از ماشین واقعی مهم است؛ هدر X-Forwarded-For آدرس اتصال را خودکار عوض نمیکند.
متغیرها و مسیرهای مشترک#
در هر shell تازهٔ وبسرور، بلوک فقط شاخهٔ خودت را تعریف کن. اینها متغیر shell
هستند؛ Apache داخل فایل config مقدار $APACHE_LOG یا $PHP_BRANCH را از shell
تو جایگزین نمیکند. نمونهٔ config با مسیر کامل نوشته میشود و جایگزینی مسیر RHEL
در درس توضیح داده شده است.
برای Debian/Ubuntu:
APACHE_SERVICE=apache2
APACHE_CTL=apache2ctl
APACHE_USER=www-data
APACHE_LOG=/var/log/apache2
WWW_CONF=/etc/apache2/sites-available/100-www.conf
APP_CONF=/etc/apache2/sites-available/120-app.conf
WP_CONF=/etc/apache2/sites-available/140-wp.conf
AUTH_FILE=/etc/apache2/lab-users
LAB_PYTHON=python3
PHP_BRANCH=8.3
در Debian 13 خط آخر را PHP_BRANCH=8.4 قرار بده؛ 8.3 برای Ubuntu 24.04 است.
ابزارهای Python lab با sudo apt install python3 python3-venv آماده میشوند.
برای Alma/Rocky:
APACHE_SERVICE=httpd
APACHE_CTL=httpd
APACHE_USER=apache
APACHE_LOG=/var/log/httpd
WWW_CONF=/etc/httpd/conf.d/100-www.conf
APP_CONF=/etc/httpd/conf.d/120-app.conf
WP_CONF=/etc/httpd/conf.d/140-wp.conf
AUTH_FILE=/etc/httpd/lab-users
LAB_PYTHON=python3.12
برای backendهای Python جدید sudo dnf install python3.12 python3.12-pip را روی
release دارای این بستهها اجرا کن. پایتون سیستم را جایگزین نکن. نصب dependencyهای
برنامه در venv با نسخهٔ ثبتشده انجام میشود؛ ساخت Hugo این سایت dependency تازهای دانلود نمیکند.
| مورد | Debian/Ubuntu | Alma/Rocky |
|---|---|---|
| فایل اصلی | /etc/apache2/apache2.conf | /etc/httpd/conf/httpd.conf |
| پورتها | /etc/apache2/ports.conf | Listen در config اصلی و ssl.conf |
| فایل global دوره | /etc/apache2/conf-available/apache-lab.conf | /etc/httpd/conf.d/00-apache-lab.conf |
| فعالسازی سایت | a2ensite | خواندن فایل .conf در conf.d |
| کنترل ماژول | a2enmod/a2dismod | conf.modules.d و فهرست httpd -M |
| تنظیم pool FPM | /etc/php/PHP_BRANCH/fpm/pool.d/ | /etc/php-fpm.d/ |
| سرویس FPM | php8.4-fpm یا php8.3-fpm | php-fpm |
| socket WordPress | /run/php/wordpress.sock | /run/php-fpm/wordpress.sock |
در مسیرهای شامل PHP_BRANCH، شمارهٔ واقعی جایگزین میشود؛ این رشته نام پوشهٔ
واقعی نیست. فایلهای .bak را بیرون از الگوی Include نگه دار. فایلهای تم توزیع
و config پیشفرض را قبل از حذف بخشهایشان بخوان؛ Listen 443 یا LoadModule تکراری نساز.
روال اعمال هر تغییر#
config و وضعیت قبل را خصوصی ثبت کن، تغییر را در فایل خواندهشده انجام بده، سپس:
sudo "$APACHE_CTL" -t
sudo systemctl reload "$APACHE_SERVICE"
sudo journalctl -u "$APACHE_SERVICE" -n 30 --no-pager
این سه فرمان را مرحلهبهمرحله اجرا کن؛ اگر syntax test شکست خورد، reload نکن.
بعد از reload یک درخواست تازه و آزمون منفی مربوط بفرست. -t رفتار برنامه را تست
نمیکند. تغییر MPM، ServerLimit یا بعضی ماژولها restart میخواهد و پیامد آن در
درس گفته میشود. FPM configtest/restart و systemd daemon-reload مراحل جدا دارند.
فایل عمومی ca.crt شب ۱۱ باید در مسیر اعلامشدهٔ هر دو کلاینت و edge قرار بگیرد؛
در غیر این صورت، شکست curl ممکن است فقط خطای اعتماد باشد. کلید خصوصی CA روی
ماشین صادرکننده میماند و در هیچ وبسرور یا گزارش عمومی قرار نمیگیرد.
برای برگشت، فایل سالم و تغییرهای runtime مانند boolean یا firewall را بازیابی و همین روال را تکرار کن. configtest موفق بدون پاسخ سالم، پایان کار نیست.
پایهٔ شبکهٔ lab فقط دو کلاینت .20 و .21 را روی 80/443 مجاز میکند و مسیر
SSH واقعی مدیر را نگه میدارد. در UFW برای هر مبدأ و پورت قانون scoped بساز؛ در
firewalld از rich rule با source و zone واقعی کارت lab استفاده کن. قواعد عمومی
قدیمی نباید allowlist را بیاثر کنند. تمرین شب ۲۲ این پایه را موقتاً به .20
محدود میکند و سپس برمیگرداند.
برای آزمایش پراکسی مورد اعتماد در شب ۲۳، مجوز مبدأ .40 را فقط روی پورت لازم
اضافه کن و پس از پایان، آن را مطابق توپولوژی نهایی بازبینی کن.
کدام درسها یک مسیر و کدام آزمایش مستقلاند؟#
شبهای ۱ تا ۲۰ پایهٔ سایت ثابتاند. مTLS شب ۲۱ میزبان جدا دارد؛ firewall شب ۲۲
آزمایش قطع دسترسی کنترلشده است. شبهای ۲۵ تا ۲۷ هرکدام نگاشت اصلی app را تغییر
میدهند و پس از آزمون به baseline مشخص برمیگردند. WebSocket و SSE مسیرهای خاص
پیش از / دارند و میتوانند کنار برنامهٔ systemd شب ۳۰ کار کنند.
شبهای ۳۱ تا ۳۳ و ۳۹ روی Clone مستقل هستند؛ CGI، mod_php و FPM را همزمان روی
یک پسوند با چند handler فعال نکن. مسیر اصلی پس از آن event + PHP-FPM است.
شبهای ۳۴ و ۳۵ دو شاخهٔ توزیع برای یک هدفاند و شب ۳۶ آنها را به pool مستقل
WordPress میرساند. مدیریت کد با حساب انتشار و نوشتن upload با runtime انجام میشود.
منابع و دامنهٔ CIS#
مرجع رفتار Apache، مستندات رسمی نسخهٔ 2.4 است؛ جزئیات package و backport از توزیع گرفته میشود. برای PHP و WordPress به PHP-FPM و راهنمای مدیریت WordPress ارجاع میدهیم. هر درس منابع مرتبط خودش را هم دارد.
در بررسی منابع دوره، صفحهٔ CIS Apache HTTP Server
نسخهٔ Benchmark برابر 2.4.0 را فهرست میکند. در ممیزی واقعی نسخهٔ سند، profile،
دامنه و تاریخ را ثبت و با PDF منتخب تطبیق بده. درسهای ۴۷ تا ۴۹ روش جمعآوری
شاهد و اصلاح را آموزش میدهند؛ شناسهٔ کنترل، نتیجهٔ آزمون یا گزارش انطباق ساختگی ندارند.
فهرست ۵۰ شب#
نصب و میزبانهای مجازی#
- شب ۱: آزمایشگاه و مسیر یک درخواست HTTP
- شب ۲: نصب apache2 روی Debian و Ubuntu
- شب ۳: نصب httpd روی AlmaLinux و Rocky Linux
- شب ۴: فایلهای پیکربندی، Include و ماژولها
- شب ۵: اولین میزبان مجازی با DocumentRoot مستقل
- شب ۶: چند سایت و پاسخ به نام ناشناس
- شب ۷: مجوز فایل و برچسب SELinux
- شب ۸: Directory، Location و Alias
- شب ۹: لاگها، reload و تشخیص ۴۰۳ تا ۵۰۳
- شب ۱۰: Redirect، Rewrite و مرز .htaccess
TLS، HTTP/2 و کنترل دسترسی#
- شب ۱۱: CA آزمایشگاهی و گواهی با نام درست
- شب ۱۲: HTTPS و انتخاب گواهی با SNI
- شب ۱۳: گواهی عمومی، ACME و تمدید قابل آزمون
- شب ۱۴: سیاست TLS و HSTS با امکان بازگشت
- شب ۱۵: HTTP/2 و انتخاب MPM
- شب ۱۶: Security Headers برای پاسخ موفق و خطا
- شب ۱۷: CSP از گزارش خطا تا سیاست اجرایی
- شب ۱۸: فشردهسازی و cache محتوای ثابت
- شب ۱۹: اجازهٔ دسترسی فقط از IPهای مشخص
- شب ۲۰: احراز هویت و IP بهصورت همزمان
اعتماد، پراکسی و برنامههای متصل#
- شب ۲۱: mTLS و گواهی کلاینت برای ورودی خصوصی
- شب ۲۲: محدودیت شبکه با UFW و firewalld
- شب ۲۳: اعتماد به پراکسی و IP واقعی کلاینت
- شب ۲۴: پراکسی معکوس اولین برنامه
- شب ۲۵: پراکسی زیرمسیر، redirect و cookie
- شب ۲۶: TLS معتبر میان Apache و backend
- شب ۲۷: توزیع بار و رفتار هنگام خرابی backend
- شب ۲۸: WebSocket و آزمون رفتوبرگشت پیام
- شب ۲۹: SSE، پاسخ جریانی و timeout
- شب ۳۰: اجرای پایدار برنامه پشت Apache با systemd
CGI، روشهای PHP و راهاندازی WordPress#
- شب ۳۱: CGI با یک برنامهٔ کوچک و محدود
- شب ۳۲: PHP با mod_php روی Debian و Ubuntu
- شب ۳۳: PHP-CGI، Action و جلوگیری از اجرای مستقیم
- شب ۳۴: PHP-FPM روی Debian و Ubuntu
- شب ۳۵: PHP-FPM روی AlmaLinux و Rocky Linux
- شب ۳۶: pool مستقل و حساب کماختیار برای WordPress
- شب ۳۷: ظرفیت FPM، OPcache و slow log
- شب ۳۸: آمادهسازی WordPress، دیتابیس و فایلها
- شب ۳۹: اجرای WordPress با mod_php و PHP-CGI
- شب ۴۰: سایت WordPress با PHP-FPM و HTTPS
بهرهبرداری، سختسازی و ممیزی CIS#
- شب ۴۱: پیوندهای WordPress، upload و HTTPS پشت پراکسی
- شب ۴۲: backup، بازیابی، cron و ارتقای WordPress
- شب ۴۳: سختسازی پایهٔ Apache و بستن مسیرهای اضافی
- شب ۴۴: محدودیت درخواست، اتصال کند و بودجهٔ منابع
- شب ۴۵: سختسازی با SELinux، AppArmor و systemd
- شب ۴۶: مانیتورینگ خصوصی، خطا و چرخش لاگ
- شب ۴۷: CIS Apache؛ نسخه، دامنه و baseline
- شب ۴۸: ممیزی CIS با شاهد و بررسی فقطخواندنی
- شب ۴۹: اصلاح یافتههای CIS و آزمون عدم خرابی
- شب ۵۰: پروژهٔ نهایی و تحویل وبسرور قابل نگهداری