ECS (Ubuntu 22.04) 安全加固实战:SSH 密钥登录 + UFW 防火墙 + Fail2ban 防暴力破解

举报
yd_273651526 发表于 2026/10/30 10:36:17 2026/10/30
【摘要】 前面几篇文章记录了在华为云弹性云服务器 ECS(Ubuntu 22.04 LTS)上从零部署 Docker + Nginx 静态服务、做系统运维优化、以及用 Shell + Crontab 实现定时备份。服务跑起来之后,下一个绕不开的问题就是安全。只要 ECS 绑定了公网 IP,就会持续暴露在公网扫描之下。本文记录一次完整的安全加固落地过程:SSH 改密钥登录、UFW 配置最小化防火墙规则、...

前面几篇文章记录了在华为云弹性云服务器 ECS(Ubuntu 22.04 LTS)上从零部署 Docker + Nginx 静态服务、做系统运维优化、以及用 Shell + Crontab 实现定时备份。服务跑起来之后,下一个绕不开的问题就是安全。

只要 ECS 绑定了公网 IP,就会持续暴露在公网扫描之下。本文记录一次完整的安全加固落地过程:SSH 改密钥登录、UFW 配置最小化防火墙规则、Fail2ban 自动封禁暴力破解 IP,并在结尾附上加固前后的效果对比和踩坑记录。

一、为什么必须做安全加固

服务器上线第一天,就可以在 /var/log/auth.log 里看到大量这样的记录:

Oct 28 03:12:41 ecs-xxxx sshd[18233]: Failed password for root from 45.x.x.x port 51233 ssh2
Oct 28 03:12:44 ecs-xxxx sshd[18241]: Failed password for root from 103.x.x.x port 41802 ssh2

统计一下暴力破解的规模:

# 统计当天失败登录尝试的来源 IP Top 10
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10

我的这台机器上线不到一周,失败登录尝试已经超过 8000 次,绝大多数是在爆破 root 密码。默认配置下(root + 密码登录 + 22 端口)等于把大门敞开,加固刻不容缓。

本文的加固目标:

目标 手段
杜绝密码暴力破解 SSH 仅允许密钥登录
最小化攻击面 UFW 只放行必要端口
自动封禁恶意 IP Fail2ban 联动防火墙
出问题能回滚 保留一个已验证的后备通道

二、加固前的准备:留好"后悔药"

安全加固最大的风险是把自己锁在门外。动手前先做两件事:

1. 在华为云控制台确认可以 VNC 登录

即使 SSH 全部配错,华为云控制台的「远程登录」(VNC)也能进入系统救急。操作路径:ECS 控制台 → 找到目标实例 → 远程登录。先确认这条路能走通,再开始改配置。

2. 本地生成并验证密钥对

本地电脑执行(Windows 10/11 自带 OpenSSH,PowerShell 直接可用):

# 生成 ed25519 密钥对,比 RSA 更安全且更短
ssh-keygen -t ed25519 -C "huawei-ecs-admin"
# 默认保存在 C:\Users\<你的用户名>\.ssh\id_ed25519

强烈建议同时设置密钥 passphrase,这样即使私钥文件泄露也不会被直接利用。


三、第一步:SSH 改密钥登录

1. 上传公钥到服务器

用当前的密码登录方式先把公钥写上去:

# 在本地执行(PowerShell),把公钥追加到服务器的 authorized_keys
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh ubuntu@<ECS公网IP> "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

注意两点权限细节,配错了密钥登录会直接失败:

  • ~/.ssh 目录权限必须为 700
  • authorized_keys 文件权限必须为 600

2. 验证密钥登录成功

不要直接改配置,先新开一个终端验证:

ssh -i $env:USERPROFILE\.ssh\id_ed25519 ubuntu@<ECS公网IP>
# 能免密码直接登录,说明密钥配置生效

3. 修改 sshd 配置

确认密钥可登录后,编辑 /etc/ssh/sshd_config(或规范一点,放到独立配置文件里):

sudo vim /etc/ssh/sshd_config.d/99-hardening.conf

写入:

# 禁止密码登录(密钥验证通过后再开启这一行)
PasswordAuthentication no
# 禁止 root 直接登录
PermitRootLogin no
# 只保留协议 2(新版默认即是,显式声明无妨)
Protocol 2
# 限制最大认证尝试次数
MaxAuthTries 3

建议先用普通用户(如 ubuntu)操作,PermitRootLogin no 生效后 root 就进不来了。日常工作也应以普通用户 + sudo 进行。

重启服务并确认状态:

sudo systemctl restart ssh
sudo systemctl status ssh

此时保持当前会话不要退出,再开新终端测试登录。新终端能正常进,老会话才能关——这是改 SSH 配置的铁律。


四、第二步:UFW 配置最小化防火墙

华为云安全组已经做了第一层端口管控,主机层面的 UFW 是第二道防线,两层配合、纵深防御。

1. 设置默认策略并放行必要端口

