跳转到帖子
在手机APP中查看

一个更好的浏览方法。了解更多

PHP论坛人

主屏幕上的全屏APP,带有推送通知、徽章等。

在iOS和iPadOS上安装此APP
  1. 在Safari中轻敲分享图标
  2. 滚动菜单并轻敲添加到主屏幕
  3. 轻敲右上角的添加按钮。
在安卓上安装此APP
  1. 轻敲浏览器右上角的三个点菜单 (⋮) 。
  2. 轻敲添加到主屏幕安装APP
  3. 轻敲安装进行确认。

Debian 13 自動安全更新

精选回复

適用環境

作業系統:Debian 13

VPS規格:2 vCPU / 2GB RAM

權限要求:需具備 root 權限或 sudo 權限

網路需求:需能連線至 Debian 官方套件庫





----------
前言
----------

對於長期運行的論壇網站,自動安全更新是降低人工維護成本、及時修補已知漏洞的第一道防線

然而,不加控制的自動更新同樣可能破壞生產環境,例如,核心升級觸發重開機、PHP版本跳升導致擴充套件相容性斷裂等

本文的目標是在「及時修補安全漏洞」與「維持服務穩定」之間取得平衡,並提供足夠的監控機制讓團隊掌握每一次更新的狀態


-----------------------
事前準備與快照備份
-----------------------

強烈建議:在任何系統層級變更前,先對VPS建立快照(Snapshot)或映像備份

這是生產環境的基本操作紀律,不論操作多熟練皆不應跳過


---------------------
確認目前系統版本
---------------------

cat /etc/os-release


uname -r



預期輸出

PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
...
6.12.xx+deb13-cloud-amd64






----------------------------
確認APT套件庫來源正常
----------------------------

apt update


若出現 404 Not Found 或 GPG 錯誤,必須先修正 /etc/apt/sources.list 再繼續,否則後續步驟都無意義


Debian 13 標準 sources.list 參考

deb http://deb.debian.org/debian trixie main contrib non-free-firmware
deb http://deb.debian.org/debian trixie-updates main contrib non-free-firmware
deb http://security.debian.org/debian-security trixie-security main contrib non-free-firmware


---------------------
全面更新現有套件
---------------------

在設定自動更新前,應先手動將系統更新至最新狀態,確保基線一致

apt update -y && apt full-upgrade -y




關於 full-upgrade   vs   upgrade 的差異

指令:apt upgrade
說明:僅更新可直接升級的套件,不處理相依性衝突

指令:apt full-upgrade
說明:可在必要時移除或新增套件以解決相依問題,適合版本跨越升級


提示:升級過程若出現「是否覆蓋設定檔?」提示,建議選 N(保留原有設定)

避免覆蓋 /etc/nginx/nginx.conf、/etc/mysql/ 等自訂組態



-------------------------
升級後清理多餘套件
-------------------------

apt autoremove --purge -y


apt clean



----------------------
安裝必要套件
----------------------

apt install -y unattended-upgrades apt-listchanges needrestart







說明:
unattended-upgrades  自動安全更新的核心引擎

apt-listchanges  更新前顯示套件變更摘要,有助於審閱 changelog

needrestart  偵測哪些服務使用了已更新的函式庫,提示需重啟的服務


新手容易遺漏:needrestart 是避免「套件已更新但舊版函式庫仍在記憶體中執行」的關鍵工具

例如 OpenSSL 更新後,若 Nginx 未重啟,仍會繼續使用舊版 libssl,安全修補形同虛設




------------------------
啟用自動安全更新
------------------------

啟用自動安全更新
dpkg-reconfigure --priority=low unattended-upgrades



畫面將出現:
Automatically download and install stable updates?
<Yes> /  <No>


選擇 <Yes>,確認啟用自動下載並安裝穩定版更新



-----------------------------------
設定更新來源規則(僅安全更新)
-----------------------------------

此檔案定義哪些套件庫的更新會被自動安裝,以及各項行為控制



寫入生產環境設定
vi /etc/apt/apt.conf.d/50unattended-upgrades



貼上以下內容



// =========================
// 自動安全更新設定 - LNMP 環境
// 最後修改:請填入日期與操作人員
// =========================

Unattended-Upgrade::Origins-Pattern {
    // Debian 官方穩定版
    "origin=Debian,codename=${distro_codename},label=Debian";
    // Debian 安全更新(兩種格式皆需保留,視 Debian 版本而定)
    "origin=Debian,codename=${distro_codename},label=Debian-Security";
    "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
};

