2084 字
10 分钟
Linux 服务器安全防护手册(一):第一道防线 —— SSH、防火墙与 Fail2ban

分层防御总览#

Linux 服务器安全不是靠单一工具就能解决的。业界标准做法是分层防御(Defense in Depth):每一层解决不同的问题,层层叠加形成纵深防护。

第1层 UFW / nftables → 控制哪些端口对外暴露
第2层 Fail2ban → 检测暴力破解,自动封禁攻击 IP
第3层 SSH 加固 → 杜绝弱密码、root 登录等常见入侵入口
第4层 AppArmor / SELinux → 限制进程能访问的文件和资源
第5层 Auditd → 记录所有关键操作,出事可溯源

本文是系列第一篇,聚焦前三层——SSH 加固、UFW 防火墙和 Fail2ban。这三层配置完成后,你的服务器将免疫 90% 以上的自动化攻击。

本文以 Ubuntu 24.04 LTS 为基准环境配置。Debian 用户可直接套用;RHEL/AlmaLinux/Rocky Linux 用户需将 apt 替换为 dnf,UFW 替换为 firewalld


SSH 加固#

SSH 是服务器的入口。根据 2025-2026 年各安全厂商的入侵分析报告,超过 80% 的 Linux 服务器入侵始于 SSH 暴力破解或弱密码。加固 SSH 是整个安全体系中最重要的一步。

1. 生成 Ed25519 密钥对#

Ed25519 比 RSA 更安全、更快、密钥更短。2025 年起 OpenSSH 默认使用 Ed25519。

Terminal window
# 在本地机器执行(不是在服务器上)
ssh-keygen -t ed25519 -C "your-email@example.com"
# 将公钥复制到服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server
# 如果 ssh-copy-id 不可用,手动复制
cat ~/.ssh/id_ed25519.pub | ssh user@your-server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

验证:用密钥登录一次,确认无需密码即可连接后再继续下一步。保持当前 SSH 会话不要断开,另开一个终端窗口测试。

2. 配置 sshd_config#

Terminal window
# 先备份原配置
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

编辑 /etc/ssh/sshd_config

# ===== 端口 =====
# 改用非标准端口可减少 99% 的自动化扫描噪音
Port 2222
# ===== 认证方式 =====
# 禁用 root 直接登录
PermitRootLogin no
# 禁用密码认证——只允许密钥登录
PasswordAuthentication no
# 禁用空密码
PermitEmptyPasswords no
# 启用公钥认证
PubkeyAuthentication yes
# ===== 登录限制 =====
# 只允许指定用户登录
AllowUsers deploy
# 最大尝试次数
MaxAuthTries 3
# 最大并发未认证连接数
MaxStartups 3:30:10
# ===== 超时 =====
# 客户端无操作 5 分钟后发送保活探测
ClientAliveInterval 300
# 最多发 2 次
ClientAliveCountMax 2
# ===== 禁用不需要的功能 =====
X11Forwarding no
AllowTcpForwarding no
PermitTunnel no
AllowAgentForwarding no
# ===== 强加密套件 =====
# 只允许现代加密算法
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256@libssh.org
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
HostKeyAlgorithms ssh-ed25519

CIS Level 2 建议使用 AllowUsers 白名单。只把需要 SSH 登录的用户加进去,这是最小权限原则的体现。

配置生效前先做语法检查,防止把自己锁在外面:

Terminal window
sudo sshd -t
# 无输出 = 语法正确

如果报错,根据提示修复后再执行下一步。

Terminal window
sudo systemctl reload sshd

3. 更新 UFW 规则以匹配新端口#

如果之前 UFW 已允许 22 端口,需要先更新为新的 SSH 端口再重载 sshd:

Terminal window
sudo ufw delete allow 22/tcp
sudo ufw allow 2222/tcp

4. 用 ssh-audit 检查配置#

ssh-audit 是开源的 SSH 配置审计工具,能检查加密算法、密钥交换、MAC 等是否安全。

Terminal window
# 安装
sudo apt install ssh-audit -y
# 审计本地 SSH 服务
ssh-audit localhost -p 2222
# 输出会给出打分和建议。目标是消除所有 warn 和 fail 项。

UFW 防火墙#

UFW(Uncomplicated Firewall)是 Ubuntu 默认的主机防火墙,本质是 iptables/nftables 的易用前端。CIS Level 1 要求启用主机防火墙并采用默认拒绝策略。

1. 基础配置#

Terminal window
# 安装(Ubuntu 通常已预装)
sudo apt install ufw -y
# 设置默认策略:入站拒绝,出站允许
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 允许必要端口
sudo ufw allow 2222/tcp # SSH(使用上面配置的新端口)
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
# 如果服务器需要响应 ping(ICMP),编辑 /etc/ufw/before.rules
# 找到 "ok icmp codes for INPUT" 部分,确认相关规则未被注释
# 启动防火墙
sudo ufw enable
# 查看状态
sudo ufw status verbose

2. 进阶:限制 SSH 来源 IP#

生产环境中,如果运维人员有固定办公 IP 或通过 VPN 访问,应限制 SSH 只允许这些 IP:

Terminal window
# 删除之前的开放规则
sudo ufw delete allow 2222/tcp
# 只允许特定 IP 段访问 SSH
sudo ufw allow from 192.168.10.0/24 to any port 2222 proto tcp
# 允许公司 VPN 出口 IP
sudo ufw allow from 203.0.113.5 to any port 2222 proto tcp

