14 10 月 2026

SSH 是服务器的门,门不牢,里面装修得再好也白搭。密码认证、22 端口、root 直登——这三样凑齐,等于把「欢迎光临」贴在门上。

这篇是 SSH 安全的完整方案:密钥认证、端口隐藏、双因素、跳板机架构、审计日志。按优先级排好了,从最容易做到最高级。

需要云服务器可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,网关层减少暴露面。

一、SSH 威胁到底有多大

看一组真实数据:

# 装 fail2ban 前,先看看每天有多少暴力破解
grep "Failed password" /var/log/secure | wc -l
# 常见结果: 每天几百到几千次

grep "Failed password" /var/log/secure | awk '{print $9}' | sort | uniq -c | sort -rn | head
# root / admin / test / oracle... 常见被尝试的用户名

自动化扫描器 7×24 在扫全网 22 端口。弱密码的 root 账号被攻破只是时间问题,通常几天到几周。

二、第一优先级:密钥认证 + 禁密码

这是必做项,十分钟搞定,挡掉 99% 的暴力破解。

1. 生成密钥对(本地机器操作)

# 现代推荐 ed25519(比 RSA 更短更快更安全)
ssh-keygen -t ed25519 -C "your@email.com"

# 老系统不支持 ed25519 时用 RSA 4096
ssh-keygen -t rsa -b 4096 -C "your@email.com"

# 生成的两个文件:
# ~/.ssh/id_ed25519     私钥(永远不外传!)
# ~/.ssh/id_ed25519.pub 公钥(放服务器上)

私钥加密码短语(passphrase):私钥文件被盗也用不了,多一层保护。

2. 传公钥到服务器

# 方式一: ssh-copy-id(推荐)
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@服务器IP

# 方式二: 手动
cat ~/.ssh/id_ed25519.pub | ssh root@服务器IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# 方式三: 云厂商控制台直接绑密钥(买机器时就能选)

3. 验证密钥能登录(关键!先验证再禁密码)

# 另开一个终端,测试密钥登录
ssh -i ~/.ssh/id_ed25519 root@服务器IP
# 能登上,继续下一步;登不上,别动配置!

4. 禁密码认证

# /etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin prohibit-password    # root 可以登,但必须用密钥

# 更严: 完全禁 root 登录(先用普通用户测试 sudo)
# PermitRootLogin no

systemctl restart sshd

顺序不能错:先传密钥 → 验证能登 → 再禁密码。反了就把自己锁外面了。

三、第二优先级:改端口 + 降权限

1. 改 SSH 端口

# /etc/ssh/sshd_config
Port 22222          # 别用 22

# 云安全组/NAT 映射同步放行新端口!
# 防火墙:
ufw allow 22222/tcp
ufw delete allow 22/tcp

改端口挡掉 90% 的自动化扫描(它们默认扫 22)。这是安全 by obscurity,但对扫盲式攻击极其有效。

2. 限制可登录用户

# 只允许特定用户/组登录
AllowUsers deploy admin
# 或
AllowGroups ssh-users

# 创建专用部署用户(日常用这个,不用 root)
useradd -m -s /bin/bash deploy
usermod -aG sudo deploy

3. 空闲超时

# /etc/ssh/sshd_config
ClientAliveInterval 300      # 5 分钟无操作发探测包
ClientAliveCountMax 2        # 两次无响应断开
# 效果: 挂着的 SSH 会话 10 分钟自动断,防座位离开被蹭

四、第三优先级:双因素认证(2FA)

密钥也可能泄露(笔记本被偷、私钥误传 Git)。加一道动态码:

# 安装 Google Authenticator PAM 模块
apt install -y libpam-google-authenticator

# 为用户配置(以 deploy 为例)
su - deploy
google-authenticator
# 按提示: y(时间令牌) y(重复) y(防重放) n(限速)
# 会生成二维码和 5 个备用验证码(备用码存好!)

配置 PAM:

# /etc/pam.d/sshd(文件末尾加)
auth required pam_google_authenticator.so

sshd 配置:

# /etc/ssh/sshd_config
KbdInteractiveAuthentication yes
PasswordAuthentication no       # 密钥 + 2FA
UsePAM yes
systemctl restart sshd
# 之后登录: 密钥 + 6 位动态码

备用恢复码:那 5 个备用码要离线保存(手机丢了/换手机时救命)。

五、第四优先级:跳板机架构

机器多了,每台都开 22 暴露公网?不优雅也不安全。跳板机(堡垒机)模式:

运维 → SSH → 跳板机(唯一暴露 22) → 内网机器(无公网 IP)
                 ┌─→ web1 (内网)
你的电脑 ──SSH──→ 跳板机 ─┼─→ web2 (内网)
                 └─→ db1 (内网,只许跳板机连)

好处:

  • 公网只开一个入口,攻击面缩到最小
  • 内网机器可以完全禁公网 SSH
  • 登录行为集中审计