// 套件黑名單:以下套件不會被自動更新
Unattended-Upgrade::Package-Blacklist {
    // 核心:自動更新核心可能觸發重開機或模組相容性問題
    "linux-image-*";
    "linux-headers-*";
    "linux-modules-*";

    // PHP:版本跳升可能破壞論壇擴充套件(如 IPS、XenForo)
    // 若確認論壇相容,可移除以下黑名單項目
    "php*";

    // MySQL / MariaDB:主版本升級需要手動 schema 遷移
    "mysql-server*";
    "mariadb-server*";

    // Nginx:主要設定變更需人工確認
    // 安全性修補通常可接受,依環境決定是否保留此黑名單
    // "nginx*";
};

// 是否自動重開機(生產環境強烈建議 false)
Unattended-Upgrade::Automatic-Reboot "false";

// 若上方設定為 true,指定重開機時間(避開尖峰時段)
Unattended-Upgrade::Automatic-Reboot-Time "08:00";

// 是否允許在有使用者登入時自動重開機
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";

// 自動移除已不需要的核心套件(節省 /boot 空間)
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

// 自動移除更新後不再需要的相依套件
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";

// 自動移除已廢棄套件
Unattended-Upgrade::Remove-Unused-Dependencies "true";

// 寄送更新通知 Email(需有 MTA,如 msmtp / postfix)
// Unattended-Upgrade::Mail "your-sre-team@example.com";
// Unattended-Upgrade::MailReport "on-change";  // only-on-error | on-change | always

// 分割差異:僅在發生錯誤時寄信(減少通知噪音)
Unattended-Upgrade::MailOnlyOnError "true";

// 詳細日誌(建議 production 環境開啟,便於事後審計)
Unattended-Upgrade::Verbose "false";

// 最小化 APT 輸出(減少日誌雜訊)
Unattended-Upgrade::MinimalSteps "true";




儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter



提醒:php* 黑名單在論壇環境非常重要

Debian 安全更新有時會一併跳升 PHP 次版本(如 8.2 → 8.3)

可能導致舊版論壇外掛或 composer.lock 鎖定的套件出現相容性問題,應先在測試環境驗證後再手動升級



------------------------
啟用自動更新排程
------------------------

APT的定期排程由 apt.conf.d/20auto-upgrades 控制


編輯
vi /etc/apt/apt.conf.d/20auto-upgrades


貼上以下內容



// 每天更新套件清單
APT::Periodic::Update-Package-Lists "1";

// 每天下載可升級的套件(但不安裝,由 Unattended-Upgrade 控制)
APT::Periodic::Download-Upgradeable-Packages "1";

// 每 7 天自動清除已下載但不再需要的套件快取
APT::Periodic::AutocleanInterval "7";

// 每天執行自動更新(值為間隔天數)
APT::Periodic::Unattended-Upgrade "1";





儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter




----------------------------------------------------
重啟 unattended-upgrades 服務使設定生效
----------------------------------------------------

啟用
systemctl enable unattended-upgrades



重啟
systemctl restart unattended-upgrades



確認服務狀態,預期輸出應包含 active (running)
systemctl status unattended-upgrades



------------------------------------------------
確認 needrestart 設定(避免服務靜默中斷)
------------------------------------------------

needrestart 在套件更新後自動偵測哪些服務仍在使用舊版函式庫,是LNMP環境特別重要的環節


-----------------
查看預設設定
-----------------

cat /etc/needrestart/needrestart.conf | grep -v '^#' | grep -v '^$'


------------------
調整重啟模式
------------------

編輯
vi /etc/needrestart/needrestart.conf


搜尋
$nrconf{restart}


接著修改以下設定(生產環境建議使用 i 互動模式)


# 模式說明
# l = list only(僅列出,不重啟)← 生產環境推薦,人工確認後再重啟
# i = interactive(互動詢問)
# a = automatically(自動重啟服務,不含核心)← 可接受,但需謹慎
$nrconf{restart} = 'l';



建議:若論壇有 SLA 要求,應使用 l 模式,搭配後述的 Cron 監控,由維運人員在離峰時段手動重啟



---------------------------------
手動檢查需要重啟的服務
---------------------------------

needrestart -k


輸出示範:
NEEDRESTART-VER: 3.x
NEEDRESTART-SVC: nginx.service
NEEDRESTART-SVC: php8.3-fpm.service
NEEDRESTART-SVC: mariadb.service



看到以上輸出時,依序重啟(建議在低流量時段執行)


systemctl restart nginx


systemctl restart php8.3-fpm


systemctl restart mariadb





-----------------------------
重啟後確認各服務狀態
-----------------------------

systemctl status nginx php8.3-fpm mariadb



--------------------
重開機驗證
--------------------

初次設定完成後建議重開機,確保核心與服務以乾淨狀態啟動


重開機
reboot




重開機後驗證清單


確認自動更新服務正在運行,應顯示 active (running)
systemctl status unattended-upgrades



