複数のSSH Keyを切り替えてGitHubにアクセスする

GitHub じゃなくてもいいんですが、まぁ一番良く使うのは GitHub だろうなぁと。
言いたい事はほぼ [ココ](https://qiita.com/0ta2/items/25c27d447378b13a1ac3) に書かれているわけですが、ちょっとだけ追加を。
ほぼ備忘録です。

GitHub に個人用アカウントと会社用アカウントを作りたい、という人はちょっとはいるのではないかと。少なくともココにいる。
さらに同じ PC で、個人用アカウントでも会社用アカウントでも接続したい、ということは時々あるのではないかと。
悪い事したいわけじゃなくてね。ほら、その、ちょっと色々と都合がね。
その時に（特に terminal で各種 git コマンドを打つ時に）、どうやって SSH Key を切り替えるのか、というやり方。

# １つ目の SSH Key （個人用アカウント）

会社は変わるかもしれない、でも個人は変わらない、ということで個人用アカウントを優先します。
ssh key を作って GitHub に登録するやり方は探せばいっぱい出てくるので、簡単に。

1. `ssh-keygen` で ssh 公開鍵と秘密鍵を作る
    * `> ssh-keygen -t rsa -b 4096 -C "hogehoge@hugahuga"`
    * `~/.ssh/id_rsa`（個人用秘密鍵）と`~/.ssh/id_rsa.pub`（個人用公開鍵）を作ったとする（デフォルトのまま）
1. GitHub のアカウントを作って、個人用公開鍵を登録
    * [GitHub にログインして一番右上のプルダウン > Settings > SSH and GPG keys](https://github.com/settings/keys) で

SSH Key 自体は別に GitHub のために作るものじゃないので、これは要するに「普段使っている SSH Key を GitHub 個人用アカウントに紐づけている」ということ。

# ２つ目の SSH Key （会社用アカウント）

やり方は１つ目と全く同じ。ただし ssh-keygen が interactive に聞いてくる中で、key の保存先を `~/.ssh/id_rsa_github` と入力するものとする。これを会社用アカウントに紐付ける。
すなわち、`~/.ssh/id_rsa_github.pub` の中身を会社用アカウントのSSH keyとして登録する。

あくまで上記は一例なので、個人用アカウントも会社用アカウントもデフォルトの SSH Key じゃなくて専用の SSH Key を作っても良い。
下の説明の前提となる条件設定だと思ってください。

今、個人用アカウントの GitHub のアカウント名は privateAccount, 会社用アカウントのアカウント名は companyAccount だということにします。

# SSH Key の切り替え（その１） - SSH の設定で

例えば `~/.ssh/config` に以下の内容を書く。

```
Host github_private
    Hostname github.com
    IdentityFile ~/.ssh/id_rsa
    User git
    IdentitiesOnly yes

Host github_company
    Hostname github.com
    IdentityFile ~/.ssh/id_rsa_github
    User git
    IdentitiesOnly yes
```

初めて `~/.ssh/config` を書く場合は、`chmod 600 ~/.ssh/config` を忘れずに。

## 個人用アカウントを使う

個人用アカウントで private_repository という repository を作ったとします。
これを clone するときは、普通は

```
> git clone git@github.com:privateAccount/private_repository.git
```

です。
これを以下のように変えると、明示的に個人用アカウントの SSH Key が使えます。

```
> git clone github_private:privateAccount/private_repository.git
```

GitHub 上の shell account である git@github.com の代わりに .ssh/config で設定した github_private を使う、ってことですね。

## 会社用アカウントを使う

会社用アカウントを使う場合も同様です。
会社用アカウントで company_repository という repository を作ったら、以下で clone 出来ます。

```
> git clone github_company:companyAccount/company_repositry.git
```

## メリット・デメリット

予め ssh の設定をしておいて、git clone 時に指定すれば、後は設定云々を気にせずに使えます。（clone した repository の .git/config に、この設定が書き込まれるから）
ただ既に clone しちゃった repository には使えませんし、個人的に SSH の設定が git の中に混じっちゃうのはちょっと気持ち悪いかな、、、と。

# SSH Key の切り替え（その２） - ssh-agent で

pass phase の入力無しに楽に ssh したい！と言えば ssh-agent なわけで。
まずは設定。
ZSH の人は以下の設定を `~/.zshrc` とかに加える。

```
if [[ ${SSH_AUTH_SOCK} = "" && -x /usr/bin/ssh-agent ]]; then
    eval `ssh-agent` > /dev/null 2>&1
fi
ssh-add -l >/dev/null
if [[ $? = 1 ]]; then
    eval `ssh-add ~/.ssh/id_rsa > /dev/null 2>&1`
elif [[ $? = 2 ]]; then
    echo "cannot access to ssh-agent"
fi
```

ssh-agent が起動してると、`SSH_AUTH_SOCK`環境変数に ssh-agent の file socket のファイル名が入っている。
だから上の設定は、最初の if 文は ssh-agent が起動して無くて、ssh-agent のコマンドがあったら、ssh-agent を起動する。
次の if 文は、何も SSH Key が登録されてなかったら、デフォルトの SSH Key を食べさせますよ、と言うこと。
`ssh-add -l` は、何か登録されてたら 0、何も登録されてなかったら 1、ssh-agent と通信できなかったら 2 を exit status として返すことを利用している。

## 個人用アカウントを使う

上の設定で ssh-agent にデフォルトの SSH Key を登録しているので、何も考えなくても使える。

## 会社用アカウントを使う

会社用アカウントを使う場合は、デフォルトの SSH Key を消して、`id_rsa_github` の方を登録すれば良い。

```
> ssh-add -d ~/.ssh/id_rsa && ssh-add ~/.ssh/id_rsa_github
```

また個人用アカウントを使う場合は、逆のことをすれば良い。
いちいち打ち込むのは非常に面倒臭いけど、`.zshrc` とかに alias で登録すれば良いんじゃないのかな。

## 今どっちなのか確認

これをやってて問題になるのは、「さて今どっちだっけ」となってしまうことである。
私の脳みそにはそんなこと覚えてられる容量は無い。
ひとつの方法は

```
> ssh-add -l
```

として、id_rsa_github が出てくれば会社用アカウントの状態だし、id_rsa が出てくれば個人用アカウントの状態。
ただこれはちょっと味気ない。
そこで

```
> ssh -T git@github.com
Hi XXXXX! You've successfully authenticated, but GitHub does not provide shell access.
```

こうすると、上記の `XXXXX` のところに GitHub のアカウント名が出てくるので、

```
> ssh -T git@github.com |& cut -d' ' -f2
XXXXX!
```

と GitHub のアカウント名だけ取れる。
（BASH と ZSH だったら `|&` で大丈夫のはず）
ビックリされちゃってるけど、元気がよろしくて良いね！ということで。
後は `.zshrc` とかに（略
例えばこんな感じに

```
alias gitkey-company="ssh-add -D && ssh-add ~/.ssh/id_rsa_github"
alias gitkey-private="ssh-add -D && ssh-add ~/.ssh/id_rsa"
alias gitkey-check="ssh -T git@github.com |& cut -d' ' -f2"
```

（ssh-add -D は登録されてる key を全消しするので、重複して叩いてもエラーが出なくなる）

## メリット・デメリット

普段はほぼ個人用アカウントを使っているけど、ちょっとした時だけ会社用アカウントを使う、っていう場合には、他に何にも影響を与えないので、こっちの方がいいと思う。
頻繁に会社用アカウントを使う場合は、SSH の設定の方がいいんじゃないかな。