MAROON ACADEMY

آموزش آپدیت امن PHP در Ubuntu با کمترین قطعی

راهنمای عملی به‌روزرسانی PHP و PHP-FPM روی سرور Ubuntu؛ از بکاپ و بررسی مخزن تا ری‌استارت کنترل‌شده، تست Laravel و مسیر بازگشت امن.

امنیت سرور

برای آپدیت امن PHP روی Ubuntu ابتدا نسخه‌ای را که واقعاً به وب‌سایت سرویس می‌دهد شناسایی کنید، از تنظیمات و داده‌ها نسخه پشتیبان بگیرید، بسته‌های همان شاخه را از مخزن معتبر ارتقا دهید، پیکربندی PHP-FPM و Nginx را آزمایش کنید و در پایان سرویس و مسیر سلامت برنامه را کنترل کنید. بررسی php -v به‌تنهایی کافی نیست؛ ممکن است CLI به‌روز باشد اما Nginx هنوز به سوکت PHP-FPM قدیمی متصل بماند.

تیم PHP در اکتبر ۲۰۲۶ برای CVE-2026-109618 و CVE-2026-109619 نسخه‌های اضطراری PHP 8.5.12، 8.4.27، 8.3.36 و 8.2.35 را منتشر کرد و به همه نصب‌های پردازش‌کننده درخواست وب توصیه به آپدیت فوری داد. در اطلاعیه تکمیلی ۲۳ اکتبر نیز پیشنهاد شد تا انتشار bugfix بعدی، برای کاهش یک مسیر نادر RCE با شناسه CVE-2026-115560 مقدار session.upload_progress.enabled=0 اعمال شود. این مسیر فقط ترکیب غیرمعمولی از تغییر runtime در session.serialize_handler را درگیر می‌کند؛ اگر قابلیت upload progress برای برنامه ضروری است، پیش از غیرفعال‌سازی سازگاری را بررسی کنید. WAF سپر موقت است، نه جایگزین patch.

آپدیت امنیتی یا مهاجرت به نسخه اصلی جدید؟

ارتقا از PHP 8.3.x به آخرین 8.3.x معمولاً یک به‌روزرسانی نگهداری است، اما رفتن از 8.2 به 8.3 یا از 8.3 به 8.4 مهاجرت نسخه اصلی محسوب می‌شود و باید ابتدا در staging از نظر سازگاری Laravel، Composer و کد اختصاصی آزمایش شود. برای رخداد امنیتی فعلی، patch همان شاخه پشتیبانی‌شده مسیر کم‌ریسک‌تری است؛ شاخه پایان‌عمر باید با backport معتبر محافظت و سپس مهاجرت داده شود.

مرحله اول: نسخه واقعی وب‌سایت را پیدا کنید

با دسترسی sudo، نسخه CLI، سرویس‌های FPM و مقصد fastcgi_pass را جداگانه ببینید:

php -v
systemctl list-units --type=service --all | grep -E 'php.*fpm'
sudo grep -RIn 'fastcgi_pass.*php' /etc/nginx/sites-enabled /etc/nginx/conf.d
php-fpm8.3 -v

در فرمان آخر عدد 8.3 را با نسخه سرویس خود عوض کنید. خروجی Nginx معمولاً مسیری مانند /run/php/php8.3-fpm.sock نشان می‌دهد؛ همین سوکت مشخص می‌کند درخواست وب به کدام runtime می‌رسد. اگر Apache با mod_php دارید، ماژول بارگذاری‌شده را با apache2ctl -M | grep php بررسی کنید. فایل عمومی phpinfo() نسازید؛ چنین صفحه‌ای جزئیات حساس سرور را افشا می‌کند.

مرحله دوم: نامزد بسته و فضای دیسک را بررسی کنید

فهرست بسته‌ها را تازه کنید، اما قبل از نصب ببینید مخزن شما چه نسخه‌ای ارائه می‌دهد:

sudo apt update
apt-cache policy php8.3-cli php8.3-fpm php8.3-common
apt list --upgradable 2>/dev/null | grep -E '^php'
df -h

نسخه مورد انتظار باید در بخش Candidate دیده شود. اگر هنوز build اصلاح‌شده در دسترس نیست، مخزن را بی‌دلیل عوض نکنید؛ اطلاعیه امنیتی Ubuntu یا فروشنده LTS را برای backport بررسی کنید. اضافه‌کردن PPA ناشناس ممکن است زنجیره تأمین و چرخه به‌روزرسانی سرور را آسیب‌پذیر کند. پیش از ادامه نیز مطمئن شوید پارتیشن‌های ریشه و /boot فضای کافی دارند.