用 SSH 配置简化(~/.ssh/config):

# 跳板机
Host jump
    HostName 跳板机IP
    User deploy
    Port 22222
    IdentityFile ~/.ssh/id_ed25519

# 内网机器(通过跳板机)
Host web1
    HostName 10.0.0.11
    User deploy
    ProxyJump jump           # 自动走跳板机

Host db1
    HostName 10.0.0.21
    ProxyJump jump

之后 ssh web1 自动跳板,无感内网访问。

NAT 场景的变体:NAT 型机器没有内网互通,跳板机模式不适用。替代方案是密钥 + 改端口 + 2FA 三板斧,靠服务商网关做入口收敛。

六、审计:谁登录过、干了什么

# 1. 登录记录
last                     # 成功登录历史
lastb                    # 失败尝试(暴力破解证据)
last -f /var/log/wtmp    # 指定月份文件

# 2. 开启 sshd 详细日志
# /etc/ssh/sshd_config
LogLevel VERBOSE         # 记录密钥指纹,能追到具体哪把钥匙

# 3. 会话录制(高安全要求)
# 装 auditd + 配置 execve 审计,或用 asciinema/tlog 录制

日志外传:日志只存本机,入侵者会删。定期外传:

# 每天把登录日志推到远程日志服务器或对象存储
grep "Accepted" /var/log/secure | tail -100 >> /var/log/ssh-audit.log
rsync -az /var/log/ssh-audit.log 日志服务器:/audit/$(hostname)/

七、加固配置模板

整合版 /etc/ssh/sshd_config,按需取:

# ===== 端口与网络 =====
Port 22222
AddressFamily inet

# ===== 认证 =====
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
PermitEmptyPasswords no
KbdInteractiveAuthentication yes          # 2FA 用
ChallengeResponseAuthentication yes       # 老版本写法
AuthenticationMethods publickey,keyboard-interactive   # 密钥+2FA(没装2FA就只留 publickey)

# ===== 权限收敛 =====
PermitRootLogin no                        # 有 deploy + sudo 后,禁 root 直登
AllowUsers deploy admin
MaxAuthTries 3                            # 每次连接最多试 3 次
MaxSessions 5                             # 每连接最多 5 个会话
LoginGraceTime 30                         # 30 秒内没认证完就断

# ===== 会话管理 =====
ClientAliveInterval 300
ClientAliveCountMax 2
TCPKeepAlive yes
UsePAM yes

# ===== 功能收敛 =====
X11Forwarding no                          # 不需要图形转发就关
AllowAgentForwarding no                   # 不让 SSH 当代理跳板(除非你就是跳板机)
AllowTcpForwarding no
PermitTunnel no
GatewayPorts no
PrintMotd no

# ===== 日志 =====
SyslogFacility AUTH
LogLevel VERBOSE

# ===== 性能 =====
Compression yes                           # 小带宽有用
UseDNS no                                 # 不反查 DNS,加速登录
# 改完必须先测语法!
sshd -t && systemctl reload sshd
# 报错就别 reload,sshd -t 会告诉你哪行有问题

八、常见问题

Q:改完配置把自己锁外面了?
云厂商控制台有 VNC 救援,进去改回来。预防:改配置前开两个会话,一个改一个留着,改完先测再关旧的。

Q:ssh-keygen 生成的公钥在哪?
~/.ssh/id_ed25519.pub(本地机器),内容是 ssh-ed25519 xxxx 备注。整个复制粘贴到服务器 ~/.ssh/authorized_keys,一行一个。

Q:密钥认证还是被爆破?
密钥本身爆不了(2048 位以上)。看到大量失败记录说明它们在试,但碰巧撞对私钥的概率约等于零。检查是不是有人试密码登录(禁掉 PasswordAuthentication)。

Q:多台机器管密钥麻烦?
用 Ansible 批量分发公钥(见Ansible 入门),或者上跳板机统一入口。

Q:2FA 手机丢了怎么办?
用备用恢复码登录(配置时生成的 5 个),重新配置。所以备用码必须离线保存。

Q:NAT 型服务器的 SSH 怎么管?
映射端口给 SSH(别用 22),密钥登录必开,能改映射端口更好。NAT 机型没有独立 IP,公网扫到的概率天然低,再叠加密钥 + 改端口,安全性足够。

小结

SSH 加固按优先级:密钥认证 + 禁密码(必做)→ 改端口 + 限用户 → 双因素 → 跳板机架构 + 审计。前三项一两个小时做完,挡住几乎所有攻击;后两项按机器数量和合规要求逐步上。所有配置改完先 sshd -t 验证,别把自己锁门外。

更多安全内容见财富云计算知识库:防火墙、fail2ban、端口最小化、应急排查全系列。需要云服务器可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上。

延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:WAF 规则实战:ModSecurity 与雷池部署调优
  2. 下一篇:网站被挂马:排查、清除与防护完整流程
发表评论 12