VPS SSH 安全加固:5 步提升服务器安全性

说明: 本文为配置思路与示例整理,不代表作者已在自己的服务器上逐项验证全部命令。执行涉及公网暴露、账户权限、数据删除或服务重启的操作前,请先备份,并结合官方文档与实际环境核验。

一台暴露在公网上的 VPS,SSH 端口每秒都在被扫描。不做任何加固的服务器,可能在上线几小时内就被暴力破解。本文手把手教你 5 步加固 SSH,显著提升服务器安全性。

为什么要加固 SSH?

如果你在公网 VPS 上跑 ss -ntu | grep :22,会看到密密麻麻的连接记录——全是来自全球各地的暴力破解尝试。根据 SSHGuard 的统计,一台默认配置的 VPS 平均每小时会收到 数百次 登录失败尝试。

常见的攻击手段:

  • 密码暴力破解:自动化工具穷举常见密码
  • 用户名枚举:尝试 rootadminubuntu 等常见用户名
  • 端口扫描:扫描常用端口发现 SSH 服务
  • 零日漏洞:利用 SSH 协议或软件本身的漏洞

本文将从 5 个维度加固你的 SSH 服务,每一步都有具体的命令和验证方法。

第一步:修改默认 SSH 端口

SSH 默认端口是 22,这也是所有扫描器首先检查的端口。改用非标准端口可以过滤掉大部分自动化扫描。

修改配置

BASH
# 备份原始配置
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

# 编辑配置文件
sudo vim /etc/ssh/sshd_config

找到 #Port 22 这一行,修改为:

TEXT
Port 2222

💡 选择端口号时避免使用已知的服务端口(如 8080、3306 等),推荐 1024-65535 范围内的随机端口。

重启服务并验证

BASH
# 重启 SSH 服务
sudo systemctl restart sshd

# 验证新端口监听
sudo ss -tlnp | grep sshd

输出应该类似:

TEXT
LISTEN  0  128  0.0.0.0:2222  0.0.0.0:*  users:(("sshd",pid=1234,fd=3))

⚠️ 关键提醒

在断开当前连接前,先在新终端测试新端口能否连接! 这是最常见的"把自己锁在外面"的操作。

BASH
# 新终端测试(不要关闭当前会话)
ssh -p 2222 your_user@your_server_ip

确认能连上后,再关闭旧会话。

第二步:配置 SSH 密钥认证

密钥认证比密码认证安全得多——暴力破解一把 256 位的密钥,在现有算力下需要极长时间。

生成密钥对

在你的本地机器上(不是服务器)执行:

BASH
# 生成 Ed25519 密钥(推荐,比 RSA 更安全更快)
ssh-keygen -t ed25519 -C "your_email@example.com"

# 如果你的系统不支持 Ed25519,用 RSA 4096 位
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

部署公钥到服务器

BASH
# 方法一:ssh-copy-id(最简单)
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 your_user@your_server_ip

# 方法二:手动复制
cat ~/.ssh/id_ed25519.pub | ssh -p 2222 your_user@your_server_ip \
  "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

验证密钥登录

BASH
# 用密钥登录(应该无需输入密码)
ssh -p 2222 -i ~/.ssh/id_ed25519 your_user@your_server_ip

第三步:禁用密码登录

确认密钥认证正常后,彻底关闭密码登录:

BASH
sudo vim /etc/ssh/sshd_config

修改以下配置项:

TEXT
# 禁用密码认证
PasswordAuthentication no

# 禁用空密码
PermitEmptyPasswords no

# 禁用 root 密码登录(推荐同时禁用 root 登录)
PermitRootLogin prohibit-password

重启服务:

BASH
sudo systemctl restart sshd

验证配置生效:

BASH
# 检查配置是否生效
sshd -T | grep -E "passwordauthentication|permitemptypasswords"

预期输出:

TEXT
passwordauthentication no
permitemptypasswords no

第四步:安装和配置 fail2ban

fail2ban 是一个入侵防御工具,它会监控日志文件,自动封禁多次登录失败的 IP 地址。

安装

BASH
# Debian/Ubuntu
sudo apt update && sudo apt install -y fail2ban

# CentOS/RHEL
sudo yum install -y epel-release && sudo yum install -y fail2ban

配置

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

添加 SSH 保护配置:

INI
[DEFAULT]
# 封禁时间:1小时
bantime = 3600
# 检测时间窗口:10分钟
findtime = 600
# 最大失败次数:5次
maxretry = 5

