努力
加油

云服务器使用Ubuntu系统时,如何配置安全更新和自动升级?

在云服务器上使用 Ubuntu,配置自动安全更新和升级是运维中最基础也最关键的一环。很多新手容易把“安全补丁”和“常规版本升级”混为一谈,导致要么服务器裸奔,要么因为内核或核心库升级导致服务重启甚至崩溃。

作为过来人,我直接给出最稳妥、生产环境常用的方案:只开启未雨绸缪(Unattended Upgrades)的安全补丁自动安装,关闭非必要的常规升级,并配合云厂商的快照机制。

以下是具体操作步骤和避坑指南:

1. 核心工具:unattended-upgrades

Ubuntu 自带的 unattended-upgrades 包就是专门干这个活的。它默认已经预装,但默认行为可能是禁用的或者配置不全。

第一步:安装依赖(如果尚未安装)

sudo apt install unattended-upgrades apt-listchanges

注:apt-listchanges 可选,但它能在升级前记录变更日志,方便事后审计,强烈建议安装。

第二步:修改配置文件

编辑 /etc/apt/apt.conf.d/50unattended-upgrades 文件。

关键配置点:

  1. 启用自动重启(谨慎使用):
    找到 Unattended-Upgrade::Automatic-Reboot,默认为 false。

    • 建议:保持为 false。除非你确定你的应用支持无感重启且内核升级不会导致业务中断,否则不要让它自动重启服务器。手动重启可控性更强。
    • 如果你确实需要,可以设为 true,并设置 Automatic-Reboot-WithUsers 为 false。
  2. 指定要自动更新的来源(白名单机制):
    这是最重要的一步。默认情况下,它会尝试更新所有已启用的仓库。我们需要限制它只更新安全补丁。

    确保以下部分被取消注释(去掉前面的 //):

    Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}-security";
        // "${distro_id}:${distro_codename}-updates";
        // "${distro_id}:${distro_codename}-proposed";
        // "${distro_id}:${distro_codename}-backports";
    };
    • 解释:
      • ${distro_id}:${distro_codename}-security:这是核心。只允许来自官方安全仓库的更新。这能确保你拿到的是修复漏洞的补丁,而不是新功能或可能导致不稳定的测试版。
      • 其他行(updates, proposed, backports)建议注释掉。如果你想接收常规的 bug 修复而非仅安全补丁,可以放开 updates,但在生产环境中,我建议通过定期手动 apt upgrade 来控制节奏,以避免意外。
  3. 配置邮件通知(可选但推荐):
    在文件末尾添加:

    Unattended-Upgrade::Mail "your-email@example.com";
    Unattended-Upgrade::MailOnlyOnError "true";

    这样只有出错了才发邮件,避免日常刷屏。

第三步:启用定时任务

编辑 /etc/apt/apt.conf.d/20auto-upgrades 文件,确保内容如下:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
  • Update-Package-Lists: 每天同步一次软件源列表。
  • Unattended-Upgrade: 每天执行一次自动升级检查。

保存后,你可以手动触发一次以测试配置是否生效:

sudo unattended-upgrades --dry-run -v

查看输出,确认它只拉取了 -security 源的包。


2. 为什么不建议直接开启 apt full-upgrade?

很多教程会教你写 crontab 跑 apt-get update && apt-get upgrade -y。这在个人电脑上没问题,但在云服务器上是大忌:

  1. 内核升级风险:常规升级可能包含 Linux 内核更新。虽然大多数云主机重启即可,但如果涉及驱动或模块变化,可能导致网络异常或启动失败。
  2. 依赖冲突:某些库的版本更新可能导致现有服务(如 Nginx, MySQL, Python 环境)报错。
  3. 不可控的时间窗口:自动脚本可能在业务高峰期运行,消耗 I/O 和 CPU,影响性能。

最佳实践:让 unattended-upgrades 处理紧急安全漏洞(CVE),而将常规的软件包管理和版本升级纳入人工计划,每月固定时间进行一次全量升级和维护。


3. 云厂商特有的“外挂”:快照与镜像

无论你本地配置得多好,代码和配置都可能出错。对于阿里云、腾讯云、华为云等国内主流厂商,务必利用其控制台功能:

  1. 创建自定义镜像:
    在配置好系统、安装好基础软件后,制作一个标准镜像。每次重大变更(如升级 Ubuntu 大版本)都基于此镜像创建新实例。

  2. 自动快照策略:
    在云盘设置中,开启每日自动快照。这样即使自动升级搞挂了系统,你也可以在几分钟内回滚到昨天的状态。

  3. 云监控告警:
    配置 CPU、内存、磁盘使用率告警。虽然这不直接管理更新,但能让你第一时间发现因更新导致的异常负载。


4. 常见问题排查

  • 问题:自动升级没生效?

    • 检查 /var/log/unattended-upgrades/unattended-upgrades.log。
    • 常见原因:50unattended-upgrades 语法错误(缩进不对)、网络不通无法连接安全源、磁盘空间不足。
  • 问题:升级后服务起不来?

    • 由于我们限制了只更新 -security,这种情况较少见。但如果发生,首先检查 journalctl -xe 看服务日志。
    • 如果是数据库或服务配置因版本变更而失效,通常需要重新生成配置文件(如 dpkg-reconfigure)。
  • 问题:如何排除某个特定包不被自动更新?

    • 在 50unattended-upgrades 文件的 Unattended-Upgrade::Package-blacklist 中添加包名:
      Unattended-Upgrade::Package-blacklist {
        "nginx";
        "mysql-server";
      };

总结

在云服务器上,安全 > 稳定 > 功能。

  1. 使用 unattended-upgrades 仅启用 -security 源。
  2. 禁用自动重启。
  3. 保留完整的操作日志。
  4. 结合云厂商的快照功能作为最后防线。

这套组合拳既能保证你的服务器免受最新漏洞威胁,又不会因为频繁的自动升级引入不可预测的风险。记住,自动化是为了减轻负担,而不是替代你的监控和备份意识。