如果你经常用 Git 做 push 和 pull,每次输用户名密码确实有点烦。SSH 密钥免密配置不算复杂,但中间有几个环节容易踩坑,比如密钥格式、远程地址、平台对算法的支持。下面按我平时处理的顺序整理一下,你照着走一遍基本能通。
先确认现有密钥,再决定是否重新生成
配置SSH免密前,先确认当前是否已经存在SSH密钥。在终端执行ls -la ~/.ssh,若看到id_rsa和id_rsa.pub文件,说明本地已有密钥对,可直接使用;如果只有known_hosts或没有该目录,则需要重新生成。注意,Git在Windows下使用默认路径是C:\Users\你的用户名\.ssh,可以通过git config --global core.sshCommand确认Git调用的是哪个SSH客户端,避免因OpenSSH与PuTTY的密钥格式不一致导致认证失败。
这一步很多人会跳过,结果直接生成新密钥覆盖了旧密钥。如果你之前已经在 GitHub 或 GitLab 上配置过公钥,覆盖后需要把新公钥重新添加到平台,否则其他仓库也会跟着失效。建议先确认现有密钥是否还在使用,不确定的话可以先备份 ~/.ssh 目录,再生成新的。
生成密钥:优先 Ed25519,注意 passphrase 的取舍
生成新密钥时,建议使用Ed25519算法,它比RSA更安全且生成速度快。执行ssh-keygen -t ed25519 -C "你的邮箱",然后按三次回车,默认保存位置即可,不要设置密码短语(passphrase),否则每次push/pull仍要输入密码,违背免密初衷。如果服务器或Git平台(如GitHub)不支持Ed25519,再改用ssh-keygen -t rsa -b 4096。生成后,务必用cat ~/.ssh/id_ed25519.pub查看公钥内容,供下一步添加。
关于 passphrase,如果你担心私钥泄露,可以先设置一个,然后用 ssh-agent 记住它。具体做法是生成时输入 passphrase,之后执行 eval `ssh-agent -s` 和 ssh-add,按提示输入一次,本次会话内就免密了。这个方案适合长期开着终端的开发场景,重启后需要重新 ssh-add。如果你只是偶尔推送,不设 passphrase 更省事,但私钥文件要保护好。
把公钥添加到平台,并确认远程地址是 SSH 格式
SSH公钥需要添加到Git平台的账号中,以GitHub为例,登录网站后进入Settings > SSH and GPG keys,点击New SSH key,粘贴公钥。同时,本地仓库的远程地址必须是SSH格式,而不是HTTPS。检查git remote -v,如果显示的是https://github.com/用户/仓库.git,需要执行git remote set-url origin git@github.com:用户/仓库.git。注意区分不同平台,如GitLab使用git@gitlab.com:用户/仓库.git,Gitee使用git@gitee.com:用户/仓库.git,地址前缀必须与平台匹配。
这里最容易出问题的是远程地址没有改过来。很多仓库在 clone 时用的是 HTTPS,你只添加了公钥,但 push 时 Git 仍然走 HTTPS 认证,自然还是要求输入用户名密码。改完地址后用 git remote -v 再确认一次,看到开头是 git@ 而不是 https:// 才算改对。
验证连接,别急着直接 push
配置完成后,不要急着push,先执行ssh -T git@github.com(根据平台替换域名)验证连接。首次连接会提示确认主机指纹,输入yes并回车。如果看到Hi 用户名! You've successfully authenticated,说明SSH密钥生效。若报错Permission denied (publickey),检查公钥是否粘贴完整、是否有换行符,或当前用户是否加载了正确的密钥。可以用ssh-add -l查看已加载的密钥列表,若为空,执行ssh-add ~/.ssh/id_ed25519手动加载。
验证连接这一步能帮你把问题隔离出来:如果是认证失败,报错会直接告诉你 publickey 被拒绝;如果是网络或地址错误,报错内容会不一样。看到 successful authenticated 之后再 push,能省掉不少排查时间。
多个平台共用一个密钥?建议拆开并配置 config 文件
一个常见坑是多个平台共用一个SSH密钥时,可能会出现连接混乱。解决方案是为每个平台生成独立密钥,并在~/.ssh/config文件中配置Host别名,例如:Host github.com,HostName github.com,User git,IdentityFile ~/.ssh/id_ed25519_github。另外,如果遇到git pull时仍提示输入密码,检查远程地址是否仍是HTTPS,或者Git凭据管理器重新指向了旧地址。在Windows上,若使用PuTTY生成的密钥,需要先转换为OpenSSH格式,或配置GIT_SSH为plink.exe,否则无法识别。
config 文件的作用是告诉 SSH 客户端:连 github.com 时用哪个私钥,连 gitlab.com 时用哪个私钥。如果你只有一个密钥,不写 config 也能工作;但当你为不同平台生成了多个密钥,不写 config 的话 SSH 默认会找 id_rsa 或 id_ed25519,可能拿错密钥导致认证失败。写完 config 后建议用 ssh -T git@github.com 再验证一次,确认实际加载的是对应的 IdentityFile。
权限和安全上的收尾
配置免密后,建议将私钥文件权限收紧为600,执行chmod 600 ~/.ssh/id_ed25519,防止其他用户读取。同时,在Git配置中启用credential helper仅适用于HTTPS,对SSH无效,无需配置。若担心私钥泄露,可以考虑在生成密钥时设置passphrase,并配合ssh-agent在会话内记忆,这样既不用每次输入,又保留一层保护。具体做法:生成时输入passphrase,然后执行eval `ssh-agent -s`、ssh-add,按提示输入一次后,本次会话内免密。
权限这块,Linux 和 macOS 上如果私钥权限过宽,SSH 客户端会直接拒绝使用,报错类似 UNPROTECTED PRIVATE KEY FILE。Windows 上虽然不强制,但如果你在使用 WSL 或 Git Bash,建议也设置一下。私钥文件属于敏感信息,不要把它提交到 Git 仓库里,也不要用网盘同步。
最后补充一点:如果你改了密钥或 config 文件后仍然不生效,可以加 -v 参数调试,例如 ssh -vT git@github.com,输出里会显示实际使用了哪个私钥文件,能更快定位问题。整个过程其实不复杂,关键是每一步做完都验证一下,别等到 push 时才看报错。