SSH 安全登录终极配置:从密钥生成到 fail2ban

目录

VPS 暴露在公网,第一道防线就是 SSH。默认配置(22 端口 + 密码登录)等于把家门钥匙挂在门把手上——你不去看 /var/log/auth.log,永远不知道每天有几千次自动化爆破在尝试你的 root 密码。

这篇把 SSH 安全登录的完整流程从头讲到尾:密钥生成 → 公钥上传 → 服务端配置 → 防火墙 → fail2ban,每一步都说清楚为什么这么做。

一、最终目标

流程图流程图

四道关卡叠加,攻击成本指数级上升。

二、第一步:本地生成密钥对

在你自己的电脑上(不是 VPS):

2.1 PowerShell / Bash / Zsh 都一样

ssh-keygen -t ed25519 -C "my-vps-key" -f ~/.ssh/my-vps-key
参数 含义
-t ed25519 算法(ed25519 比 RSA 更短更安全)
-C "..." 注释,方便区分多个密钥
-f path 私钥文件名

提示输入 passphrase(密钥保护密码):

  • 本地开发机:可设可不设,设了每次用都要输
  • 服务器中转 / 自动化场景:直接回车不设

2.2 生成结果

会得到两个文件:

文件 用途
~/.ssh/my-vps-key 私钥,绝不能泄露,绝不上传
~/.ssh/my-vps-key.pub 公钥,传到所有要登录的服务器

2.3 查看公钥内容

cat ~/.ssh/my-vps-key.pub

输出类似:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...........xxxxxxxx my-vps-key

整行复制下来。

三、第二步:把公钥放到 VPS

3.1 方式一:ssh-copy-id(最简单)

ssh-copy-id -i ~/.ssh/my-vps-key.pub root@<VPS_IP>
# 输入一次密码,自动放到 ~/.ssh/authorized_keys

3.2 方式二:手动 echo(万能)

如果商家不支持 ssh-copy-id 或 Windows 没装:

# 先用密码 SSH 进去
ssh root@<VPS_IP>

# 在 VPS 上跑
mkdir -p ~/.ssh
chmod 700 ~/.ssh

# 把整行公钥追加到 authorized_keys
echo "ssh-ed25519 AAAAC3...... my-vps-key" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

# 验证权限
ls -la ~/.ssh/

权限必须是:

drwx------ 2 root root .          (.ssh 700)
-rw------- 1 root root authorized_keys   (600)

🪤 90% 的“密钥登录失败”都是权限错。权限太宽 sshd 会拒绝读密钥,就一直要密码。

3.3 验证密钥登录可用

开一个新终端(旧的别关,万一密钥配错可以救):

ssh -i ~/.ssh/my-vps-key root@<VPS_IP>

不让你输密码、直接进去——成功。

四、第三步:配置 sshd

4.1 备份原配置

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

4.2 修改 /etc/ssh/sshd_config

sudo vim /etc/ssh/sshd_config