مرحله سوم: بکاپ کوچک و قابل بازگشت بسازید

تنظیمات PHP و Nginx را خارج از مسیر عمومی سایت آرشیو کنید:

sudo tar -czf "/root/php-config-$(date +%F-%H%M).tar.gz" /etc/php /etc/nginx

این فایل جای بکاپ برنامه و پایگاه داده را نمی‌گیرد. از snapshot سرویس‌دهنده نیز استفاده و امکان restore را بررسی کنید. مسیر release فعلی، نسخه composer.lock و migrationهای در انتظار را ثبت کنید؛ snapshot ماشین مجازی معمولاً از downgrade بسته مسیر برگشت مطمئن‌تری است.

مراحل امن آپدیت PHP شامل بکاپ، بررسی بسته، راه‌اندازی PHP-FPM و تست سلامت سایتترتیب امن کار: بکاپ، تأیید بسته، راه‌اندازی کنترل‌شده سرویس و بررسی سلامت واقعی وب‌سایت.

مرحله چهارم: برنامه را برای وقفه کوتاه آماده کنید

اگر فقط یک PHP-FPM instance دارید، restart می‌تواند چند ثانیه درخواست‌ها را متوقف کند؛ بنابراین عنوان «کمترین قطعی» واقع‌بینانه‌تر از وعده قطعی صفر است. عملیات را در بازه کم‌ترافیک انجام دهید. برای یک برنامه Laravel می‌توانید صفحه نگهداری با refresh خودکار فعال کنید:

cd /var/www/example.com
php8.3 artisan down --retry=60 --refresh=15

مسیر و نسخه PHP را با سرور خود هماهنگ کنید. گزینه --retry به کلاینت‌ها می‌گوید چه زمانی دوباره تلاش کنند و --refresh مرورگر را دوره‌ای تازه می‌کند. در معماری چند نودی بهتر است هر نود جداگانه از load balancer خارج، به‌روزرسانی و پس از health check دوباره وارد مدار شود.

مرحله پنجم: بسته‌های PHP را ارتقا دهید

روی Ubuntu استاندارد، ارتقای تعاملی اجازه می‌دهد فهرست تغییرات را پیش از تأیید ببینید:

sudo apt update
sudo apt upgrade

فهرست بسته‌ها را بخوانید و مطمئن شوید بسته‌های php8.3-cli، php8.3-fpm، php8.3-common و extensionهای مورد استفاده واقعاً ارتقا می‌یابند. اجرای apt update فقط index مخزن را تازه می‌کند و PHP را آپدیت نمی‌کند. همچنین از نصب کورکورانه یک شماره نسخه از مخزنی که آن را ارائه نمی‌دهد خودداری کنید؛ شماره revision بسته Ubuntu ممکن است با رشته upstream یکسان نباشد، زیرا اصلاح امنیتی گاهی backport می‌شود.

مرحله ششم: پیکربندی را پیش از restart آزمایش کنید

پیش از دست‌زدن به سرویس، syntax هر دو لایه را کنترل کنید:

sudo php-fpm8.3 -t
sudo nginx -t

هر دو فرمان باید موفق باشند. در صورت خطا، مسیر فایل و شماره خط را از خروجی بخوانید و restart نکنید؛ سرویس فعلی ممکن است همچنان سالم باشد. پس از موفقیت تست‌ها، FPM را restart و Nginx را بدون قطع connectionهای فعال reload کنید:

sudo systemctl restart php8.3-fpm
sudo systemctl reload nginx
sudo systemctl is-active php8.3-fpm nginx

برای Apache نام سرویس و روش اتصال متفاوت است. اگر mod_php فعال است، برای بارگذاری binary جدید معمولاً restart خود Apache لازم می‌شود. روی سرور حساس، مستندات توزیع و معماری همان میزبان را مبنا قرار دهید.

مرحله هفتم: Laravel و فرایندهای طولانی‌مدت را تازه کنید

Composer را با همان binary مورد نظر اجرا کنید تا وابستگی‌ها علیه PHP اشتباه بررسی نشوند:

cd /var/www/example.com
php8.3 "$(command -v composer)" check-platform-reqs --no-dev
php8.3 artisan optimize:clear
php8.3 artisan optimize
php8.3 artisan reload
php8.3 artisan up

