Ubuntu服务器默认的SSH服务一旦暴露在公网,通常几个小时内就会被扫描器标记,随后开始持续不断的暴力破解尝试。攻击者主要利用弱口令、默认账户和未限制的认证方式,因此安全配置的核心不是单一措施,而是围绕SSH访问控制、认证策略、日志监控和自动封禁形成多层防线。
先确认暴力破解的入口和风险点
在Ubuntu服务器上,最常见的暴力破解目标是SSH服务。攻击者会用常见用户名如root、admin、ubuntu、test,配合弱密码字典反复尝试登录。默认情况下,如果root账户允许密码登录,且没有失败次数限制,服务器被攻破只是时间问题。另一个风险点是系统可能安装了其他远程管理服务,例如VNC或数据库服务,但SSH仍然是主要入口。检查当前SSH配置可以用以下命令:
sudo cat /etc/ssh/sshd_config | grep -E "PermitRootLogin|PasswordAuthentication|MaxAuthTries|PubkeyAuthentication"
输出结果会直接显示当前认证策略。如果PermitRootLogin为yes且PasswordAuthentication为yes,说明服务器处于高风险状态。
第一层:修改SSH核心认证参数
编辑SSH配置文件:
sudo nano /etc/ssh/sshd_config
建议修改或确认以下参数:
PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes MaxAuthTries 3 LoginGraceTime 30 AllowUsers yourusername Protocol 2
PermitRootLogin no直接禁止root远程登录,这是降低风险最有效的一步。PasswordAuthentication no意味着只允许密钥登录,密码暴力破解将完全失效。MaxAuthTries 3限制单次连接最多尝试3次认证,超过后断开。LoginGraceTime 30设置认证超时时间为30秒,防止攻击者长时间占用连接。AllowUsers后面写实际允许登录的普通用户名,多个用户用空格分隔。修改完成后重启SSH服务:
sudo systemctl restart ssh
在禁用密码登录之前,务必先配置好SSH密钥并测试能够正常登录,否则可能导致自己无法连接服务器。
第二层:配置SSH密钥登录并加固密钥管理
如果还没有密钥,在本地电脑生成:
ssh-keygen -t ed25519 -a 100
ed25519算法比RSA更短且安全性高。生成后将公钥上传到服务器:
ssh-copy-id -i ~/.ssh/id_ed25519.pub yourusername@server_ip
上传成功后测试密钥登录,确认无误后再将PasswordAuthentication设为no。服务器端的公钥默认保存在~/.ssh/authorized_keys,建议设置权限:
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys
同时可以在sshd_config中增加以下参数,进一步限制密钥登录环境:
PermitEmptyPasswords no StrictModes yes AuthorizedKeysFile .ssh/authorized_keys
StrictModes yes会检查用户目录和密钥文件权限,如果权限过于宽松则拒绝登录,这能防止其他本地用户篡改密钥文件。
第三层:使用Fail2ban自动封禁暴力破解IP
即使只允许密钥登录,攻击者仍会不断尝试连接并消耗资源。Fail2ban可以监控SSH日志,自动将频繁失败的IP加入防火墙黑名单。安装:
sudo apt update sudo apt install fail2ban -y
创建本地配置文件,避免直接修改默认文件:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
编辑jail.local,找到[sshd]部分,设置:
[sshd] enabled = true port = 22 filter = sshd logpath = /var/log/auth.log maxretry = 3 bantime = 3600 findtime = 600
maxretry 3表示在findtime 600秒内失败3次就封禁,bantime 3600表示封禁1小时。对于攻击频繁的服务器,可以将bantime设为86400甚至更长。重启服务:
sudo systemctl restart fail2ban sudo systemctl enable fail2ban
查看封禁状态:
sudo fail2ban-client status sshd
输出中会显示当前封禁的IP数量。如果服务器使用非标准SSH端口,需要将port改为实际端口。
第四层:修改默认SSH端口并限制来源IP
将SSH端口从22改为高位端口,例如2222或更高,可以减少大量自动化扫描流量。修改sshd_config:
Port 2222
重启SSH后,连接时需要指定端口:
ssh -p 2222 yourusername@server_ip
如果服务器只允许固定IP访问,可以使用防火墙直接限制来源。Ubuntu默认使用ufw:
sudo ufw allow from 192.168.1.0/24 to any port 2222 proto tcp sudo ufw enable
这样只有指定网段的设备能连接SSH端口,其他来源直接丢弃。如果无法固定IP,至少可以限制SSH端口只对必要的业务IP开放。
第五层:配置防火墙默认拒绝策略
ufw默认允许所有出站流量,但入站流量需要明确放行。建议先设置默认策略:
sudo ufw default deny incoming sudo ufw default allow outgoing
然后只开放业务需要的端口,例如:
sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw allow 2222/tcp
启用ufw前确认当前SSH端口已放行,否则会切断自己的连接。启用后查看规则:
sudo ufw status verbose
防火墙默认拒绝策略可以防止攻击者探测其他未授权服务,即使某个服务配置失误,外部也无法直接访问。
第六层:限制认证尝试频率和连接数
除了Fail2ban,还可以在SSH层面直接限制未认证连接数量。在sshd_config中增加:
MaxStartups 10:30:60 MaxSessions 5
MaxStartups 10:30:60表示在未完成认证阶段,最多允许10个并发连接,超过后开始以30%概率拒绝新连接,达到60个时全部拒绝。这能有效缓解并发暴力破解和连接耗尽攻击。MaxSessions 5限制单个用户同时打开的会话数。
第七层:监控认证日志并设置告警
Ubuntu的认证日志位于/var/log/auth.log。持续监控SSH相关记录:
sudo tail -f /var/log/auth.log | grep sshd
重点观察是否有大量Failed password、Invalid user、Connection closed by authenticating user等记录。如果使用Fail2ban,日志中会出现Ban和Unban记录。对于长期运行的服务器,可以配置logwatch或自定义脚本定期分析日志,将异常登录尝试通过邮件或消息推送告警。
一个简单的统计脚本示例,统计当天SSH失败次数:
sudo grep "$(date +%b\ %d)" /var/log/auth.log | grep "Failed password" | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -20
这个命令会列出失败尝试最多的IP地址,方便手动加入黑名单。
第八层:使用TCP Wrappers或iptables补充限制
如果不想安装Fail2ban,可以使用iptables直接限制SSH连接频率。例如限制每个IP每分钟最多新建3个SSH连接:
sudo iptables -A INPUT -p tcp --dport 2222 -m state --state NEW -m recent --set sudo iptables -A INPUT -p tcp --dport 2222 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
第一条规则将新连接记录到recent列表,第二条规则检查60秒内同一IP是否超过3次新连接,超过则丢弃。这种方式直接在内核层面生效,效率较高,但重启后规则会丢失,需要保存规则或写入启动脚本。
第九层:定期更新系统和审计账户
暴力破解往往利用已知漏洞,保持系统更新能减少被攻破后的提权风险:
sudo apt update && sudo apt upgrade -y sudo unattended-upgrades -d
同时检查系统账户,删除不必要的用户,确保没有空密码账户:
sudo awk -F: '($2 == "") {print $1}' /etc/shadow
输出为空表示没有空密码账户。检查是否有除root外的UID为0的账户:
sudo awk -F: '($3 == 0) {print $1}' /etc/passwd
正常情况下只应输出root。如果发现其他账户,需要立即审计是否被入侵。
第十层:部署SSH证书认证替代传统密钥
对于多用户或多服务器环境,可以使用SSH证书认证。与普通公钥不同,证书带有有效期和权限限制,即使私钥泄露,攻击者也只能在证书有效期内使用。配置SSH证书需要生成CA密钥,然后为用户公钥签发证书。在sshd_config中设置:
TrustedUserCAKeys /etc/ssh/ssh_ca.pub PasswordAuthentication no PubkeyAuthentication yes
证书认证能有效防止私钥长期泄露带来的风险,适合安全要求较高的生产环境。
验证配置效果
完成上述配置后,从外部网络尝试使用错误密码登录,观察是否在3次尝试后被断开,以及Fail2ban是否自动封禁IP。同时确认正常密钥登录不受影响。可以使用以下命令模拟失败登录:
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no yourusername@server_ip
如果配置正确,系统会直接拒绝密码认证,不会出现密码输入提示。
Ubuntu服务器防暴力破解的核心思路是减少攻击面、限制认证方式、自动封禁恶意来源、持续监控日志。单一措施容易被绕过,只有多层配置叠加才能形成有效防护。对于暴露在公网的服务器,至少应完成前四层配置,即修改SSH认证参数、启用密钥登录、部署Fail2ban、配置防火墙默认拒绝策略。