# 默认拒绝所有入站
sudo ufw default deny incoming
# 默认允许所有出站
sudo ufw default allow outgoing

# 放行 SSH(必须先放行,否则下一步 enable 会把自己踢下线!)
sudo ufw allow 22/tcp comment 'SSH'

# 放行 Web 服务
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

# 启用防火墙
sudo ufw enable
sudo ufw status verbose

enable 之前务必确认 22 端口规则已存在,这是和 SSH 加固同级别的"自锁"高危操作。

2. 限制 SSH 端口的连接频率

UFW 自带 rate limit,可以对 22 端口做简单限速(30 秒内超过 6 次新连接就暂时拒绝):

sudo ufw limit 22/tcp

3. 一个容易踩的坑:Docker 绕过 UFW

这是本次加固中最大的坑——Docker 发布的端口(-p 参数)会直接写 iptables,绕过 UFW 规则。也就是说即使 UFW 没放行 8080,docker run -p 8080:80 的容器依然对公网可达。

验证方法:

# 从外部扫描,如果容器端口能通,说明被 Docker 绕过了

解决方案(按需选择):

  1. 容器端口只绑定本机回环,由宿主机 Nginx 反向代理对外(我采用的方式,与上一篇文章的 Nginx 反代架构正好衔接):

    # 只监听 127.0.0.1,公网不可达
    docker run -d -p 127.0.0.1:8080:80 nginx
    
  2. 修改 /etc/docker/daemon.json 让 Docker 走 UFW 管理链(需重启 Docker,注意会短暂中断容器):

    {
      "iptables": false
    }
    

    此方案影响面较大,需自行处理 Docker 网络出站,慎用。


五、第三步:Fail2ban 自动封禁爆破 IP

UFW 是静态规则,Fail2ban 负责"动态防御":监控日志,对反复失败的 IP 自动封禁。

1. 安装与配置

sudo apt update && sudo apt install fail2ban -y

Ubuntu 22.04 的 Fail2ban 默认没有开启任何 jail,且官方推荐不要直接改 jail.conf,而是新建本地配置:

sudo vim /etc/fail2ban/jail.local

写入针对 SSHD 的规则:

[DEFAULT]
# 封禁时长 1 小时
bantime = 1h
# 10 分钟内
findtime = 10m
# 累计失败次数
maxretry = 5
# 使用 UFW 执行封禁(与我们的防火墙方案联动)
banaction = ufw

[sshd]
enabled = true
port = 22
logpath = /var/log/auth.log

启动并设置开机自启:

sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban

2. 验证效果

# 查看 sshd jail 状态(重点看 Currently banned / Total banned)
sudo fail2ban-client status sshd

运行一段时间后的输出示例:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     1437
|  `- File list:        /var/log/auth.log
`- Action
   |- Currently banned: 37
   |- Total banned:     89
   `- Banned IP list:   45.xxx.xxx.xxx 103.xxx.xxx.xxx ...

手动测试一次封禁(可选,用另一台机器或手机热点故意输错密码 5 次,观察 IP 进入 banned list)。

3. 解封误封的 IP

如果把自己公司的出口 IP 封了(比如内部测试登录失败太多次):

sudo fail2ban-client set sshd unbanip <被误封的IP>

六、加固效果与验收清单

全部完成后,做一次系统性验收:

# 1. 密码登录已被拒绝(应提示 Permission denied (publickey))
ssh -o PreferredAuthentications=password ubuntu@<ECS公网IP>

# 2. UFW 规则符合预期
sudo ufw status numbered

# 3. Fail2ban 正常运行且有封禁记录
sudo fail2ban-client status sshd

# 4. auth.log 中新的失败尝试不再出现 "Accepted password"
grep "Accepted password" /var/log/auth.log | wc -l   # 加固后新增应为 0

加固前后对比(我这台机器的实际数据):

指标 加固前 加固后
SSH 认证方式 密码 + 密钥 仅密钥
root 直接登录 允许 禁止
入站开放端口 全部依赖安全组 UFW 白名单(22/80/443)
爆破 IP 处理 仅记录日志 自动封禁 1 小时
一周失败登录尝试 8000+ 次 仍会被扫,但全部无法成功且被动态封禁

七、写在最后

安全加固不是一个一次性动作,而是一套组合拳 + 持续运营:

  1. 收缩入口:密钥登录 + 禁 root,让密码爆破直接失效;
  2. 最小暴露:UFW 白名单,并注意 Docker 端口绕过问题;
  3. 动态防御:Fail2ban 让扫描和爆破有实际成本;
  4. 持续观察:定期 fail2ban-client status 和审计日志,发现新风险。

到目前为止,这个系列已经覆盖了华为云 ECS 从部署、运维优化、数据备份到安全加固的完整闭环。下一篇文章计划记录用 HTTPS 证书自动续期 + Nginx 安全头进一步完善 Web 层安全,欢迎关注。

如果文章对你有帮助,欢迎点赞、收藏、评论区交流~

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。