关键需切断三处泄露路径:协议握手标识(设debianbanner no、versionaddendum none)、登录前横幅(清空/etc/issue与/etc/issue.net)、登录后消息(设printmotd no、printlastlog no并清空/etc/motd),验证须用nc -v ip 22确认仅返回ssh-2.0-openssh_x.yp1。

想通过 SSH 欢迎 Banner 隐藏操作系统具体版本号,关键不是“加一句欢迎语”,而是切断三处默认泄露路径:协议握手时的服务标识、登录前显示的横幅、登录后自动推送的系统消息。只要这三处都清理干净,远程连接时就只会看到 SSH-2.0-OpenSSH_X.Yp1 这样的通用标识,不再带 Ubuntu-3ubuntu0.6 或 Debian-2+deb12u2 这类发行版和补丁版本信息。
清空或重写 /etc/issue 和 /etc/issue.net
这两个文件控制本地终端、getty、telnet 以及部分 SSH 场景下未认证前显示的内容。默认常含 \r(内核版本)、\s(系统名)、\v(发行版版本)等转义符,直接暴露详细信息。
- 一键清空并设只读(推荐新手):
sudo truncate -s 0 /etc/issue /etc/issue.net && sudo chmod 644 /etc/issue /etc/issue.net - 如需保留法律提示,仅向
/etc/issue.net写入纯文本(不带任何转义符):echo "Authorized access only." | sudo tee /etc/issue.net - 修改后需重新连接 SSH 或重启 getty 才能生效,例如:
sudo systemctl restart getty@tty1
配置 sshd_config 关键参数
OpenSSH 的行为由 /etc/ssh/sshd_config 控制。以下三项必须明确设置:
- Banner /etc/issue.net:启用自定义横幅,并确保它指向你已清空或重写的文件;路径必须存在、可读、不能是软链接
-
DebianBanner no:仅 Debian/Ubuntu 系统需要,禁用发行版后缀(如
Debian-2+deb12u2) -
VersionAddendum none:OpenSSH 6.9+ 支持,彻底移除版本字符串括号内的附加信息(比
DebianBanner no更通用)
保存后执行 sudo systemctl reload sshd(reload 不中断现有连接,比 restart 更稳妥)。
关闭登录后的动态信息输出
即使登录成功,系统仍可能通过 motd、最后登录记录等方式间接暴露环境特征:
-
PrintMotd no:在
sshd_config中添加,阻止显示/etc/motd及其动态生成内容(Ubuntu 的更新提示、内核版本摘要等常由此输出) - PrintLastLog no:禁用 “Last login: …” 行,避免暴露主机名、IP 或登录时间规律
-
清空 motd 主文件:
sudo truncate -s 0 /etc/motd
对 Ubuntu/Debian,还可停用自动更新服务:sudo systemctl disable motd-news.timer
验证是否真正隐藏成功
别只看登录界面——攻击者根本不需要登录,就能拿到原始响应。务必用以下方式验证协议层输出:
- 用
nc -v your-server-ip 22连接,观察返回的第一行。正确结果应为:SSH-2.0-OpenSSH_9.2p1(无括号、无系统名、无补丁号) - 或用
ssh -o LogLevel=DEBUG1 user@host 2>&1 | grep "Remote protocol version"查看调试日志中的握手版本行 - 若仍看到完整字符串,请检查:
•/etc/issue.net是否被其他服务(如 agetty)意外调用
• 文件权限是否超标(如 640 或目录权限过松)
• 配置是否拼写错误或未 reload











