新 VPS 到手第一件事:从零加固 Linux 服务器安全

前言

新 VPS 到手的第一反应是什么?

我的第一反应是 apt update && apt upgrade。很多人装完更新之后就开始装 Docker、拉镜像、部署服务 —— 然后就忘了安全加固这回事。

直到某天 lastb 一看,几十万次 SSH 爆破尝试。虽然密码够强没被打进去,但心里还是咯噔一下。

安全加固这种事,做的时候觉得麻烦,出事的时候才后悔没做。趁服务器还是新的,把基础打好。

分层思维:安全不是一次性操作

安全加固不是装一个 fail2ban 就完事。我把流程分成四层:

┌─────────────────────────────┐
│ 第四层:监控层 │ fail2ban + 日志审计
├─────────────────────────────┤
│ 第三层:系统层 │ 自动更新 + 最小化安装
├─────────────────────────────┤
│ 第二层:认证层 │ 密钥登录 + 禁 root + sudo
├─────────────────────────────┤
│ 第一层:网络层 │ UFW 防火墙 + 改端口
└─────────────────────────────┘

从外到内逐层加固。脚本小子扫端口是第一层挡,弱密码攻击是第二层挡,已知漏洞是第三层挡,暴力破解是第四层挡。

第一层:网络层 — UFW 防火墙 + 改 SSH 端口

改 SSH 端口

默认 22 端口是全网扫描的首要目标。改成高位端口能挡掉 99% 的无差别扫描:

Terminal window
sudo nano /etc/ssh/sshd_config

找到 #Port 22,改成:

Port 9753

然后重启 SSH:

Terminal window
sudo systemctl restart sshd

配置 UFW

Ubuntu / Debian 自带的 UFW 够用了:

Terminal window
# 默认拒绝所有入站,允许所有出站
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 开放新 SSH 端口
sudo ufw allow 9753/tcp
# 如果后面要跑 Web 服务,提前开 80/443
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# 启用防火墙
sudo ufw enable
# 确认状态
1 collapsed line
sudo ufw status verbose

切记先 allow 你的 SSH 端口再 enable,不然把自己锁外面。

第二层:认证层 — 密钥登录 + 禁 root

创建普通用户

root 直接登录是安全隐患。创建一个日常使用的普通用户:

Terminal window
adduser vpsadmin
usermod -aG sudo vpsadmin

之后日常操作都用 vpsadmin,需要 root 权限时用 sudo

配置 SSH 密钥登录

在自己电脑上生成密钥对(还没生成过的话):

Terminal window
ssh-keygen -t ed25519 -C "vps@mifsh.de"

把公钥传到服务器:

Terminal window
ssh-copy-id -p 9753 vpsadmin@你的服务器IP

试试能不能用密钥登录:

Terminal window
ssh -p 9753 vpsadmin@你的服务器IP

能免密登录的话,下一步就是关掉密码登录。

加固 sshd_config

编辑 /etc/ssh/sshd_config

Port 9753
PermitRootLogin no # 禁止 root SSH 登录
PasswordAuthentication no # 禁止密码登录(只用密钥)
PubkeyAuthentication yes # 允许密钥登录
MaxAuthTries 3 # 最多试 3 次
ClientAliveInterval 300 # 5 分钟无操作断开
ClientAliveCountMax 2 # 最多 2 次无响应

重启生效:

Terminal window
sudo systemctl restart sshd

第三层:系统层 — 自动更新 + 最小化

自动安全更新

手动更新靠自觉,自动更新靠系统。Debian / Ubuntu 用 unattended-upgrades

Terminal window
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

选 Yes。之后安全补丁会自动安装。只装安全更新,不装功能更新,稳定性有保障。

禁用不必要的服务

Terminal window
# 看哪些服务在监听端口
ss -tlnp
# 关掉不需要的
sudo systemctl disable --now 不需要的服务名

每多一个监听端口的服务,就多一个潜在攻击面。

配置 SWAP

小内存 VPS 建议加 SWAP,防止 OOM:

Terminal window
sudo mkdir -p /swap
sudo dd if=/dev/zero of=/swap/swapfile bs=1M count=2048 # 2GB
sudo chmod 600 /swap/swapfile
sudo mkswap /swap/swapfile
sudo swapon /swap/swapfile
# 写入 fstab 重启后生效
echo '/swap/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

第四层:监控层 — fail2ban + 日志审计

fail2ban 防爆破

有人疯狂试你 SSH 密码?fail2ban 自动封 IP:

Terminal window
sudo apt install fail2ban

默认配置就能用,但建议加一点定制。创建 /etc/fail2ban/jail.local

[DEFAULT]
bantime = 3600 # 封禁 1 小时
findtime = 600 # 10 分钟窗口
maxretry = 3 # 最多试 3 次
[sshd]
enabled = true
port = 9753 # 改成你的 SSH 端口
logpath = /var/log/auth.log

重启生效:

Terminal window
sudo systemctl restart fail2ban

查看封禁列表:

Terminal window
sudo fail2ban-client status sshd

你可能会看到几十个被封的 IP。那些全是僵尸网络在扫端口 ——fail2ban 挡的就是这些。

看一眼谁在扫你

Terminal window
# 最近失败的登录尝试
sudo lastb | head -20
# SSH 认证失败日志
sudo grep "Failed password" /var/log/auth.log | tail -20

你会看到满屏的 rootadminubuntu 尝试登录。全是脚本。

完整的一键检查清单

加固完成后,跑一遍确认:

Terminal window
# 1. SSH 配置检查
sudo sshd -t # 配置语法正确?
sudo systemctl status sshd # SSH 在跑?
# 2. 防火墙检查
sudo ufw status verbose # 规则正确?
# 3. fail2ban 检查
sudo fail2ban-client status # 在跑?
sudo fail2ban-client status sshd # 监狱生效?
# 4. 自动更新检查
sudo systemctl status unattended-upgrades
# 5. 监听端口检查
4 collapsed lines
ss -tlnp # 只有必要的端口在监听
# 6. 最后登录记录
last -10

总结

这套流程我每次开新 VPS 都走一遍,熟手十分钟搞定。核心思想就三层:

  1. 挡在外面 — 改端口 + 防火墙,别让人随便连
  2. 进不来 — 禁 root + 密钥认证,没有密钥就免谈
  3. 监控着 — fail2ban + 自动更新,出事了能发现、能响应

没有完美的安全,只有「让攻击成本高于攻击收益」。对于一个跑自托管服务的 VPS 来说,上面这些配置足够让 99.99% 的攻击者换目标了。

毕竟他们扫的是 22 端口的 root 用户 —— 你两个都改了,他们连试的兴趣都没有。