📖 前言
在自动化备份、CI/CD 部署等场景中,我们经常需要脚本免密登录远程服务器进行文件传输。传统的密码认证方式存在两个问题:
- 安全性:密码在网络上传输,有被窃听的风险
- 自动化困难:密码需要明文写在脚本里,管理和维护都很麻烦
SSH 公钥认证是解决这些问题的标准方案。本文将手把手教你如何从零开始配置 SSH 公钥认证,让你的 WinSCP 脚本能够免密上传文件到 SFTP 服务器。
🎯 适用场景
- Windows 服务器通过 WinSCP 自动备份文件到 Linux SFTP 服务器
- CI/CD 流水线自动部署文件到远程服务器
- 任何需要脚本免密 SFTP 传输的场景
📋 环境说明
| 角色 | 操作系统 | IP | 用户 |
|---|---|---|---|
| 客户端(运行脚本) | Windows Server | 172.16.0.60 | Administrator |
| SFTP 服务器(接收文件) | Ubuntu | 172.16.0.70 | vodserver |
🔑 第一步:在 Windows 上生成密钥对
1.1 下载 PuTTYgen
PuTTYgen 是 PuTTY 套件中的密钥生成工具。
- 独立版下载 :访问 PuTTY 官网(https://www.putty.org/),下载
puttygen.exe单文件 - 完整套件:下载 PuTTY 安装包,安装时勾选 PuTTYgen 组件
- WinSCP 自带 :如果已安装 WinSCP,PuTTYgen 可能在
C:\Program Files (x86)\WinSCP\PuTTYgen.exe
1.2 生成密钥对
-
打开 PuTTYgen
- 双击
puttygen.exe打开 - 如果安装了完整套件,在开始菜单搜索 "puttygen"
- 双击
-
配置参数
Parameters:选择 RSANumber of bits in a generated key:填写 2048 或 4096(推荐 2048 已足够)
-
生成密钥
- 点击
Generate按钮 - 在进度条下方的空白区域随意移动鼠标,直到进度条走完
- 移动鼠标是为了生成随机数据,提高密钥安全性
- 点击
1.3 保存公钥
⚠️ 重要:公钥格式必须正确,否则 OpenSSH 服务器无法识别!
- 在
Public key for pasting into OpenSSH authorized_keys file文本框中,选中所有内容并复制 (以ssh-rsa开头的一整行) - 打开记事本,粘贴复制的公钥内容
- 保存为
id_rsa.pub(或任意名称,后缀为.pub)
❌ 错误做法 :不要点击 PuTTYgen 界面上的
Save public key按钮。该按钮保存的格式是 PuTTY 专属格式,OpenSSH 服务器无法识别。
正确的公钥格式示例:
ssh-rsa AA********************************************************************************************************************************************************************************************************************************************************************************************************************************************************EqLs5 rsa-key-20260827
| 公钥组成部分 | 说明 |
|---|---|
ssh-rsa |
密钥类型标识符 |
AAAAB3... |
Base64 编码的密钥体 |
rsa-key-20260827 |
注释(便于识别,可自定义) |
1.4 保存私钥
私钥是 WinSCP 脚本用来认证的"钥匙",必须妥善保管!
- 在 PuTTYgen 窗口,点击
Save private key按钮 - 弹出警告:"Are you sure you want to save this key without a passphrase?"(是否在不设置密码短语的情况下保存?)
- 因为这是自动化脚本使用,我们选择
Yes - 如果在交互式场景中使用,建议设置密码短语提高安全性
- 因为这是自动化脚本使用,我们选择
- 给私钥命名,必须使用
.ppk后缀 ,如id_rsa_for_winscp.ppk - 保存在安全位置(如
D:\keys\)
🔒 安全提示:私钥文件相当于你的密码,请勿上传到代码仓库或分享给他人!
🖥️ 第二步:在 SFTP 服务器上部署公钥
2.1 登录服务器
使用密码登录 SFTP 服务器:
bash
ssh vodserver@172.16.0.70
输入密码 vodserver(以实际密码为准)
2.2 创建 .ssh 目录
如果 .ssh 目录不存在,创建它并设置正确的权限:
bash
mkdir -p ~/.ssh
chmod 700 ~/.ssh
chmod 700确保只有目录所有者(你自己)可以读写执行,这是 SSH 的安全要求。
2.3 将公钥添加到 authorized_keys
有三种方法可供选择,根据你的习惯使用其中一种即可。
方法一:使用 echo 命令直接追加(最简单,推荐)
bash
echo 'ssh-rsa AA********************************************************************************************************************************************************************************************************************************************************************************************************************************************************EqLs5 rsa-key-20260827' >> ~/.ssh/authorized_keys
⚠️ 注意:请将上面的公钥替换为你的实际公钥内容!
方法二:使用编辑器手动粘贴
bash
vi ~/.ssh/authorized_keys
# 或
nano ~/.ssh/authorized_keys
按 i 进入插入模式,粘贴公钥内容,按 Esc,输入 :wq 保存退出。
⚠️ 重要 :如果
authorized_keys文件已存在且有其他公钥,使用>>追加 ,不要用>覆盖,否则会删除已有的公钥!
方法三:通过 SFTP/SCP 上传公钥文件(适合不熟悉命令行的用户)
如果你不习惯用 echo 命令或 vim 编辑器,也可以先把公钥文件上传到服务器,然后再追加到 authorized_keys。
第1步:上传公钥文件到服务器
使用 WinSCP 命令行上传:
powershell
# 使用 WinSCP 上传公钥文件
& "C:\Program Files (x86)\WinSCP\WinSCP.com" /command `
"open sftp://vodserver:vodserver@172.16.0.70/ -hostkey=""*""" `
"put D:\id_rsa.pub /home/vodserver/" `
"exit"
或使用 SCP 命令(需安装 OpenSSH 客户端):
cmd
scp D:\id_rsa.pub vodserver@172.16.0.70:/home/vodserver/
或使用 WinSCP 图形界面:
- 打开 WinSCP,用密码登录
vodserver@172.16.0.70 - 将
id_rsa.pub文件拖拽到远程目录/home/vodserver/
第2步:SSH 登录服务器
bash
ssh vodserver@172.16.0.70
输入密码 vodserver
第3步:创建 .ssh 目录并追加公钥
bash
# 创建 .ssh 目录(如果不存在)
mkdir -p ~/.ssh
# 将上传的公钥文件内容追加到 authorized_keys
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
# 设置正确的权限(关键步骤!)
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
# 删除临时上传的公钥文件
rm ~/id_rsa.pub
第4步:退出服务器
bash
exit
2.4 设置文件权限(最关键的一步!)
无论使用哪种方法,最后都必须设置正确的权限:
bash
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
为什么权限如此重要?
SSH 服务会检查 authorized_keys 文件的权限。如果文件权限过于宽松(如其他用户可读写),SSH 会认为不安全而拒绝公钥认证。
| 文件/目录 | 正确权限 | 错误权限 |
|---|---|---|
~/.ssh/ |
700 (drwx------) |
755 或 777 |
~/.ssh/authorized_keys |
600 (-rw-------) |
644 或 666 |
2.5 退出服务器
bash
exit
🧪 第三步:验证公钥认证
3.1 使用 WinSCP 测试
在 Windows PowerShell 中执行:
powershell
& "C:\Program Files (x86)\WinSCP\WinSCP.com" /command "open sftp://vodserver@172.16.0.70/ -hostkey=""*"" -privatekey=""D:\id_rsa_for_winscp.ppk""" "ls" "exit"
预期输出:
- 列出远程目录内容
- 不需要输入密码
3.2 使用 SSH 命令测试(需安装 OpenSSH 客户端)
cmd
ssh -i D:\id_rsa_for_winscp.ppk vodserver@172.16.0.70
预期结果:直接登录成功,不需要输入密码。
3.3 测试失败排查
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 仍然提示输入密码 | 权限设置错误 | chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys |
| 连接被拒绝 | SSH 服务未运行 | sudo systemctl start ssh |
| 公钥格式错误 | 使用了 PuTTYgen 的 Save public key 格式 |
使用 ssh-rsa 开头的那一行 |
| 私钥路径错误 | .ppk 文件路径不正确 |
确认私钥文件路径和文件名 |
| 服务器无法连接 | 防火墙拦截 22 端口 | 检查防火墙规则,放行 22 端口 |
🔧 第四步:修改备份脚本
验证公钥认证成功后,修改脚本中的 WinSCP 上传部分:
修改前(密码认证)
powershell
$UploadScript = @"
open sftp://$SftpUser:$SftpPassword@$SftpServer:$SftpPort/ -hostkey="*"
put "$ServerDumpFile" "$SftpRemotePath/"
exit
"@
修改后(公钥认证)
powershell
$UploadScript = @"
open sftp://$SftpUser@$SftpServer:$SftpPort/ -hostkey="*" -privatekey="D:\id_rsa_for_winscp.ppk"
put "$ServerDumpFile" "$SftpRemotePath/"
exit
"@
关键变化:
- 去掉
:$SftpPassword(不再需要密码) - 添加
-privatekey="D:\id_rsa_for_winscp.ppk"(指定私钥文件)
完整的 SFTP 配置变量
powershell
# ---------- SFTP Config ----------
$SftpServer = "172.16.0.70"
$SftpPort = 22
$SftpUser = "vodserver"
$SftpPrivateKey = "D:\id_rsa_for_winscp.ppk" # 私钥文件路径
$SftpRemotePath = "/home/vodserver/oracle/backup/dmp/"
🛡️ 安全最佳实践
1. 主机密钥验证(Host Key)
在生产环境中,建议用实际的主机密钥指纹替换 -hostkey="*":
powershell
# 先通过 WinSCP 获取主机密钥指纹
# 然后用实际的指纹替换
open sftp://vodserver@172.16.0.70/ -hostkey="ssh-rsa 2048 xx:xx:xx:xx:..." -privatekey="D:\id_rsa_for_winscp.ppk"
2. 私钥文件保护
- 将私钥文件放在只有脚本运行账户能访问的目录
- 不要将私钥文件上传到代码仓库
- 考虑使用 Windows 证书存储或凭据管理器
3. 定期轮换密钥
建议每半年或一年重新生成密钥对并更新服务器上的公钥。
📋 完整配置检查清单
| 步骤 | 检查项 | 状态 |
|---|---|---|
| 1 | PuTTYgen 生成 RSA 密钥对 | ☐ |
| 2 | 保存公钥为 .pub 文件(以 ssh-rsa 开头) |
☐ |
| 3 | 保存私钥为 .ppk 文件 |
☐ |
| 4 | 服务器上创建 ~/.ssh/ 目录(权限 700) |
☐ |
| 5 | 公钥内容追加到 ~/.ssh/authorized_keys |
☐ |
| 6 | authorized_keys 权限设置为 600 |
☐ |
| 7 | WinSCP 测试免密登录成功 | ☐ |
| 8 | 备份脚本中的 open 命令改用 -privatekey |
☐ |
| 9 | 脚本中移除密码相关变量 | ☐ |
📝 三种部署方法对比
| 方法 | 优点 | 缺点 | 适用人群 |
|---|---|---|---|
| 方法一:echo 直接追加 | 无需上传文件,一步完成 | 公钥内容需要手动复制粘贴 | 熟悉命令行的用户 |
| 方法二:编辑器粘贴 | 直观,可检查内容 | 需要熟悉 vi/nano 编辑器 | 习惯用编辑器的用户 |
| 方法三:SFTP/SCP 上传 | 适合不熟悉命令行的用户 | 需要多几步操作 | 新手或习惯 GUI 的用户 |
三种方法效果完全相同,选择你习惯的方式即可。
🚀 总结
SSH 公钥认证配置的核心步骤可以概括为:
- 生成:在 Windows 上用 PuTTYgen 生成密钥对
- 部署 :将公钥部署到 SFTP 服务器的
~/.ssh/authorized_keys - 应用:修改 WinSCP 脚本使用私钥认证
- 验证:测试免密登录是否成功
配置完成后,你的备份脚本将能够:
- 无需人工干预自动运行
- 不再需要明文保存密码
- 享受更高的安全性
📚 参考资料
本文档基于实际生产环境配置经验编写,如有问题欢迎交流讨论。 😊