確認排程設定正確載入
apt-config dump APT::Periodic



預期顯示
APT::Periodic "";
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";








模擬執行自動更新(--dry-run 不會實際安裝套件)
unattended-upgrade --dry-run --verbose




確認LNMP核心服務正常 (此時還未安裝LNMP服務)
systemctl status nginx


systemctl status php8.3-fpm


systemctl status mariadb




確認論壇網站可正常回應 (此時還未安裝LNMP服務)
curl -I http://localhost





----------------------------------------
強制執行一次完整更新(驗證流程)
----------------------------------------

unattended-upgrade --verbose


執行後

查看日誌確認無錯誤
tail -50 /var/log/unattended-upgrades/unattended-upgrades.log



-----------------------------
監控自動更新執行狀態
-----------------------------

啟用
systemctl enable cron


啟動
systemctl start cron



檢查狀態,確認已運行 active (running)
systemctl status cron

---------------------

建立監控腳本

---------------------

比起直接在 crontab 寫複雜指令,建議將監控邏輯封裝成獨立腳本,方便維護與版本控管

建立

vi /usr/local/bin/check-unattended-upgrades.sh

check-unattended-upgrades.sh

貼上以下內容

儲存檔案並離開vi編輯器

按 Esc,輸入 :wq,按 Enter

本帖最后于,由Jack编辑

  • 楼主
--------------------
給予執行權限
--------------------

chmod +x /usr/local/bin/check-unattended-upgrades.sh


chown root:root /usr/local/bin/check-unattended-upgrades.sh



-------------------------------
設定 Cron 排程
-------------------------------

編輯
crontab -e


在未尾加入以下內容



# ====================
# 自動更新監控排程
# ====================

# 每天早上 7:00 檢查自動更新是否有錯誤
0 7 * * * /usr/local/bin/check-unattended-upgrades.sh

# 每天早上 6:00 檢查 needrestart(列出需重啟服務但不自動重啟)
0 6 * * * /usr/sbin/needrestart -k >> /var/log/needrestart-daily.log 2>&1





儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter

------------------------
驗證監控腳本
------------------------

/usr/local/bin/check-unattended-upgrades.sh







--------------------------
定期維護建議
--------------------------

查看日誌目錄
ls -lah /var/log/unattended-upgrades/


即時監看日誌
tail -f /var/log/unattended-upgrades/unattended-upgrades.log


查看詳細除錯日誌
tail -f /var/log/unattended-upgrades/unattended-upgrades.log.1


建議每週至少檢查一次,確認:
無 ERROR 字樣
有正常的 Packages that will be upgraded: 記錄(或「無可用更新」)
更新時間點符合預期




unattended-upgrades 的日誌自帶 logrotate 設定,通常不需額外設定。確認方式:

cat /etc/logrotate.d/unattended-upgrades






---------------------------------------
定期清理舊核心(釋放 /boot 空間)
---------------------------------------

僅在確認新核心運作正常後執行(重開機後驗證 uname -r 版本)


查看目前使用的核心
uname -r


列出所有已安裝核心
dpkg --list | grep linux-image


自動移除舊核心(保留當前使用版本)
apt autoremove --purge -y



--------------------------
手動檢查安全性 CVE
--------------------------

自動更新補的是套件層級的安全修補,但部分 CVE 需要手動確認影響範圍:


查看 Debian Security Tracker(需連網)
https://security-tracker.debian.org/tracker/



本機檢查哪些套件有可用的安全更新
apt list --upgradable 2>/dev/null | grep -i security



-----------------------
測試環境先行原則
-----------------------

對於任何計畫性的手動升級(特別是黑名單中的 PHP、MariaDB、Nginx),務必遵循:

測試環境驗證 → 確認服務正常 → 安排維護時窗 → 生產環境升級 → 監控 15分鐘
  • 楼主
-------------------
常見問題排除
-------------------

問題一:服務未自動更新

確認服務狀態
systemctl status unattended-upgrades



若未啟動,手動啟動
systemctl start unattended-upgrades


systemctl enable unattended-upgrades




確認排程設定
apt-config dump APT::Periodic::Unattended-Upgrade






問題二:套件被保留(held back)


查看被保留的套件
apt-mark showhold


查看升級摘要
apt upgrade --simulate


手動處理相依性問題
apt full-upgrade


原因說明:套件被保留通常是因為升級需要移除或新增其他套件,apt upgrade 不會自動處理,須用 full-upgrade




問題三:更新失敗(網路問題)

確認 DNS 解析正常
host deb.debian.org


測試套件庫連線
curl -I http://deb.debian.org/debian/dists/trixie/Release


重建套件快取
apt clean

apt update




