好久没写博客了,先记一下现在用的 SSH 配置。
我在 Mac 上连接博客服务器,用的是 1Password 自带的 SSH Agent。私钥放在 1Password 里,连接的时候按提示授权,本地只留公钥和 SSH 配置。
平时还是一句 ssh blog,不用另外换客户端。
下面以 macOS 为例,服务器地址和用户名换成自己的就行。
把密钥放进 1Password
打开 1Password,新建一个 SSH Key 项目。
已经有密钥的话,在 Add Private Key 里选 Import a Key File,导入原来的私钥。有口令就输一下,保存即可。注意别选成了 .pub,那个是公钥。
也可以直接选 Generate New Key 生成一把,普通场景用 Ed25519 就行,老环境有特殊要求再单独处理。支持的格式可以看官方文档。
如果导入的是原来的密钥,服务器端一般不用改。如果是新生成的,就得把公钥加到服务器对应用户的 ~/.ssh/authorized_keys 中,另起一行追加,别覆盖原来的内容。
文件还不存在的话,先在服务器上准备一下:
# 用准备登录的那个用户执行
mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
这里的用户要对得上。公钥放在 ubuntu 的目录里,后面就用 ubuntu 登录。
旧连接先留着,等新配置能正常登录再关,省得把自己锁在外面。
开启 Agent
在 1Password 的 Settings → Developer 中打开 Use the SSH Agent,客户端保持运行。配了 Touch ID 的话,后面就可以用指纹授权。
开关的位置和授权设置见官方说明。
然后从刚才的 SSH Key 项目里下载公钥,放到本机的:
~/.ssh/server.pub
接下来编辑 ~/.ssh/config,添加一个主机:
Host blog
HostName server.example.com
User ubuntu
IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
IdentityFile ~/.ssh/server.pub
IdentitiesOnly yes
blog 是自己起的别名,HostName 换成服务器的 IP 或域名。如果端口不是 22,再加一行 Port。已有 Host blog 的直接改原来的那段。
重点是下面这两行:
IdentityFile ~/.ssh/server.pub
IdentitiesOnly yes
这里填的确实是公钥路径。SSH 用它找到 1Password 中对应的私钥,再交给 Agent 完成签名,不需要把私钥下载回来。
IdentitiesOnly yes 也一起加上,否则密钥多了,客户端可能挨个尝试,还没试到正确的那把就被服务器断开了。官方文档里有解释这个认证次数限制。
还有,IdentityAgent 那个路径里有空格,引号别漏。
配置完试一下:
ssh blog
1Password 弹出授权,确认之后就能继续连接。是否每次都弹窗跟授权设置和锁定状态有关。
顺便配上 GitHub
GitHub 也是一样的做法。准备一把密钥,把公钥加到 GitHub 的 SSH and GPG keys 页面,类型选认证密钥,再把公钥保存为本机的 ~/.ssh/github.pub。
在配置里加上:
Host github.com
User git
IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
IdentityFile ~/.ssh/github.pub
IdentitiesOnly yes
然后测试:
ssh -T [email protected]
第一次连接可能先让你确认主机指纹,核对远端身份后再接受。这个提示和 1Password 的密钥授权是两回事。
仓库地址也得是 SSH 格式:
[email protected]:YOUR_NAME/YOUR_REPO.git
拿不准就 git remote -v 看一眼。如果还是 https:// 开头,拉代码自然不会用到这里的配置。
连不上时看哪里
先开详细日志,比反复改配置有用:
ssh -v blog
如果报 Too many authentication failures,先看是不是试了太多密钥。检查 IdentityFile、IdentitiesOnly,以及其他匹配的配置块有没有额外指定身份。最终生效的配置可以这样看:
ssh -G blog
如果是 Permission denied (publickey),就核对用户名、服务器上的公钥、本地 .pub 文件是不是对应同一把密钥,再去 1Password 的 SSH Agent 页面看看密钥是否可用,授权有没有被取消。
还有一种容易绕进去的情况:ssh 能连,ssh-add -l 却说找不到密钥。
因为 ssh-add 看的是 SSH_AUTH_SOCK,不会去读 Host blog 下面的 IdentityAgent。临时指定一下就能查看 1Password Agent 中的密钥指纹:
SSH_AUTH_SOCK="$HOME/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock" ssh-add -l
注意这条是 Shell 命令,双引号里用了 $HOME。别照着上面的 SSH 配置写成 "~/Library/...",Shell 不会展开引号里的波浪号。
至于终端能用、其他软件不能用,要看那个客户端是否支持 IdentityAgent 和公钥形式的 IdentityFile,有些需要另外设置 SSH_AUTH_SOCK。可以对照兼容性列表查一下。
就这些,配好之后还是照常用 SSH。以后加服务器,复制一段 Host,换上地址、用户名和对应公钥就行。