check-platform-reqs نسخه PHP و extensionهای لازم را با پکیج‌های نصب‌شده تطبیق می‌دهد. فرمان artisan reload سرویس‌های طولانی‌مدتی را که از رویداد reload پشتیبانی می‌کنند تازه می‌کند؛ workerهای Supervisor، Horizon، Octane یا Reverb را نیز مطابق پیکربندی واقعی خود restart یا reload کنید. قبل از artisan up باید بررسی‌های اولیه موفق باشند؛ خارج‌کردن زودهنگام از حالت نگهداری ریسک نمایش خطا به کاربران را بالا می‌برد.

مرحله هشتم: نسخه، سلامت و لاگ را بعد از آپدیت کنترل کنید

نسخه CLI و FPM، وضعیت سرویس و پاسخ مسیر سلامت را جداگانه بسنجید:

php8.3 -v
php-fpm8.3 -v
systemctl is-active php8.3-fpm nginx
curl -fsS -o /dev/null -w '%{http_code}\n' https://example.com/up
curl -I https://example.com

Laravel به‌طور پیش‌فرض می‌تواند مسیر سلامت /up داشته باشد؛ اگر پروژه شما آن را تغییر داده، URL صحیح را جایگزین کنید. انتظار پاسخ موفق کافی نیست: ورود، فرم حیاتی، اتصال دیتابیس، صف و عملیات اصلی کسب‌وکار را نیز smoke test کنید. سپس خطاهای تازه را بخوانید:

sudo journalctl -u php8.3-fpm --since "10 minutes ago" --no-pager
sudo tail -n 100 /var/log/nginx/error.log

لاگ ممکن است مسیر فایل، IP یا داده حساس داشته باشد؛ آن را در کانال عمومی کپی نکنید. چند دقیقه مصرف CPU، حافظه، نرخ 5xx و زمان پاسخ را زیر نظر بگیرید تا ناسازگاری دیرهنگام آشکار شود.

خطاهای رایج بعد از آپدیت PHP

CLI جدید است اما سایت هنوز نسخه قدیمی دارد

مقصد fastcgi_pass و سوکت فعال Nginx را دوباره بررسی کنید. چند شاخه PHP می‌توانند هم‌زمان نصب باشند و update-alternatives فقط CLI را تغییر دهد.

سایت خطای 502 می‌دهد

ابتدا systemctl status php8.3-fpm و لاگ journal را ببینید. علت رایج، اجرا نشدن FPM یا تفاوت مسیر سوکت در Nginx و pool است. تنظیم را حدس نزنید؛ مسیر listen را در فایل pool با fastcgi_pass تطبیق دهید و پیش از reload دوباره nginx -t بزنید.

extension لازم پیدا نمی‌شود

با php8.3 -m فهرست ماژول‌ها را ببینید و بسته extension را فقط از مخزن معتبر همان شاخه نصب کنید. خطای Composer را با --ignore-platform-reqs پنهان نکنید؛ این گزینه می‌تواند برنامه ناسازگار را وارد production کند.

مخزن هنوز نسخه اصلاح‌شده ندارد

اعلامیه توزیع را بررسی کنید؛ ممکن است fix با شماره بسته مخصوص Ubuntu backport شده باشد. برای شاخه پایان‌عمر، دسترسی را محدود و مهاجرت به نسخه پشتیبانی‌شده را فوری کنید.

جمع‌بندی

آپدیت امن PHP یک فرمان واحد نیست. نسخه وب را از روی PHP-FPM یا Apache شناسایی کنید، بکاپ بگیرید، syntax را پیش از restart آزمایش کنید و پس از ارتقا runtime وب و سلامت برنامه را بررسی کنید. در رخداد PHP2Shell، patch رسمی اولویت فوری است.

برای کاهش سطح حمله، راهنمای امن‌سازی اولیه VPS اوبونتو را تکمیل کنید. اگر Nginx شما هنوز HTTPS ندارد، آموزش نصب SSL رایگان با Let's Encrypt را ببینید. برای تشخیص خطاهای برنامه پس از تغییر runtime نیز مقاله رفع خطای 500 وردپرس یک مسیر عیب‌یابی مبتنی بر لاگ ارائه می‌دهد.

منابع رسمی: اطلاعیه امنیتی PHP و نسخه‌های اصلاح‌شده، دانلودهای رسمی PHP، مدیریت بسته در Ubuntu Server، به‌روزرسانی خودکار Ubuntu، کنترل و reload در Nginx و راهنمای استقرار Laravel 13.