[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
backend = systemd

启动并验证

BASH
# 启动 fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# 查看 SSH jail 状态
sudo fail2ban-client status sshd

输出示例:

TEXT
Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed: 156
|  `- File list: /var/log/auth.log
`- Actions
   |- Currently banned: 3
   |- Total banned: 45
   `- Banned IP list: 80.66.66.70 45.77.123.12 198.51.100.42

常用管理命令

BASH
# 查看所有被封禁的 IP
sudo fail2ban-client status sshd

# 手动解封 IP
sudo fail2ban-client set sshd unbanip 192.168.1.100

# 手动封禁 IP
sudo fail2ban-client set sshd banip 10.0.0.1

第五步:配置防火墙(nftables)

只开放必要的端口,其余全部拒绝。

创建防火墙规则

BASH
sudo vim /etc/nftables.conf

写入以下内容:

TEXT
#!/usr/sbin/nft -f

# 清空旧规则
flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # 允许已建立的连接
        ct state established,related accept

        # 允许回环接口
        iif lo accept

        # 允许 ICMP(ping)
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept

        # 允许 SSH(自定义端口)
        tcp dport 2222 accept

        # 允许 HTTP/HTTPS
        tcp dport { 80, 443 } accept

        # 允许其他需要的服务端口(按需添加)
        # tcp dport 8080 accept

        # 记录并拒绝其他所有连接
        log prefix "nft-dropped: " counter drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

启用防火墙

BASH
# 应用规则
sudo nft -f /etc/nftables.conf

# 设置开机自动加载
sudo systemctl enable nftables

# 验证规则
sudo nft list ruleset

验证防火墙工作正常

BASH
# 从本地检查端口监听
sudo ss -tlnp

# 从外部测试(在另一台机器上)
# 应该只有 2222 和 80/443 能连通
nmap -p 22,2222,80,443,8080 your_server_ip

一键加固脚本

把上面的步骤整合成一个自动化脚本:

BASH
#!/bin/bash
# VPS SSH 安全加固脚本
# 使用前请确保已有 SSH 密钥!

set -e

NEW_PORT=2222
echo "🔒 开始 SSH 安全加固..."

# 1. 安装 fail2ban
echo "📦 安装 fail2ban..."
apt update && apt install -y fail2ban

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

[sshd]
enabled = true
port = ${NEW_PORT}
filter = sshd
logpath = /var/log/auth.log
backend = systemd
EOF

systemctl enable fail2ban
systemctl restart fail2ban

# 3. 修改 SSH 配置
echo "🔧 修改 SSH 配置..."
sed -i "s/^#Port 22/Port ${NEW_PORT}/" /etc/ssh/sshd_config
sed -i "s/^Port 22$/Port ${NEW_PORT}/" /etc/ssh/sshd_config
sed -i "s/^PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config
sed -i "s/^PermitRootLogin yes/PermitRootLogin prohibit-password/" /etc/ssh/sshd_config

# 4. 重启 SSH
systemctl restart sshd

echo "✅ 加固完成!请验证新端口 ${NEW_PORT} 可以连接后再关闭当前会话。"
echo "📋 验证命令: ssh -p ${NEW_PORT} your_user@your_server_ip"

加固效果验证清单

完成所有步骤后,逐项验证:

BASH
# 1. 确认 SSH 监听在新端口
ss -tlnp | grep sshd

# 2. 确认 fail2ban 运行正常
systemctl status fail2ban

# 3. 确认防火墙规则已加载
nft list ruleset

# 4. 从外部扫描端口(应该只剩 2222 和 80/443)
nmap -p 1-1000 your_server_ip

# 5. 检查 SSH 日志,确认加固生效
sudo journalctl -u sshd --since "1 hour ago" | tail -20

总结

加固措施 安全提升 操作难度
修改 SSH 端口 过滤大部分自动扫描
密钥认证 防暴力破解 ⭐⭐
禁用密码登录 杜绝密码攻击
fail2ban 自动封禁攻击 IP ⭐⭐
防火墙 端口级访问控制 ⭐⭐⭐

5 步加固下来,你的 VPS 安全水平将显著提升。记住,安全是一个持续的过程——定期检查 fail2ban 日志、更新系统补丁、审计访问记录,才能长期保持安全。

🔐 安全不是一次性配置,而是持续的习惯。

评论