任何一台有公网 IP 的服务器上线几小时内就会被自动化扫描器盯上——加固不是可选项。一台 2核2G 的轻量应用服务器(价格查询于 2026-10-02,阿里云活动价为 ¥38/年),哪怕只跑个简单的个人主页,如果不管它,每天也会在 /var/log/auth.log 里留下成百上千次爆破记录。不要赌扫描脚本的运气,做完前 3 项,你就能挡住 95% 的自动化攻击。
换掉 22 端口:筛掉九成僵尸网络盲扫
扫描器最喜欢低成本遍历默认端口。改掉 22 端口,大部分自动化攻击脚本连你的 SSH 服务都找不到。一台全天候开机的服务器,换掉默认端口后错误登录尝试记录会从每天上千条暴跌到个位数。
# 修改 SSH 配置文件
sudo sed -i 's/^#Port 22/Port 3922/' /etc/ssh/sshd_config
sudo systemctl restart ssh
验证方法:执行 ss -tuln | grep 3922,看到监听记录代表新端口已接管监听。不要断开当前连接,新开一个终端测试能否用新端口登入。
关掉密码登录:只给 Ed25519 密钥开门
密码总能被字典跑出来,而 Ed25519 密钥目前无法被暴力破解。关闭密码验证机制,字典爆破直接变成无用功。就算黑客拿到了你的服务器 IP 和用户名,没有存在本地硬盘里的私钥文件,依然连不上。
# 禁用密码认证
sudo sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart ssh
验证方法:使用 ssh -o PubkeyAuthentication=no user@ip -p 3922 测试登录,服务端直接拒绝并抛出 Permission denied (publickey) 报错,代表阻断生效。
开启 UFW 防火墙:非必要端口一律锁死
Ubuntu 默认不开启防火墙,所有监听中的端口都向全网敞开。用 UFW 封死非业务端口,直接切断暴露面。在当前版本 UFW 0.36.2 中,操作只有几行命令。非业务端口不对外响应,扫描器探测时只会收到网络超时反馈。
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 放行刚刚修改的 SSH 端口
sudo ufw allow 3922/tcp
# 放行 Web 端口
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
验证方法:执行 sudo ufw status verbose,确认输出状态为 active 且放行列表里包含 3922。
配置 Fail2Ban:自动拉黑爆破 IP
剩下那些能扫出自定义端口的进阶扫描器,交由 Fail2Ban 对付。只要输错 3 次密钥,它直接让防火墙把该 IP 关 24 小时禁闭。这既消耗了攻击者的节点池资源,又避免了服务器 CPU 被无休止的握手请求耗尽。
sudo apt install fail2ban -y
cat << INNER_EOF | sudo tee /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 3922
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
INNER_EOF
sudo systemctl restart fail2ban
验证方法:运行 sudo fail2ban-client status sshd,查看当前被防火墙拦截的 IP 列表。
拒绝 root 远程登录:阻断账号猜测
root 是所有 Linux 都有的最高权限账号,它是爆破者必然会用的目标用户名。关闭 root 远程登录权限,攻击者连要猜的用户名是什么都不知道。把日常权限交给普通账户,需要改配置时再用 sudo 执行,攻击链的实施难度成倍增加。
sudo sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sudo systemctl restart ssh
验证方法:用 root 身份发起 SSH 连接,即使提供正确的密钥也会被系统无情踢出。
撤下数据库公网 IP:防范勒索病毒洗劫
数据库跑在公网上属于勒索重灾区。不论是 MySQL 还是 Redis,都不该向外网监听,只让同一台机器上的业务程序访问它就够了。一旦公网可达,未授权访问漏洞分分钟让你发现数据表全变成了索要数字货币的勒索信。
# MySQL 配置绑定本地
sudo sed -i 's/^bind-address.*/bind-address = 127.0.0.1/' /etc/mysql/mysql.conf.d/mysqld.cnf
sudo systemctl restart mysql
验证方法:执行 netstat -tuln | grep 3306,确认监听地址从 0.0.0.0 变成了 127.0.0.1。
开启自动更新功能:拦截已知高危漏洞
手动打补丁既容易忘,速度也赶不上黑客跑 0day 漏洞的自动化程序。通过 unattended-upgrades 让系统自己去拉取核心安全补丁。它只针对关键漏洞热修复,不碰常规应用程序更新,给业务带来的停机风险极低。
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
验证方法:执行 systemctl status unattended-upgrades 确认服务运行正常,后续系统在后台默默拦截已披露的旧版本漏洞。
限制 docker 组权限:堵死本地提权通道
给普通用户赋予 docker 组成员身份,等同于直接向他移交系统底层控制权。攻击者借此启动一个特权容器并挂载宿主机根目录,不用密码也能改写系统配置。日常运维应当强制普通用户带着 sudo 执行 docker 命令,以此将特权行为纳入系统审计框架。
验证方法:普通用户执行 groups 如果没看到 docker 字样,代表当前用户隔离规范。
清理云厂商内置插件:拔掉未知后门
众多公有云平台会在镜像里强制塞入云盾或类似监控组件。这些闭源程序占用几百兆内存,同时作为一个能远程拉起特权脚本的黑盒持续潜伏。拿回机器的主动权,第一步就是删掉它们。
# 以阿里云为例,官方提供的组件卸载脚本
wget -qO- http://update.aegis.aliyun.com/download/uninstall.sh | sudo bash
验证方法:执行 ps aux | grep -i aliyun,确认列表里没有任何挂机的监控进程。
设置云盘定期快照:留存最后防线
一切防线都有防穿的几率。服务器被恶意破坏后,排查隐藏木马和修补后门的时间远大于直接重装。前往云控制台开启硬盘自动快照,保留最近 7 天的记录。遇到事故按一下回滚按钮,业务又能照常流转。
运行一把梭加固脚本
将上述针对 SSH 与防火墙的核心配置提取为一个脚本,起新机时直接一键部署:
#!/bin/bash
# 执行前确保云端安全组已放行 3922 端口,并将公钥存入 ~/.ssh/authorized_keys
sed -i 's/^#Port 22/Port 3922/' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart ssh
ufw default deny incoming
ufw default allow outgoing
ufw allow 3922/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
回答 3 个常见问题
Q:修改了 SSH 端口后,发现新开终端连接超时? 如果是云服务器,不仅需要在系统内配好 UFW 防火墙放行,还必须登录云控制台,在实例的「安全组」设置里添加入站规则放行 3922 端口,这两层墙缺一不可。
Q:Fail2Ban 拦截了我自己的 IP 怎么处理?
去服务商后台使用 VNC 网页终端强制登录。VNC 走的是虚拟化底层链路,不受 UFW 网络隔离规则限制。登入后敲入 sudo fail2ban-client set sshd unban <你的公网IP> 即可解除锁定。
Q:挂在内网、不绑弹性公网 IP 的机器也要做这些吗? 需要。只要公网暴露的那台反代服务器被拿下,黑客立刻会把它当跳板机对内网网段横向渗透。内网不设防,等于前门一破所有服务器就全线沦陷。
如果你只打算挑 3 件事做,关密码、改端口和配防火墙的防御收益最高。做足这 3 步,你就在攻防博弈的存活率测试中跑赢了 95% 的公网节点。