最近闲得无聊注册了一个新域名,顺便弄了一大堆新账号(Github、Twitter等),准备来一次彻底的改头换面。

注册新域名后第一件事就是弄了这个博客。注册Github时发现一个SSH公钥只能关联一个Github账号,使用https的话又要经常输入密码。所以只好Google搜索一下解决方案。顺便在这里留下总结,以便日后查看。

SSH 配置

首先看一下SSH的配置文件 ~/.ssh/config 的格式:

1
2
3
4
5
Host  alias                 # 该配置的匹配模式
HostName hostname # 远程主机名
Port port # 远程主机端口
User user # 连接远程主机的用户名
IdentityFile key # 改配置使用的密钥

真实的SSH配置文件的属性要比这个多得多,这里只说几个等下会用到的。更多的属性可以参考 这里

其中:

  • Host 属性用于确定何时使用该配置,可使用通配符,相当于一个别名
  • HostName 为该配置的真实主机名,如过是 Github 的话则为 github.com
  • Port 为远程主机的端口,默认为 22
  • User 为连接远程主机的用户名,在 Github 中为 git
  • IdentityFile 为该配置使用的密钥文件

例如一个配置文件如下:

1
2
3
4
5
6
7
8
9
10
Host  world
HostName world.com
Port 2222
User hello
IdentityFile ~/.ssh/world

Host bar
HostName bar.com
User foo
IdentityFile ~/.ssh/bar

如果在终端输入

1
ssh world

则相当于在终端输入了

1
ssh -p 2222 -i '~/.ssh/world' hello@world.com

如输入

1
ssh bar

则相当于输入

1
ssh -i '~/.ssh/bar' foo@bar.com

这里需要多个密钥,可以通过 ssh-keygen 命令来来生成:

1
2
3
4
5
6
# 在 `~/.ssh/` 目录下生成私钥 `world` 和公钥 `world.pub`
ssh-keygen -t rsa -C "hello@world.com" -f ~/.ssh/world
# 期间会提示输入密码,可为空

# 在 `~/.ssh/` 目录下生成私钥 `bar` 和公钥 `bar.pub`
ssh-keygen -t rsa -C "foo@bar.com" -f ~/.ssh/bar

这样一来,只要写入多个配置,就可以实现通过不同的别名来使用不同的密钥去访问一个远程主机。从而就可通过为不同的Github账户配置不同的别名来达到通过SSH方式在一台主机上使用多个Github账号。

为Github编写SSH配置文件

先来看一下github的仓库地址: `git@github.com:hardo/blog.git`

我们发现github仓库地址的用户名均为 git, 主机名均为 github.com, 每个用户的仓库放在同名目录中。

假如现在有两个Github账号 hellohardo

先为这两个账号生成密钥:

1
2
3
4
5
# 在 `~/.ssh/` 目录下生成私钥 `hello` 和公钥 `hello.pub`
ssh-keygen -t rsa -C "hello@world.com" -f ~/.ssh/hello

# 在 `~/.ssh/` 目录下生成私钥 `hardo` 和公钥 `hardo.pub`
ssh-keygen -t rsa -C "i@hardo.me" -f ~/.ssh/hardo

然后将 hello.pub 文件里的内容复制到 Github 账号 hello 的设置里,将 hardo.pub 文件里的内容复制到 hardo 的设置里。

~/.ssh/config 文件里输入如下配置信息:

1
2
3
4
5
6
7
8
9
Host  hello.github.com
HostName github.com
User git
IdentityFile ~/.ssh/world

Host hardo.github.com
HostName github.com
User git
IdentityFile ~/.ssh/bar

配置完成后,便可以使用不同的别名来区分不同的用户:

1
2
3
4
5
6
7
8
9
10
11
# 使用 hello 用户克隆 hello 的 test 仓库
git clone git@hello.github.com:hello/test.git
# 其中前面的 git 用户名可以省略,
# 但为了便于识别这里还是加上

# 使用 hello 用户克隆 hardo 的 blog 仓库
git clone git@hello.github.com:hardo/blog.git
# 如过没有权限的话,将不可推送到默认源

# 使用 hardo 用户克隆 hardo 的 blog 仓库
git clone git@hardo.github.com:hardo/blog.git

虽然远程用户是没问题了,但这里还有一个本地用户的问题。
如果设置了全局用户名和邮箱地址,则不论向哪个用户克隆的仓库commit代码都将是全局的用户邮箱所为对应的用户。这看起来会很奇怪,看起来是两个用户,一看commit信息却是一个用户。
我们要做的是删除Git的全局用户配置,为每个仓库单独配置用户。
或者将全局用户配置为一个用户,然后为另一个用户的所有仓库添加单独的本地用户信息。

1
2
3
4
5
6
7
8
9
10
11
# 取消全局的用户配置
git config --global --unset user.name
git config --global --unset user.email

# 进入一个仓库
git clone git@hardo.github.com:hardo/blog.git
cd blog

# 为仓库单独配置用户
git config user.name 'hardo'
git config user.email 'i@hardo.me'

在 Hexo 中配置部署信息

本博客是用 Hexo 生成的,Hexo 很方便的一项功能就是一条命令行就可以部署到Github pages。在 Hexo 的全局配置文件 _config.yml 中可以配置:

1
2
3
4
deploy:
type: git
repo: git@hardo.github.com:hardo/blog.git
branch: gh-pages

输入 hexo deploy ,一切正常。但是去看 gh-pages 分支的commit信息,发现推送者是本地配置的全局用户。配置文件里可不以改本地用户博主也不清楚,也懒得去查(懒癌晚期)。不过让我在 博客仓库 的根目录里发现了 .deploy_git 目录,猜想应该是生成后的仓库。于是去这个目录下改了本地用户信息:

1
2
3
cd .deploy_git
git config user.name 'hardo'
git config user.email 'i@hardo.me'

改完之后再重新部署,发现果然成功了!

当然,如果你没有配置全局用户的话,第一次部署会失败。虽然失败了,但还是会生成 .deploy_git 目录,进入该目录改下配置然后再重新部署就行了。