🐠

GitHub のリポジトリ操作の認証にSSH公開鍵を設定する

に公開
  • ssh-keygen のときのメールアドレスのコメントはどうするのがいいのか
  • パスフレーズの入力って毎回みんなしてるの?
  • https URL でクローンできないの辛い
  • 専用の鍵を自動で指定して使ってほしい

このあたりの説明も網羅的に書きました。

やりたいこと

GitHub 上の認証が必要なリポジトリ(プライベートリポジトリなど)の Git 操作を行えるようにする。そのさいに PAT (Personal Access Token) は使わずにSSHの公開鍵/秘密鍵を使う。

環境は MacOS です。

手順

1. ssh-keygen コマンド

ssh-keygen -t ed25519 -C "your-email@example.com"

-t は暗号化アルゴリズムの指定です。指定しない場合のデフォルトは RSA で 鍵長は 2048 bit です。 ed25519 は RSA より強力かというと特にそういうわけではないようなのですが、 GitHub 公式のドキュメントでは ed25519 を使うように書かれています。

-C は公開鍵の末尾に入るコメントの内容なのですが、指定しないとデフォルトでは account名@host名 で勝手に書かれてしまうので実害はうすいですがなんとなく後悔しがちです。GitHub で使っているメールアドレスなどを指定しましょう。あるいは https://github.com/settings/emailsKeep my email addresses private に以下のような記載があり、その xxxxx@users.noreply.github.com のメールアドレスを使うのも1つの選択です。私はそうしてます。

We’ll remove your public profile email and use xxxxx@users.noreply.github.com when performing web-based Git operations (e.g. edits and merges) and sending email on your behalf. If you want command line Git operations to use your private email you must set your email in Git.

Previously authored commits associated with a public email will remain public.

ssh-keygen の -C オプションのコメント領域の用途は別にメールアドレスを書くために限定されないのですが、詳細はこちらの記事が分かりやすくて好きです。ありがとうございます。

https://sussan-po.com/2022/07/06/ssh-keygen-command/

2. SSHキーペアを作成

ssh-keygen コマンドでキーペアを作成します。インタラクティブにいくつか質問されます。

Enter file in which to save the key

保存フォルダを変えたいことはあまりない気がしますが、ファイル名を変えたい場合はここで指定。私は GitHub のキーペアは GitHub でのみ使うようにしたいので id_ed25519_gh のように GitHub 用と分かる名前にしてます。

Enter passphrase for ... / Enter same passphrase again:

パスフレーズ(パスワードみたいの)をさらに設定したい場合にはここで入力します。基本的に設定しましょう。あとの節で ssh-agent を設定しますが、そうするとパスフレーズはキャッシュされるので毎回入力しなくてもよくはなります。

$ ssh-keygen -t ed25519 -C "your-email@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/your-home/.ssh/id_ed25519): /Users/your-home/.ssh/id_ed25519_gh
Enter passphrase for "/Users/your-home/.ssh/id_ed25519_gh" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/your-home/.ssh/id_ed25519_gh
Your public key has been saved in /Users/your-home/.ssh/id_ed25519_gh.pub
The key fingerprint is:
SHA256:(省略) your-email@example.com
The key's randomart image is:
+--[ED25519 256]--+
(省略)
ls -l ~/.ssh/

などして、秘密鍵と公開鍵が作成されていることを確認してください。

  • id_ed25519_gh: 秘密鍵。秘密なので権限が -rw------- で他の人が読み取りできない設定になっているはず
  • id_ed25519_gh.pub: 公開鍵。公開なので権限が -rw-r--r-- と広めになっているはず。 pub は Public のことですかね。

3. GitHub に公開鍵を登録

pbcopy < ~/.ssh/id_ed25519_gh.pub

のようにコマンドでコピーするか、ファイルを直接開いて中身をコピー。間違って秘密鍵をコピーしないように。
ssh-ed25519 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx your-email@example.com みたいな形式のほうが公開鍵。-----BEGIN OPENSSH PRIVATE KEY----- ... のほうは秘密鍵なので違うから。

https://github.com/settings/keys を開いて New SSH key ボタンを押す。

  • Title: なんでもいいけど、複数のPC端末から GitHub に鍵を登録するなら、その端末の区別がわかるようにするのもいい。あるいは複数端末で同じ秘密鍵という方法もあるのかもだけど、分けたほうが流出時に個別に無効化できてよい。
  • Key: さっきコピーしたやつをペーストする。

Add SSH Key ボタンで保存。

登録すると https://github.com/settings/keysAuthentication keys の公開鍵の一覧のところに表示されるはず。

その鍵を GitHub の Organization などでも使えるようにしたい場合は、 Configure SSO から任意の Org を Authorize する。

4. SSH の疎通確認

ssh -T git@github.com で SSH 接続してみます。

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

successfully authenticated と返事が返ってきてたら疎通できているということです。
ちなみに git@github.com への直接の SSH 接続はあくまで疎通確認でしか使いません。

ここまでうまくいってたら、 Private なリポジトリの git clone などを試してみましょう。

補足

むしろ、このあたりの情報をまとめて書き残しておきたかったからこの記事を書きました。

補足1: 秘密鍵の自動指定

