使用公钥连接 SSH:Linux 与 Windows 操作端完全命令指南
2026-07-22
基础学习笔记
00

目录

使用公钥连接 SSH:Linux 与 Windows 操作端完全命令指南
一、背景与准备
二、Linux 操作端
1. 生成密钥对
2. 查看公钥内容
3. 把公钥拷贝到服务器
4. 使用私钥登录
5. 用 ssh-agent 免去重复输入 passphrase(可选)
三、Windows 操作端
0. 确认 OpenSSH 客户端已安装(如未安装)
1. 生成密钥对
2. 查看公钥内容
3. 把公钥拷贝到服务器
4. 使用私钥登录
5. 用 ssh-agent 免去重复输入 passphrase(可选)
四、首次连接:校验主机指纹(重要)
五、服务端确认清单(Linux 服务器)
六、用 ~/.ssh/config 管理多台服务器(实战推荐)
七、强化安全:关闭密码登录 + 基础加固
7.1 关闭密码登录(核心)
7.2 加固建议(来自实战经验,按需采用)
八、延伸:用同一套密钥免密传文件
scp(简单传文件)
rsync(增量同步,推荐)
九、排错速查
十、小结与参考资料

使用公钥连接 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. 查看公钥内容

bash
cat ~/.ssh/id_ed25519.pub # 输出类似:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... 我的工作机 2026

3. 把公钥拷贝到服务器

方法一:ssh-copy-id(推荐,最简单)

bash
ssh-copy-id user@server-ip # 输入一次服务器密码,公钥自动写入 ~/.ssh/authorized_keys 并修正权限 # 指定某个密钥上传(有多把密钥时): ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server-ip

方法二:手动管道(没有 ssh-copy-id 时)

bash
cat ~/.ssh/id_ed25519.pub | ssh user@server-ip \ "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && \ chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"

4. 使用私钥登录

bash
ssh user@server-ip # 直接连上,不需要密码 ssh -i ~/.ssh/id_ed25519 user@server-ip # 显式指定使用的私钥

5. 用 ssh-agent 免去重复输入 passphrase(可选)

bash
eval "$(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. 生成密钥对

powershell
ssh-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,可直接用:

powershell
ssh-copy-id user@server-ip

旧版本没有 ssh-copy-id,用管道命令等价实现(这是最后一次需要输密码):

powershell
type $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. 使用私钥登录

powershell
ssh user@server-ip ssh -i $env:USERPROFILE\.ssh\id_ed25519 user@server-ip # 显式指定私钥

5. 用 ssh-agent 免去重复输入 passphrase(可选)

powershell
Set-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!。确认是正常变更后,删除旧指纹再重连:

bash
ssh-keygen -R server-ip

五、服务端确认清单(Linux 服务器)

公钥登录要稳定工作,权限与归属必须正确(SSH 对权限非常敏感,不对会直接拒绝认证):

路径正确权限含义
~/.ssh/700只有自己能读写执行
~/.ssh/authorized_keys600只有自己能读写
~/.ssh/id_ed25519(私钥)600只有自己能读写
~/.ssh/id_ed25519.pub(公钥)644自己可读写,其他人只读
~/.ssh/config600权限过开 SSH 会忽略该配置

修复权限命令:

bash
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub chmod 600 ~/.ssh/config

确认 sshd 允许公钥登录:

bash
sudo grep -i PubkeyAuthentication /etc/ssh/sshd_config # 应为:PubkeyAuthentication yes

六、用 ~/.ssh/config 管理多台服务器(实战推荐)

连多台机器或用不同密钥时,用别名一键登录,Linux / macOS / Windows 写法完全一致,且全程通过命令创建:

bash
cat >> ~/.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

配置后直接:

bash
ssh 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
PortSSH 端口(默认 22)Port 2222
IdentityFile使用哪个私钥IdentityFile ~/.ssh/id_work
ServerAliveInterval多少秒发一次心跳(防断连)ServerAliveInterval 60
ServerAliveCountMax心跳失败几次后断开ServerAliveCountMax 3
ForwardAgent是否转发本地 agent(跳板机用)ForwardAgent yes

防止长时间不操作掉线(推荐加在所有连接上):

bash
cat >> ~/.ssh/config <<'EOF' Host * ServerAliveInterval 60 ServerAliveCountMax 3 EOF

通过跳板机登录内网(ProxyJump)

bash
cat >> ~/.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
bash
ssh internal # 自动先连跳板机,再跳到内网机器,一步到位 scp file.txt internal:~/ # scp 也走代理

ProxyJump 需要 OpenSSH 7.3+(2016 年起,绝大多数现代系统支持)。临时跳转不改 config 可用:ssh -J user@跳板机IP user@内网IP


七、强化安全:关闭密码登录 + 基础加固

务必先用私钥成功登录一次,再执行下列操作,否则可能把自己锁在门外。

7.1 关闭密码登录(核心)

bash
sudo 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 会话不要关闭:

bash
sshd -t # 检查语法,无输出表示 OK sudo systemctl restart sshd

永远先跑 sshd -t 再重启。配置写错一行可能让 SSH 直接挂掉、彻底登不进去。留一个当前会话确认能新连上再放手。

进阶可叠加:限制来源 IP(AllowUsers)、fail2ban 自动封禁暴力 IP、双因子认证(2FA)。这些属于服务器安全范畴,本文聚焦于公钥登录,故不展开。


八、延伸:用同一套密钥免密传文件

配好公钥后,scp / rsync 也能免密,且比密码方式顺手得多。

scp(简单传文件)

bash
scp ~/report.pdf user@server-ip:~/ # 上传文件 scp -r ~/myapp user@server-ip:~/ # 上传目录(-r) scp user@server-ip:/var/log/nginx/access.log ~/Downloads/ # 下载

rsync(增量同步,推荐)

bash
rsync -avz ~/myapp user@server-ip:~/ # 同步到服务器 rsync -avz --delete ~/myapp/ user@server-ip:~/myapp/ # 镜像同步(删除目标多余文件) rsync -avz --dry-run ~/myapp user@server-ip:~/ # 先模拟,不真正传输

新版 OpenSSH 已将 scp 标记为废弃,建议逐步迁移到 rsyncsftprsync 只传变化部分、支持断点续传;注意源路径末尾 / 表示传内容、不加 / 表示传目录本身。


九、排错速查

现象可能原因处理
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_configauthorized_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. 再考虑服务与网络

经验:能登录 ≠ 配置没问题,不能登录 ≠ 密码错。问题往往已经写在日志里,只是还没去看。

开启详细日志定位:

bash
ssh -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协作,人工编辑

本文作者:张老板

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!