跳转至

Ubuntu 26.04 关机公告和 wall 命令失效问题

背景与摘要

近期在 Ubuntu 26.04 服务器上进行计划外重启时,管理员发现传统的系统关机警告 (shutdown broadcast) 和广播命令 (wall) 无法通知到处于活跃状态的用户。调查指出,这两个问题虽然表现相似但根源不同:wall 失效是因为现代 systemd 为了兼容 2038 年问题,在编译时去除了 /run/utmp 的支持;而关机警告失效是因为 systemd-logind 无法追踪 SSH 登录关联的 TTY。由于替代工具 wwho 依赖复杂的后备机制且受到 AppArmor 限制,进一步加剧了系统消息广播的混乱。

Summary

在 Ubuntu 26.04 服务器上执行计划外重启时,管理员发现关机警告广播和传统的 wall 命令不再通知活跃用户。调查显示,这是两个不同的根本原因: 1. wall 失效源于现代 systemd(从 Debian 13 / Ubuntu 25.10 开始)由于 2038 年 (Y2038) 的合规性考量,在编译时去除了 /run/utmp 支持。 2. 关机广播失效是因为 Ubuntu 26.04 中的 systemd-logind 无法追踪 SSH 登录的 TTY 关联,这意味着公告永远无法到达活跃的终端会话。

此外,像 whow 这样的替代工具依赖于复杂的后备机制,并进一步受到 AppArmor 限制的影响。

When performing unscheduled reboots on Ubuntu 26.04 servers, administrators discovered that shutdown warning broadcasts and the traditional wall command no longer notify active users. Investigation reveals these are two distinct root causes: 1. The wall failure stems from modern systemd (starting in Debian 13 / Ubuntu 25.10) being built without /run/utmp support due to Y2038 compliance concerns. 2. The shutdown broadcast failure occurs because systemd-logind in Ubuntu 26.04 fails to track TTY associations for SSH logins, meaning announcements never reach active terminal sessions.

Additionally, alternative tools like who and w rely on complex fallbacks and are further impacted by AppArmor restrictions.


1. The Breakdown of wall

古老的 wall 程序(来自 bsdutils 包)完全依赖传统的 /var/run/utmp(或 /run/utmp)文件来确定谁登录了以及在哪里登录的。

The venerable wall program (from the bsdutils package) relies entirely on the traditional /var/run/utmp (or /run/utmp) file to determine who is logged in and where.

  • 原因: 从 Debian 13 ("Trixie") 和 Ubuntu 25.10 开始,systemd 在编译时去除了 utmp 支持,主要是因为该格式的 2038 年问题 (Y2038 problem)
    • The Cause: Starting with Debian 13 ("Trixie") and Ubuntu 25.10, systemd is built without utmp support, primarily due to the format's Y2038 problem.
  • 影响: 由于缺少 utmpwall 在静默中失效,什么也不做。
    • The Impact: Because utmp is absent, wall fails silently and does nothing.
  • 权宜之计:
    • Workarounds:
  • 您必须编写自定义脚本来查询带有伪终端 (ptys) 的活跃用户会话,并直接广播消息。
    • You must write custom scripts to query active user sessions with pseudo-terminals (ptys) and broadcast messages directly.
  • 存在一个名为 wtmpdb 的替代项目,它也恢复了 last 命令。但是,它需要手动配置 PAM,而且 Ubuntu 26.04 的 OpenSSH 目前在编译时没有包含 wtmpdb 支持。
    • A replacement project exists called wtmpdb, which also restores the last command. However, it requires manual PAM configuration, and Ubuntu 26.04's OpenSSH is currently built without wtmpdb support.

2. Broken Shutdown Broadcasts

通常,运行诸如下面的命令:

Normally, running a command like:

shutdown -r +NN "<有关情况的消息>"
会触发由 systemd 管理的定期警告。在 Ubuntu 26.04 上,这些消息无法广播给 SSH 用户。 triggers periodic warnings managed by systemd. On Ubuntu 26.04, these messages fail to broadcast to SSH users.

  • 原因: 在 Ubuntu 26.04(特色是 systemd 259.5)中,systemd-logind 无法映射 SSH 登录所使用的 TTY。运行 loginctlloginctl -j 会发现 SSH 会话完全缺乏 TTY 信息(尽管本地控制台登录显示正常)。
    • The Cause: In Ubuntu 26.04 (featuring systemd 259.5), systemd-logind fails to map the TTYs used by SSH logins. Running loginctl or loginctl -j reveals a complete lack of TTY information for SSH sessions (though local console logins display correctly).
  • 对比: 像 Ubuntu 24.04 (systemd 255.4) 和 Fedora 44 (启用了 UTMP 的 systemd 259.7) 这样的旧版本中没有这个 bug。
    • Comparison: This bug is absent in older versions like Ubuntu 24.04 (systemd 255.4) and Fedora 44 (systemd 259.7 with UTMP enabled).
  • 影响: 由于 logind 仅将关机警告传输到它主动跟踪的 TTY 上,因此 SSH 会话不会收到任何提前通知。
    • The Impact: Because logind only transmits shutdown warnings to TTYs it actively tracks, SSH sessions receive no advance notice.

3. Quirks with who, w, and AppArmor

有趣的是,像 who (来自 GNU Coreutils) 和 w (来自 procps) 这样的实用程序在 Ubuntu 26.04 上可能仍然会显示 PTY 信息——前提是您禁用了 AppArmor:

Interestingly, utilities like who (from GNU Coreutils) and w (from procps) may still display PTY information on Ubuntu 26.04—provided you have AppArmor disabled:

$ who
cks      sshd pts/0   Jul 20 21:47 (...)
$ lsb_release -r
Release:        26.04

Why do they still work (partially)?

  • GNU Coreutils who 尝试通过库 API 查询 systemd。如果会话的 TTY 信息缺失,它会回退到扫描 /dev/pts(注意:备选的基于 Rust 的 uutils 版本受 Launchpad bug #2152801 影响)。
    • GNU Coreutils who attempts to query systemd via library APIs. If session TTY info is missing, it falls back to scanning /dev/pts. (Note: The alternative Rust-based uutils version suffers from Launchpad bug #2152801).
  • Procps w 当 systemd 和 utmp 均无法报告 TTY 数据时,它利用一种类似的回退机制。由于它们的回退方法不同,whow 在 Ubuntu 26.04 上有时可能会报告相互矛盾的信息。
    • Procps w utilizes a similar fallback mechanism when both systemd and utmp fail to report TTY data. Because their fallback methods differ, who and w may occasionally report conflicting information on Ubuntu 26.04.

The AppArmor Complication

Ubuntu 26.04 中的默认 AppArmor 配置文件阻止 who 访问 /run/systemd/sessions(系统 API 所依赖的路径)。有趣的是,这一限制仅影响 who;而 w 完全绕过了这一限制,因为它缺少专门的 AppArmor 配置文件。

Default AppArmor profiles in Ubuntu 26.04 block who from accessing /run/systemd/sessions (which the systemd API relies on). Amusingly, this restriction only impacts who; w bypasses this limitation entirely as it lacks a specific AppArmor profile.


原文的观察和讨论可见于 Systemd, Shutdown, and Wall on Ubuntu 26.04

Original observations and discussion can be found on Systemd, Shutdown, and Wall on Ubuntu 26.04.