Linux服务器维护清单:每周、每月检查与版本升级
按周和按月检查更新、磁盘、服务、证书、账户、内核与日志,规划发行版升级,并执行多数人跳过的备份恢复测试,避免漏洞、磁盘耗尽和无法恢复。
Linux 服务器维护的实际内容
Linux 服务器维护是一组按固定计划执行的检查,而不是一个永远不会结束的项目。每周确认更新已安装、磁盘空间充足、没有服务停止运行,以及备份任务已完成。每月测试一次恢复流程,检查证书到期时间,审计账户和密钥,并清理旧内核和日志。每次发行版发布新版本时,规划版本升级,并执行一直推迟的重启。
构建服务器是另一项工作,新 VPS 上的前 10 分钟介绍了这部分内容。本页介绍的是之后一整年的维护工作。下面的每一项都说明它要防止的故障,因为没有明确后果的检查清单,最终会被人悄悄停止执行。
这里的命令仅供示例,运行前应先阅读。请将命令输出与您自己的服务器进行比较,因为磁盘可用空间或进程数的健康值取决于服务器的用途。不同发行版的检查方式不同时,文中会明确说明。示例使用 Debian 和 Ubuntu,以及 apt。在 RHEL 系列中,工具是 dnf,并且有多个路径不同。
如何选择并坚持执行 Linux 服务器维护周期
每周检查应覆盖那些无需人工操作就会发生变化的项目:软件包、磁盘使用率、服务状态和计划任务。这些项目会自行变化,因此最长不应超过一周不检查。
每月检查应覆盖缓慢发生的问题:即将到期的证书、无人清理的账户、在 /boot 中不断累积的内核,以及增长到超出轮换规则范围的日志文件。它们通常不会明天就导致故障,但最终都会导致故障。
版本发布检查由日历驱动。发行版版本是唯一具有外部截止日期的维护项目,因为当前版本的支持期限会结束,无论您是否已经准备好。
为检查安排固定时间段,例如周一上午进行每周检查,每月第一天进行每月检查。等“有时间再做”的检查不算检查清单。管理少量机器后,应从一个位置统一执行这些检查,而不是手动逐台执行;相关内容请参阅从一个位置管理多台 Linux 服务器。
每周检查:更新是否实际安装?
启用 unattended-upgrades 不等于确认它已经运行。该服务可能被屏蔽,配置可能仅允许使用您未配置的源,或者某个被保留的软件包导致之后的每次运行都失败。安装方法请参阅Ubuntu 上的自动安全更新。每周任务要验证的是:已安装的自动化机制确实完成了工作。
systemctl status unattended-upgrades
journalctl -u unattended-upgrades --since "8 days ago" --no-pager
sudo tail -n 50 /var/log/unattended-upgrades/unattended-upgrades.log
apt list --upgradable
apt-mark showholdapt list --upgradable 才是准确的衡量标准,因为它报告的是当前状态,而不是预期行为。仍列在其中的安全更新表示自动化机制未正常工作,因此在确认系统已打补丁前,应先查看日志。使用 apt-mark hold 固定的软件包会永久跳过更新,且不会报告任何信息,因此应在同一轮检查中检查 apt-mark showhold。
这样可以避免以下故障:用户以为更新会自动安装,却让存在已知漏洞的软件包运行数月。
每周:磁盘和 inode 余量
根文件系统已满,会导致许多看似与磁盘无关的问题。数据库拒绝写入,日志记录停止,软件包升级在完成部分配置后失败;在某些环境中,系统甚至无法打开新会话,因为无法写入自身文件。
df -h
df -i
sudo du -xh --max-depth=1 / | sort -h | tail -20df -i是大多数人会跳过的检查。inode 是用于保存文件元数据的固定数量结构。文件系统可能耗尽 inode,即使 df -h 仍显示有数 GB 可用空间。此时写入会失败,并在输出中显示 No space left on device,同时旁边仍有剩余空间。第一次遇到这种情况时,通常会花费很长时间排查。卡住的邮件队列,或无人清理的会话目录,产生的大量小文件通常是原因。
du -xh只检查同一文件系统中的空间。在使用 bind mount 或附加存储的服务器上,这正是所需行为。对于 Docker 主机,问题通常出在镜像层和无用卷中。清理方法请参阅 在 VPS 上清理 Docker 磁盘占用。
可用空间反映的是容量。底层存储可能按自己的时间表发生故障,因此需要单独检查。相关内容请参阅 在 VPS 上监控磁盘健康状况。
每周检查:哪些服务在未通知您的情况下停止了?
systemctl list-units --state=failed
systemctl list-timers --all
journalctl -p err --since "8 days ago" --no-pager崩溃并达到重启次数上限的单元会进入 failed 状态,并一直停留在那里,不会主动提示您。系统不会通过电子邮件通知您。list-timers 更有用的一点是:它会显示每个定时器上次运行的时间和下次触发的时间。因此,如果 LAST 的值早于该定时器自身的间隔,就表示该任务根本没有运行。
重启单元前,先使用 journalctl -u <unit> -n 100 --no-pager 查看其 journal。重启只能清除表面症状,之后您可能不会再检查,直到同样的问题在更不合适的时间再次发生。
这样可以避免以下故障:监控代理、队列工作进程或备份服务在三周前的一次内存峰值后就一直停止运行。
每周:备份任务确实完成了吗?
已调度备份与已完成备份是两回事,只有后者可以用于恢复。请检查完成状态。
systemctl list-timers --all | grep -i backup
journalctl -u <your-backup-unit> --since "8 days ago" --no-pager
ls -lh /path/to/backup/target | tail确认两点。最近一次运行以零退出,并且最新归档文件既足够新,大小也大致符合预期。备份文件如果突然只有平时大小的十分之一,说明转储失败但仍写入了文件。这是最危险的备份失败形式,因为后续流程看起来都正常。
如果脚本将转储输出通过管道传给压缩程序,请在开头添加 set -o pipefail。否则,管道的退出状态取决于压缩程序,而压缩程序确实成功了:它只是压缩了错误消息。这样,任务每晚都会报告成功,同时写入一个内容为空的小型归档文件。
每月:在其他位置恢复备份
这是大多数人会跳过的项目,也是决定前面清单是否有意义的项目。
将备份恢复到另一台机器或全新的容器中,绝不要覆盖正在使用的数据。然后打开恢复的数据,确认内容真实有效。统计表中的行数。打开一个文档。登录恢复的应用。提取过程顺利完成,只能证明归档可读取,不能证明其他任何事情。
存储库工具有自己的验证方式:restic check --read-data-subset=5% 和 borg check --verify-data 读取已存储的数据,而不是索引。运行这些命令,并将其视为冒烟测试,而不是替代方案。验证只能确认字节未丢失。恢复则能确认这些字节是应用实际需要的数据。
有两个细节,很多人都是吃了亏才学会。请在不会通过 agent 预先持有密钥的机器上测试解密口令,因为无法解密的备份就不能算备份。还要记录恢复所需的时间,因为这才是实际恢复时间;而通常发现恢复时间不够的时刻,正是服务中断期间。
每月:哪些证书即将过期?
续期自动化可能会静默失败。certbot timer 可能已经续期磁盘上的证书文件,但 Web 服务器仍从内存中提供旧证书,因为用于重新加载服务的 deploy hook 没有运行。因此,应从服务器外部查询运行中的服务器实际提供的证书。
sudo certbot certificates
systemctl list-timers --all | grep -i certbot
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates-servername标志用于设置 SNI(服务器名称指示)。任何托管多个站点的地址都必须设置该标志,否则返回的会是默认证书,而不是您的证书。如果 certbot 是通过 snap 安装的,timer 的名称会有所不同,因此应匹配名称中的单词,而不要假定某个 unit 名称。
还要记得检查完全没有自动化续期的证书:邮件服务器证书、VPN 证书和内部证书颁发机构证书。这些证书可能在周末过期,而浏览器和客户端会直接拒绝它们,不会仅显示警告。
每月:用户、sudo 访问权限和 SSH 密钥
awk -F: '$3>=1000 && $3<65534 {print $1}' /etc/passwd
getent group sudo
sudo find /home /root -name authorized_keys -exec ls -l {} +
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication|port'
last -n 25sshd -T 会在合并每个 Include 后打印生效配置,这就是守护进程实际使用的配置。新版 Ubuntu 镜像会在 /etc/ssh/sshd_config.d/ 中提供 drop-in 文件,这些文件可能覆盖主配置文件。因此,仅查看 sshd_config 可能得到完全相反的结论。在 RHEL 系列系统中,管理组是 wheel,而不是 sudo,因此请相应调整 getent 行。
然后直接检查 authorized_keys 文件。访问权限由密钥授予,而不是由账户授予。因此,承包商在六个月前结束工作后遗留的密钥仍可用于登录,用户列表不会标记这种情况。密钥包含注释字段。请使用该字段,并删除所有无法归属到具体人员的密钥。
检查登录历史时,journalctl -t sshd --since "30 days ago" | grep -i accepted 根据 syslog 标识符匹配,而不是根据单元名称匹配。这一点很重要,因为 Ubuntu 24.04 通过 socket 激活 SSH,所以每个连接都会记录在按连接生成的单元下,直接使用 journalctl -u ssh 可能会遗漏这些记录。
每月:旧内核和已满的 /boot
/boot 在标准 VPS 镜像中通常是一个独立分区,容量只有几百 MB。每次内核更新都会向其中添加一个内核映像和一个 initramfs。该分区填满后,下一次升级会中途失败,并留下未配置的软件包;如果周五突然遇到这种情况,会造成严重问题。
uname -r
df -h /boot
dpkg -l 'linux-image-*' | grep '^ii'
sudo apt autoremove --purgeuname -r 始终先执行:它会显示当前正在运行的内核,而该内核必须在清理操作中保留。对于 Debian 和 Ubuntu,apt autoremove 可以处理常规情况,因为内核会标记为自动安装,当前内核也会受到保护。对于手动安装的内核,或已经足够满、导致 apt 自身无法运行的 /boot,请参阅在 Ubuntu 上清理旧内核。
每月:日志增长与 systemd journal
journalctl --disk-usage
sudo du -xh --max-depth=1 /var/log | sort -h | tail
sudo logrotate --debug /etc/logrotate.conflogrotate --debug 是试运行,不会写入任何内容,因此可安全地在运行中的服务器上执行。建议运行此命令,因为轮转规则按路径匹配:应用在升级期间更改日志位置后,将不再匹配自身的规则,该文件会无限增长,直到占满磁盘。
systemd 会限制 journal 的大小,但限制值取决于文件系统容量的一定比例,而不是您指定的固定数值。如果需要设置明确的上限,请在 /etc/systemd/journald.conf 中设置 SystemMaxUse=,然后重启 systemd-journald。sudo journalctl --vacuum-time=14d 会立即回收空间,但它是一次性操作,不是持久化策略,因此应与配置更改配套使用。
每次发布:不断推迟的重启
磁盘上的更新内核软件包并不是正在运行的内核。在重启之前,机器仍运行旧内核;即使环境支持实时修补,它也只能覆盖部分修复。
uname -r
ls -l /var/run/reboot-required
cat /var/run/reboot-required.pkgs
sudo needrestart该标志文件是 Debian 和 Ubuntu 遵循的约定,由软件包脚本写入。RHEL 系列系统不会创建此文件。在这些系统上,应通过 needs-restarting -r 提出等效问题;该命令来自 dnf-utils。needrestart 默认安装在近期的 Ubuntu 服务器映像中,可进一步检查低于内核的层级:它会列出仍映射磁盘上已被替换的库的进程。因此,修补后的 OpenSSL 要到使用它的服务重启后才会生效。
请安排重启,而不是回避重启。在 /etc/apt/apt.conf.d/50unattended-upgrades、Unattended-Upgrade::Automatic-Reboot "true"; 和 Unattended-Upgrade::Automatic-Reboot-Time "03:00"; 中,将决定交给您指定的时间。计划内重启也是验证机器能否恢复运行的唯一测试,因为错误的 fstab 条目或从未启用的服务,会在启动时暴露问题,其他时候则不会。
按版本规划发行版升级
Ubuntu LTS 版本提供五年的标准支持,临时版本提供九个月的标准支持,因此这个选择会影响您未来数年的升级工作量。相关权衡请参阅 服务器上的 LTS 与临时版本。
lsb_release -a
cat /etc/update-manager/release-upgradesdo-release-upgrade 会读取该文件,Prompt=lts 会将范围限制为仅执行 LTS 到 LTS 的升级。LTS 到 LTS 的升级路径通常会在新版本的第一个点版本发布时开放,而不是在版本正式发布当天开放。因此,请检查您的计算机实际提供的升级选项,不要根据假定日期制定计划。升级过程详见 将 Ubuntu 24.04 升级到 26.04。
预留三个月的缓冲时间。创建一个已测试还原流程的快照,列出第三方 apt 软件源(升级会禁用这些软件源,而且每个软件源都需要为新版本配置新的目标),并在开始前确定回滚方案。截至 August 2026,Ubuntu 24.04 LTS 的标准支持将持续到 April 2029,因此这属于排期工作,不是紧急事项。
要自动化的事项,以及应保留手动执行的事项
将已经确定的决策自动化:安全更新、日志轮换、证书续期和备份任务。告警也应自动化,因为依赖您记得执行的检查,在凌晨 2 点不会自动发生。外部监控工具,例如使用 Uptime Kuma 自托管状态监控,可以发现主机无法访问这一问题。任何主机内脚本都无法报告主机本身已无法访问。
保留两项手动执行:恢复测试和账户审计。这两项都需要由人员判断结果是否正确。如果您更愿意在浏览器中查看机器状态,而不是使用终端,请参阅Cockpit 与 Webmin 的服务器管理对比,了解这两个常用 Web 控制台的区别。
自动化本身也需要检查。因此,此列表中的第一项每周任务是验证更新程序。静默失败的自动化比没有自动化更糟,因为它同时消除了故障提示和定期检查的习惯。
完整检查清单
每周和每月命令,可直接复制
# weekly
systemctl list-units --state=failed
systemctl list-timers --all
journalctl -u unattended-upgrades --since "8 days ago" --no-pager
apt list --upgradable
apt-mark showhold
df -h
df -i# monthly
sudo certbot certificates
awk -F: '$3>=1000 && $3<65534 {print $1}' /etc/passwd
getent group sudo
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication'
uname -r
dpkg -l 'linux-image-*' | grep '^ii'
journalctl --disk-usage此处特意未包含恢复测试。恢复测试不是一条命令,也不应在同一台机器上执行。请在其他位置执行恢复,然后打开数据并确认数据有效。
FAQ
我应该多久执行一次 Linux 服务器维护?
对于会自行变化的项目,应每周检查:更新状态、磁盘和 inode 余量、失败的单元,以及备份任务是否完成。对于缓慢恶化的项目,应每月检查:恢复测试、证书过期时间、账户和 SSH 密钥审核、旧内核以及日志增长情况。每次发行版发布后执行一次版本升级,并重启以使用当前内核。运行正常的服务器每周检查只需几分钟,这正是应每周执行,而不是等出现异常后再执行的原因。
备份任务报告成功后,为什么还要测试恢复?
因为任务报告的是自身的退出状态,而该状态为成功时,归档文件仍可能不可用。将转储通过管道传给压缩程序时,如果没有 set -o pipefail,返回的是压缩程序的状态。因此,转储失败但只生成错误消息时,命令仍会以零状态退出,并写入一个很小的文件。将数据恢复到另一台机器,打开数据,并统计一项内容。恢复过程还会记录自身耗时,该时长才是实际恢复时间。
每次更新内核后都必须重启吗?
必须在新内核成为正在运行的内核之前重启。在 Debian 和 Ubuntu 上,存在 /var/run/reboot-required 表示某个软件包要求重启,/var/run/reboot-required.pkgs 用于指出具体原因。在 RHEL 系列中,该文件不存在;needs-restarting -r 从 dnf-utils 获取信息,并回答同一问题。应在 /etc/apt/apt.conf.d/50unattended-upgrades 中设置自动重启时间窗口,而不是无限期推迟。因为一台一年未重启的机器不仅运行着旧内核,其启动路径也未经测试。
哪些检查可以安全地自动化?
自动执行已经确定处理方式的操作:安全更新、日志轮换、证书续期和计划备份。通知也应自动化,这样失败的单元或正在填满的磁盘无需人工运行命令就能通知您。恢复测试和密钥审核应保留手动执行,因为这两项都需要人员判断结果是否正确。还应增加一项针对自动化本身的检查,因为更新程序静默失败时,看起来与一切正常完全相同。