我的服务器上线30分钟就被攻击者盯上了——3个设置立刻把他们挡在门外

我的服务器上线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地址。

SSH日志

攻击者的手段并不高明,但非常执着

让我看看他们在猜什么用户名:

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大军

攻击来源IP

三个设置,三步绝杀

面对这种情况,我的处理策略是分层的:先降低可见性(让服务器不再容易被扫描发现),再消除密码攻击面(让即使发现了也进不来),最后加上自动封禁机制(让反复尝试的被永久拉黑)。

设置一:换掉22端口——让服务器从”攻击地图”上消失

更改SSH端口是业界有争议的做法。有人坚持”安全不能依赖模糊性”(Security through obscurity),这在理论上当然正确——如果你依赖端口变更作为唯一的安全措施,那确实可笑。

但实战中,更换端口解决的是一个非常具体的问题:日志噪音。扫描22端口的bot流量没有智力,它们不会去全端口扫描——成本太高。它们的目标是那台在22端口应答了”我是SSH”的服务器。

操作步骤:

1
2
# 不修改主配置文件,而是创建独立的加固配置
sudo nano /etc/ssh/sshd_config.d/99-homeops-hardening.conf

第一行也是最重要的一行:

1
Port 52522

关键操作顺序(避免锁死自己)

  1. 先在UFW防火墙开放新端口
  2. 重新加载SSH配置
  3. 从另一个终端用新端口测试登录
  4. 确认成功后,删除旧的22端口防火墙规则
1
2
3
4
5
6
7
8
# 先开新门
sudo ufw allow 52522/tcp
# 重载SSH
sudo systemctl reload ssh
# 用另一个终端窗口测试新端口登录
ssh -p 52522 user@your-server.com
# 确认成功后,关掉旧门
sudo ufw delete allow OpenSSH

Ubuntu特别提醒:如果你是从现有的22端口SSH会话中改端口,需要额外禁用ssh.socket监听器(它会覆盖端口设置),只需在确认新端口工作后:

1
sudo systemctl disable --now ssh.socket

这个操作完成后,日志立刻安静了下来。不是攻击停止了,而是你的服务器不再看起来像一个”典型的SSH目标”

换端口后日志清零

设置二:密钥认证——让密码猜解变得毫无意义

换端口让服务器安静了很多,但真正的安全加固在于彻底消除密码攻击面

攻击者手里的bot程序日复一日地尝试着root/admin/test123/changeme这样的字典组合。只要保留密码登录,总有一个组合会让它蒙对一次。

打开之前的加固配置文件,追加这些行:

1
2
3
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no

然后测试配置合法性并重载:

1
2
sudo sshd -t
sudo systemctl reload ssh

在此之后,创建一个非root用户并赋予sudo权限:

1
2
sudo adduser home-ops-relay-admin
sudo usermod -aG sudo home-ops-relay-admin

然后把SSH公钥copy过去:

1
2
3
4
5
sudo mkdir -p /home/home-ops-relay-admin/.ssh
sudo cp ~/.ssh/authorized_keys /home/home-ops-relay-admin/.ssh/authorized_keys
sudo chown -R home-ops-relay-admin:home-ops-relay-admin /home/home-ops-relay-admin/.ssh
sudo chmod 700 /home/home-ops-relay-admin/.ssh
sudo chmod 600 /home/home-ops-relay-admin/.ssh/authorized_keys

验证效果——强制密码认证,看是否能登录:

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
2
3
4
5
6
[sshd]
enabled = true
port = 52522
maxretry = 3
findtime = 10m
bantime = 1h

启动并验证:

1
2
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

有了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程序发现并开始暴力破解。

核心措施

  1. 更改SSH默认端口——消除来自自动化扫描的绝大部分噪音
  2. 禁用密码认证,强制使用SSH密钥——彻底消灭密码猜解攻击面
  3. 部署Fail2ban——对重复攻击者自动封禁,增加攻击成本
  4. 操作顺序至关重要:先开新路,测试成功,再关旧路

管理建议:这三个设置应该在服务器上线之前就配置完成,而不是等到看到攻击日志之后。在防火墙规则允许的情况下,更好的做法是先在非默认端口上完成密钥配置和Fail2ban部署,最后再让服务器接入公网。