LoginSignup
9
11

More than 5 years have passed since last update.

GitHubで複数のアカウントを使う方法

Last updated at Posted at 2018-12-30

概要

GitHub上に2つのアカウントを所有し、それぞれのリモートリポジトリにSourceTreeからpushした際に認証エラーが発生した。原因と解決法を以下に書き残す。

再現

環境

  • macOS 10.14.2
  • SourceTree 3.0.1

手順

GitHubからログアウトし、SourceTree上でConnect Accountをクリックする。

Screen Shot 2018-12-31 at 5.32.45.png

ブラウザが起動し、GitHubのログイン画面が表示されるため、登録したいアカウントでログインする。

screencapture-github-login-2018-12-31-05_33_11.png

Generate KeyをクリックしてSSHキーを生成する。必要に応じてパスフレーズを設定し、Saveをクリックして登録を完了させる。これを登録したいアカウント分繰り返す。

Screen Shot 2018-12-31 at 5.33.40.png

各アカウント上の適当なリモートリポジトリをcloneして変更をpushすると、一つのアカウントでは成功するが、その他のアカウントでは以下のようなエラーが発生して失敗する。

Screen Shot 2018-12-31 at 2.28.12.png

原因

リモートリポジトリを更新する際、別アカウントの秘密鍵を使って公開鍵認証を試みたため、認証エラーが発生した。アカウントと秘密鍵が正しく紐づいていないことが原因である。

解決法

SSH接続チェック(秘密鍵指定なし)

まず、SSH接続が可能であることを確認するため、以下のコマンドを実行する。

$ ssh -T git@github.com
Hi {アカウントA}! You've successfully authenticated, but GitHub does not provide shell access.

SSH接続は可能であるが、秘密鍵を指定しないとアカウントAが使われた。これは、デフォルトの秘密鍵としてアカウントAのものが選ばれたためである。デフォルトの秘密鍵がどのように決まるかは、#秘密鍵を指定しない場合の挙動についてにて後述する。

エージェントキー削除

SourceTree上でSSHキーを生成した際に、エージェントキーに追加される秘密鍵を削除する。以下のコマンドでは -D オプションで全てのキーを削除しているが、個別に削除する場合は -d オプションを使うこと。

$ ssh-add -l
4096 SHA256:{ハッシュ} Generated by Sourcetree on macOS for {アカウントA}-GitHub (RSA)
4096 SHA256:{ハッシュ} Generated by Sourcetree on macOS for {アカウントB}-GitHub (RSA)
$ ssh-add -D
All identities removed.
$ ssh-add -l
The agent has no identities.

SSH接続チェック(秘密鍵指定あり)

秘密鍵を指定してアカウントを使い分けるため、-i オプションを付けて再試行する。秘密鍵は ~/.ssh 配下に配置されており、SourceTree上で生成した場合は {アカウント名}-GitHub のようなファイル名になっている。

$ ls ~/.ssh
{アカウントA}-GitHub   {アカウントB}-GitHub      config
{アカウントA}-GitHub.pub   {アカウントB}-GitHub.pub  known_hosts
$ ssh -T git@github.com -i ~/.ssh/{アカウントA}-GitHub
Hi {アカウントA}! You've successfully authenticated, but GitHub does not provide shell access.
$ ssh -T git@github.com -i ~/.ssh/{アカウントB}-GitHub
Hi {アカウントB}! You've successfully authenticated, but GitHub does not provide shell access.

秘密鍵を指定することで、それぞれのアカウントでSSH接続することができた。

~/.ssh/config の修正

~/.ssh/config に設定を記述することで、前述のコマンドと同じことをスマートに実現できる。以下の記述例にて、sshコマンド実行時に接続先ホストしか指定していない点に注目する。

$ cat ~/.ssh/config
Host {接続先名}
    HostName github.com
    User git
    IdentityFile ~/.ssh/{アカウント名}-GitHub
$ ssh -T {接続先名}

上記を踏まえて、~/.ssh/config を以下のように修正する。

~/.ssh/config
# --- Sourcetree Generated ---
Host {アカウント名}-GitHub
    HostName github.com
-   User {アカウント名}
+   User git
    PreferredAuthentications publickey
    IdentityFile /Users/thara/.ssh/{アカウント名}-GitHub
    UseKeychain yes
    AddKeysToAgent yes
# ----------------------------

エージェントキー追加

エージェントキーから削除した秘密鍵を再登録する。

