Apache و Nginx
رفع بالا نیامدن Apache: پورت 80 اشغال و خطای کانفیگ
بالا نیامدن Apache روی VPS معمولا از سه جا می آید: پورت 80 یا 443 را برنامه دیگری گرفته، یک خط کانفیگ خطا دارد، یا سرویس به خاطر فایل، گواهی یا حافظه شروع نمی شود. با سه دستور systemctl status، ss و apachectl configtest می توانید در چند دقیقه علت را پیدا کنید.
اگر Apache بعد از ریستارت، تغییر کانفیگ یا نصب گواهی بالا نمی آید، تقریبا همیشه خود سرویس علت را در لاگ نوشته است. این مقاله برای کسی است که روی VPS یا سرور اختصاصی دسترسی root دارد. روی هاست اشتراکی cPanel دسترسی به سرویس ندارید و بالا نیامدن Apache را باید با تیکت به پشتیبانی بدهید. اگر روی هاست اشتراکی صفحه 403 می بینید، رفع خطای 403 Forbidden را بخوانید.
اول وضعیت سرویس را ببینید
نام سرویس به توزیع بستگی دارد. روی AlmaLinux، Rocky، CentOS و سرورهای cPanel نام آن httpd و روی Debian و Ubuntu apache2 است. این دستور وضعیت را نشان می دهد:
systemctl status httpd
# روی Debian و Ubuntu:
systemctl status apache2
در خروجی دنبال خط Active: بگردید. failed یعنی سرویس شروع شده و خطا داده است. خط های آخر همان خروجی معمولا پیام خطا را دارند. اگر کوتاه بود، متن کامل تر را با journalctl بخوانید:
journalctl -xeu httpd --no-pager | tail -n 40
روی Debian و Ubuntu به جای httpd از apache2 استفاده کنید. دو فایل لاگ هم هست: /var/log/httpd/error_log روی خانواده RHEL و /var/log/apache2/error.log روی Debian. روی سرور cPanel لاگ اصلی /usr/local/apache/logs/error_log است.
تست کانفیگ پیش از هر ریستارت
دستور زیر بدون بالا آوردن سرویس، فایل های کانفیگ را بررسی می کند و شماره خط خطا را می دهد:
apachectl configtest
# معادل آن:
httpd -t
# روی Debian و Ubuntu:
apache2ctl configtest
اگر خروجی Syntax OK باشد، مشکل از نگارش کانفیگ نیست و باید سراغ پورت، فایل ها یا حافظه بروید. اگر خطا داشت، این جدول رایج ترین پیام ها را توضیح می دهد.
| پیام | معنی | راه حل |
|---|---|---|
AH00526: Syntax error on line N of ... | خطای نگارشی در همان خط | فایل و شماره خط را باز کنید و اشتباه تایپی یا آکولاد ناقص را اصلاح کنید |
Invalid command 'X', perhaps misspelled or defined by a module not included | دستور از ماژولی است که بارگذاری نشده | ماژول را نصب یا فعال کنید یا خط را بردارید |
AH00112: Warning: DocumentRoot [...] does not exist | مسیر پوشه سایت وجود ندارد | مسیر را درست کنید یا پوشه را بسازید |
SSLCertificateFile: file '...' does not exist or is empty | فایل گواهی نیست یا خالی است | مسیر یا فایل را اصلاح کنید |
پیش از ویرایش هر فایل کانفیگ از آن نسخه پشتیبان بگیرید، مثلا cp /etc/httpd/conf/httpd.conf /root/httpd.conf.bak. بعد از هر تغییر apachectl configtest را اجرا کنید و فقط وقتی Syntax OK دیدید ریستارت یا reload بزنید. روی سرور cPanel فایل httpd.conf را مستقیم ویرایش نکنید، چون WHM آن را دوباره می سازد. تغییرها را از WHM و بخش Apache Configuration و Include Editor اعمال کنید.
علت اول: پورت 80 یا 443 اشغال است
شایع ترین علت بالا نیامدن Apache همین است. در لاگ خطایی شبیه این می بینید:
(98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
no listening sockets available, shutting down
AH00015: Unable to open logs
یعنی پورت را برنامه دیگری گرفته است. با دستور زیر ببینید کدام:
ss -ltnp | grep -E ':80 |:443 '
ستون آخر نام و PID پروسه را نشان می دهد. اگر دستور ss نبود، netstat -ltnp همین کار را می کند. حالت های رایج:
- Nginx روی همان پورت شنود می کند. اگر هر دو را نصب کرده اید، یکی باید پورت دیگری بگیرد یا Nginx جلوی Apache قرار بگیرد (reverse proxy). در این حالت Nginx روی 80 و 443 و Apache روی پورتی مثل 8080 است.
- یک نمونه قدیمی httpd هنوز زنده است. بعد از
systemctl stop httpdاگرssهنوز پروسه httpd نشان می دهد، آن را باkill PIDمتوقف کنید وsystemctl start httpdبزنید. - سرویس دیگری مثل Caddy، Docker یا یک برنامه آزمایشی پورت را گرفته است.
systemctl stopیاdocker psنشان می دهد کدام است. - در کانفیگ دو بار
Listen 80نوشته شده است. در این حالتssپروسه دیگری نشان نمی دهد و خطا از تکرار است. دستورgrep -rn "^Listen" /etc/httpdفایل های درگیر را پیدا می کند.
اگر می خواهید Apache روی پورت دیگری شنود کند، خط Listen را در httpd.conf یا ports.conf عوض کنید و VirtualHost را هم با همان پورت هماهنگ کنید. روی سرور هایی که SELinux فعال است، پورت غیر استاندارد باید مجاز شود:
semanage port -a -t http_port_t -p tcp 8080
برای ساختن این دستور ممکن است policycoreutils-python-utils لازم باشد.
علت دوم: خطای کانفیگ یا ماژول
بعد از هر تغییر در کانفیگ، اضافه کردن Virtual Host، نصب ماژول یا به روزرسانی بسته ها ممکن است Apache از شروع بماند. apachectl configtest را اجرا کنید و خط خطا را اصلاح کنید.
نکته های کاربردی:
- وقتی خط شماره N در فایلی در
conf.dیاsites-enabledاست، مشکل همان فایل است و لازم نیستhttpd.confرا بگردید. - روی Debian و Ubuntu با
apache2ctl -Mماژول های بارگذاری شده را ببینید و باa2enmod نامیاa2dismod نامفعال و غیرفعال کنید. - بعد از به روزرسانی Apache، گاهی دستورهای قدیمی حذف یا عوض شده اند.
Order allow,denyوAllow fromدر نسخه 2.4 به ماژول سازگاری نیاز دارند و نگارش درستRequireاست. - اگر هر Virtual Host یک فایل جدا دارد، فایل ها را یکی یکی با
#غیرفعال کنید تا فایل خراب مشخص شود.
برای آشنایی با نگارش دستورها مستندات httpd.apache.org مرجع رسمی است.
علت سوم: مشکل گواهی SSL
اگر بعد از نصب یا تمدید گواهی بالا نمی آید، پیام در لاگ معمولا به SSLCertificateFile یا SSLCertificateKeyFile اشاره دارد. چند حالت رایج:
- مسیر گواهی بعد از تمدید یا انتقال عوض شده و فایل قدیمی پاک شده است.
- کلید خصوصی با گواهی جور نیست. هر دو را با
openssl x509 -noout -modulus -in cert.pem | openssl md5وopenssl rsa -noout -modulus -in key.pem | openssl md5بررسی کنید. دو خروجی باید یکی باشد. - فایل گواهی خالی یا ناقص ذخیره شده است.
ls -lاندازه فایل را نشان می دهد. - پرمیشن فایل کلید اجازه خواندن به root نمی دهد.
برای ابزار صدور و تمدید خودکار، نصب Certbot برای Nginx و Apache را ببینید. اگر Certbot کانفیگ را خراب کرده، فایلی که ساخته است معمولا *-le-ssl.conf نام دارد و آن را موقتا غیرفعال کنید.
علت چهارم: دیسک پر یا حافظه تمام شده
Apache برای نوشتن لاگ و فایل pid به دیسک نیاز دارد. وقتی پارتیشن پر باشد، خطای No space left on device یا AH00015: Unable to open logs می بینید. این دو دستور را اجرا کنید:
df -h
df -i
اگر Use% در یکی از پارتیشن ها 100 درصد است، فایل های قدیمی یا لاگ های بزرگ را پاک کنید. ستون IUse% در دستور دوم پر بودن inode را نشان می دهد و آن هم همین علامت را می دهد.
اگر بالا آمدن سرویس با killed تمام می شود، شاید کمبود RAM باعث شده باشد هسته سرویس را ببندد:
dmesg -T | grep -i -E "out of memory|killed process"
journalctl -k | grep -i "out of memory"
اگر خطی با نام httpd دیدید، سرور RAM کافی ندارد. تعداد پروسه ها را در تنظیمات MPM کم کنید، سایت های سنگین را جدا کنید یا حافظه سرور را بیشتر کنید. در مقایسه VPS ایران و خارج می توانید مشخصات رایج را ببینید.
علت پنجم: پرمیشن و SELinux
اگر خطا درباره باز نشدن فایل یا پوشه است، مالک و پرمیشن را بررسی کنید. Apache با کاربر apache یا www-data به لاگ، کلید SSL و Document Root دسترسی دارد. روی سیستم هایی که SELinux فعال است، فایل ها باید برچسب درست داشته باشند. وضعیت را با getenforce ببینید و رد پای رد شدن را با ausearch -m avc -ts recent پیدا کنید. برای آزمایش می توانید موقتا setenforce 0 بزنید. اگر مشکل رفع شد، به جای غیرفعال کردن دائمی SELinux برچسب فایل ها را اصلاح کنید.
وقتی Apache بالا آمده ولی سایت باز نمی شود
گاهی سرویس active (running) است و سایت باز نمی شود. این موارد را بررسی کنید:
curl -I http://127.0.0.1/را روی خود سرور اجرا کنید. اگر پاسخ می دهد، مشکل از فایروال یا DNS است.- با
firewall-cmd --list-allیاufw statusببینید پورت 80 و 443 باز است. - Security Group یا فایروال پنل ارائه دهنده VPS را هم بررسی کنید.
- اگر Nginx جلوی Apache است و 502 می بینید، رفع خطای 502 Bad Gateway در Nginx را بخوانید.
وقتی علت را پیدا نمی کنید
اگر apachectl configtest موفق است، پورت آزاد است و دیسک و حافظه مشکلی ندارند، Apache را مستقیم و بدون systemd اجرا کنید تا خطا روی صفحه چاپ شود. روی خانواده RHEL دستور httpd -X سرویس را در حالت single process و روی پیش زمینه بالا می آورد و هر پیام خطا را همان لحظه نشان می دهد. با Ctrl+C آن را متوقف کنید و دوباره از systemctl استفاده کنید.
اگر مشکل بعد از یک به روزرسانی شروع شده، لیست بسته های تازه را با dnf history یا grep " install \| upgrade " /var/log/dpkg.log ببینید. گاهی یک ماژول شخص ثالث مثل mod_security یا mod_pagespeed با نسخه جدید Apache سازگار نیست و بارگذاری آن خط LoadModule را از کار می اندازد. آن خط را موقتا با # غیرفعال کنید و دوباره configtest بزنید.
اگر این مقاله علت را پیدا نکرد، آخرین 50 خط لاگ خطا، خروجی apachectl configtest و خروجی ss -ltnp را کنار هم برای پشتیبانی بفرستید. این سه مورد معمولا برای تشخیص کافی اند.
چطور مطمئن شویم حل شده
بعد از اصلاح، به ترتیب این سه دستور را بزنید:
apachectl configtest
systemctl restart httpd
systemctl status httpd
وضعیت باید active (running) باشد. سپس با ss -ltnp | grep httpd ببینید پورت های درست باز شده اند و با curl -I https://example.com/ پاسخ 200 یا ریدایرکت مورد انتظار را بگیرید. برای اینکه بعد از ریبوت هم خودکار بالا بیاید، systemctl enable httpd را اجرا کنید. اگر کنترل کامل سرویس ها و لاگ ها را لازم دارید، VPS ایران پیکوهاست با دسترسی root ارائه می شود.