去年の12月に「Gitで複数アカウントのssh接続ができたー」みたいな記事を書いてましたが、最近また問題が勃発。各リポジトリのgitのconfigファイルで正しくssh接続名を指定しても、sshでユーザ切り替えをしようとしても、なぜかユーザーが切り替わりません。

自分の環境ではGitHubアカウントごとにssh接続用の秘密鍵を使い分けているのですが、どうしても片方の秘密鍵でログインされてしまいます。
おかしいなと思ってググったら、~/.ssh/configで複数アカウントを運用する上で重要な設定IdentitiesOnly yesが抜けていたことが判明しました。

問題点

gitのconfigファイルに接続先を正しく設定していても、なぜかpermission deniedになってしまう。
さらに、sshコマンドでアカウント切り替えをしようとしても、なぜかアカウントが切り替わらない。

例)

$ ssh -T GitHub-YotioSoft
Hi YotioSoft! You’ve successfully authenticated, but GitHub does not provide shell access.
$ ssh -T GitHub-Labo
Hi YotioSoft! You’ve successfully authenticated, but GitHub does not provide shell access.

上記の例では、ホスト名をGitHub-YotioSoftとして設定したGitHubのYotioSoft(個人用)のアカウントにsshで接続した後に、ホスト名をGitHub-Laboとして設定したGitHubの研究室用のアカウントにssh接続しようとしています。
見てみると、YotioSoftに接続しようとしているときに「Hi YotioSoft!」とGitHubのサーバから返ってきています。つまり、個人用のアカウントYotioSoftに接続できているということです。
そこまでは良いのですが、研究室用アカウントに接続しようとしているときも「Hi YotioSoft!」と返ってきていますね。これではアカウントの切り替えができません。

理想としては

$ ssh -T GitHub-YotioSoft
Hi YotioSoft! You’ve successfully authenticated, but GitHub does not provide shell access.
$ ssh -T GitHub-Labo
Hi [研究室用のアカウント名]! You’ve successfully authenticated, but GitHub does not provide shell access.

このようになってほしいのですが、なぜかアカウントを切り替えようとしてもYotioSoftにログインしたままになっています。秘密鍵も正しく設定できているのに、なぜだろう?

解決策

.ssh/configに問題がありました。IdentitiesOnlyの値を記述しておらず、デフォルト設定でIdentitiesOnly=noになっていたのが原因のようです。

以前は、.ssh/config

Host GitHub-YotioSoft
    HostName github.com
    User git
    Port 22
    IdentityFile ~/.ssh/id_rsa_yotiosoft

Host GitHub-Labo
    HostName github.com
    User git
    Port 22
    IdentityFile ~/.ssh/id_rsa_labo

このようにしていましたが、各ホストの設定にIdentitiesOnly yesを追記し

Host GitHub-YotioSoft
    HostName github.com
    User git
    Port 22
    IdentityFile ~/.ssh/id_rsa_yotiosoft
    TCPKeepAlive yes
    IdentitiesOnly yes

Host GitHub-Labo
    HostName github.com
    User git
    Port 22
    IdentityFile ~/.ssh/id_rsa_labo
    TCPKeepAlive yes
    IdentitiesOnly yes

このようにすると解決しました。

なお、IdentitiesOnlyの他にTCPKeepAlive yesも追記していますが、これはssh接続の維持を行わせるための設定で、ついでに設定しておいたものなので今回の話題には直接関係はありません。

IdentitiesOnlyとは

「IdentityFileで指定した秘密鍵のみを使用するか」という設定。yesならIdentityFileで指定した秘密鍵のみを使用。デフォルトではnoになっているようです。

今回の原因としては、おそらく個人用の秘密鍵と研究室用の秘密鍵を使い分けている環境下で、秘密鍵の使い分けを指示しておらず、ssh内で個人用の秘密鍵が優先されてしまったのが原因だと思われます。

まとめ

gitでssh接続で複数のアカウントを利用し、なおかつ秘密鍵を使い分けているときは、必ずIdentitiesOnly yesを設定しよう。設定しないとアカウントの切り替えがうまくいかない事態が起こりえます。

追記(2023年2月24日)

この記事へのアクセス数が増えているので、GitHub のアカウントを複数持つことについて一応注意書きをしておきます。GitHub では、無料アカウントを1人で複数持つことは規約違反にあたります。ただし、2つのアカウントを持っていて、一方のアカウントが GitHub Pro、または有償の GitHub Organization に所属している場合は規約違反にはあたりません。
なお、筆者のもう一方(研究室用)のアカウントは、研究室が有償 Organization を契約しており、アカウント自体も GitHub Pro に契約しているため契約違反には該当しません。

参考: