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 中执行:

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 执行:

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。

部署完成后新开一个终端试试:

BASH

能直接进去就说明密钥生效了。先不要关掉当前这个还连着密码登录的会话,下一步配置出错时还要靠它恢复。

配置 ~/.ssh/config

每次输入用户名、地址、端口、密钥路径太啰嗦。把它们写进配置文件,用一个别名登录。

在本地 C:\Users\用户名\.ssh\ 下新建或编辑 config 文件(没有后缀名):

PLAINTEXT
Host my-vps
    HostName 1.2.3.4
    User root
    IdentityFile ~/.ssh/id_ed25519
    # 如果端口不是 22,加一行
    Port 2222

以后只需要:

BASH
ssh my-vps

几台机器就写几段。同一个别名还可以被 scp、rsync、git 复用,比如 scp file.txt my-vps:/root/。

配置 VS Code Remote-SSH

SSH Key 和 config 就绪后,VS Code 可以直接复用这份配置:

  1. 安装扩展 Remote - SSH。
  2. 点击左下角绿色图标 ><,选择 Connect to Host…
  3. 选择刚才配置的 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 里每一行长这样:

TEXT
ssh-ed25519 AAAAC3Nza... my-laptop
ssh-ed25519 AAAAC3Nza... office-pc

末尾的注释就是区分依据,所以生成密钥时 -C 要写清楚。

确认密钥可用后关闭密码登录

密钥能稳定登录之后,可以关掉密码登录,减少被爆破的风险。

改之前保持一个已经登录的终端会话不要关,否则配置写错就再也进不去了(这时候只能去服务商控制台用 VNC 救援)。

编辑 /etc/ssh/sshd_config:

PLAINTEXT
PasswordAuthentication no
PubkeyAuthentication yes

重启 SSH 服务:

BASH
service ssh restart

然后不要断开当前会话,另开一个终端用密钥登录验证。确认能进之后,再关掉旧会话。

如果新连接被拒绝,回到还开着的会话,把 PasswordAuthentication 改回 yes 重启,先排查密钥问题。

常见问题

Permission denied (publickey) 公钥没写进 authorized_keys,或者写进去了但格式损坏(多了换行、少了空格)。在服务器上检查 cat ~/.ssh/authorized_keys,每一行应该以 ssh-ed25519 开头、以注释结尾,中间不能断行。

权限报错

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

Windows 下公钥粘进去无效 基本就是编码问题。用前面那段 PowerShell 脚本部署,它在内存里做了 Trim(),比手动复制可靠。

改了端口连不上 config 里的 Port 和服务器 /etc/ssh/sshd_config 的 Port 要一致;另外记得在防火墙或安全组里放行新端口,否则改完端口就彻底失联。

相关内容

本文以“新买 VPS 从零开始”为主线,记录 Cloudflare Tunnel 的核心原理、两种创建方式(控制台/命令行)、systemd 常驻、YAML 配置、DNS 绑定与常见 502 故障排查,并给出一套更安全的落地实践:服务只监听本机、通过 Tunnel 暴露、再叠加 Access 做强认证。

Cloudflare运维Linux

一台 2C4G VPS 上用 1Panel(LEMP + Docker)跑多个 WordPress,优化后后台变慢并出现 EdgeOne 524。本文按时间线复盘:如何从“缓存/超时”误区切换到“容器环回 + Docker 出网被 iptables FORWARD 掐死”的根因定位,最终用 host-gateway + iptables 持久化完成修复,并给出可复制的检查清单。

WordPress运维1Panel

记录一次访问 Gemini 遇到“异常流量”风控提示的排查结论:在双栈(IPv4+IPv6)环境下,Google 等高风控站点可能对会话出口识别不一致,从而触发拦截。最小成本方案是直接在 VPS 上禁用 IPv6,让所有出站稳定走 IPv4。

Google运维Linux

搜索

开始搜索
↑↓
↵
ESC
Ctrl K快捷键