仅靠PrintMotd no无法隐藏内核版本,必须同步处理SSH握手字符串(DebianBanner no + VersionAddendum none)、/etc/issue与/etc/issue.net中的\r转义符,以及登录前横幅渲染逻辑,否则nc -v IP 22仍可直接获取内核版本信息。

仅靠修改 /etc/motd 或设 PrintMotd no 无法隐藏内核版本信息——真正泄露内核版本的地方是 SSH 握手字符串、/etc/issue 中的 \r 转义符,以及登录前横幅渲染逻辑。必须同步处理这三处,否则攻击者用 nc -v IP 22 一眼就能看到 5.15.0-107-generic 这类字样。
关闭 SSH 协议层内核/发行版标识(DebianBanner + VersionAddendum)
OpenSSH 在 TCP 连接建立瞬间就发送版本字符串,例如 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2,其中括号内容常含内核编译信息。这不是文件输出,而是服务内置行为:
-
DebianBanner no:仅对 Debian/Ubuntu 有效,禁用发行版后缀(如Debian-2+deb12u2) -
VersionAddendum none:OpenSSH 6.9+ 支持,抹掉所有括号内附加字符串(包括 Ubuntu 补丁号、moduli notice 等) - 这两行必须写在
/etc/ssh/sshd_config的全局段(不在Match块内),且需sudo systemctl reload sshd生效 - 注意:
VersionAddendum none不影响主协议头SSH-2.0-OpenSSH_X.Yp1,这是 SSH 协议要求保留的;想彻底隐藏主版本号需重编译 OpenSSH,不推荐
清空并锁定 /etc/issue 和 /etc/issue.net(防止转义符泄露 \r)
这两个文件被 getty、telnet 及部分 SSH 模式读取,\r 会被替换成 uname -r 输出(即完整内核版本号),哪怕你只写了一行提示,只要含 \r 就等于主动暴露:
- 执行
sudo truncate -s 0 /etc/issue /etc/issue.net彻底清空内容 - 再运行
sudo chmod 444 /etc/issue /etc/issue.net设为只读,防止被脚本或更新意外重写 - 不要删除文件,否则
getty启动可能报错;也不要写含\r、\m、\s的“美观提示”,纯文本才安全 - 修改后需重启终端服务才能生效:
sudo systemctl restart getty@tty1(影响本地登录)或重新连接 SSH 查看登录前提示
验证是否真生效:别信登录界面,要看原始协议响应
用户看到的登录提示可能被缓存、美化或延迟渲染,而攻击者用最基础工具就能拿到原始响应。验证必须脱离 SSH 客户端:
- 从另一台 Linux 机器执行:
nc -v your-server-ip 22,首行输出应仅为SSH-2.0-OpenSSH_9.2p1,不能出现Debian、Ubuntu、5.15.0-、generic等任何内核或发行版线索 - 若仍看到括号内容,说明
DebianBanner no或VersionAddendum none未生效,检查配置文件语法、是否被 include 子配置覆盖、权限是否为 root:root - 若登录前横幅仍有版本信息,说明
/etc/issue.net被读取到了——确认该文件为空、权限为 644、路径未拼错,且Banner /etc/issue.net在sshd_config中已启用
最关键的遗漏点是:很多人改了 SSH 配置却忘了 /etc/issue 仍被本地终端和某些 SSH 兼容模式读取;也有人清空了文件,但没设只读,系统更新或日志轮转脚本又悄悄把它写回去了。真正的收敛不是“看起来干净”,而是让 nc 和 nmap -sV 都拿不到可利用的字符串。


















