
上周巡检一台刚上架的云主机,顺手翻了眼 /var/log/secure,一行 Failed password 挨着一行,密密麻麻像下雨。
跑了个按天统计:
journalctl -u sshd --since today | grep -c "Failed password"8123。
一天,八千多次,来自全世界的 IP 在轮流试 root 的密码。机器上架才三天,没绑定任何域名,没人知道它存在——但扫描器知道。
那一刻你会明白一件事:只要 22 端口对公网开着,暴力破解就不是"会不会来"的问题,是"已经来了多久"的问题。
顺便说一句,Debian/Ubuntu 的兄弟看日志路径不一样,是 /var/log/auth.log,journalctl 的单元名也得换成 -u ssh。另外别图省事直接 grep -c 统计整个 secure 文件——那文件默认按周轮转,你数出来的是好几天的量,口径错了,数字再吓人也是错的。
很多人加固 SSH 的思路是"见招拆招":装个 fail2ban、改个端口,收工。
这就像家里进了推销电话,你天天挂、天天拉黑——电话还是会来。真正安静的办法是换号码,只告诉该告诉的人。
SSH 防御也一样,分三层:
"降到 0"靠的不是封禁速度比攻击者快,是让攻击面消失。fail2ban 和改端口是止痛药,关密码登录才是手术刀。
下面 6 招,顺序就是按这个递进排的,别跳着做。

fail2ban 是一个"看日志、自动封 IP"的守护进程:同一个 IP 连续输错几次密码,就把它拉进防火墙黑名单关禁闭。
fail2ban 在 EPEL 源里,Rocky/CentOS Stream 直接装源包就行;真 RHEL 8/9 官方仓库里没有这个包,得用 EPEL 官方 RPM 地址装:
# Rocky / CentOS Stream / Alma
dnf install epel-release -y
# 真 RHEL(以 RHEL 9 为例,RHEL 8 把 9 换成 8)
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
dnf install fail2ban -y(RHEL 上如果装 fail2ban 时提示依赖缺失,多半还要先启用 CRB 仓库——RHEL 8 叫 PowerTools。)
别改默认的 jail.conf(升级会被覆盖),新建 /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 1h
# 下面这行的 x.x.x.x 换成你的办公出口IP再启动,占位符会让 fail2ban 报解析告警
ignoreip = 127.0.0.1/8 x.x.x.x(注意:fail2ban 的配置解析器不支持行内注释,# 说明文字要独占一行,写在配置项后面会被当成值的一部分。)
systemctl enable --now fail2ban,收工。
三个踩坑点,个个见血:
先说清楚,免得评论区替我补充:改端口是典型的"安全通过隐匿",靠不住。 扫描器全端口扫一遍照样能找到你。
但它的价值在于砍掉 90% 以上的脚本小子噪音——那些批量扫 22 端口的机器人不会为你一台机器做全端口扫描,日志瞬间清净,fail2ban 的压力也小了一个量级。
核心动作其实就一行,改 /etc/ssh/sshd_config:
Port 2222但光改这一行就 reload,你大概率会把自己锁在外面。正确顺序是先把路铺好,再搬家——四件事,缺一不可:
# 1. 云平台安全组放行新端口(控制台操作)
# 2. firewalld 放行(Ubuntu 默认没 firewalld,用 ufw allow 2222/tcp)
firewall-cmd --permanent--add-port=2222/tcp && firewall-cmd --reload
# 3. SELinux 机器登记新端口(让 sshd 被允许监听它)
semanage port -a -t ssh_port_t -p tcp 2222
# 4. 改 sshd_config 的 Port,然后 sshd -t 验语法、平滑重载
systemctl reload sshd # Debian/Ubuntu 服务名是 ssh:systemctl reload sshsemanage 命令没有的话装包:RHEL 8+/Rocky 是
policycoreutils-python-utils,RHEL 7 是 policycoreutils-python。如果 semanage 报 already defined,说明这个端口已经被登记过别的类型,把 -a 换成 -m 修改即可。
改完先用新端口开新终端连上,确认没问题再断旧会话——这条规矩本篇会反复出现,因为它救过我一回。
给 Ubuntu 兄弟提个醒:22.10 之后 SSH 走 systemd socket 激活,改端口得改 socket 而不是 sshd_config——systemctl edit ssh.socket,先写一行空的 ListenStream= 清掉默认值,再写 ListenStream=2222(不写空行直接加,会变成 22 和新端口同时监听),改完 systemctl restart ssh.socket 才生效。
看一眼你的失败日志,用户名那一列,root 能占掉绝大多数——攻击字典的第一个名字永远是它。
PermitRootLogin no或者折中一点:PermitRootLogin prohibit-password,root 还能用密钥登录,但密码通道焊死。
(这一行和第 4 招的 AllowUsers 写在哪?建议跟第 5 招一样统一放进
sshd_config.d/00-hardening.conf,原因第 5 招细讲——云镜像的坑在那儿等着呢。)
踩坑点只有一个,但能要命:禁之前,确认你的普通用户能正常登录、sudo 权限配好了。不然 root 一禁,普通用户又进不来,你就把自己唯一的门焊死了。
AllowUsers huwei opsadmin只有名单里的人能登录,系统里那一堆 daemon、bin、nginx 之类的账号,连被尝试的资格都没有。
踩坑点:用户名是空格分隔,写错一个字母等于把自己踢出门。这里要特别说一句:sshd -t 只验语法,验不出用户名拼错——把 opsadmin 写成 opsadmni,它照样静默通过。这一步唯一的保险就是:旧会话别断,开新终端实测登录,成功了再收工。
前面四招都是减量,这一招是归零。
密钥对(一对数学上绑定的密钥,公钥放服务器、私钥自己揣着)优先选 ed25519,更短更快更安全;老系统不兼容再退回 RSA 4096。私钥务必加 passphrase(私钥的密码),私钥丢了别人捡到也用不了。
操作顺序是生命线,一步都不能反:
# 1. 部署公钥(保持当前 SSH 会话不断开;改过端口的记得加 -p 2222)
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@服务器IP
# 2. 开一个新终端,验证密钥能登录——这步过了才往下走
# 3. 写加固配置
PasswordAuthentication no
KbdInteractiveAuthentication no # 键盘交互认证也关上,个别发行版/PAM 配置下它还能弹密码提示顺序反了,就是"运维自己把自己锁在门外"的生产事故,云主机只能走 VNC 或者挂载系统盘抢救,别问我怎么知道的。
第二个坑,云镜像用户必踩:Ubuntu 和各家云镜像普遍有 /etc/ssh/sshd_config.d/*.conf(典型的比如 50-cloud-init.conf,各家镜像文件名不完全一样,以你机器上 ls /etc/ssh/sshd_config.d/ 看到的为准),里面的 PasswordAuthentication yes 优先级高于主配置文件——你吭哧吭哧改了 sshd_config 主文件,可能压根没生效,还以为门关好了。
正确姿势:加固项统一写在
/etc/ssh/sshd_config.d/00-hardening.conf 里,然后:
sshd -t # 验语法
sshd -T | grep -E "passwordauthentication|permitrootlogin" # 看实际生效值
systemctl reload sshd # 平滑生效,不必 restart;Debian/Ubuntu 是 systemctl reload ssh记住:-t 只告诉你语法没错,-T 才告诉你最终生效的是什么。这两个字母的差别,值得刻在脑子里。
门锁好了,再装个摄像头:
lastb | head -20 # 最近的失败登录(依赖 /var/log/btmp,没有就 touch 一个)
journalctl -u sshd --since today # 今日 SSH 事件(Debian/Ubuntu 用 -u ssh)
fail2ban-client status sshd # fail2ban 的封禁战绩再进一步,写个小脚本:非白名单 IP 登录成功,立刻发告警到钉钉/企微。
但把丑话说前头:监控是兜底感知,不是防御本身。 前 5 招没做扎实,监控再灵敏,也只是让你看得更清楚地被打。
机器多了以后,还有两招更硬的:端口敲门 knockd(平时端口隐身,按约定顺序敲几个端口才开门)或者干脆把 SSH 收到企业 VPN(公司内网组网那种)或堡垒机后面,让公网扫不到你的 SSH。这俩适合多机器场景,展开又是一篇,今天先点到。
还有一个零成本的:云厂商安全组直接把 22 端口(或你的新端口)只对办公 IP 开放——相当于把第 4 招的白名单从主机层提到了网络层,攻击流量连机器都摸不到,比主机层白名单还硬。
回到开头那个数字:8123。
六招做完第二天,我又跑了一遍同样的命令。Failed password,0。
说清楚这个 0 是什么:日志并没有清净,扫描器还在连,日志里只是换了一批 Connection closed [preauth] 之类的记录——"密码错误"这个类别从日志里消失了,因为密码框没了,门没了,再大的字典也只能对着墙挥拳。
这就是我干了 15 年运维一直信的一句话:安全不是跟攻击者拼反应速度,是让攻击面消失。 先把门焊死,再装报警器,最后才是扫地。顺序反了,你就是天天站在自家门口,跟全世界的机器人打架。
生产环境,慢就是快;安全加固,先做对顺序。
关注「胡哥Linux运维」,一个 RHCA 老兵的实战笔记,不整虚的。
下篇预告:门焊死了,人进去了呢?聊聊 sudo 权限怎么收,才不会养出一个"第二个 root"。
你的机器现在一天被扫多少次?跑一下 journalctl -u sshd --since today | grep -c "Failed password",评论区报个数,看看谁的数字多离谱。
更新时间:2026-10-22
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight All Rights Reserved.
Powered By 61893.com 闽ICP备11008920号
闽公网安备35020302035593号