GitHubのSSH接続でセキュリティキーを使ってみた

# はじめに

OpenSSHでFIDOセキュリティーキーが利用できるということでちょっと使ってみました。<br>mac からGitHubのリポジトリにSSHで接続する設定でFIDOセキュリティキーをつかって色々試しました。<br>Windows、Linuxも似たような感じだと思うんですが未確認です。

**ちゃんとしたドキュメント読まないでやってみてる系なので間違っていたらスミマセン**



- 環境
  - macOS Big Sur 11.4
  - OpenSSH
        - OpenSSH_8.6p1, OpenSSL 1.1.1k 25 Mar 2021
  - Security Key
        - [Yubikey-blue](https://www.amazon.co.jp/dp/B07BYSB7FK)
        - [Yubikey-nano](https://www.amazon.co.jp/dp/B07HBDX2CM)
  - Git Client
        - GitHub Desktok Version 2.8.3 (x64) 



## OpenSSHのバージョンについて

バージョン8.2以上でないといけないようです。`ssh` コマンドでバージョン確認しときましょう。

```zsh
ssh -V
```

念の為に `ssh-keygen` も確認

```
ssh-keygen --h
```

って打って表示される usage に  **ecdsa-sk** とか  **ed25519-sk** ってのがあればOKです。 

> ssh-keygen: illegal option -- -
>
> usage: ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile]
>
> ​         [-m format] [-N new_passphrase] [-O option]
>
> ​         [-t dsa | ecdsa | **ecdsa-sk** | ed25519 | **ed25519-sk** | rsa]
>
> ​         [-w provider] [-Z cipher]



# GitHubにSSHで接続する設定手順

設定するのかなりめんどくさいと思うんですけど結構皆やってますね。<br>特に仕事だと必須だったりします。

設定はざっくり以下の手順になります。



前提. GitHubにログイン可能でレポジトリがある状態

1. ssh-keygenでキーペア(秘密鍵と公開鍵)を生成する
2. GitHubに公開鍵を登録する
3. 秘密鍵を自分のPCのssh-agentに登録する
4. 設定完了-接続確認
5. レポジトリをクローンしてみる



順番に説明していきます。



## 1. ssh-keygenでキーペア(秘密鍵と公開鍵)を生成する

`ssh-keygen`を実行します。


```zsh
ssh-keygen -t ed25519-sk
   または
ssh-keygen -t ecdsa-sk
```

- -t に **ed25519-sk** か **ecdsa-sk** のいずれかを指定することでFIDOセキュリティキーを使ってキーペアを生成します。

- セキュリティキーをPCに刺した状態で実行しましょう。

- **ed25519** とか **ecdsa** は暗号化アルゴリズムのことで **sk** っていうのはセキュリティキーの事でしょう。
  - どっちも **RSA** よりは強力と言われています。
  - **ed25519-sk** はセキュリティキー側の仕様で対応していない場合もあり、そんなときは **ecdsa-sk** を使いましょう。
  - GitHubの推奨は **ed25519-sk** のようです。こっちの方が強力なんだと思います。



キーペアの生成は対話式になっています。

- Enter PIN for authenticator: 
  - セキュリティキーに設定されたPINを入力します。
- You may need to touch your authenticator (again) to authorize key generation.
  - キーがピカピカ光るのでタッチする
- Enter file in which to save the key (/Users/gebo/.ssh/id_ecdsa_sk):
  - 生成するキーファイルの保存場所を指定します。そのままenterでデフォルトの場所
- Enter passphrase (empty for no passphrase): 
  - 秘密鍵をアクティベートするためのパスフレーズを登録。そのままenterでパスフレーズ無し
- Enter same passphrase again: 
  - パスフレーズを再入力

これで秘密鍵と公開鍵の2つのファイルができます。



今回はこんなのができました。

- 暗号化アルゴリズム
  - **ecdsa-sk**
- ファイルの場所 
  - /Users/gebo/.ssh (デフォルト)
- 生成されたファイル
  - id_ecdsa_sk (秘密鍵ファイル)
  - id_ecdsa_sk.pub (公開鍵ファイル) 



## 2. GitHubに公開鍵を登録する

これは通常のSSHと同じです。

ブラウザでGitHubにログインして Settings → SSH and GPG keys → SSH Keys → New SSH Key です。

- Title
  - yubikey-blue-ecdsa にしました。表示用の名前なのでなんでもいいです。
- Key
  - さっき生成した **id_ecdsa_sk.pub** をテキストエディタで開いて中身をコピペします。



## 3. 秘密鍵を自分のPCのssh-agentに登録する

### config作成

.sshフォルダにconfigファイルが必要です。

無い場合は作りましょう。

```zsh
touch ~/.ssh/config
```



config

- IdentityFile には秘密鍵ファイルを指定します。

```zsh
Host *
  AddKeysToAgent yes
  IdentityFile ~/.ssh/id_ecdsa_sk
```



[GitHubのヘルプ](https://docs.github.com/en/github/authenticating-to-github/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)によると

> **Note:** If you chose not to add a passphrase to your key, you should omit the `UseKeychain` line.

ということで、つまり、パスフレーズを設定している場合は `UseKeychain yes` を設定する必要があるようです。



### ssh-agentに登録

以下の２発のコマンドです。

```zsh
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ecdsa_sk
```

ssh-addコマンドの引数には先程生成した秘密鍵ファイルを指定します。





## 4. 設定完了-接続確認

接続してみましょう。PCにセキュリティキーを刺した状態で以下のコマンドを叩きます。

```zsh
ssh -T git@github.com
```

よく見るとセキュリティキーがピカピカ光っているかと思いますのでタッチします。

すかさず接続完了のメッセージが出ればOKです。おめでとうございます。

> Hi gebogebogebo! You've successfully authenticated, but GitHub does not provide shell access.



## 5. レポジトリをクローンしてみる

とりあえず何かレポジトリをクローンしてみます。<br>普通にSSHクローンするだけです。<br>Gitクライアントアプリは GitHub Desktop を使います。<br>**PCにセキュリティキー刺しときましょう**。



- 画面から Clone Repository を選択します。

- クローン方法は **URL** を選択します。
- URL は git@github.com:gebogebogebo/bonge.git のように SSH を指定します。
- Clone ボタンをクリックすると おもむろにセキュリティキーがピカピカします。
  - 画面にはなんのガイドも表示されないので気をつけましょう。
- セキュリティキーをタッチするとCloneが始まります。



以降 Fetch とか Pull とかなにかにつけてセキュリティキーが光るのでタッチしてあげましょう。



# セキュリティキーの中にSSH接続情報を保存する

ここまでの手順ではPCの.sshディレクトリに秘密鍵ファイルと公開鍵ファイルを置いてSSH接続しました。<br>この場合、PCを引っ越ししたり2台目のPCにSSHの設定する際に秘密鍵、公開鍵ファイルをコピーする必要があります。<br>また、メインPCが突然壊れて起動しなくなった場合、秘密鍵ファイルと公開鍵ファイルを取り出すことができず、詰みます。

こんな時のために、**セキュリティキーの中にSSH接続のための秘密鍵と公開鍵を記録することができます。**



やり方は簡単、 `ssh-keygen` するときに **resident** オプションを指定するだけです。

```zsh
ssh-keygen -t ecdsa-sk -O resident
```

後は普通にSSH設定をします。



さて、秘密鍵ファイルを誤ってなくしてしまいました。こんな時は

```zsh
ssh-keygen -K
```

そうすると、カレントフォルダに

- 秘密鍵ファイル(例 id_ecdsa_sk_rk)
- 公開鍵ファイル(例 id_ecdsa_sk_rk.pub)

ができます。セキュティキー内部に保存されたデータを元に同じ情報を生成しているのです。<br>Diffを取ると秘密鍵は微妙に違うのですが公開鍵は全く同じでした。

というわけで、このファイルを使ってGitHubに接続すればOKです。



# GitはすべてCliでOkのツワモノにお勧めの使い方

ここまでは Gitクライアントに GitHub Desktop を使っていましたが、中には **GitをUIから使ったら負け**  の人もいらっしゃるかと思います。そんな Git達人のための使い方です。



**セキュリティキーだけでGitHubにSSH接続する**

です。



- ssh-keygenは resident オプションで生成する

- 生成された公開鍵をGitHubに登録したら捨てる。秘密鍵ファイルも捨てる

- .ssh/configなど不要

です。



さて、GitHubへの接続方法です。

1. PCにセキュリキーを刺す
2. `command + Space` で Spotlight から `terminal.app` を起動
3. 以下ターミナルの操作ログ

```zsh
gebo ~ % eval "$(ssh-agent -s)"
Agent pid 12254
gebo ~ % ssh-add -K           
Enter PIN for authenticator: 
Resident identity added: ECDSA-SK SHA256:67WNld8AfsHNfk/pUYhi+FyaOETmtkd4aJhpO9yrqYA
gebo ~ % ssh-add -l
256 SHA256:67WNld8AfsHNfk/pUYhi+FyaOETmtkd4aJhpO9yrqYA  (ECDSA-SK)
gebo ~ % ssh -T git@github.com
Hi gebogebogebo! You've successfully authenticated, but GitHub does not provide shell access.
```

わかりますでしょうか。<br> ツワモノには**sh-add -K**だけ説明すればいいでしょう。<br>**セキュリティキーからSSH接続情報を取り出してファイルにすることなく直接ssh-addすることができます。**<br>設定ファイルなど一切必要ありません。



# おつかれさまでした

いちいちタッチするのめんどくさいんだけど GitHub は -O no-touch-required には対応していないみたいですねぇ。




## 参考

- [GitHubにssh接続できるようにする](https://qiita.com/0ta2/items/25c27d447378b13a1ac3)
- [Generating a new SSH key for a hardware security key](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key-for-a-hardware-security-key)
- [OpenSSH 8.2 がリリースされました](https://www.unixuser.org/~haruyama/blog/post/20200214.html)
- [Ubuntu 20.04 LTSでU2F/FIDOデバイスを使ったSSHの2要素認証を試す](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0620)