私の場合は GitHubで使う鍵はGitHub専用にしているのでSSHが個別の鍵を勝手に使ってくれるように以下の設定を入れています。鍵名は自身の環境にあわせて替えてください。

~/.ssh/config
Host github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_gh

補足2: SSHキーを ssh-agent に追加

まずは eval "$(ssh-agent -s)" して ssh-agent をバックグラウンドで起動しておきます。

$ eval "$(ssh-agent -s)"
> Agent pid xxxxx

~/.ssh/config の Host github.com のセクションに次の設定を追加します。

~/.ssh/config
Host github.com
    AddKeysToAgent yes
    UseKeychain yes
  • AddKeysToAgent yes: 秘密鍵の設定。SSH接続を確立する際に、使用した秘密鍵を自動的にssh-agentに追加する。ssh-agent が停止や再起動されない限り秘密鍵を再利用してくれる。
  • UseKeychain yes: 秘密鍵のパスフレーズの設定。SSH接続を開始する際に、キーチェーンにパスフレーズがないか検索しあれば使用してくれる。なければユーザに入力させてそれをキーチェーンに登録する。

UseKeychain yes はパスフレーズを使っていなかったり、パスフレーズを Mac のキーチェーンに保存しない場合には削除してください。これによって Bad configuration option: usekeychain というエラーが発生することがあります。このときは Host github.com セクションに IgnoreUnknown UseKeychain をさらに追加してあげましょう。

こんな感じです。

~/.ssh/config
Host github.com
    AddKeysToAgent yes
    IgnoreUnknown UseKeychain

そして、鍵を ssh-agent に明示的に登録します。

ssh-add --apple-use-keychain ~/.ssh/id_ed25519_gh

--apple-use-keychain は秘密鍵とパスフレーズを Mac のキーチェーンに保存するというオプションです。キーチェーンを使わないならこれも不要です。基本的に UseKeychain yes を設定していれば初回 ssh 時にパスフレーズを聞かれてそのままその値をキーチェーンに保存してくれるので ssh-add を明示的に使用する必要はないような気もします [1]

ssh-agent 周りの設定のトラブルシュートは GitHub の公式が一番詳しいです。やはり公式が最強。

https://docs.github.com/ja/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#adding-your-ssh-key-to-the-ssh-agent

結局 補足1と補足2をあわせて ssh config の設定は

~/.ssh/config
Host github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_gh
    AddKeysToAgent yes
    UseKeychain yes

かあるいは

~/.ssh/config
Host github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_gh
    AddKeysToAgent yes
    IgnoreUnknown UseKeychain

とかになりそうです。

補足3: https://github.com/ URLを git clone などしたときに自動で git@github.com: に切り替える

これを設定しておくと、ブラウザでリポジトリを開いてそのURLをコピペしてクローンすることができるので楽。

~/.gitconfig
[url "git@github.com:"]
        insteadOf = https://github.com/

補足4: Personal Access Token と OAuth

GitHub の認証方法は、単純なパスワード認証(+ MFA)や PassKey などの、人間によるインタラクティブな認証方法がまずそんざいします。それ以外の場合の認証は、SSH公開鍵以外に Personal Access Token (PAT)OAuth があります。

PAT (Personal Access Token) はより手軽で設定も楽ですが、セキュリティ的なリスクもあり、一長一短です。

それら認証方法の違いと用途をまとめました。

比較項目 SSH公開鍵認証 PAT(Personal Access Token) OAuth App/GitHub App
安全性
認証情報の保存場所 秘密鍵はローカル、公開鍵のみGitHub トークン全体がGitHubと同期 リフレッシュトークンで更新可能
漏洩時のリスク 低い(秘密鍵+パスフレーズの二重保護) 高い(トークン単体で認証可能) 中程度(トークンの無効化が容易)
暗号強度 非常に高い(RSA/Ed25519) トークン文字列の複雑さに依存 OAuth標準に準拠
ネットワーク上の安全性 認証情報が流れない HTTPS経由でトークンが流れる 認証フローで保護
権限管理 リポジトリへの全アクセス権 スコープで細かく権限設定可能 最も細かい権限設定が可能
有効期限 なし(手動で削除が必要) 期限設定可能(自動失効) 自動更新可能
利便性
初期設定の難易度 複雑(鍵生成、登録、SSH設定) 簡単(生成してコピペ) やや複雑(App登録、認証フロー実装)
日常的な使用 非常に便利(パスフレーズのみ) やや煩雑(トークン入力/保存設定) 自動更新
複数端末での利用 各端末で鍵生成が必要 同一トークンを使い回し可能 認証フローで各端末認証
リポジトリURL SSH形式(git@github.com:...) HTTPS形式(https://github.com/...) HTTPS形式
推奨用途
個人開発 ◎ 推奨 △ 使用可能 △ オーバースペック
チーム開発 ◎ 推奨 △ 補助的に使用 ○ 大規模なら検討
自動化・CI/CD × 設定が複雑 ○ 簡単だが次善 ◎ 推奨
一時的なアクセス × ◎ 権限範囲と期限を厳密に設定し使用 ○ 使用可能
サードパーティ連携 × △ 一時的でないなら非推奨 ◎ 最適
脚注
  1. しかし、明示的に ssh-add --apple-use-keychain して問題になるわけでもなく、私はやってます。ここらへんよく知らない。 ↩︎

Discussion