SSH 安全配置与密钥管理

SSH 是运维人员的命门。配置不好,服务器就是裸奔。很多新手习惯用密码登录,觉得改个复杂密码就万事大吉。大错特错。现在自动化爆破脚本满天飞,你的密码再复杂,也挡不住每秒上千次的撞库尝试。

今天聊聊怎么把 SSH 这一关守死。我不讲虚的,直接上干货。

1. 核心原则:弃用密码,拥抱密钥

密码登录是弱口令攻击的重灾区。密钥登录基于非对称加密,私钥在你手里,公钥在服务器上。没有私钥,黑客就算拿到你的服务器 IP 也进不去。

生成密钥

我在自己的 Mac 和 Linux 工作站上,通常使用 Ed25519 算法。它比传统的 RSA 更快,安全性更高,密钥更短。

ssh-keygen -t ed25519 -C "[email protected]"

执行后,系统会让你输入保存路径。直接回车用默认路径 ~/.ssh/id_ed25519 就行。接着要求设置 passphrase( passphrase 一定要设,这是私钥的第二道防线)。

> 注意:Passphrase 是你每次使用密钥时的“密码”。很多人为了省事不设,这等于把私钥明文存储。我习惯设一个强短语,然后用 ssh-agent 缓存,这样既安全又不用每次都敲。

部署公钥

把生成的公钥内容复制到目标服务器的 ~/.ssh/authorized_keys 文件中。

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote-server

这一步看似简单,但有个坑:如果目标服务器上 ~/.ssh 目录权限不是 700,或者 authorized_keys 权限不是 600,OpenSSH 会拒绝加载密钥,让你回退到密码登录。

2. 加固 sshd_config

密钥登录只是第一步。默认的 sshd_config 充满了安全隐患。你需要亲手修改 /etc/ssh/sshd_config

禁止 Root 直接登录

这是最基本的。Root 权限太高,一旦泄露后果严重。创建一个普通用户,通过 sudo 提权。

# 在 sshd_config 中
PermitRootLogin no

限制登录用户

不要允许所有系统用户通过 SSH 登录。只允许你需要管理的那几个人。

# 在 sshd_config 中
AllowUsers admin deployer
# 或者使用白名单组
AllowGroups wheel sudo ssh-users

这样,即使黑客拿到了 www-datamysql 的凭证,也登录不进来。

更改默认端口

把 22 改成其他端口。这不能阻止专业的扫描器,但能挡住 99% 的自动化垃圾流量。

# 在 sshd_config 中
Port 2222

改完后,记得在防火墙里放行新端口,并关闭旧端口。

禁用空密码

确保没有用户能设置空密码登录。

PermitEmptyPasswords no

3. 密钥管理的陷阱与最佳实践

我自己踩过的坑是:把私钥硬编码在 CI/CD 配置文件里。一旦代码仓库泄露,服务器也就跟着泄露。

私钥绝不落地

在自动化部署中,私钥应该通过环境变量或秘密管理工具(如 HashiCorp Vault, AWS Secrets Manager)注入到运行环境中,而不是以文件形式存在磁盘上。

如果你必须在本地使用密钥,确保文件权限严格:

chmod 600 ~/.ssh/id_ed25519

轮换密钥

密钥不是设了就完事。建议每 6-12 个月轮换一次密钥对。

操作流程:
1. 生成新密钥对。
2. 将新公钥添加到 authorized_keys
3. 验证新密钥可以登录。
4. 移除旧公钥。

不要同时删除旧公钥,以防新密钥有问题导致无法登录。

使用 SSH Agent Forwarding 要小心

SSH Agent 转发(ssh -A)允许你在跳板机上使用本地私钥访问后端服务器。这很方便,但如果跳板机被攻陷,攻击者就能利用你的代理访问后端。

建议:只在必要时使用,且确保跳板机安全等级极高。对于生产环境,我更倾向于使用跳板机作为独立的堡垒机,通过证书或更严格的访问控制来管理后端服务器。

4. 监控与审计

配置再完美,也要有监控。你需要知道谁在尝试登录,以及登录是否成功。

启用日志

确保 sshd_config 中日志级别足够:

LogLevel INFO

在 Linux 上,SSH 日志通常位于 /var/log/auth.log (Debian/Ubuntu) 或 /var/log/secure (CentOS/RHEL)。

使用 fail2ban

自动封禁恶意 IP 的神器。配置它监控 SSH 日志,当某个 IP 在几分钟内失败登录次数超过阈值(比如 5 次),就自动在防火墙中封禁该 IP。

# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

实测发现,开启 fail2ban 后,服务器的 SSH 暴力破解请求减少了 95% 以上。

5. 进阶:SSH 证书(Certificate Authority)

对于拥有几十台甚至上百台服务器的团队,管理 authorized_keys 文件很痛苦。这时候可以考虑 SSH 证书。

SSH 证书由 CA(证书授权机构)签发。服务器只信任 CA 的公钥,而不需要手动分发每个用户的公钥。

简要流程

1. 在 CA 服务器上生成 CA 密钥对。
2. 在用户机器上生成用户密钥。
3. 将用户公钥发送给 CA 服务器,签发证书(指定有效期、权限)。
4. 在每台服务器上安装 CA 的公钥到 TrustedUserCAKeys

这样,用户只需要持有私钥和证书,登录时无需服务器端预先配置用户公钥。证书过期后自动失效,管理成本大幅降低。

总结

SSH 安全不是配置完就一劳永逸。

1. 强制密钥登录,禁用密码。
2. 最小权限原则,禁止 Root 登录,限制用户。
3. 隐藏服务,更改默认端口。
4. 自动防御,部署 fail2ban。
5. 定期审计,检查日志,轮换密钥。

我习惯每次新服务器上线时,写一个 Ansible playbook 来自动应用这些配置。这样既保证了一致性,又避免了手误。

安全是一个过程,不是一个状态。保持警惕,定期复查。

上一篇 腾讯免费48G GPU,一键部署Ollama大模型教程