Hướng dẫn cập nhật bản vá lỗi bảo mật PHP2SHELL từ PHP8.2

Để khắc phục lỗ hổng bảo mật PHP2Shell, quý khách cần cập nhật PHP lên phiên bản đã được vá. Trong bài viết này, Long Vân hướng dẫn cách kiểm tra, sao lưu, cập nhật và khôi phục PHP khi cần thiết.

Bài viêt này minh họa việc cập nhật PHP 8.2.x lên PHP 8.2.35 hoặc bản 8.2.x mới hơn, giữ nguyên nhánh PHP đang sử dụng.

Nhánh PHP đang dùngBản vá tối thiểu cần cập nhật
PHP 8.2.xPHP 8.2.35
PHP 8.3.xPHP 8.3.36
PHP 8.4.xPHP 8.4.27
PHP 8.5.xPHP 8.5.12

Với PHP 8.3, 8.4 và 8.5, thực hiện tương tự: thay 8.2 trong lệnh bằng nhánh đang dùng; với Remi, thay php82 bằng php83, php84 hoặc php85. Không chọn một nhánh khác với PHP hiện tại. Thông tin bản vá được đối chiếu ngày 23/10/2026.

Phạm vi: Máy chủ Linux cài PHP bằng APT hoặc DNF/Remi, không sử dụng panel. Không áp dụng cho Docker hoặc PHP tự biên dịch. Với DirectAdmin, xem hướng dẫn riêng tại đây.

Trước khi thao tác trên máy chủ production, Quý khách nên tạo snapshot toàn bộ VPS/VM (hoặc bản sao lưu hệ thống có thể khôi phục), đồng thời sao lưu mã nguồn website và cơ sở dữ liệu theo quy trình hiện có. Nên thực hiện trong thời gian ít truy cập do việc cập nhật có thể khởi động lại PHP-FPM/Apache và gây gián đoạn ngắn.

Bước 1: Kiểm tra PHP đang sử dụng

Kiểm tra hệ điều hành và phiên bản PHP:

cat /etc/os-release
php -v

Với Ubuntu/Debian có nhiều phiên bản PHP, kiểm tra riêng PHP 8.2:

php8.2 -v

Với Remi cài song song, kiểm tra bằng đường dẫn riêng:

/opt/remi/php82/root/usr/bin/php -v

Chỉ tiếp tục với hướng dẫn minh họa bên dưới khi phiên bản cần cập nhật thuộc nhánh PHP 8.2.

Kiểm tra thêm PHP của website: Với WordPress, vào Công cụ > Sức khỏe trang web > Thông tin > Máy chủ. PHP dòng lệnh có thể khác PHP đang phục vụ website.

Nếu chưa xác định được website sử dụng PHP nào, liên hệ bộ phận kỹ thuật trước khi cập nhật.

Bước 2: Sao lưu PHP trước khi cập nhật

Tạo thư mục lưu cấu hình và thông tin phiên bản:

mkdir -m 700 /root/php82-backup

Thực hiện tiếp các câu lệnh dưới đây the từng phiên bản hệ điều hành.

Ubuntu/Debian

Sao lưu cấu hình bằng lệnh cp:

cp -a /etc/php/8.2 /root/php82-backup/
mkdir /root/php82-backup/packages

APT không có lệnh hoàn tác giao dịch. Vì vậy, cần lưu thêm bộ cài đúng phiên bản hiện tại để sử dụng khi khôi phục.

Lấy danh sách các gói PHP 8.2 đang cài:

dpkg-query -W -f='${binary:Package}\t${Version}\t${db:Status-Status}\n' | awk '$3 == "installed" && $1 ~ /^(php8\.2($|[-:])|libapache2-mod-php8\.2($|:))/ {print $1 "=" $2}' > /root/php82-backup/packages.txt
cat /root/php82-backup/packages.txt

Nếu danh sách có tên gói và phiên bản, tải bộ cài:

cd /root/php82-backup/packages
xargs -r apt-get download < /root/php82-backup/packages.txt
ls -lh /root/php82-backup/packages

Chỉ tiếp tục khi tải thành công toàn bộ gói trong danh sách. Nếu danh sách rỗng hoặc kho không còn phiên bản cũ, dừng lại và liên hệ kỹ thuật. Không dùng riêng các file có sẵn trong cache APT vì có thể thiếu gói hoặc sai phiên bản.

AlmaLinux/Rocky Linux/RHEL dùng PHP hệ thống

Sao lưu cấu hình và ghi nhận các gói đang cài:

cp -a /etc/php.ini /etc/php.d /root/php82-backup/
rpm -qa > /root/php82-backup/packages.txt

Nếu sử dụng PHP-FPM, sao lưu thêm:

cp -a /etc/php-fpm.conf /etc/php-fpm.d /root/php82-backup/

Remi cài song song

Sao lưu thư mục cấu hình PHP 8.2:

cp -a /etc/opt/remi/php82 /root/php82-backup/
rpm -qa > /root/php82-backup/packages.txt

Với DNF/Remi, Bước 5 sử dụng dnf history undo để hoàn tác giao dịch cập nhật. Cách này không lưu bộ cài cũ và chỉ thực hiện được khi DNF còn truy cập được các phiên bản cần khôi phục, đồng thời không có xung đột phụ thuộc. Nếu cần bảo đảm khả năng khôi phục khi kho đã xóa phiên bản cũ, phải lưu bộ cài riêng trước khi cập nhật.

Bước 3: Tiến hành cập nhật PHP

Trường hợp A: Ubuntu/Debian

Cập nhật danh sách phần mềm và kiểm tra bản PHP có sẵn:

apt-get update
apt-cache policy php8.2-common

Kiểm tra dòng Candidate. Nếu phiên bản là 8.2.35 hoặc bản 8.2.x mới hơn, chạy:

apt-get install --only-upgrade 'php8.2*'

Nhập Y để xác nhận. --only-upgrade chỉ nâng cấp các gói đã cài.

Nếu website dùng PHP-FPM với Nginx hoặc Apache, kiểm tra cấu hình và khởi động lại PHP-FPM:

php-fpm8.2 -t && systemctl restart php8.2-fpm
systemctl is-active php8.2-fpm

Nếu website dùng Apache mod_php, cập nhật thêm module PHP của Apache và khởi động lại Apache:

apt-get install --only-upgrade libapache2-mod-php8.2
apache2ctl configtest && systemctl restart apache2
systemctl is-active apache2

Chỉ chạy khối dịch vụ phù hợp; nếu dùng cả hai, thực hiện cả hai. Kết quả kiểm tra dịch vụ cần là active.

Trường hợp B: AlmaLinux/Rocky Linux/RHEL dùng PHP hệ thống

Áp dụng khi các gói có tên php-cli, php-common, php-fpm. Chạy:

dnf --refresh upgrade 'php' 'php-*'

Kiểm tra phiên bản được đề xuất vẫn cùng nhánh hiện tại và đạt mốc vá, sau đó nhập y. Nếu đề xuất chuyển nhánh, nhập n và dừng lại.

Với PHP-FPM, khởi động lại dịch vụ:

php-fpm -t && systemctl restart php-fpm
systemctl is-active php-fpm

Nếu website dùng Apache mod_php, thực hiện thay bằng:

httpd -t && systemctl restart httpd
systemctl is-active httpd

Nếu máy chủ dùng cả hai, khởi động lại cả hai dịch vụ.

Trường hợp C: Remi cài song song nhiều phiên bản

Áp dụng khi các gói có tên php82-php-*, php83-php-*, php84-php-* hoặc php85-php-*.

Cập nhật nhánh PHP 8.2:

dnf --refresh upgrade 'php82' 'php82-*'

Kiểm tra phiên bản được đề xuất đã đạt mốc vá, sau đó nhập y. Khởi động lại PHP-FPM tương ứng:

/opt/remi/php82/root/usr/sbin/php-fpm -t && systemctl restart php82-php-fpm
systemctl is-active php82-php-fpm

Kết quả kiểm tra dịch vụ cần là active.

Ghi lại giao dịch cập nhật DNF

Nếu dùng DNF/Remi, sau khi cập nhật chạy:

dnf history list

Ghi lại ID của giao dịch vừa cập nhật PHP để dùng khi khôi phục. Ví dụ ID là 25, kiểm tra nội dung bằng:

dnf history info 25

25 chỉ là ví dụ; thay bằng ID thực tế. Không mặc định giao dịch cuối cùng luôn là giao dịch cập nhật PHP.

Lưu ý: Giữ nguyên kho phần mềm và module/stream hiện tại. Không xác nhận nếu trình cập nhật đề xuất gỡ gói hoặc chuyển nhánh. Nếu kho chưa có bản vá, liên hệ kỹ thuật; không tự đổi kho để ép cập nhật. Nếu được hỏi thay file cấu hình, kiểm tra nội dung thay đổi trước khi chọn.

Bước 4: Kiểm tra sau khi cập nhật

Chạy lại lệnh kiểm tra phiên bản:

php -v