找到以下行(如果前面有 # 要去掉):

# 改端口(建议 1024-65535 之间随机选一个)
Port 22000

# 开启密钥登录
PubkeyAuthentication yes

# 指定授权文件位置
AuthorizedKeysFile .ssh/authorized_keys

# 关闭密码登录
PasswordAuthentication no

# 关闭空密码
PermitEmptyPasswords no

# 关闭挑战应答(PAM 那套)
ChallengeResponseAuthentication no

# root 只能密钥登录(保留 root 但禁密码)
PermitRootLogin prohibit-password

# 限制登录尝试次数
MaxAuthTries 3
配置项 改前 改后 作用
Port 22 22000 避开自动化扫描
PubkeyAuthentication yes/no yes 启用密钥
PasswordAuthentication yes no 关闭密码登录
PermitEmptyPasswords no/yes no 禁止空密码
PermitRootLogin yes prohibit-password root 只允许密钥
MaxAuthTries 6 3 限制单次连接的尝试次数

4.3 检查配置语法(关键!)

sudo sshd -t

没有输出 = 配置正确。如果有 Bad configuration option 之类的错误,绝对不要重启 sshd——重启会导致 sshd 起不来,你就被锁外面了。

4.4 防火墙先开新端口

sudo ufw allow 22000/tcp
sudo ufw status

4.5 重启 sshd

sudo systemctl restart sshd
sudo systemctl status sshd

确认状态 active (running)。

4.6 确认监听端口

sudo ss -tlnp | grep ssh
# 应该显示
# LISTEN 0 128 0.0.0.0:22000 0.0.0.0:* users:(("sshd",pid=xxx,fd=3))

4.7 新终端验证新端口

别关旧终端,新开:

ssh -p 22000 -i ~/.ssh/my-vps-key root@<VPS_IP>

进得去——再删 22 端口的防火墙规则:

sudo ufw delete allow 22

五、第四步:fail2ban 兜底

即使密钥登录、改了端口,攻击者还是可能扫到你的端口疯狂尝试。fail2ban 会监控日志,N 次失败自动封 IP M 分钟。

5.1 装 + 配置

sudo apt install -y fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo vim /etc/fail2ban/jail.local

把 [sshd] 段改成:

[sshd]
enabled = true
port = 22000
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
backend = auto

# 自己的家庭/办公 IP 加白名单,避免自封
ignoreip = 127.0.0.1/8 ::1 <你的家庭 IP>

5.2 启动

sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban

5.3 常用命令

# 总览
sudo fail2ban-client status

# 看 sshd jail(含被封 IP 列表)
sudo fail2ban-client status sshd

# 手动封 / 解封
sudo fail2ban-client set sshd banip 1.2.3.4
sudo fail2ban-client set sshd unbanip 1.2.3.4

六、本地 SSH config(开发体验飞升)

每次 ssh -p 22000 -i ~/.ssh/my-vps-key root@<IP> 太累。

编辑 ~/.ssh/config:

Host myvps
    HostName 1.2.3.4
    Port 22000
    User root
    IdentityFile ~/.ssh/my-vps-key
    ServerAliveInterval 60
    ServerAliveCountMax 3

之后只用:

ssh myvps
配置项 含义
Host 别名
HostName 真实 IP/域名
Port 端口
User 默认用户
IdentityFile 私钥路径
ServerAliveInterval 多少秒发一次心跳(防止 NAT 断开)
ServerAliveCountMax 心跳几次没回应才认定断了

七、Termius / Tabby / 其它 GUI 客户端

这类工具的“添加密钥”功能:

  1. 生成密钥:在客户端里 Keys → Generate Key
  2. 导入私钥:把本地生成的私钥整个文件内容粘贴进去(不要只贴公钥)
  3. 绑定到主机:在主机配置里选这个 key

不同客户端 UI 不一样,原理都是一样:私钥放在客户端 / 本地,公钥放在 VPS 的 ~/.ssh/authorized_keys。

八、所有关键文件位置

文件 作用 权限
本地 ~/.ssh/private_key 私钥 600
本地 ~/.ssh/public_key.pub 公钥 644
本地 ~/.ssh/config 客户端配置 600
VPS /etc/ssh/sshd_config 服务端配置 644
VPS ~/.ssh/authorized_keys 已授权公钥列表 600
VPS /var/log/auth.log SSH 登录日志 -
VPS /etc/fail2ban/jail.local fail2ban 配置 -

九、踩坑清单

现象 原因 解决
密钥配了还是要密码 ~/.ssh 或 authorized_keys 权限不对 chmod 700 ~/.ssh; chmod 600 authorized_keys
改端口连不上 防火墙没放新端口 VNC 进去 ufw allow 新端口
sshd restart 后服务起不来 配置语法错 用 sshd -t 提前检查
改了配置没生效 没 restart sshd systemctl restart sshd
改端口没生效(仍 22) 云厂商平台代理 SSH ss -lntp grep :22 看监听的是 sshd 还是 init
fail2ban 把自己封了 没加 ignoreip VNC 进去 fail2ban-client set sshd unbanip 你的IP
部分商家轻量服务器没法改端口 平台层硬编码 22 去厂商控制台改

十、几条实用经验

  • 不要用 RSA,用 ed25519。短、快、安全。
  • 公钥可以放多份,authorized_keys 一行一个,多设备共用同一 VPS 很方便。
  • 私钥分机器:每台开发机生成自己的密钥,VPS 上 authorized_keys 加多行,任何一台机器丢失只需要删那行。
  • 改完 sshd 一定先 sshd -t 再 restart——这一条能救命。
  • fail2ban 不是万能:它防 SSH 爆破有用,对零日漏洞无能为力。保持系统更新才是根本。
  • 永远不要图省事用密码登录——爆破一旦被打穿,整台机器没了。

完成这一套,你的 SSH 已经能扛住绝大多数自动化攻击。剩下的就是养成“系统勤更新、关注 CVE”的习惯。