十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

macOS下配置SSH Keychain让Git免输passphrase

macOS下配置SSH Keychain让Git免输passphrase 我用macOS做开发小半年的时候终于被git的passphrase逼疯了。准确说不是git本身的问题是SSH密钥的passphrase。每次执行git pull或者git push终端就弹一行Enter passphrase for key /Users/me/.ssh/id_ed25519:。我一开始以为这跟password是一回事后来才发现完全不是而且网上很多教程把这两个词混着用越看越迷糊。如果你也在这个问题上卡过我把我后来踩过的坑、试过的方案、最后稳定的配置一次性说清楚。这个内容适合谁就是在Mac上用git、并且SSH密钥设置了passphrase、被反复输入提示折磨的人。无论你是走GitHub、Gitee还是公司内网的GitLab只要走的是SSH协议这套方法都通用。我最后用的方案是“SSH config macOS钥匙串Keychain”配置完之后git操作不再问passphrase重启终端也不问稳得很。下面直接进入正题。1. 先搞明白你输入的不是password是passphrase1.1 passphrase到底是哪来的很多人一开始就搞混一个概念git提示你输入的passphrase跟你git平台的登录密码password完全是两码事。password是你登录GitHub、Gitee时用的账号密码而passphrase是你在本机生成SSH密钥时自己设置的一串口令用来加密本地私钥文件。生成密钥的命令是ssh-keygen -t ed25519 -C your_emailexample.com执行之后它会问Enter passphrase (empty for no passphrase):如果你当时输入了一串字符那你的私钥文件就是被加密的。这个加密的意义在于就算别人拷走了你的私钥文件没有passphrase也解不开用不了。你可以把password理解成大门的门锁钥匙而passphrase是装这把钥匙的保险柜密码。git推送代码时要用SSH密钥也就是那把钥匙但每次得先输入保险柜密码才能把钥匙取出来于是就有了开头那个反复弹出来的提示。1.2 为什么每次都要输入git到底在问谁这里有个关键点git其实不负责认证它把认证的工作交给了系统底层的SSH客户端。你执行git pushgit会调用ssh去连远程服务器SSH客户端需要读取你的私钥完成握手发现私钥文件被passphrase加密了就会提示你输入。这个提示是SSH发的不是git发的。macOS默认情况下并不会主动帮你把密钥缓存起来所以每次新的SSH会话它都可能重新问你一次。有些朋友说“我明明看到Mac弹了对话框让我输密码我也勾选记住了为什么下次还问”原因就在你用的是哪种认证方式——如果走的是HTTPS仓库地址Mac的钥匙串可能记住的是账号密码但走SSH时钥匙串默认不参与私钥passphrase的存储除非你显式配置。所以核心问题有两个第一让SSH知道去钥匙串里查passphrase第二把passphrase安全地写进钥匙串。这两个动作做完了这个问题就彻底解决了。2. 方案选型四种干掉passphrase提示的思路我网上搜了一圈方案五花八门总结下来无非四种各有优劣。我按推荐程度排序讲。2.1 方案一SSH config macOS Keychain推荐这是我最推荐的方案也是我目前在用的。原理很简单在~/.ssh/config里加两个选项一个是UseKeychain yes让SSH优先从macOS钥匙串里读取passphrase另一个是AddKeysToAgent yes把解锁后的密钥自动加入系统ssh-agent之后一段时间的SSH连接都不用再解锁。这个方案的好处是一劳永逸只要配置一次重启终端、重启电脑都没问题而且passphrase是存在系统钥匙串里的安全性比明文写在文件里高得多。缺点是依赖macOS特有的钥匙串服务Linux上不支持但macOS用户不受影响。2.2 方案二ssh-add把密钥加入agent这个方案比较“轻量”。核心思想是用ssh-agent在内存里缓存解密后的密钥eval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519执行第一条命令会启动后台的ssh-agent进程第二条命令会要求你输入一次passphrase然后把解密后的私钥加载到内存。之后一段时间内重启前再连SSH服务器就不会重复询问passphrase了。优点是操作很简单适合临时解决不用改任何配置文件。缺点是session一结束就失效你要是重启电脑或者隔了很久重新开一个终端还得再来一遍。而且多个终端窗口并存时有时候agent环境变量没同步新开的窗口会提示找不到agent。2.3 方案三彻底移除passphrase如果你觉得这个passphrase实在太烦也可以直接把私钥的passphrase去掉ssh-keygen -p -f ~/.ssh/id_ed25519命令会让你输入旧passphrase然后提示输入新passphrase时直接回车留空这样私钥就不再加密了。网上有些教程让你这么做但我不推荐尤其是笔记本用户。理由很简单私钥文件一旦丢失没有passphrase的人直接就能用。除非你确认这台机器只是测试环境或者有完整可靠的磁盘加密否则轻易别动这个念头。2.4 方案四用GPG签名替代SSH认证这个方案比较冷门适合已经在用GPG密钥做commit签名的人。GitHub等平台支持用GPG公钥做SSH认证配置好之后走的是另一套认证链路。但门槛高布线复杂属于“吃力不一定讨好”的类型。如果你不是GPG重度用户不建议从这里入手。我个人觉得方案一已经能解决99%的需求没必要引入额外的复杂度。下面是方案对比简表方便你快速决定方案操作难度是否持久安全性适用场景SSH config Keychain中高重启不失效高依赖系统钥匙串日常开发主力方案ssh-add临时加载低低重启失效高密钥只在内存临时应急、测试环境移除passphrase低高低私钥泄露即风险测试机、临时容器GPG认证替代高高高已有GPG基础设施的用户3. 实操5分钟配置好SSH免输passphrase我直接给出我最终稳定运行几个月的配置流程照着做就行。3.1 第一步确认当前SSH密钥状态先看看你的~/.ssh目录下有什么ls -la ~/.ssh/通常会有id_ed25519、id_ed25519.pub这类文件也可能是id_rsa、id_rsa.pub。确认之后再看下系统的ssh-agent当前加载了哪些密钥ssh-add -l如果提示The agent has no identities.说明agent里是空的后面配置完需要重新加载。如果你用的是公司电脑可能还会有多套密钥后面我会专门说多密钥的情况。3.2 第二步修改SSH config文件用编辑器打开或新建~/.ssh/confignano ~/.ssh/config我最小的推荐配置是这样Host * AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_ed25519说明一下这三行的作用AddKeysToAgent yesSSH客户端在解锁密钥后自动把它交给本机的ssh-agent缓存。UseKeychain yes这是macOS专有选项告诉SSH在需要passphrase时去系统钥匙串里找如果找不到就弹普通输入提示并且在后续通过ssh-add保存时写入钥匙串。IdentityFile ~/.ssh/id_ed25519指定默认私钥文件路径。如果你的文件名不是默认的这里要改成你自己的路径。保存退出后最好再设置一下config文件的权限因为SSH对配置文件权限有严格检查权限过宽会报警或拒绝读取chmod 700 ~/.ssh chmod 600 ~/.ssh/config chmod 600 ~/.ssh/id_ed255193.3 第三步把passphrase存进Keychain这一步是关键。在较新版本的macOS上ssh-add的旧参数-K已经被改成了--apple-use-keychain。如果你用的是macOS Ventura或更新版本就执行ssh-add --apple-use-keychain ~/.ssh/id_ed25519它会提示你输入一次passphrase输入正确后私钥的passphrase会写入系统钥匙串同时密钥本身也会加载到ssh-agent中。如果你用的是老版本macOS可以用ssh-add -K ~/.ssh/id_ed25519效果一样只是参数名不同。有一个小细节需要注意如果你的密钥之前没有通过--apple-use-keychain加载过就算改了config也不会自动生效。首次必须手动执行一次这条命令系统才会把passphrase保存到钥匙串。3.4 第四步验证是否生效验证分两层。第一层看SSH连接是否正常ssh -T gitgithub.com能输出Hi xxx! Youve successfully authenticated之类的提示就说明SSH链路是通的。第二层测试passphrase是否还需要手动输入——把当前shell里已加载的agent密钥清掉模拟一个“冷启动”场景ssh-add -D ssh -T gitgithub.com如果不再提示Enter passphrase for key ...直接就认证成功了说明SSH已经从钥匙串里读取到passphrase大功告成。这时候你再去项目里跑一下git pull、git push应该都不会再打断你输入passphrase了。4. 实操中的坑从踩坑到稳定复现配置过程中我踩过几个坑这里按出现的频率和迷惑程度一一说明。4.1 重启终端后又开始要passphrase这是我第一次配置时遇到的问题。我明明执行了ssh-add --apple-use-keychain当时也生效了但只要重启终端马上又开始问passphrase。后来排查发现问题出在两点第一config文件里AddKeysToAgent没有配。没有这个选项的话SSH虽然能从钥匙串拿passphrase但不会把密钥交给agent缓存每次新SSH会话都有可能重新发起完整的认证流程。第二有些情况下agent没有自动启动。macOS新版系统里ssh-agent是由launchd管理的理论上会按需启动但如果你的shell配置里自己启动了一个旧的agent进程反而会干扰。检查方法echo $SSH_AUTH_SOCK如果这个变量有值说明shell里已经有一个agent环境。如果为空SSH会去找系统默认的agent。在多数正常配置下这个变量应该被正确设置。4.2 多个密钥环境的细节处理我这台Mac上同时有GitHub的密钥和公司GitLab的密钥最开始在config里只写了一个默认的IdentityFile结果GitHub有时公钥不匹配直接认证失败。这里的关键是给不同主机做专门配置。举个例子Host github.com HostName github.com User git AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_ed25519_github Host gitlab.company.com HostName gitlab.company.com User git AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_ed25519_company这样SSH连接不同主机时会精确匹配各自对应的密钥。如果同一台主机上你配置了多个密钥SSH默认会依次尝试直到匹配成功为止。要是某个密钥被锁比如passphrase输错太多次SSH有时候会静默跳过表现为认证失败但只要把该密钥的passphrase重新通过ssh-add --apple-use-keychain加载一次就好。4.3 系统更新后的行为变化这个坑蛮值得说。macOS Ventura之后Apple把ssh-add -K改成了--apple-use-keychain很多老教程的命令在新系统上会直接报错显示option requires an argument -- K之类的提示。而且新版SSH对config的解析更严格行尾空格、多余引号都可能导致整个配置被忽略。你要是升级系统后突然发现passphrase又开始弹了先检查config文件里有没有格式问题再重新执行一次新的ssh-add --apple-use-keychain。另外一个容易忽略的点是如果你在~/.ssh/config里写了UseKeychain no那所有相关设置都会失效。这个选项默认就是no所以必须显式写yes。4.4 钥匙串权限相关的坑有些环境下尤其是公司电脑用户可能没有权限写入登录钥匙串比如使用了一些统一管理工具执行ssh-add --apple-use-keychain时虽然不报错但实际上没有写入成功。这种情况可以通过钥匙串访问App查看里面有没有对应私钥的条目。如果没有就需要找IT管理员确认钥匙串的写权限策略。个人Mac一般不会遇到但公司统一管理的机器值得提前留意。5. 常见问题速查与排查思路我把实际操作中容易碰到的问题整理成一份速查表供你对照排查。现象可能原因解决办法输入正确passphrase但SSH仍然拒绝公钥没配置到git平台把id_ed25519.pub内容添加到GitHub/Gitee的SSH keysssh-add命令报option requires an argument -- KmacOS Ventura后参数变更改用ssh-add --apple-use-keychain ~/.ssh/id_ed25519重启终端后需要重新输入passphrase缺少AddKeysToAgent yes在~/.ssh/config中补上该选项重新执行ssh-add提示Could not open a connection to your authentication agentagent环境变量未设置或agent未启动执行eval $(ssh-agent -s)后再测多个Key时总是选错密钥config中未做主机匹配把不同主机的IdentityFile独立配置到对应Host块中执行ssh -T时报Permission denied (publickey)密钥本身不匹配远端用ssh -vvT查看SSH尝试了哪些密钥确认公钥已正确上传config文件写了但没生效权限过高或格式错误执行chmod 600 ~/.ssh/config并用ssh -G github.com验证解析结果换了新电脑密钥文件拷过去还是问passphrase私钥文件本身加密macOS钥匙串没存对应条目在新机器上执行一次ssh-add --apple-use-keychain输入原passphrase完成绑定这里再补充一个排查神器。SSH自带详细调试输出遇到任何认证相关问题都可以用ssh -vvT gitgithub.com-v加得越多输出越详细-vvv能看到握手过程、密钥尝试顺序、远端返回的结果。如果看到Offering public key: /Users/xxx/.ssh/id_ed25519 ...说明这个密钥已经参与了认证尝试如果连这条路都没走到说明本地SSH配置层面就有问题优先检查agent和config。最后分享一个我自己的使用习惯。我把~/.ssh/config纳入dotfiles版本管理所有新机器都从仓库里同步这份配置再配合一次ssh-add --apple-use-keychain基本能做到新机器五分钟内进入“git push不再问passphrase”的状态。如果你经常换机器强烈建议也把这套配置沉淀下来省得每次重新踩一遍坑。
返回列表