Nếu Ubuntu/Debian cài nhiều phiên bản, kiểm tra đúng nhánh, ví dụ:

php8.2 -v

Nếu dùng Remi cài song song:

/opt/remi/php82/root/usr/bin/php -v

Bước 5: Khôi phục PHP nếu cập nhật gặp lỗi

Ubuntu/Debian: Cài lại từ bộ cài đã lưu

Kiểm tra các file sao lưu:

ls -lh /root/php82-backup/packages

Cài lại phiên bản PHP trước cập nhật:

apt-get install --no-download --allow-downgrades /root/php82-backup/packages/*.deb

Kiểm tra danh sách hạ phiên bản và nhập Y. Sau khi cài thành công, khôi phục cấu hình:

cp -a /root/php82-backup/8.2/. /etc/php/8.2/

AlmaLinux/Rocky Linux/RHEL và Remi: Hoàn tác bằng DNF

Xem lịch sử và kiểm tra ID đã ghi tại Bước 3:

dnf history list
dnf history info 25

Thay 25 bằng ID giao dịch cập nhật PHP cần hoàn tác. Khi đã xác nhận đúng giao dịch, chạy:

dnf history undo 25

Kiểm tra danh sách thay đổi rồi nhập y. Lệnh hoàn tác toàn bộ giao dịch đã chọn, không chỉ một gói PHP. DNF có thể không khôi phục được nếu kho không còn phiên bản cũ hoặc các gói phụ thuộc đã thay đổi.

Sau khi hoàn tác thành công, khôi phục cấu hình theo đúng kiểu cài đặt.

PHP hệ thống:

cp -a /root/php82-backup/php.ini /etc/php.ini
cp -a /root/php82-backup/php.d/. /etc/php.d/

Nếu đã sao lưu cấu hình PHP-FPM, chạy thêm:

cp -a /root/php82-backup/php-fpm.conf /etc/php-fpm.conf
cp -a /root/php82-backup/php-fpm.d/. /etc/php-fpm.d/

Remi cài song song:

cp -a /root/php82-backup/php82/. /etc/opt/remi/php82/

Nếu khôi phục gói thất bại, dừng lại và liên hệ kỹ thuật. Không dùng --force, --nodeps hoặc --allowerasing để ép thực hiện. Nếu giao dịch đề xuất thay đổi ngoài phạm vi dự kiến, không xác nhận.

Các lệnh cp ghi đè file đã sao lưu nhưng không xóa file mới phát sinh sau cập nhật. Nếu có file cấu hình mới gây lỗi, cần xác định và xử lý riêng.

Khởi động lại và kiểm tra PHP

Chọn khối tương ứng với cách cài PHP 8.2 trên máy chủ.

Ubuntu/Debian dùng PHP-FPM:

php-fpm8.2 -t && systemctl restart php8.2-fpm
systemctl is-active php8.2-fpm
php8.2 -v

AlmaLinux/Rocky Linux/RHEL dùng PHP-FPM hệ thống:

php-fpm -t && systemctl restart php-fpm
systemctl is-active php-fpm
php -v

Remi cài song song:

/opt/remi/php82/root/usr/sbin/php-fpm -t && systemctl restart php82-php-fpm
systemctl is-active php82-php-fpm
/opt/remi/php82/root/usr/bin/php -v

Nếu dùng Apache mod_php, khởi động lại Apache thay cho PHP-FPM:

# Ubuntu/Debian
apache2ctl configtest && systemctl restart apache2
systemctl is-active apache2

# AlmaLinux/Rocky Linux/RHEL
httpd -t && systemctl restart httpd
systemctl is-active httpd

Chỉ chạy khối Apache đúng hệ điều hành. Nếu dùng cả FPM và mod_php, khởi động lại cả hai.

Kết quả cần xác nhận: PHP trở về phiên bản trước cập nhật, dịch vụ là active và website hoạt động trở lại. Kiểm tra cả PHP của website như Bước 4; khởi động lại queue worker nếu có.

Như vậy, Long Vân đã hướng dẫn quý khách kiểm tra, sao lưu và cập nhật bản vá bảo mật cho PHP 8.2 mà không thay đổi nhánh PHP đang sử dụng, đồng thời cung cấp phương án khôi phục khi gặp lỗi. Với PHP 8.3, 8.4 và 8.5, quý khách có thể thực hiện tương tự theo phiên bản tương ứng.

Chúc quý khách thực hiện thành công! Nếu cần hỗ trợ trong quá trình cập nhật, vui lòng liên hệ bộ phận kỹ thuật Long Vân để được hướng dẫn.