目录
使用公钥连接 SSH:Linux 与 Windows 操作端完全命令指南
本文记录用公钥(密钥对)免密码、更安全地远程登录服务器的做法。全程通过命令行完成,不依赖任何图形界面。操作端(你手头的电脑)分别覆盖 Linux 与 Windows,服务端以常见的 Linux 为例。这些都是实际运维中反复用到的步骤,照着做基本能一次配通。
本文在通用做法基础上,融合了知识库「Linux运维」中多篇实战文章的要点(密钥免密登录、Windows 免密、SSH 安全加固、登录权限排错),参考资料见文末。
一、背景与准备
- 你需要知道服务器的 IP 或域名、登录用户名,以及当前可用的密码(首次拷贝公钥时需要)。
- 服务端已安装并运行
sshd(OpenSSH 服务端),且网络可达(防火墙放通 22 端口)。 - 几个基本概念:
- 公钥(public key):可以放心公开,放到服务器上。
- 私钥(private key):必须保密,只留在你的电脑里,绝不外传、绝不进聊天工具/网盘。
- 登录时,服务器用你事先放上去的公钥,验证你本地持有的私钥;配对成功即放行,全程不传输密码,因此能抵御撞库与暴力破解。
两种登录方式对比
| 方式 | 原理 | 安全性 | 便利性 |
|---|---|---|---|
| 密码登录 | 每次输入密码 | 有被暴力破解风险 | 方便但烦人 |
| 密钥登录 | 本机有私钥、服务器有公钥,验证成对关系 | 极高(私钥不出本机) | 一次配好,以后免密 |
密钥登录不仅更安全,也更方便——配好以后
ssh 服务器别名一秒连上,不用每次输密码。
二、Linux 操作端
1. 生成密钥对
bash# 推荐 ed25519 算法(现代、安全、生成快)
ssh-keygen -t ed25519 -C "我的工作机 2026"
参数说明:
-t ed25519:使用 Ed25519 算法(推荐)。-C "注释":给密钥加注释,帮助识别是哪台机器生成的(建议填上)。
兼容老设备时用 RSA 4096:
ssh-keygen -t rsa -b 4096 -C "注释"(生成慢、文件大,但安全)。
执行后会有两次提示:
Enter file in which to save the key (/home/用户名/.ssh/id_ed25519):
直接回车用默认路径。
Enter passphrase (empty for no passphrase):
- 直接回车(不设密码短语):最方便,以后连接完全免密,但私钥文件被盗后无任何保护。
- 设一个密码短语(推荐):私钥被盗也需要知道密码短语才能用;配合
ssh-agent只需输一次。
注意:这个「密码短语」不是远程服务器的密码,是用来保护本地私钥文件的。
完成后生成两个文件:
~/.ssh/ ├── id_ed25519 # 私钥(绝不能泄露!) └── id_ed25519.pub # 公钥(可以随意分发)
2. 查看公钥内容
bashcat ~/.ssh/id_ed25519.pub
# 输出类似:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... 我的工作机 2026
3. 把公钥拷贝到服务器
方法一:ssh-copy-id(推荐,最简单)
bashssh-copy-id user@server-ip
# 输入一次服务器密码,公钥自动写入 ~/.ssh/authorized_keys 并修正权限
# 指定某个密钥上传(有多把密钥时):
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server-ip
方法二:手动管道(没有 ssh-copy-id 时)
bashcat ~/.ssh/id_ed25519.pub | ssh user@server-ip \
"mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && \
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
4. 使用私钥登录
bashssh user@server-ip # 直接连上,不需要密码
ssh -i ~/.ssh/id_ed25519 user@server-ip # 显式指定使用的私钥
5. 用 ssh-agent 免去重复输入 passphrase(可选)
basheval "$(ssh-agent -s)" # 启动 agent
ssh-add ~/.ssh/id_ed25519 # 加入私钥(需输一次密码短语)
ssh-add -l # 查看已加载的密钥
ssh-add -t 8h ~/.ssh/id_ed25519 # 8 小时后自动过期,更安心
三、Windows 操作端
Windows 10(1809 起)与 Windows 11 已内置 OpenSSH 客户端。以下在 PowerShell 或 命令提示符(CMD) 中均可。
0. 确认 OpenSSH 客户端已安装(如未安装)
powershell# 以管理员身份运行 PowerShell Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 ssh -V # 能输出版本号即表示可用
1. 生成密钥对
powershellssh-keygen -t ed25519 -C "my-winpc"
路径直接回车,默认保存到:
C:\Users\<你的用户名>\.ssh\id_ed25519 C:\Users\<你的用户名>\.ssh\id_ed25519.pub
在 PowerShell 中用户目录用
$env:USERPROFILE表示(CMD 下是%USERPROFILE%)。
2. 查看公钥内容
powershell# PowerShell cat $env:USERPROFILE\.ssh\id_ed25519.pub # CMD type %USERPROFILE%\.ssh\id_ed25519.pub
3. 把公钥拷贝到服务器
Windows 版 OpenSSH 较新版本自带 ssh-copy-id,可直接用:
powershellssh-copy-id user@server-ip
旧版本没有 ssh-copy-id,用管道命令等价实现(这是最后一次需要输密码):
powershelltype $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@server-ip ` "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
cmd:: CMD 写法 type %USERPROFILE%\.ssh\id_ed25519.pub | ssh user@server-ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
4. 使用私钥登录
powershellssh user@server-ip ssh -i $env:USERPROFILE\.ssh\id_ed25519 user@server-ip # 显式指定私钥
5. 用 ssh-agent 免去重复输入 passphrase(可选)
powershellSet-Service ssh-agent -StartupType Automatic # 设为开机自启(仅需一次) Start-Service ssh-agent ssh-add $env:USERPROFILE\.ssh\id_ed25519
四、首次连接:校验主机指纹(重要)
第一次连某台服务器时,SSH 会提示无法确认主机身份:
The authenticity of host 'server-ip (1.2.3.4)' can't be established. ED25519 key fingerprint is SHA256:abcd1234...xyz. Are you sure you want to continue connecting (yes/no/[fingerprint])?
这台服务器的指纹应当是固定的。请先核对再输入 yes,可避免中间人攻击:
bash# 在服务器本机执行,拿到标准指纹
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
# 输出首段 SHA256:xxxx 应与你本地提示一致
确认无误后输入 yes,指纹会被写入本地的 ~/.ssh/known_hosts,之后不再提示。
如果服务器重装过 / IP 被复用,会提示
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!。确认是正常变更后,删除旧指纹再重连:bashssh-keygen -R server-ip
五、服务端确认清单(Linux 服务器)
公钥登录要稳定工作,权限与归属必须正确(SSH 对权限非常敏感,不对会直接拒绝认证):
| 路径 | 正确权限 | 含义 |
|---|---|---|
~/.ssh/ | 700 | 只有自己能读写执行 |
~/.ssh/authorized_keys | 600 | 只有自己能读写 |
~/.ssh/id_ed25519(私钥) | 600 | 只有自己能读写 |
~/.ssh/id_ed25519.pub(公钥) | 644 | 自己可读写,其他人只读 |
~/.ssh/config | 600 | 权限过开 SSH 会忽略该配置 |
修复权限命令:
bashchmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/config
确认 sshd 允许公钥登录:
bashsudo grep -i PubkeyAuthentication /etc/ssh/sshd_config
# 应为:PubkeyAuthentication yes
六、用 ~/.ssh/config 管理多台服务器(实战推荐)
连多台机器或用不同密钥时,用别名一键登录,Linux / macOS / Windows 写法完全一致,且全程通过命令创建:
bashcat >> ~/.ssh/config <<'EOF'
# 家里的树莓派
Host pi
HostName 192.168.1.200
User pi
Port 22
IdentityFile ~/.ssh/id_ed25519
# 公司服务器(非标准端口)
Host office
HostName 10.0.0.50
User fengge
Port 2222
IdentityFile ~/.ssh/id_ed25519
EOF
chmod 600 ~/.ssh/config
配置后直接:
bashssh pi # 等价于 ssh -i ~/.ssh/id_ed25519 pi@192.168.1.200
ssh office
常用配置项
| 配置项 | 说明 | 例子 |
|---|---|---|
Host | 别名(自己取的名字) | Host myserver |
HostName | 真实 IP 或域名 | HostName 192.168.1.100 |
User | 登录用户名 | User ubuntu |
Port | SSH 端口(默认 22) | Port 2222 |
IdentityFile | 使用哪个私钥 | IdentityFile ~/.ssh/id_work |
ServerAliveInterval | 多少秒发一次心跳(防断连) | ServerAliveInterval 60 |
ServerAliveCountMax | 心跳失败几次后断开 | ServerAliveCountMax 3 |
ForwardAgent | 是否转发本地 agent(跳板机用) | ForwardAgent yes |
防止长时间不操作掉线(推荐加在所有连接上):
bashcat >> ~/.ssh/config <<'EOF'
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
EOF
通过跳板机登录内网(ProxyJump)
bashcat >> ~/.ssh/config <<'EOF'
Host jumpserver
HostName 跳板机公网IP
User user
IdentityFile ~/.ssh/id_ed25519
Host internal
HostName 192.168.0.100
User admin
IdentityFile ~/.ssh/id_ed25519
ProxyJump jumpserver
EOF
bashssh internal # 自动先连跳板机,再跳到内网机器,一步到位
scp file.txt internal:~/ # scp 也走代理
ProxyJump需要 OpenSSH 7.3+(2016 年起,绝大多数现代系统支持)。临时跳转不改 config 可用:ssh -J user@跳板机IP user@内网IP。
七、强化安全:关闭密码登录 + 基础加固
务必先用私钥成功登录一次,再执行下列操作,否则可能把自己锁在门外。
7.1 关闭密码登录(核心)
bashsudo sed -i 's/^#*PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo grep -i PasswordAuthentication /etc/ssh/sshd_config # 应为 no
7.2 加固建议(来自实战经验,按需采用)
编辑 /etc/ssh/sshd_config:
bash# 禁止 root 远程直登(日常用普通用户 + sudo)
PermitRootLogin no
# 改掉默认 22 端口,挡掉大部分自动化扫描
Port 2222
# 限制登录尝试次数
MaxAuthTries 3
LoginGraceTime 60
改完后务必先校验语法再重启,且保留当前 SSH 会话不要关闭:
bashsshd -t # 检查语法,无输出表示 OK
sudo systemctl restart sshd
永远先跑
sshd -t再重启。配置写错一行可能让 SSH 直接挂掉、彻底登不进去。留一个当前会话确认能新连上再放手。
进阶可叠加:限制来源 IP(AllowUsers)、fail2ban 自动封禁暴力 IP、双因子认证(2FA)。这些属于服务器安全范畴,本文聚焦于公钥登录,故不展开。
八、延伸:用同一套密钥免密传文件
配好公钥后,scp / rsync 也能免密,且比密码方式顺手得多。
scp(简单传文件)
bashscp ~/report.pdf user@server-ip:~/ # 上传文件
scp -r ~/myapp user@server-ip:~/ # 上传目录(-r)
scp user@server-ip:/var/log/nginx/access.log ~/Downloads/ # 下载
rsync(增量同步,推荐)
bashrsync -avz ~/myapp user@server-ip:~/ # 同步到服务器
rsync -avz --delete ~/myapp/ user@server-ip:~/myapp/ # 镜像同步(删除目标多余文件)
rsync -avz --dry-run ~/myapp user@server-ip:~/ # 先模拟,不真正传输
新版 OpenSSH 已将
scp标记为废弃,建议逐步迁移到rsync或sftp。rsync只传变化部分、支持断点续传;注意源路径末尾/表示传内容、不加/表示传目录本身。
九、排错速查
| 现象 | 可能原因 | 处理 |
|---|---|---|
Permission denied (publickey) | 公钥没上传 / 服务端权限不对 | 客户端 ssh-add;服务端重设 ~/.ssh 700、authorized_keys 600 |
Connection refused | 服务器 SSH 没开 / 端口不对 | ssh -p 端口 user@IP;服务器侧 systemctl status sshd |
Connection timeout | 网络不通 / 防火墙拦截 | ping IP 测网络;检查防火墙是否放行对应端口 |
| 连上后频繁掉线 | 没有心跳包 | config 加 ServerAliveInterval 60 |
REMOTE HOST IDENTIFICATION HAS CHANGED! | 服务器重装 / IP 复用 | ssh-keygen -R 服务器IP 后重连 |
| 仍要求输入密码 | PubkeyAuthentication 为 no,或公钥未写入 | 检查 sshd_config 与 authorized_keys |
进阶排错 SOP(很多「登录失败」其实不是密码错,而是权限/安全策略触发限制):
bash# 1. 看日志(服务端)
sudo more /var/log/secure # 或 /var/log/auth.log
# 2. 看账号状态
sudo chage -l root
# 3. 看权限(尤其安全相关目录不能被「所有人可写」)
ls -ld /etc/security # 若变为 777 等,PAM 会直接拒绝登录,chmod 744 修复
# 4. 再考虑服务与网络
经验:能登录 ≠ 配置没问题,不能登录 ≠ 密码错。问题往往已经写在日志里,只是还没去看。
开启详细日志定位:
bashssh -v user@server-ip # 常规排错
ssh -vvv user@server-ip # 最详尽
ssh -o PreferredAuthentications=publickey user@server-ip # 强制只走公钥,验证密钥本身
十、小结与参考资料
小结:公钥登录的核心是「本地生成密钥对 → 公钥上传服务器 authorized_keys → 私钥本地登录」。Linux 用 ssh-copy-id 一条命令搞定上传,Windows 用管道命令等价实现;两端都用 ssh-keygen 生成、ssh 登录。用 ~/.ssh/config 配别名(含跳板机 ProxyJump)能大幅减少重复输入;确认可用后关闭密码登录并做基础加固。这些步骤都经过实测,配好就是一劳永逸的免密登录。
参考资料(知识库「Linux运维」):
- 《Linux SSH 远程连接——密钥免密登录与 scp/rsync 传文件》(冯哥的缓存)
- 《如何在Windows上免密码自动登录Linux服务器?》(我的技术日志)
- 《SSH安全加固:6招堵住服务器最危险的漏洞》(朝夕闻风)
- 《登录权限异常?一个被忽略的文件属性,竟让root无法SSH登录!》(赵楠的成长日记)
ai协作,人工编辑