该怎么写ssh的config文件?

之前一直用一套公钥私钥走天下,感觉并不太安全,于是思考了这样一套管理ssh key的方案:

  1. 每台设备生成一套自己的密钥,~/.ssh/id_ed25519,并把公钥导入github
  2. 不同的服务器,使用一套单独的密钥,server_a_key server_a_key.pub gitlab_key gitlab_key.pub。通过yadm加密,借助github的私有仓库同步
  3. 一些不重要的小设备,如nas或是树莓派,通用一套默认的密钥,default_key default_key.pub,也加密后同步

在此我遇到了一点困难,那就是ssh的config文件好像写不明白了。我希望对github使用id_ed25519密钥,对gitlab使用gitlab_key密钥,对server_a使用server_a_key密钥,最后如果都不在上述范围之列,则使用default_key,我的配置文件是这么写的:

Host Github
    Hostname github.com
    User wang1zhen
    IdentityFile ~/.ssh/id_ed25519

Host Gitlab
    Hostname gitlab.com
    User wang1zhen
    IdentityFile ~/.ssh/gitlab_key

Host server_a
    Hostname x.x.x.x
    User wang1zhen
    IdentityFile ~/.ssh/server_a_key

Host *
    IdentityFile ~/.ssh/default_key

这么设置后,发现gitlab的仓库同步是失败的,通过ssh -v [email protected]发现:

ssh -v gitlab.com
OpenSSH_9.0p1 Debian-1+b2, OpenSSL 3.0.5 5 Jul 2022
debug1: Reading configuration data /home/wang1zhen/.ssh/config
debug1: /home/wang1zhen/.ssh/config line 10: Applying options for *

我百思不得其解,为什么会匹配到的是*而非我要求的Gitlab呢?该如何指定ssh,在连接github时使用github的密钥,连接gitlab时使用gitlab的密钥,而不要像现在这样混乱?

1 个赞

我也是:

  • 几台个人电脑用的是同一个密钥,说不定还是几年前的一台已经淘汰的电脑上创建的
  • 服务器创建后,需要 git clone,就复制本地的私钥

这一个私钥泄露了,就全完了

HostName 不是用来匹配的,ssh 要用紧跟着 Host 的名字:

- ssh -v gitlab.com
+ ssh -v Gitlab

试试看改成下面这样:

Host github.com
    Hostname github.com
    User wang1zhen
    IdentityFile ~/.ssh/id_ed25519

Host gitlab.com
    Hostname gitlab.com
    User wang1zhen
    IdentityFile ~/.ssh/gitlab_key

Host server_a
    Hostname x.x.x.x
    User wang1zhen
    IdentityFile ~/.ssh/server_a_key

Host *
    IdentityFile ~/.ssh/default_key

因为你用命令行执行的时候 ssh -v gitlab.com 会匹配 Host gitlab.com 这一项。

  1. 你这样配置,平时应当用 ssh Gitlab

  2. 你想对 host 配 ssh key,用 Match keyword

Match canonical host="gitlab.com"
 IdentityFile ~/.ssh/gitlab_key
1 个赞

看来我之前理解有误,Host xxx是用于ssh xxx进行匹配的,而非基于我ssh gitlab.com去匹配Hostname gitlab.com的。多谢指教。

我现在的问题是,我想通过ssh来同步git仓库,对于git该怎么配置,使得git push [email protected]:repo.git的时候,使用我gitlab的key呢?

这样写还是匹配不到:

ssh -vv gitlab.com
OpenSSH_9.0p1 Debian-1+b2, OpenSSL 3.0.5 5 Jul 2022
debug1: Reading configuration data /home/wang1zhen/.ssh/config
debug2: checking match for 'canonical host="gitlab.com"' host gitlab.com originally gitlab.com
debug2: match not found
debug1: /home/wang1zhen/.ssh/config line 10: Applying options for *
CanonicalizeHostname yes

$ cat ~/.ssh/config
...
Host 别名
    Hostname ...
...

$ cat .git/config
...
[remote "origin"]
        url = git@别名:path/to/project.git
        fetch = +refs/heads/*:refs/remotes/origin/*
...

感谢!!!

canonicalize的作用我不太了解,不过确实按照

也就是在config文件这样改:

CanonicalizeHostname yes
...
Match canonical host="gitlab.com" 
    User git                      
    IdentityFile ~/.ssh/gitlab_key
...

是可以的,不过我还是采用了

这个比较偷懒的方案,直接

Host gitlab.com
    Hostname gitlab.com
    User git
    IdentityFile ~/.ssh/gitlab_key

这样ssh在见到gitlab.com的时候就会能够匹配到这个Host,然后使用对应的密钥了,避免了

毕竟一个个仓库改过来还是有点费事的。

再次感谢大家的帮助!

重点不是方便还是费事,而是我用中文标记的那两个地方必需一致才能工作。

明白。主要是当时拉取仓库的时候是直接git clone [email protected]:repo.git这样拉下来的,.git/config里面的url就是[email protected]:repo.git,所以干脆就把别名起成github.com,从而不用改每个仓库的.git/config

这把所有私钥都放到了一台机器上,要泄漏不都一起泄漏了?这和只用一对密钥有什么区别?

这就是passphrase该管的事儿了吧……我这么做只是考虑到同步的方便,安全性上,用于同步的远程仓库借助yadm的gpg加密,同步到本地确实就只能用passphrase来确保安全了(当然我图方便并没有设置)。有啥相对方便又不太折腾的方法的话,欢迎分享。