重装之后的第一件事不是装软件

系统重装完,ssh root@ip 一通,密码进去——这一步就已经错了。

上一台机器出事,本质就是「密码可以被人猜」。所以这次第一件事是:把密码登录这条路彻底关掉,改成密钥。

SSH 换密钥

本地生成一对 ed25519(比 RSA 短、比 RSA 快、强度还更高):

ssh-keygen -t ed25519 -f ~/.ssh/cyk_server -N ""

把公钥追加到服务器的 ~/.ssh/authorized_keys,权限必须是这套:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

然后写一份加固配置,放在 sshd_config.d/ 下(注意文件名要排在云厂商的默认配置前面,因为 sshd 是「先读到的生效」):

PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
MaxAuthTries 3

prohibit-password 的意思不是「允许 root 用密码」,而是「root 只能用密钥」——等于把 root 远程登录变相禁掉了。

改完先 sshd -t 验证语法,再 reload。验证前不要关当前窗口,不然配错了就真的进不去了。

现在登录长这样:

ssh cyk-server

.ssh/config 里配好别名,不用记 IP、不用带 -i。

端口从 12 个砍到 3 个

老机器上开了一堆端口:MySQL、Redis、Nacos、MinIO 控制台……每个都是当年「临时测一下」留下的。

新机器只留:

端口 用途
22 SSH
80 HTTP(301 跳 HTTPS)
443 HTTPS

图床的 9000 和 9090 全部改成只监听 127.0.0.1,需要的时候用 SSH 隧道临时打开:

ssh -L 9000:127.0.0.1:9000 -L 9090:127.0.0.1:9090 ubuntu@ip -N

隧道比开放端口好在:它要求先有 SSH 密钥。开端口是「对全世界开一扇门」,隧道是「拿着钥匙才给你开」。

fail2ban

老机器被打了 4466 次,一次告警都没有。这次装上:

apt install fail2ban

默认策略是「10 分钟内失败 5 次封 10 分钟」——10 分钟太短了,换个时间再来就跟没封一样。改成封一天:

# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 86400
findtime = 600
maxretry = 5

有个副作用要记住:自己输错 5 次也会被封一天。被 DROP 掉的表现是「连接超时」而不是「拒绝连接」,很容易误判成网络问题。解封:

fail2ban-client set sshd unbanip 你的IP

服务不再直接对外

图床(MinIO)收到内网,对外只通过 nginx 反代一个路径:

location ^~ /cykblog/ {
proxy_pass http://127.0.0.1:9000;
add_header Cache-Control "public, max-age=2592000";
proxy_set_header Host $host;
}

这里有个坑:前缀 location 必须写 ^~。否则下面那条「静态资源后缀」的正则 location 会优先匹配,把 /cykblog/xxx.webp 当成磁盘文件去找,直接 404。

文件管理(FileBrowser)也收到内网,但因为它有网页界面、还要长期对外,所以在 nginx 前面又加了一道 Basic Auth:

location ^~ /files/ {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://127.0.0.1:8081;
}

密码文件用 openssl 直接生成,不用额外装包:

printf 'user:%s\n' "$(openssl passwd -apr1 '你的密码')" > /etc/nginx/.htpasswd

现在访问 /files/ 是两层:先进 nginx 的认证,再进 FileBrowser 自己的登录页。这套软件官方已经停止维护了,多一层能挡住「拿已知漏洞直接打」的自动化扫描。

证书

Let’s Encrypt,certbot 自动续期,90 天一轮。装完确认一下定时任务在:

systemctl list-timers | grep certbot

一个反直觉的点

加固做完之后,日常使用几乎没有变麻烦:

  • SSH 还是敲一句,只是不用输密码了
  • 图床上传还是拖文件,只是先开个隧道(或者用 PicGo 配好一次)
  • 网页访问完全没区别

真正变麻烦的只有一件事:换新设备的时候要加一次公钥。三十秒的事。

反过来想,那台老机器省下的这三十秒,代价是两周的 root 权限在别人手里。