原创内容,转载请注明出处:https://www.myzhenai.com.cn/post/5135.html
因为PHP曝发了严重的 编号:CVE-2026-109618、CVE-2026-109619 0-day(零日)安全漏洞,所以必须要升级系统内的PHP安全补丁,
我有几台服务器,其他的服务器都是用的apt安装的php、nginx、mysql等环境,并且系统上有安装自动更新脚本,系统会自动更新安全补丁
我最担心的是其中一台服务器,因为是以前用军哥的lnmp一键安装脚本安装的服务环境,并且安装面板现在已经不支持高版本的php、nginx、mysql等服务器环境了
并且我安装完,就把lnmp安装包删除了,只留下一下lnmp程序,也不能通过脚本自带的upgrade.sh来升级了
我想,倒不如把lnmp服务环境卸载了,改装成系统自己库里的安装方式,但我又不想重装服务器,怎么办?
于是,我列出一个步骤,按照步骤一步一步来执行。
一、整理计划,列出需要备份的文件
1、备份nginx网站信息,免得重新配置网站的信息
2、备份PHP设置信息
3、备份mysql数据库信息
4、备份ssl证书
5、备份一些运维脚本
BK="/root/server-backup-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BK"/{nginx,php,mysql,ssl,acme,cron,scripts,misc}
echo "$BK" > /root/server-backup-LATEST.path# apt tar -C /etc -czf "$BK/nginx/etc-nginx.tar.gz" nginx cp -a /etc/nginx/sites-available "$BK/nginx/sites-available" 2>/dev/null || true cp -a /etc/nginx/sites-enabled "$BK/nginx/sites-enabled" 2>/dev/null || true nginx -T > "$BK/nginx/nginx-T.txt" 2>&1 || true # 若仍是 LNMP: # tar -C /usr/local/nginx -czf "$BK/nginx/nginx-conf.tar.gz" conf # cp -a /usr/local/nginx/conf "$BK/nginx/conf-copy"
# apt(8.3) tar -C /etc -czf "$BK/php/etc-php.tar.gz" php php -i > "$BK/php/php-i.txt" 2>&1 php -m > "$BK/php/php-modules.txt" 2>&1 cp -a /etc/php/8.3/fpm/pool.d "$BK/php/pool.d" 2>/dev/null || true # LNMP: # tar -C /usr/local/php -czf "$BK/php/php-etc.tar.gz" etc
# 逻辑备份(必做) mysqldump -uroot -p --all-databases --single-transaction \ --routines --triggers --events --hex-blob \ | gzip -c > "$BK/mysql/all-databases.sql.gz" # 配置 cp -a /etc/mysql "$BK/mysql/etc-mysql" 2>/dev/null || true # 或:cp -a /etc/my.cnf /etc/mysql/my.cnf* "$BK/mysql/" 2>/dev/null || true mysql -uroot -p -e "SHOW DATABASES;" > "$BK/mysql/databases.txt"
# 线上证书(apt) cp -a /etc/nginx/ssl "$BK/ssl/nginx-ssl" 2>/dev/null || true # acme 账户与续签状态(强烈建议) tar -C /root -czf "$BK/acme/dot-acme.sh.tar.gz" .acme.sh # LNMP 旧路径若还在: # cp -a /usr/local/nginx/conf/ssl "$BK/ssl/lnmp-ssl" 2>/dev/null || true # cp -a /usr/local/nginx/cert "$BK/ssl/lnmp-cert" 2>/dev/null || true
我们需要先将这些配置信息备份到一个我们重装环境不会影响到的地方,特别是nginx网站设置和ssl签约证书,如果我们不做备份的话,那么装好环境后我们还要重新设置
二、导出站点地图
1、把每个 vhost 的 server_name、root、是否 443、证书路径、PHP 处理方式列成表,接下来按表恢复,避免漏站。
VHOST_DIR=/usr/local/nginx/conf/vhost
OUT=/root/vhost-map-$(date +%Y%m%d-%H%M%S).txt
{
echo "生成时间: $(date '+%F %T')"
echo "配置目录: $VHOST_DIR"
echo
printf "%-28s | %-40s | %-6s | %-55s | %s\n" \
"server_name" "root" "HTTPS" "ssl_certificate" "php/fastcgi"
printf "%s\n" "-----------------------------+------------------------------------------+--------+---------------------------------------------------------+----------------"
for f in "$VHOST_DIR"/*.conf; do
[[ -f "$f" ]] || continue
[[ "$f" == *.bak* ]] && continue
# 每个 conf 可能有多个 server{},按 server 块粗分
awk -v file="$f" '
/server[[:space:]]*\{/ { in_server=1; names=""; root=""; listen443=0; cert=""; php=""; next }
in_server && /listen[[:space:]]+.*443/ { listen443=1 }
in_server && $1=="server_name" {
line=$0; sub(/^[[:space:]]*server_name[[:space:]]+/, "", line); sub(/;.*/, "", line);
gsub(/[[:space:]]+/, " ", line); names=line
}
in_server && $1=="root" {
root=$2; gsub(/;/, "", root)
}
in_server && $1=="ssl_certificate" {
cert=$2; gsub(/;/, "", cert)
}
in_server && /fastcgi_pass/ {
php=$0; gsub(/^[[:space:]]+/, "", php); gsub(/;/, "", php)
}
in_server && /include[[:space:]]+.*enable-php/ {
if (php=="") php=$0; gsub(/^[[:space:]]+/, "", php); gsub(/;/, "", php)
}
in_server && /^[[:space:]]*\}/ {
if (names != "") {
https = (listen443 ? "yes" : "no")
if (cert=="") cert="-"
if (php=="") php="-"
if (root=="") root="-"
printf "%-28s | %-40s | %-6s | %-55s | %s\n", names, root, https, cert, php
}
in_server=0; names=""; root=""; listen443=0; cert=""; php=""
}
' "$f"
echo " # 来源文件: $f"
done
} | tee "$OUT"
echo
echo "已写入: $OUT"这个是自动识别我们服务器里的nginx网站设置里,识别出我们服务器上的所有网站和网站配置信息,方便下一步我们按照这个表来进行工作
三、停止服务器
lnmp stop # 注意:个别环境 lnmp stop 停不干净 MySQL,需 systemctl / 手动确认端口
四、卸载lnmp安装环境
lnmp-uninstall-only/
├── uninstall.sh ← 必须(卸载入口)
├── lnmp.conf ← 必须(uninstall 会 source)
└── include/
├── main.sh ← 必须(Check_DB / Remove_StartUp 等)
└── version.sh ← 建议带上(保险)从你的lnmp脚本安装包里,将这几个脚配文件和conf文件,复制到一个新的目录下,就按照这个层级来存放,并把这目录和文件上传到服务器上,我们需要运行lnmp的卸载脚本来卸载
cd /tmp/lnmp-uninstall-only ls uninstall.sh lnmp.conf include/main.sh bash uninstall.sh # 选 1 = 卸载 LNMP
五、apt安装新的服务
apt-get update apt-get install -y curl ca-certificates gnupg2 lsb-release apt-transport-https apt-get install -y nginx nginx -v systemctl enable nginx systemctl start nginx # 若端口仍被占用,可先 enable,最后 再 start
1、先安装nginx
curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" \ > /etc/apt/sources.list.d/php-sury.list apt-get update apt-get install -y \ php8.3-cli php8.3-fpm php8.3-common \ php8.3-mysql php8.3-xml php8.3-mbstring php8.3-curl \ php8.3-gd php8.3-zip php8.3-opcache php8.3-readline # 按站点需要追加,例如: # apt-get install -y php8.3-imagick php8.3-intl php8.3-bcmath php8.3-soap php -v systemctl enable --now php8.3-fpm ls -l /run/php/php8.3-fpm.sock
2、接着安装PHP
fastcgi_pass unix:/run/php/php8.3-fpm.sock; systemctl reload php8.3-fpm
3、设置用户和用户组,因为lnmp默认使用的是www:www这样的用户和用户组,所以在这里我们也要按照这样来设置
# 若尚无 www 用户则创建(已有可跳过) id www >/dev/null 2>&1 || useradd -r -s /usr/sbin/nologin -d /var/www -M www # PHP-FPM 池 sed -i -E \ 's/^(user|group|listen\.owner|listen\.group) = www-data/\1 = www/' \ /etc/php/8.3/fpm/pool.d/www.conf grep -E '^(user|group|listen\.owner|listen\.group)' /etc/php/8.3/fpm/pool.d/www.conf # Nginx # 将 nginx.conf 中的 user 行改为: # user www www; sed -i -E 's/^user\s+.*/user www www;/' /etc/nginx/nginx.conf grep -E '^user' /etc/nginx/nginx.conf systemctl restart php8.3-fpm nginx -t && systemctl reload nginx
4、接下来安装mysql
# 使用现行 MySQL 官方 GPG 密钥(旧密钥可能过期导致 apt update 失败)
curl -fsSL https://repo.mysql.com/RPM-GPG-KEY-mysql-2025 \
| gpg --dearmor -o /usr/share/keyrings/mysql-archive-keyring.gpg
CODENAME="$(lsb_release -sc)"
cat >/etc/apt/sources.list.d/mysql.list <<EOF
deb [signed-by=/usr/share/keyrings/mysql-archive-keyring.gpg] http://repo.mysql.com/apt/debian ${CODENAME} mysql-8.0
deb [signed-by=/usr/share/keyrings/mysql-archive-keyring.gpg] http://repo.mysql.com/apt/debian ${CODENAME} mysql-tools
EOF
apt-get update
apt-get install -y mysql-community-server
systemctl enable --now mysql
mysql -V
mysql -uroot -p -e "SELECT VERSION();"如果你的系统是debina的时候,安装时要注意
不要装成 MariaDB
Debian 的 default-mysql-server 往往会拉 MariaDB。要 Oracle MySQL 就用官方源装 mysql-community-server。
官方源 GPG 密钥
旧密钥过期会导致 apt update 失败(EXPKEYSIG)。用现行官方密钥再装。
先空实例,再导业务数据
装好后先确认能 mysql -uroot -p 登录,再导入。
不要把旧 LNMP 的物理数据目录直接接到新实例
用 mysqldump 逻辑备份恢复,不要整目录替换 datadir。
用命令挨个库的导入,不要整个库导入。
mysqldump -uroot -p --single-transaction --routines --triggers --databases 库名 \ | gzip -c > 库名.sql.gz
这几项全部装完后用命令检查一下!
nginx -v php -v mysql -V systemctl is-active nginx php8.3-fpm mysql systemctl is-enabled nginx php8.3-fpm mysql ls -l /run/php/php8.3-fpm.sock id www
六、恢复站点、库、证书
vhost 迁到 /etc/nginx/sites-available,证书路径改为 /etc/nginx/ssl/
保留旧 include 习惯时,可做 /etc/nginx/lnmp-compat/(如 anti-scan、rewrite、enable-php-pathinfo、fastcgi)
fastcgi_pass 指向 unix:/run/php/php8.3-fpm.sock
1、指定备份路径,就是前边我闪进行备份的路径,这里设置变量
BK="$(cat /root/server-backup-LATEST.path)" echo "BK=$BK" ls "$BK"
2、新建目录,有一些需要的目录我们需要在这里新建
mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled mkdir -p /etc/nginx/ssl mkdir -p /etc/nginx/lnmp-compat/rewrite mkdir -p /root/old-nginx-conf if [[ -f "$BK/nginx/nginx-conf.tar.gz" ]]; then tar -C /root/old-nginx-conf -xzf "$BK/nginx/nginx-conf.tar.gz" OLD_CONF=/root/old-nginx-conf/conf elif [[ -d "$BK/nginx/conf-copy" ]]; then OLD_CONF="$BK/nginx/conf-copy" else echo "未找到 nginx conf 备份"; exit 1 fi echo "OLD_CONF=$OLD_CONF" ls "$OLD_CONF/vhost"
3、查找lnmp兼容片段
for f in enable-php.conf enable-php-pathinfo.conf fastcgi.conf pathinfo.conf anti-scan.conf; do [[ -f "$OLD_CONF/$f" ]] && cp -a "$OLD_CONF/$f" /etc/nginx/lnmp-compat/ done [[ -d "$OLD_CONF/rewrite" ]] && cp -a "$OLD_CONF/rewrite/." /etc/nginx/lnmp-compat/rewrite/ sed -i -E \ 's|fastcgi_pass[[:space:]]+127\.0\.0\.1:9000;|fastcgi_pass unix:/run/php/php8.3-fpm.sock;|g' \ /etc/nginx/lnmp-compat/enable-php*.conf 2>/dev/null || true sed -i -E \ 's|fastcgi_pass[[:space:]]+unix:/tmp/php-cgi\.sock;|fastcgi_pass unix:/run/php/php8.3-fpm.sock;|g' \ /etc/nginx/lnmp-compat/enable-php*.conf 2>/dev/null || true ls -la /etc/nginx/lnmp-compat/
4、主配置检查
grep -E '^user |sites-enabled' /etc/nginx/nginx.conf
# 确认有:user www www;
# 确认 http{} 内有:include /etc/nginx/sites-enabled/*;
rm -f /etc/nginx/sites-enabled/default5、恢复站点信息,nginx的站点信息
for f in "$OLD_CONF"/vhost/*.conf; do
[[ -f "$f" ]] || continue
[[ "$f" == *.bak* ]] && continue
cp -a "$f" "/etc/nginx/sites-available/$(basename "$f")"
done
for f in /etc/nginx/sites-available/*.conf; do
sed -i \
-e 's|/usr/local/nginx/conf/ssl/|/etc/nginx/ssl/|g' \
-e 's|/usr/local/nginx/cert/|/etc/nginx/ssl/|g' \
-e 's|include[[:space:]]\+rewrite/|include /etc/nginx/lnmp-compat/rewrite/|g' \
-e 's|include[[:space:]]\+enable-php|include /etc/nginx/lnmp-compat/enable-php|g' \
-e 's|include[[:space:]]\+fastcgi\.conf|include /etc/nginx/lnmp-compat/fastcgi.conf|g' \
-e 's|include[[:space:]]\+anti-scan\.conf|include /etc/nginx/lnmp-compat/anti-scan.conf|g' \
-e 's|fastcgi_pass[[:space:]]\+127\.0\.0\.1:9000;|fastcgi_pass unix:/run/php/php8.3-fpm.sock;|g' \
-e 's|fastcgi_pass[[:space:]]\+unix:/tmp/php-cgi\.sock;|fastcgi_pass unix:/run/php/php8.3-fpm.sock;|g' \
"$f"
done
for f in /etc/nginx/sites-available/*.conf; do
ln -sfn "$f" "/etc/nginx/sites-enabled/$(basename "$f")"
done
ls -la /etc/nginx/sites-enabled/6、恢复ssl证书
mkdir -p /etc/nginx/ssl if [[ -d "$BK/nginx/cert-copy" ]]; then cp -a "$BK/nginx/cert-copy/." /etc/nginx/ssl/ elif [[ -f "$BK/nginx/nginx-cert.tar.gz" ]]; then tar -C /etc/nginx/ssl -xzf "$BK/nginx/nginx-cert.tar.gz" elif [[ -d "$OLD_CONF/ssl" ]]; then cp -a "$OLD_CONF/ssl/." /etc/nginx/ssl/ else echo "未找到证书备份,请手动放入 /etc/nginx/ssl/" fi find /etc/nginx/ssl -type f | head -40
7、重启服务器环境
nginx -t # 若旧 LNMP nginx 还在: /usr/local/nginx/sbin/nginx -s quit 2>/dev/null || true sleep 1 systemctl enable nginx systemctl restart nginx systemctl reload php8.3-fpm systemctl is-active nginx php8.3-fpm mysql
七、防跨站设置,lnmp中的防跨站都是在网站根目录下新建一个.user.ini文件,但是转换到apt后,主要是在fastcgi中约定,现在为了兼容lnmp和apt,两个地方都做了设置
fastcgi配置
# 常见位置二选一(有哪个改哪个)
FCGI=""
[[ -f /etc/nginx/lnmp-compat/fastcgi.conf ]] && FCGI=/etc/nginx/lnmp-compat/fastcgi.conf
[[ -z "$FCGI" && -f /etc/nginx/fastcgi.conf ]] && FCGI=/etc/nginx/fastcgi.conf
[[ -n "$FCGI" ]] || { echo "未找到 fastcgi.conf,请指定路径"; exit 1; }
echo "使用: $FCGI"
cp -a "$FCGI" "${FCGI}.bak.$(date +%Y%m%d%H%M%S)"
# 删除旧的 open_basedir 行(含过宽的 /var/www/html)
sed -i '/PHP_ADMIN_VALUE.*open_basedir/d' "$FCGI"
# 收紧:仅本站 document_root + tmp/proc + MySQL sock
cat >> "$FCGI" <<'EOF'
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/tmp/:/proc/:/run/mysqld/:/var/run/mysqld/";
EOF
grep open_basedir "$FCGI"
nginx -t && systemctl reload nginx
systemctl reload php8.3-fpm.user.ini配置
# 自动遍历 /home/wwwroot 下一级目录(按实际结构改)
for d in /home/wwwroot/*/; do
d="${d%/}"
[[ -d "$d" ]] || continue
# 跳过明显非站点目录(可按需增删)
base=$(basename "$d")
[[ "$base" == "logs" || "$base" == "default" ]] && continue
chattr -i "$d/.user.ini" 2>/dev/null || true
cat > "$d/.user.ini" <<EOF
open_basedir=${d}/:/tmp/:/proc/:/run/mysqld/:/var/run/mysqld/
EOF
chown www:www "$d/.user.ini" 2>/dev/null || chown www-data:www-data "$d/.user.ini"
chmod 644 "$d/.user.ini"
chattr +i "$d/.user.ini"
echo "---- $d/.user.ini ----"
lsattr "$d/.user.ini"
cat "$d/.user.ini"
done到这一步,我们的服务器无缝迁移的工作就算完成了。大家可以重启一下环境。
nginx -t && systemctl reload nginx systemctl reload php8.3-fpm
发布时 IP 属地:海南省海口市


0 条评论
表情面板
您的邮箱地址和手机号码不会被公开。 必填项已用 * 标注