VPS 安全入门:SSH 密钥、防火墙与 Fail2ban
Ubuntu 安装完成后,新的 VPS 不能直接视为安全。服务器在完成访问控制配置前就已经暴露在扫描器面前:攻击者会尝试 SSH 密码,寻找公开的管理面板,并检查常见漏洞。本指南将从零开始完成 VPS 的基础防护:创建独立用户,配置 SSH 密钥登录,通过 UFW 限制网络端口,并启用 Fail2ban。只要命令由拥有 sudo 权限的用户执行,以下步骤适用于 Ubuntu 22.04 和 24.04。
开始配置前:列出需要使用的端口
不要为了“以防万一”而打开端口。普通 Web 服务器通常只需要:
22/tcp— SSH,最好按 IP 限制;改用其他端口只能作为额外措施;80/tcp— HTTP,通常用于跳转到 HTTPS 以及验证证书;443/tcp— HTTPS。
如果前面运行着 Nginx 或 Caddy,3000、8080 或 9000 之类的应用端口不应直接暴露在互联网中。请将应用绑定到 127.0.0.1,或者只允许内网访问该端口。先确认服务器正在监听哪些端口:
sudo ss -tulpn安装 Docker 后,还要单独检查它添加的 iptables 规则:-p 3000:3000 可能绕过你预期的网络结构,直接开放端口。对于公开服务,更安全的做法是使用 HTTPS 代理,并隐藏内部端口。
第 1 步:更新系统并创建管理员用户
使用服务商提供的账户连接 VPS,然后安装更新:
sudo apt update
sudo apt full-upgrade -y
sudo apt install -y ufw fail2ban unattended-upgrades创建一个专用的个人用户。将 alex 替换为你自己的用户名:
sudo adduser alex
sudo usermod -aG sudo alex在单独的终端窗口确认新账户可以正常使用之前,不要删除原有访问方式。这是一条重要规则:当当前会话仍然保持打开时,修复 SSH 配置错误会容易得多。
第 2 步:创建 SSH 密钥并安装到服务器
在自己的 Linux、macOS 或 Windows PowerShell 电脑上执行:
ssh-keygen -t ed25519 -C "alex@my-computer"按 Enter 将密钥保存到默认文件,并设置 passphrase(密钥口令)。私钥不能发送到聊天中,不能放进代码仓库,也不能复制到 VPS。服务器上只需要传输扩展名为 .pub 的公钥文件:
ssh-copy-id alex@SERVER_IP如果没有 ssh-copy-id,可以在 PowerShell 中使用 Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub 查看公钥,然后将它添加到服务器:
sudo install -d -m 700 -o alex -g alex /home/alex/.ssh
sudo nano /home/alex/.ssh/authorized_keys
sudo chown alex:alex /home/alex/.ssh/authorized_keys
sudo chmod 600 /home/alex/.ssh/authorized_keys将公钥粘贴为一行,并在关闭密码登录前验证登录:
ssh alex@SERVER_IP
sudo whoami最后一条命令的预期结果是 root。如果 SSH 客户端找不到密钥,请明确指定它:ssh -i ~/.ssh/id_ed25519 alex@SERVER_IP。
第 3 步:禁止 root 和密码登录
先备份 SSH 配置:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config确认文件中包含以下参数:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
MaxAuthTries 3在 Ubuntu 中,设置也可能位于 /etc/ssh/sshd_config.d/*.conf,所以请检查最终生效的配置:
sudo sshd -t
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries'如果 sshd -t 报错,在修复语法前不要重启服务。检查成功后应用设置:
sudo systemctl reload ssh保留旧的 SSH 连接处于打开状态,并在新窗口中使用密钥验证登录。没有验证过密钥就关闭密码登录,是最常见的服务器失去访问权限的原因。
第 4 步:配置 UFW,同时避免锁死 SSH
UFW 是 Linux 网络规则的便捷封装。先设置安全的默认策略,再允许 SSH 和 Web 端口:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw enable只有在 SSH 规则已经添加后,才确认启用防火墙。查看结果:
sudo ufw status verbose
sudo ufw status numbered如果办公室使用固定的公网 IP,可以将 SSH 限制到该地址:
sudo ufw delete allow 22/tcp
sudo ufw allow from YOUR.PUBLIC.IP to any port 22 proto tcp comment 'SSH office'只有在 IP 固定且拥有服务商控制台的情况下才使用这种方式:地址变化后,你可能会把自己挡在服务器之外。
如何临时开放应用端口
如果需要直接检查服务,可以创建限制来源地址的规则:
sudo ufw allow from YOUR.PUBLIC.IP to any port 8080 proto tcp测试完成后,根据 ufw status numbered 显示的编号删除它:
sudo ufw delete RULE_NUMBER不要使用 sudo ufw allow 1:65535/tcp:这条规则会让防火墙变成形式上的摆设。
第 5 步:为 SSH 启用 Fail2ban
Fail2ban 会分析日志,并在多次登录失败后添加临时封禁规则。它不能替代 SSH 密钥和防火墙,但可以减少自动化密码尝试造成的噪声。
创建本地配置,避免软件包更新覆盖你的设置:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local在 [DEFAULT] 部分设置合理的值:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
banaction = ufw
[sshd]
enabled = true
port = 22启动服务并检查 jail:
sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd在 sshd 的输出中查看失败尝试次数和已封禁的地址。不要把自己的 IP 加入封禁列表。如需永久排除某个地址,可在 [DEFAULT] 中使用参数 ignoreip = 127.0.0.1/8 YOUR.PUBLIC.IP。
第 6 步:启用自动更新
自动更新对安全软件包很有帮助,但内核重启仍然需要人工控制:
sudo dpkg-reconfigure -plow unattended-upgrades
sudo systemctl status unattended-upgrades每周检查一次是否需要重启:
test -f /var/run/reboot-required && echo 'Требуется перезапуск'手动重启前,确认你有可用的密钥以及 VPS 控制台访问权限。重启后检查应用服务、Nginx、UFW 和 Fail2ban 是否正常运行。
第 7 步:从外部验证结果
请从另一台电脑检查防护,不要只根据配置文件的内容判断:
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no alex@SERVER_IP这条命令应该以拒绝连接结束。单独验证密钥登录:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 alex@SERVER_IP在 VPS 上检查监听地址和规则:
sudo ss -lntup
sudo ufw status numbered
sudo fail2ban-client status sshd如果应用不需要直接访问,应用端口应该监听 127.0.0.1。你可以从外部节点使用 nmap SERVER_IP,但只能扫描自己的服务器:未经允许检查他人基础设施,可能违反法律和服务商规则。
备份与恢复
SSH 防护无法防止数据被删除、管理员操作失误或应用遭到入侵。请将数据库、配置文件和用户文件的副本保存在 VPS 之外。最基本的方案是每天备份,保留前几天的多个版本,并定期验证能否恢复。
不要把密码和令牌以明文写入脚本。一旦发生泄露,应立即撤销该秘密并创建新的秘密。
如何为安全项目选择 VPS
安全始于对基础设施的控制。使用 VPS 时,你可以自行选择操作系统、防火墙规则、访问方式、备份方案以及服务的部署位置。对于小型网站或 API,稳定的网络、SSD 和恢复控制台通常比过多的虚拟 CPU 核心更重要。
在 tropic.host 上启动 VPS 项目时,先明确项目对外提供的入口:多数情况下 SSH、HTTP 和 HTTPS 就足够了。数据库和管理面板应保留在内部网络中。随着项目增长,可以将应用、数据库和监控分别部署到不同的 VPS,以隔离故障影响范围。选择稳定的网络、便捷的控制台和适合扩展的资源配置,能让安全策略更容易长期执行。
常见错误
- 未验证密钥登录就关闭密码。保留当前会话,并单独测试新的登录方式。
- 在可以限制可信地址的情况下,仍让全世界都能访问
22/tcp。 - 直接发布 Docker 端口。应先检查 Docker 和 UFW 的规则。
- 安装 Fail2ban 后就再也不查看日志。每次修改后都应检查
journalctl -u ssh和 jail 状态。
总结
只要按照正确顺序操作,VPS 的基础防护并不需要太多时间:创建独立用户,安装 SSH 密钥,验证访问,禁止 root 和密码登录,启用 UFW,配置 Fail2ban 及自动更新。之后再加入备份、日志记录和外部监控。
这些步骤不能让服务器绝对不可入侵,但可以解决初始配置中最常见的错误。下一步应根据具体应用调整安全配置:更新依赖,限制服务权限,保护管理面板,并定期检查开放端口。
FAQ
需要修改 SSH 的默认端口吗?
不一定。修改端口可以减少自动化扫描的噪声,但不能替代密钥、禁用密码、UFW 和 Fail2ban。如果修改端口,请同时更新防火墙规则和 Fail2ban jail 中的 port 参数。
配置 UFW 后失去访问权限怎么办?
使用服务商提供的 Web 控制台或救援控制台,检查 SSH 规则和 sshd 配置。在新登录方式确认可用之前,不要关闭旧的工作会话。
Fail2ban 足够保护 SSH 吗?
不够。Fail2ban 只能对已经发生的登录失败做出反应。基础防护应包括 SSH 密钥、关闭密码认证、为用户设置最小权限,以及限制访问范围的防火墙。
可以只允许一个 IP 连接 SSH 吗?
可以,只要该地址固定:在 UFW 中添加针对该 IP 的 allow from 规则。请提前准备服务商控制台或备用访问方式,因为 IP 变更后连接会被阻断。
应该多久检查一次 VPS 安全性?
每次修改 SSH、防火墙或 Docker 端口发布规则后,都应检查端口并测试登录。日常至少每周查看一次更新和日志,并定期进行备份恢复测试。