問題四:/boot 空間不足導致核心更新失敗

查看 /boot 使用狀況
df -h /boot

ls -lah /boot/


確認目前使用的核心版本
uname -r


移除舊核心(請確認要移除的版本不是目前使用中的)
apt autoremove --purge linux-image-<舊版本號>






問題五:unattended-upgrades 鎖定(lock file 問題)

確認是否有 lock 檔
ls -la /var/lib/dpkg/lock*

ls -la /var/lib/apt/lists/lock



確認是否有 apt 進程在執行
ps aux | grep apt



若無相關進程但 lock 仍存在(系統崩潰後的殘留)
確認無 apt 進程後再執行
rm /var/lib/dpkg/lock-frontend


rm /var/lib/dpkg/lock


dpkg --configure -a





問題六:更新後 Nginx / PHP-FPM / MariaDB 無法啟動

查看各服務錯誤日誌
journalctl -xe -u nginx --since "1 hour ago"


journalctl -xe -u php8.3-fpm --since "1 hour ago"


journalctl -xe -u mariadb --since "1 hour ago"




測試 Nginx 設定檔語法
nginx -t


測試 PHP-FPM 設定
php-fpm8.3 --test



若為設定檔被覆蓋導致,從備份恢復 (這也是為什麼升級時要選 N 保留原有設定)





---------------------------------
LNMP 論壇環境特別注意事項
---------------------------------

PHP 版本管理

論壇軟體(IPS、XenForo 等)對 PHP 版本相依性非常敏感

建議將 PHP 相關套件加入黑名單,並採用手動控制PHP版本升級的策略


查看目前安裝的 PHP 套件
dpkg --list | grep php


手動鎖定特定 PHP 版本(避免自動升級)
apt-mark hold php8.3 php8.3-fpm php8.3-mysql php8.3-common



確認鎖定狀態
apt-mark showhold



--------------------------------
MariaDB / MySQL 保護
--------------------------------

資料庫的主版本升級(如 MariaDB 10.x → 11.x)需要執行 mysql_upgrade 或 mariadb-upgrade,否則可能導致資料字典不一致

絕對不能讓自動更新自行完成主版本跳升

鎖定 MariaDB
apt-mark hold mariadb-server mariadb-client mariadb-common



------------------------
Nginx 安全更新策略
------------------------

Nginx 的安全更新風險相對低,但仍可能因 header 行為變更影響論壇的 CSP / CORS 設定

建議:
移除 50unattended-upgrades 中 Nginx 的黑名單註解(讓安全更新自動安裝)

但在 Cron 監控中加入 Nginx 重啟後的健康檢查




------------------------------
記憶體考量(2 GB RAM)
------------------------------

2GB RAM 的 VPS 在自動更新期間(通常在凌晨),系統負載會短暫升高

建議在 50unattended-upgrades 中確認 MinimalSteps "true" 已啟用,讓更新分批執行,降低記憶體峰值壓力


同時確認論壇的 PHP-FPM 設定合理

查看 PHP-FPM 進程設定(避免 OOM)
cat /etc/php/8.3/fpm/pool.d/www.conf | grep -E "pm\.|max_children|memory"



建議 pm.max_children 不超過 (可用記憶體 MB / 平均每個 PHP 進程記憶體) 的計算結果

在 2GB 環境下,若 MariaDB + Nginx 各佔約 200 MB,PHP-FPM 可用約 1.2 GB,建議 pm.max_children = 10~15(視每個進程實際用量而定)



--------------------------
附錄:快速驗證清單
--------------------------

完成所有設定後,執行以下快速驗證:


1. 自動更新服務正常運行
systemctl is-active unattended-upgrades


2. 排程設定正確
apt-config dump APT::Periodic



3. 更新來源設定無語法錯誤
apt-config dump | grep -A 20 "Unattended-Upgrade::Origins"



4. 乾跑測試無錯誤
unattended-upgrade --dry-run --verbose 2>&1 | tail -20



5. LNMP 服務全部正常
for svc in nginx php8.3-fpm mariadb; do
    echo -n "$svc: "
    systemctl is-active $svc
done



6. 監控腳本可正常執行
/usr/local/bin/check-unattended-upgrades.sh && cat /var/log/unattended-upgrades-last-run.txt



7. 確認黑名單套件已鎖定
apt-mark showhold

创建帐户或登录后发表意见

帐户

导航

搜索

搜索

配置浏览器推送通知

Chrome (安卓)
  1. 轻敲地址栏旁的锁形图标。
  2. 轻敲权限 → 通知。
  3. 调整你的偏好。
Chrome (台式电脑)
  1. 点击地址栏中的挂锁图标。
  2. 选择网站设置。
  3. 找到通知选项并调整你的偏好。