没有固定 IP 的环境至少要保持 Fail2ban 开启(见下节)。

3. 开启日志#

Terminal window
sudo ufw logging medium
# 日志级别:off | low | medium | high
# 查看被拦截的连接
grep "UFW BLOCK" /var/log/ufw.log | tail -20

4. 应用级规则#

UFW 内置常见应用的预设规则,可以直接用应用名配置:

Terminal window
# 列出已知应用
sudo ufw app list
# 允许 Nginx 全量(HTTP + HTTPS)
sudo ufw allow "Nginx Full"
# 只允许 HTTPS
sudo ufw allow "Nginx HTTPS"

Fail2ban 防暴力破解#

Fail2ban 监控服务日志,当检测到来自同一 IP 的多次失败尝试后自动调用防火墙封禁该 IP。CIS Level 1 推荐部署 Fail2ban 保护 SSH。

1. 安装#

Terminal window
sudo apt install fail2ban -y

2. 创建配置文件#

不要直接修改 /etc/fail2ban/jail.conf(升级时会覆盖),应在 jail.local 中覆盖配置:

Terminal window
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

编辑 /etc/fail2ban/jail.local

[DEFAULT]
# ===== 白名单 =====
# 你自己的办公 IP、VPN 网段等,这些 IP 永远不会被封
ignoreip = 127.0.0.1/8 ::1
# ===== 封禁策略 =====
# 统计窗口:在此时间内累计失败次数
findtime = 10m
# 最大失败次数
maxretry = 5
# 封禁时长
bantime = 1h
# ===== 累进封禁(累犯加重处罚)=====
bantime.increment = true
# 封禁时长倍乘因子(第1次1h → 第2次2h → 第3次4h → ...)
bantime.factor = 2
# 最大封禁时长上限
bantime.maxtime = 7d
# ===== 通知(可选)=====
# destemail = admin@yourdomain.com
# sendername = Fail2Ban
# mta = sendmail
# action = %(action_mwl)s
# ===== SSH Jail =====
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
# SSH 更敏感,直接封 1 天
bantime = 1d
# ===== Nginx 防暴力破解(如果运行了 Nginx)=====
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
# ===== 防恶意扫描 =====
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 3

3. 启动与验证#

Terminal window
# 启动服务
sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
# 查看所有 Jail 状态
sudo fail2ban-client status
# 查看 SSH Jail 封禁情况
sudo fail2ban-client status sshd

4. 常用管理命令#

Terminal window
# 查看被封禁的 IP 列表
sudo fail2ban-client get sshd banned
# 手动封禁某个 IP
sudo fail2ban-client set sshd banip 192.0.2.10
# 手动解封某个 IP
sudo fail2ban-client set sshd unbanip 192.0.2.10
# 查看 Fail2ban 日志
sudo journalctl -u fail2ban -f

5. Fail2ban 与 UFW 的联动态#

默认情况下 Fail2ban 使用 iptables 封禁。如果你的系统后端是 nftables(Ubuntu 22.04+),需要确认 Fail2ban 的 banaction 配置正确:

Terminal window
# 检查后端
sudo fail2ban-client get banaction
# 如果不是使用 ufw 或 nftables,编辑 jail.local 的 [DEFAULT] 段:
# banaction = ufw

验证清单#

完成配置后,按顺序逐项验证:

☐ 密钥登录正常(不再需要输入密码)
☐ sshd -t 语法检查无报错
☐ root 登录被拒绝:ssh root@server -p 2222 → Permission denied
☐ 密码登录被拒绝(在另一台机器上测试:ssh -o PreferredAuthentications=password user@server -p 2222)
☐ UFW 状态为 active,默认策略为 deny (incoming)
☐ 只开放了 2222、80、443 三个端口
☐ Fail2ban 状态为 active,sshd jail 正常运行
☐ 故意输错密码 3 次后 IP 被封禁

速查表#

Terminal window
# ===== SSH =====
ssh-keygen -t ed25519 -C "your-email" # 生成密钥
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host # 复制公钥
sudo sshd -t # 检查配置语法
sudo systemctl reload sshd # 重载 SSH 配置
# ===== UFW =====
sudo ufw status verbose # 查看详细状态
sudo ufw allow 443/tcp # 开放端口
sudo ufw delete allow 443/tcp # 删除规则
sudo ufw allow from 192.168.1.0/24 to any port 2222 # 限制来源 IP
sudo ufw logging medium # 开启日志
# ===== Fail2ban =====
sudo fail2ban-client status # 查看所有 jail
sudo fail2ban-client status sshd # 查看 SSH jail
sudo fail2ban-client get sshd banned # 被封 IP 列表
sudo fail2ban-client set sshd unbanip <IP> # 手动解封
sudo systemctl restart fail2ban # 重启 Fail2ban

延伸阅读#

  • ssh-audit — SSH 服务器安全审计工具
  • BetterCrypto.org — SSH 和 TLS 加密配置最佳实践
  • CrowdSec — Fail2ban 的现代替代品,基于社区威胁情报(开源)

下一篇:Linux 服务器安全防护手册(二):系统层加固——用户权限、内核参数调优、自动更新与文件系统加固。

Linux 服务器安全防护手册(一):第一道防线 —— SSH、防火墙与 Fail2ban
https://blog.syomega.top/posts/linux-security-1/
作者
酱w
发布于
2026-05-16
许可协议
CC BY-NC-SA 4.0