
我的服务器上线30分钟就被攻击者盯上了——3个设置立刻把他们挡在门外
Diebug我的服务器上线30分钟就被攻击者盯上了——3个设置立刻把他们挡在门外
我需要一台干净的SSH跳板机来管理家庭实验室里的服务器。这台机器应该安安静静地待在网络边缘,只做一件事:给我一个可控的入口,让我能安全接入内网的各个服务。
需求本身很简单——一台Ubuntu服务器,只跑SSH,不暴露任何控制面板、Web服务、文件共享。它应该是最”无聊”的一台服务器,没有人会对它产生兴趣。
我错得很离谱。
问题初现:服务器上线不到30分钟就热闹起来了
在锁定安全设置之前,我先检查了一下服务器到底在开放什么端口:
1 | sudo ss -tulpn |
输出完全符合预期:SSH在22端口监听,仅此而已。这台服务器刚运行了大约一个小时。
然后我决定看看有没有”敲门的人”——最近一小时内SSH服务收到了什么样的连接尝试:
1 | sudo journalctl -u ssh --since "1 hour ago" | grep -Ei "failed|invalid|disconnect|authentication" |
几百次。 不是偶尔一两次好奇的试探——是几百次登录尝试,对着一个一小时前还不存在的IP地址。

攻击者的手段并不高明,但非常执着
让我看看他们在猜什么用户名:
1 | sudo journalctl -u ssh --since "1 hour ago" | grep -Eio "invalid user [^ ]+" | sort | uniq -c | sort -nr | head |
结果在意料之中,但也有几个有趣的发现:
root——必试admin——经典vagrant——针对DevOps环境的自动化工具ansible——针对IT运维平台的利用minecraft——游戏服务器经常被当作攻击跳板jenkins——CI/CD系统的凭证泄露是近两年的大热点
这不是定向攻击。攻击者并不知道这台服务器属于谁、运行什么服务。这只是互联网背景噪音——全自动的扫描脚本在持续扫描公网IP段的22端口,用字典里累积的用户名-密码组合逐个尝试。
再看看攻击的IP来源:
1 | sudo journalctl -u ssh --since "1 hour ago" | grep -Eio "from ([0-9]{1,3}\.){3}[0-9]{1,3}" | awk '{print $2}' | sort | uniq -c | sort -nr | head |
IP来源分布非常分散——从俄罗斯的VPS、东南亚的家宽、到美国的云主机都有。这不是一个攻击者,这是一个全球分布的自动化bot大军。

三个设置,三步绝杀
面对这种情况,我的处理策略是分层的:先降低可见性(让服务器不再容易被扫描发现),再消除密码攻击面(让即使发现了也进不来),最后加上自动封禁机制(让反复尝试的被永久拉黑)。
设置一:换掉22端口——让服务器从”攻击地图”上消失
更改SSH端口是业界有争议的做法。有人坚持”安全不能依赖模糊性”(Security through obscurity),这在理论上当然正确——如果你依赖端口变更作为唯一的安全措施,那确实可笑。
但实战中,更换端口解决的是一个非常具体的问题:日志噪音。扫描22端口的bot流量没有智力,它们不会去全端口扫描——成本太高。它们的目标是那台在22端口应答了”我是SSH”的服务器。
操作步骤:
1 | # 不修改主配置文件,而是创建独立的加固配置 |
第一行也是最重要的一行:
1 | Port 52522 |
关键操作顺序(避免锁死自己):
- 先在UFW防火墙开放新端口
- 重新加载SSH配置
- 从另一个终端用新端口测试登录
- 确认成功后,删除旧的22端口防火墙规则
1 | # 先开新门 |
Ubuntu特别提醒:如果你是从现有的22端口SSH会话中改端口,需要额外禁用
ssh.socket监听器(它会覆盖端口设置),只需在确认新端口工作后:
1 sudo systemctl disable --now ssh.socket
这个操作完成后,日志立刻安静了下来。不是攻击停止了,而是你的服务器不再看起来像一个”典型的SSH目标”。

