Skip to content

🔑 SSH 安全加固 ​

SSH 是管理 Linux 服务器的命脉,也是攻击者的头号目标。一台暴露在公网上的服务器,每天可能遭受成千上万次 SSH 爆破尝试。做好 SSH 加固,能让 99% 的攻击无功而返。

为什么 SSH 必须加固 ​

bash
# 看一眼你的 SSH 登录失败记录,可能会吓一跳
sudo journalctl -u ssh --since "1 hour ago" | grep "Failed password" | wc -l

真实数据

一台新上线的云服务器,开启 22 端口不到 5 分钟就会开始收到爆破请求。这些来自全球各地的肉鸡,用常见用户名(root/admin/pi)和弱密码字典疯狂尝试。

密钥登录:告别密码 ​

密码可以被猜到、被爆破、被键盘记录器偷走。密钥则几乎不可能。

生成密钥对 ​

bash
# 在本机(你的电脑)执行,不是服务器!
ssh-keygen -t ed25519 -C "your_email@example.com"

参数说明:

  • -t ed25519:使用 Ed25519 算法(比 RSA 更安全更快)
  • -C "...":备注,方便区分不同密钥

生成后会在 ~/.ssh/ 下得到:

  • id_ed25519——私钥,绝不能泄露
  • id_ed25519.pub——公钥,放到服务器上

把公钥上传到服务器 ​

bash
# 方法一:ssh-copy-id 自动完成
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server

# 方法二:手动粘贴
cat ~/.ssh/id_ed25519.pub
# 然后登录服务器,把内容追加到 ~/.ssh/authorized_keys
echo "ssh-ed25519 AAAAC3..." >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh

提示

确保 ~/.ssh 权限为 700,authorized_keys 为 600。权限太宽 SSH 会拒绝使用密钥。

修改 SSH 配置 ​

编辑 /etc/ssh/sshd_config,逐项加固:

bash
# 先用密钥登录确认没问题,再改配置!
sudo vim /etc/ssh/sshd_config

必改项 ​

bash
# 1. 禁止 root 直接登录
PermitRootLogin no

# 2. 禁止密码登录(仅密钥)
PasswordAuthentication no

# 3. 禁止空密码
PermitEmptyPasswords no

# 4. 修改默认端口(可选,减少噪音)
Port 2222

# 5. 限制登录用户
AllowUsers yourusername

# 6. 限制登录尝试次数
MaxAuthTries 3

# 7. 缩短登录超时
LoginGraceTime 30

# 8. 禁止 .rhosts 文件(防止 rlogin 攻击)
IgnoreRhosts yes

# 9. 禁用不安全的转发
X11Forwarding no
AllowTcpForwarding no

注意

每次改完 sshd_config 后不要退出当前 SSH 会话! 新开一个终端测试能否正常登录。如果配置有误导致连不上,你还能在原会话中回滚。

配置修改后重启服务:

bash
sudo sshd -t             # 先检查配置文件语法
sudo systemctl restart ssh   # 注意:Ubuntu/Debian 服务名是 ssh,不是 sshd

改端口后的注意事项 ​

如果修改了默认端口:

  • 别忘了在防火墙放行新端口:sudo ufw allow 2222/tcp
  • 旧端口 22 不要急于关闭,确定新端口正常工作后再关
  • ssh-copy-id 和 scp 需要加 -p 2222 指定端口

fail2ban:自动封禁爆破 IP ​

fail2ban 监控登录日志,发现多次失败就自动拉黑 IP。

bash
# 安装
sudo apt install fail2ban

# 创建本地配置(不要直接改 jail.conf)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo vim /etc/fail2ban/jail.local

关键配置段落:

ini
[sshd]
enabled  = true
port     = 2222           # 改成你的 SSH 端口
maxretry = 5              # 最多尝试次数
bantime  = 3600           # 封禁时长(秒),-1 为永久
findtime = 600            # 统计窗口(秒)

启动并查看状态:

bash
sudo systemctl enable fail2ban --now
sudo fail2ban-client status sshd   # 查看 sshd jail 状态(包含被封 IP)
sudo fail2ban-client get sshd banned  # 仅列出被封禁的 IP

完整加固脚本 ​

把下面的脚本保存为 ssh-harden.sh,在新服务器上跑一次即可:

bash
#!/bin/bash
# ssh-harden.sh — SSH 一键加固脚本
# 使用方法:sudo bash ssh-harden.sh

set -e

echo "=== SSH 安全加固脚本 ==="
echo "请确保你已有密钥登录能力,否则执行后可能无法登录!"
read -p "确认继续?(y/N) " confirm
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && exit 0

# 备份原始配置
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)

# 写入加固配置
cat >> /etc/ssh/sshd_config <<'EOF'

# === 安全加固配置 ===
PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30
IgnoreRhosts yes
X11Forwarding no
AllowTcpForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
EOF

# 检查配置
if sshd -t; then
    systemctl restart ssh
    echo "✅ SSH 加固完成"
else
    echo "❌ 配置文件有误,已保留备份"
    exit 1
fi

# 安装并配置 fail2ban
if ! command -v fail2ban-client &>/dev/null; then
    apt update && apt install -y fail2ban
fi

cat > /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
bantime   = 3600
findtime  = 600
maxretry  = 5

[sshd]
enabled   = true
logpath   = %(sshd_log)s
EOF

systemctl enable fail2ban --now
echo "✅ fail2ban 已启动"

执行前

在服务器上运行前,先把你的公钥放好,确认密钥登录正常,再跑脚本。

🧪 练习题 ​

  1. 用 ssh-keygen 生成一对 Ed25519 密钥,并用 ssh-copy-id 部署到服务器
  2. 修改 sshd_config 将端口改为 2222,用新端口登录成功后关闭 22
  3. 装好 fail2ban,故意用错误密码尝试登录 6 次,看 fail2ban 是否自动封禁你的 IP

防线有了,接下来该给流量加密了——HTTPS 与 SSL/TLS(文章待补充)。



🎯 本章要点 ​

  • Ed25519 比 RSA 更安全更快,是当前 SSH 密钥最佳实践
  • 修改 /etc/ssh/sshd_config 设置 PasswordAuthentication no 禁用密码登录
  • 改完 SSH 配置后新开终端测试登录,确认能登再关旧连接

有问题或补充?欢迎留言