$ ssh-add ~/.ssh/{アカウントA}-GitHub
Identity added: /Users/thara/.ssh/{アカウントA}-GitHub (Generated by Sourcetree on macOS for {アカウントA}-GitHub)
$ ssh-add ~/.ssh/{アカウントB}-GitHub
Identity added: /Users/thara/.ssh/{アカウントB}-GitHub (Generated by Sourcetree on macOS for {アカウントB}-GitHub)
$ ssh-add -l
4096 SHA256:{ハッシュ} Generated by Sourcetree on macOS for {アカウントA}-GitHub (RSA)
4096 SHA256:{ハッシュ} Generated by Sourcetree on macOS for {アカウントB}-GitHub (RSA)

SSH接続検証

接続先ホストのみを指定してsshコマンドを実行し、#SSH接続チェック(秘密鍵指定あり)と同じ結果が得られることを確認する。接続先が git@github.com から {アカウント名}-GitHub に置き換わっているところが要点である。

$ ssh -T {アカウントA}-GitHub
Hi {アカウントA}! You've successfully authenticated, but GitHub does not provide shell access.
$ ssh -T {アカウントB}-GitHub
Hi {アカウントB}! You've successfully authenticated, but GitHub does not provide shell access.

リモートリポジトリの修正

SourceTree上にて、push先の各リモートリポジトリのURLを#SSH接続検証の要点を踏まえて以下のように修正する。

Screen Shot 2018-12-31 at 5.51.18.png

リモートリポジトリをcloneする場合は、同様にURLを修正してcloneする。

Screen Shot 2018-12-31 at 4.47.48.png

動作確認

各リモートリポジトリへ変更をpushし、正常に完了することを確認する。

Screen Shot 2018-12-31 at 6.29.12.png

秘密鍵に関わる挙動について

SSH接続の際に秘密鍵を指定しない場合はデフォルトで ~/.ssh/id_rsa が使われるが、自分の環境では同ファイルが存在しないのにアカウントAがデフォルトとして用いられた。デフォルトの秘密鍵は複数存在し得るのだが、それを知らず理解に苦しんだため、調査結果を備忘録として以下に書き残す。

秘密鍵を指定せず git@github.com へSSH接続をした時のログを -v オプションを付与して詳細に出力すると、秘密鍵の候補の一覧が確認できる。候補の詳細はopensshのソースコード中のコメントに記載されている。

$ ssh -vT git@github.com
OpenSSH_7.9p1, LibreSSL 2.7.3
...
debug1: rekey after 134217728 blocks
debug1: Will attempt key: Generated by Sourcetree on macOS for {アカウントA}-GitHub RSA SHA256:{ハッシュ} agent
debug1: Will attempt key: Generated by Sourcetree on macOS for {アカウントB}-GitHub RSA SHA256:{ハッシュ} agent
debug1: Will attempt key: /Users/thara/.ssh/id_rsa 
debug1: Will attempt key: /Users/thara/.ssh/id_dsa 
debug1: Will attempt key: /Users/thara/.ssh/id_ecdsa 
debug1: Will attempt key: /Users/thara/.ssh/id_ed25519 
debug1: Will attempt key: /Users/thara/.ssh/id_xmss 
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering public key: Generated by Sourcetree on macOS for {アカウントA}-GitHub RSA SHA256:{ハッシュ} agent
debug1: Server accepts key: Generated by Sourcetree on macOS for {アカウントA}-GitHub RSA SHA256:{ハッシュ} agent
debug1: Authentication succeeded (publickey).
...

上記のログより、秘密鍵の候補として最上位に選出されたアカウントAのエージェントキーで認証を行い、成功したことが分かる。エージェントキーが存在する時に秘密鍵を指定せずSSH接続を行なった場合は、登録されている順にエージェントキーで認証を試み、失敗した場合に ~/.ssh/id_rsa が用いられる。

まとめ

~/.ssh/config の設定を修正し、リモートリポジトリのURLを変えることで、複数のGitHubのアカウントを共存させることができた。最後に、問題発生当初に実施していた手順と処理の流れを以下に示す。

SourceTree上でアカウントAとアカウントBを登録した。
  ↓
両アカウントの公開鍵と秘密鍵が生成された。
同時に、エージェントキーが追加された。
  ↓
両アカウントのリモートリポジトリを git@github.com:{アカウント名}/{リポジトリ名} の形式でcloneした。
  ↓
git@github.com:アカウントA/リポジトリ へ変更をpush。
秘密鍵が指定されていないためエージェントキーを検索し、先に登録されたアカウントAの秘密鍵が選出される。アカウントと秘密鍵が正しく紐づいているため、処理が正常に完了した。
  ↓
git@github.com:アカウントB/リポジトリ へ変更をpush。
上記と同様にアカウントAの秘密鍵が選出される。アカウントと秘密鍵が紐づいていないため、認証エラーが発生して処理が失敗した。

9
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11