设置二:密钥认证——让密码猜解变得毫无意义
换端口让服务器安静了很多,但真正的安全加固在于彻底消除密码攻击面。
攻击者手里的bot程序日复一日地尝试着root/admin/test123/changeme这样的字典组合。只要保留密码登录,总有一个组合会让它蒙对一次。
打开之前的加固配置文件,追加这些行:
1 | PasswordAuthentication no |
然后测试配置合法性并重载:
1 | sudo sshd -t |
在此之后,创建一个非root用户并赋予sudo权限:
1 | sudo adduser home-ops-relay-admin |
然后把SSH公钥copy过去:
1 | sudo mkdir -p /home/home-ops-relay-admin/.ssh |
验证效果——强制密码认证,看是否能登录:
1 | ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no -p 52522 user@your-server.com |
应该被拒绝。 这正是我们想要的结果。
到了这一步,攻击者的密码字典已经完全没有用了。即使他们猜到了地球上最复杂的密码,只要不是你的私钥持有者,就进不来。
设置三:Fail2ban——最后一层自动防御
前两层解决了密码攻击和扫描噪音,但还有一类攻击者:那些即使被拒绝也反复尝试的bot。单独一次尝试不危险,但如果同一个IP在短时间内连接了十几次,说明它在扫描你开放的其他端口或者在寻找新的攻击向量。
Fail2ban就是处理这种”不知放弃者”的工具。当同一个IP在设定时间窗口内失败达到阈值时,Fail2ban会在防火墙层面直接封禁该IP。
安装和配置非常简单:
1 | sudo apt update && sudo apt install fail2ban |
创建SSH专用的Jail配置:
1 | sudo nano /etc/fail2ban/jail.d/sshd.local |
配置内容:
1 | [sshd] |
启动并验证:
1 | sudo systemctl enable --now fail2ban |
有了Fail2ban,即使有bot不死心地在换端口后通过全端口扫描找到了你的SSH服务,它也只有三次机会。三次失败之后,它的IP就被拉黑了——1小时内完全无法连接你服务器的任何端口。
三层的深度防御架构
这三个设置构成了一个简单但完整的纵深防御(Defense in Depth)体系:
| 防御层 | 解决的问题 | 攻破难度 |
|---|---|---|
| 更换SSH端口 | 消除背景扫描噪音,让服务器不在”钓鱼列表”中 | 低(只防自动化扫描) |
| 密钥认证 | 彻底杜绝密码猜解攻击 | 高(需要私钥) |
| Fail2ban | 对重复攻击者自动封禁IP | 中高(单IP只有3次机会) |
每一层单独拿出来都不完美。更换端口可以通过全端口扫描绕过,密钥认证不会阻止DDoS式的连接尝试,Fail2ban可以通过切换IP绕过。但这三个层叠加在一起,你的服务器就成了一个对自动化攻击而言”既不显眼又极难对付”的目标——攻击者通常更倾向于选择更容易搞定的目标。
AISOC视角:公网服务器暴露面的安全运营
在企业安全运营的日常工作中,”公网暴露面收敛”是一个持续性的命题。运维人员随手开一台测试服务器、顺手开放22端口的现象非常普遍。
SOC团队应该关注以下几点:
- 资产发现自动化:定期扫描企业的公网IP段,发现所有开放22端口(以及其他管理端口)的设备,确保它们都在登记册中
- 基线检查:对每台公网SSH服务器强制执行最小基线——禁止密码登录、禁止Root直接登录、必须配置Fail2ban或等效方案
- 日志接入SOC:SSH认证失败日志应接入SIEM,异常的高频失败尝试应触发实时告警
- 定期渗透测试:至少每季度对公网暴露面做一次发现式渗透测试,确保没有新的未加固的SSH服务悄然上线
在AISOC平台上,可以针对Linux服务器的SSH配置合规性进行自动化基线扫描,一旦检测到违反基线的配置(如开启密码认证、Root可登录、未安装Fail2ban等),自动发出告警并触发工单。结合威胁情报,还能对连接服务器SSH端口的可疑IP进行实时碰撞检测,实现从被动防御到主动发现的安全运营升级。
总结
一台公网SSH服务器需要面对的,不是某个特定攻击者的定点打击,而是来自全球各地的自动化bot的持续扫描。这种”背景噪音”级别的攻击不复杂,但非常持久。
核心风险:默认配置的公网SSH服务器在30分钟内就会被全球自动化bot程序发现并开始暴力破解。
核心措施:
- 更改SSH默认端口——消除来自自动化扫描的绝大部分噪音
- 禁用密码认证,强制使用SSH密钥——彻底消灭密码猜解攻击面
- 部署Fail2ban——对重复攻击者自动封禁,增加攻击成本
- 操作顺序至关重要:先开新路,测试成功,再关旧路
管理建议:这三个设置应该在服务器上线之前就配置完成,而不是等到看到攻击日志之后。在防火墙规则允许的情况下,更好的做法是先在非默认端口上完成密钥配置和Fail2ban部署,最后再让服务器接入公网。