/ AIBLOG

技术笔记

SSH 免密登录实战:Windows / macOS / Linux 密钥认证完全指南

每天都要 SSH 连服务器,每次都输密码,繁琐不说还容易被暴力破解。其实只要配置一次密钥认证,之后就可以免密、安全、快速地登录远程主机。这篇文章手把手带你完成这件事,Windows、macOS、Linux 三个平台全覆盖。

为什么要用 SSH 密钥?

  • 不用再输密码:配置好后 ssh user@host 直接进入,脚本和 CI 也能自动化连接。
  • 比密码更安全:密码可以被猜测或暴力破解,密钥是 2048/4096 位的非对称加密,几乎不可能被攻破。
  • 可以精细控制:密钥可以设置口令(passphrase),还可以随时吊销、更换,管理多台服务器非常方便。

密钥是怎么工作的?

SSH 密钥是一对文件:

  • 私钥id_ed25519id_rsa):只留在你自己的电脑上,绝不能外传,相当于你的"钥匙"。
  • 公钥id_ed25519.pubid_rsa.pub):可以随便分发,把它放到远程主机的 authorized_keys 文件里,相当于把"锁的备份"给了服务器。

登录时,服务器用公钥验证你的身份,本地用私钥完成签名——私钥从未离开你的电脑,所以非常安全。

准备工作

  • 一台本地电脑(Windows 10/11、macOS 或 Linux 均可)。
  • 一台能通过 SSH 登录的远程主机(Linux 服务器、云主机、VPS 等),已知其 IP 和登录用户名,并且当前能用密码登录。
  • Windows 用户请确认系统自带 OpenSSH(Win10 1809 及以上默认自带,无需额外安装)。

第一步:生成本地密钥对

Windows(PowerShell 或 CMD)

打开 PowerShell 或命令提示符,执行:

1ssh-keygen -t ed25519 -C "you@example.com"

按提示操作:回车确认默认保存位置(C:\Users\你的用户名\.ssh\id_ed25519),然后设置一个 passphrase(推荐,不想设就直接回车)。

如果你需要兼容很老的服务器(不支持 Ed25519),可以改用 ssh-keygen -t rsa -b 4096

macOS

打开终端,执行:

1ssh-keygen -t ed25519 -C "you@example.com"

同样回车确认保存位置(~/.ssh/id_ed25519),再设置 passphrase 即可。

Linux

打开终端,命令与 macOS 完全一致:

1ssh-keygen -t ed25519 -C "you@example.com"

生成完成后,可以用下面的命令确认文件已生成:

1ls -la ~/.ssh/

你会看到 id_ed25519(私钥)和 id_ed25519.pub(公钥)两个文件。

第二步:把公钥放到远程主机

这里有三条路,任选其一。

方法一:ssh-copy-id(macOS / Linux 首选)

这是最省事的方式,一条命令完成上传并自动追加到 authorized_keys

1ssh-copy-id user@your-server-ip

输入一次远程密码后,公钥就装好了。

方法二:Windows 手动上传(PowerShell)

Windows 没有 ssh-copy-id,用下面这一行代替(会先读取你的公钥,然后远程执行追加命令):

1type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@your-server-ip "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

方法三:纯手动(任何平台通用)

先在本地查看公钥内容:

1cat ~/.ssh/id_ed25519.pub

复制输出的整行内容,然后登录远程主机:

1ssh user@your-server-ip

在远程主机上执行(把 粘贴公钥 替换为刚复制的内容):

1mkdir -p ~/.ssh
2chmod 700 ~/.ssh
3echo "粘贴公钥内容" >> ~/.ssh/authorized_keys
4chmod 600 ~/.ssh/authorized_keys
权限很重要:~/.ssh 目录必须是 700,authorized_keys 文件必须是 600,否则 SSH 会拒绝使用。

第三步:验证免密登录

在本地执行:

1ssh user@your-server-ip

如果不再要求输入密码(或只需输入 passphrase),说明配置成功!

常见问题排查

还是提示要密码?

  1. 确认公钥确实在远程的 ~/.ssh/authorized_keys 里,而且是一整行。
  2. 检查权限:chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
  3. ssh -v user@host 查看详细输出,重点看 Authentications that can continue

提示 Permissions too open(Windows 常见) PowerShell 里执行:

1icacls $env:USERPROFILE\.ssh\id_ed25519 /inheritance:r /grant:r "$($env:USERNAME):R"

服务器不允许密钥登录(只认密码)?

部分云厂商默认没有开启 PubkeyAuthentication,或 sshd_config 里被设成了 no,这时即使公钥已装好,登录时仍会要求密码。解决办法:

  1. 先用密码方式登录远程主机(若密码登录也被禁止,用云厂商控制台自带的 VNC / 网页终端进入)。
  2. 编辑 /etc/ssh/sshd_config,确认或取消注释这一行:
1PubkeyAuthentication yes
  1. 重启 SSH 服务使其生效:
1sudo systemctl restart sshd
旧系统(CentOS 6 等)用 sudo service sshd restart;Ubuntu/Debian 也可用 sudo service ssh restart

不允许 root 登录?

很多服务器出于安全默认 PermitRootLogin no,root 即使装了密钥也登不进去。解决思路:

  • 推荐做法:改用普通用户登录,需要管理操作时用 sudo 提权;把公钥装到该普通用户的 ~/.ssh/authorized_keys 即可。
  • 必须用 root 时:编辑 /etc/ssh/sshd_config,设置为:
1PermitRootLogin prohibit-password

这个值表示"允许 root 用密钥登录、禁止密码登录",比 yes 安全得多。保存后重启 sshd,并把公钥装到 root 的 ~/.ssh/authorized_keys(普通用户可用 sudo 完成前面三步命令)。

  • 还是登不上? 检查 sshd_config 里是否有 AllowUsers / AllowGroups / DenyUsers 限制,确认你的用户名在允许列表内,改完同样要重启 sshd。

连不上,报 Permission denied (publickey) 远程服务器可能禁用了密码登录。请先用带密码的方式通过其他通道(如云厂商控制台的 VNC)登录,检查 /etc/ssh/sshd_config 中的 PubkeyAuthentication yes,然后重启 sshd。

多台服务器都要免密? 把同一把公钥分别装到每台服务器即可;如果想用不同密钥连不同主机,可以在 ~/.ssh/config 里配置:

1Host myserver
2 HostName your-server-ip
3 User yourname
4 IdentityFile ~/.ssh/id_ed25519

安全建议

  • 私钥绝不外传id_ed25519(无 .pub 后缀的那个)谁都不能给,也不要提交到 Git 仓库。
  • 给私钥设 passphrase:即使电脑丢失,别人也打不开你的私钥。
  • 配置好后关闭密码登录:在 sshd_config 里设置 PasswordAuthentication no 并重启 sshd,从此只有持钥匙的人能进。
  • 定期轮换密钥:离职、怀疑泄露时,及时换新并清理远程 authorized_keys
  • 开启 root 密钥登录要谨慎PermitRootLogin 保持 prohibit-password 而非 yes,并优先使用普通用户 + sudo。

配置一次,终身受益。现在就动手吧!