SSH Key 通过一对密钥验证登录身份。配置完成之后,登录 VPS、使用 VS Code Remote-SSH、跑自动化脚本都不再依赖服务器密码,多台设备的权限也可以分别授权和回收。
这篇文章按实际配置顺序走:先生成密钥,再部署到服务器,然后写 config、接上 VS Code,最后处理多设备和关闭密码登录。
密钥如何验证身份
SSH Key 是一对密钥文件:私钥留在自己电脑上,公钥放到服务器上。
- 私钥(Private Key):保存在本地,不能泄露,也不要拷贝给别的电脑。
- 公钥(Public Key):可以公开,部署到服务器的
~/.ssh/authorized_keys里。
登录时不会传输私钥。服务器拿存储的公钥发起一次加密握手,只有持有对应私钥的一方才能正确应答,从而确认「你确实拥有私钥」。
与密码登录的区别
| 登录方式 | 优点 | 缺点 |
|---|---|---|
| 密码 | 简单,开箱即用 | 易被爆破、不适合自动化、VS Code 反复弹窗 |
| SSH Key | 安全、免密、体验顺滑 | Windows 下配置时容易遇到编码和换行问题 |
密码登录还有一个隐患:一旦密码在别处泄露,攻击者可以直接尝试登录。密钥只存在于本地,服务器上只有公钥,泄露公钥无法用来登录。
在 Windows 生成密钥
在本地 PowerShell 中执行:
ssh-keygen -t ed25519 -C "my-laptop"一路回车即可。这里有一个选择:
- 回车留空:登录时不用输入私钥密码,最省事。
- 设置 Passphrase:私钥文件泄露后还能多一道保护,但每次使用密钥都要解锁,自动化脚本会变麻烦。
生成后在 C:\Users\用户名\.ssh\ 下会得到两个文件:
id_ed25519:私钥,妥善保管id_ed25519.pub:公钥,需要部署到 VPS
-C 后面的注释只是标签,用来在服务器的 authorized_keys 里区分是哪台设备。多设备场景下建议写清楚,比如 my-laptop、office-pc。
把公钥部署到 VPS
Linux 和 macOS 上可以直接用 ssh-copy-id,Windows 没有这个命令。手动复制粘贴公钥又容易出问题:PowerShell 输出文本时可能带上 BOM、CRLF 或者额外的换行,粘进 authorized_keys 后 SSH 会认为格式非法,密钥直接失效。
下面的脚本会读取公钥并在内存里清理格式,同时支持 2222 这类非标准端口。把整段粘贴进 PowerShell 执行:
& {
# --- 配置开始 ---
$ErrorActionPreference = "Stop"
$KeyPath = "$env:USERPROFILE\.ssh\id_ed25519"
# 1. 检查或生成密钥(如不存在则生成)
if (-not (Test-Path $KeyPath)) {
Write-Host "正在生成密钥..." -ForegroundColor Yellow
# -N "" 表示无密码,为了极致快;如需密码去掉 -N "" 即可
ssh-keygen -t ed25519 -f $KeyPath -C "windows_auto_key" -N ""
} else {
Write-Host "✅ 检测到已有密钥,准备复用" -ForegroundColor Green
}
# 2. 读取公钥(核心:内存清洗格式,防止乱码)
$Pub = (Get-Content "$KeyPath.pub" -Raw).Trim()
# 3. 交互输入地址(支持端口)
Write-Host "`n请输入 VPS 连接信息:" -ForegroundColor Cyan
Write-Host " - 默认端口(22)直接输:[email protected]" -ForegroundColor Gray
Write-Host " - 非标准端口请加参数:-p 2222 [email protected]" -ForegroundColor Gray
$RawInput = Read-Host "> "
if (-not $RawInput) { Write-Error "地址不能为空"; return }
# 关键处理:按空格分割参数,确保 -p 2222 能被 SSH 正确识别
$TargetArgs = $RawInput -split ' '
Write-Host "`n正在连接服务器上传公钥..." -ForegroundColor Cyan
Write-Host "⚠️ 注意:接下来请输入一次服务器的【登录密码】" -ForegroundColor Yellow
# 执行 SSH 组合拳
ssh $TargetArgs "mkdir -p ~/.ssh && echo '$Pub' >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
if ($?) {
Write-Host "`n🎉 配置成功!" -ForegroundColor Green
Write-Host "请尝试直接登录: ssh $RawInput" -ForegroundColor Gray
}
}脚本做三件事:确保本地有密钥、清理公钥格式、通过一次密码登录把公钥写进服务器并设置正确权限。
权限这一步不能省。~/.ssh 必须是 700,authorized_keys 必须是 600,否则 SSH 会拒绝使用这个密钥,并在日志里报 bad permissions。
部署完成后新开一个终端试试:
能直接进去就说明密钥生效了。先不要关掉当前这个还连着密码登录的会话,下一步配置出错时还要靠它恢复。
配置 ~/.ssh/config
每次输入用户名、地址、端口、密钥路径太啰嗦。把它们写进配置文件,用一个别名登录。
在本地 C:\Users\用户名\.ssh\ 下新建或编辑 config 文件(没有后缀名):
Host my-vps
HostName 1.2.3.4
User root
IdentityFile ~/.ssh/id_ed25519
# 如果端口不是 22,加一行
Port 2222以后只需要:
ssh my-vps几台机器就写几段。同一个别名还可以被 scp、rsync、git 复用,比如 scp file.txt my-vps:/root/。
配置 VS Code Remote-SSH
SSH Key 和 config 就绪后,VS Code 可以直接复用这份配置:
- 安装扩展 Remote - SSH。
- 点击左下角绿色图标
><,选择 Connect to Host… - 选择刚才配置的
my-vps。
连接成功后可以直接打开远程文件夹、保存代码、使用终端。网络短暂波动时 VS Code 会尝试自动重连。
这一步能省掉多少事,取决于你平时怎么改服务器上的文件。用 VS Code 连上去之后,编辑远程的 nginx.conf、wp-config.php 和本地文件没有区别,也不用来回 scp。
多设备授权与回收
不要把 A 电脑的私钥拷贝给 B 电脑。每台电脑分别生成一对密钥,只把各自的公钥部署到服务器:
- A 电脑生成一对 Key,把公钥给 VPS。
- B 电脑生成一对 Key,把公钥给 VPS。
- VPS 的
authorized_keys里会有两行记录。
这样做的价值在回收:如果 B 电脑丢失或换了,只需从 authorized_keys 里删掉 B 对应的那一行,A 电脑完全不受影响。如果两台电脑共用一把私钥,就只能一起换。
authorized_keys 里每一行长这样:
ssh-ed25519 AAAAC3Nza... my-laptop
ssh-ed25519 AAAAC3Nza... office-pc末尾的注释就是区分依据,所以生成密钥时 -C 要写清楚。
确认密钥可用后关闭密码登录
密钥能稳定登录之后,可以关掉密码登录,减少被爆破的风险。
改之前保持一个已经登录的终端会话不要关,否则配置写错就再也进不去了(这时候只能去服务商控制台用 VNC 救援)。
编辑 /etc/ssh/sshd_config:
PasswordAuthentication no
PubkeyAuthentication yes重启 SSH 服务:
service ssh restart然后不要断开当前会话,另开一个终端用密钥登录验证。确认能进之后,再关掉旧会话。
如果新连接被拒绝,回到还开着的会话,把 PasswordAuthentication 改回 yes 重启,先排查密钥问题。
常见问题
Permission denied (publickey)
公钥没写进 authorized_keys,或者写进去了但格式损坏(多了换行、少了空格)。在服务器上检查 cat ~/.ssh/authorized_keys,每一行应该以 ssh-ed25519 开头、以注释结尾,中间不能断行。
权限报错
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keysWindows 下公钥粘进去无效
基本就是编码问题。用前面那段 PowerShell 脚本部署,它在内存里做了 Trim(),比手动复制可靠。
改了端口连不上
config 里的 Port 和服务器 /etc/ssh/sshd_config 的 Port 要一致;另外记得在防火墙或安全组里放行新端口,否则改完端口就彻底失联。
相关内容
本文以“新买 VPS 从零开始”为主线,记录 Cloudflare Tunnel 的核心原理、两种创建方式(控制台/命令行)、systemd 常驻、YAML 配置、DNS 绑定与常见 502 故障排查,并给出一套更安全的落地实践:服务只监听本机、通过 Tunnel 暴露、再叠加 Access 做强认证。
一台 2C4G VPS 上用 1Panel(LEMP + Docker)跑多个 WordPress,优化后后台变慢并出现 EdgeOne 524。本文按时间线复盘:如何从“缓存/超时”误区切换到“容器环回 + Docker 出网被 iptables FORWARD 掐死”的根因定位,最终用 host-gateway + iptables 持久化完成修复,并给出可复制的检查清单。
记录一次访问 Gemini 遇到“异常流量”风控提示的排查结论:在双栈(IPv4+IPv6)环境下,Google 等高风控站点可能对会话出口识别不一致,从而触发拦截。最小成本方案是直接在 VPS 上禁用 IPv6,让所有出站稳定走 IPv4。