Windowsで(Yubikeyを使って)GPGでSSHする

# WindowsでYubikeyを使ってGPGでSSHする

## はじめに

### 感想

二度とやらん

### これ何

この記事は[mixiアドベントカレンダー2021](https://qiita.com/advent-calendar/2021/mixi) 5日目の記事です。

今年2021年11月1日からmixiにジョインしました。

ジョインした際に支給されたMacで初めてYubikey経由のSSHを設定したので、いっそWindowsでもYubikey経由でSSHができるようにしたい！なんならGPGの鍵から生成した公開鍵でSSHできたら素敵やん！とプライベートで使っているWindows11のPCで設定した時に躓きまくって傷だらけになったので、備忘録も兼ねて書いてみます。

### ところで今日は

僕の誕生日です🎉🎉🎉

https://amazon.pito.run

## 今回の目的

Yubikeyの機能を使ってSSHする事を目指します。

Yubikeyを活用する方法として、ざっと2種類挙げられるかなと思います。

### 1. `ssh-keygen` のオプションタイプ指定でFIDOを利用した鍵タイプ `ed25519-sk` または `ecdsa-sk` を指定して、暗号化する際にYubikeyを必須化させる

1の場合、SSH相手先がこのキータイプに対応しないと使えません。また、そもそもWindows10以降標準でインストールされているOpenSSHは2021年12月現在、 `OpenSSH_for_Windows_8.1p1` が使われています。

しかし、残念ながらこの fido対応になったopensshバージョンは [8.2](https://www.openssh.com/txt/release-8.2) からで、windows標準のopensshでは非対応です。だからといって手動で別バージョンを入れるのはちょっと・・・

また、このFIDOに対応してるSSHサーバーじゃないと相手先が復号化出来ないので、利用可能な範囲が狭くなってしまいます。

### 2. Yubikeyに保存したGPG鍵を利用して、gpg-agentを経由してSSHする
 
デジタル署名に使われるGPGの秘密鍵から公開鍵を生成して、それを用いてSSHをします。

---

sshでの認証する時のエージェントをgpg-agentに移譲することで、GPGで管理している鍵を使用して認証するように出来ます。GPGの鍵がSSH相手先で対応している鍵タイプであればそのまま利用できます。

・・・ところでこの手順、Yubikeyあまり関係ない話題になってしまうのですが、すみません、あしからず。

## 作業手順

### お断り

windowsで主に引っかかるSSH via GPGをするための環境構築を解説するので、鍵の作成と鍵をyubikeyへ移動する話は解説しません。Yubikeyまで鍵を移動する方法やそもそものGPG鍵の作成方法についてはわかりやすい解説があったので、下記ページ等を参考にしてください。

#### 鍵の作成
https://qiita.com/cocoabreak/items/d96cd0ba56cdcbf62d32#%E9%8D%B5%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B

#### GPG鍵をYubikeyへ移動する
https://keens.github.io/blog/2021/03/23/yubikeywotsukau_openpghen/

### GPGをインストール

[gpg4win](https://www.gpg4win.org/)をダウンロード、インストール、パスを通しておきます。

パッケージマネージャー利用者は下記コマンドでinstall可能です。

このGPG4WINにはKleopatraというGUIアプリが付いてきてしまうので、ついCUIで完結できたら良かったんですが、GNUPG2.3.2以降にディレクトリ指定周りの[バグが存在する](https://github.com/ScoopInstaller/Main/issues/2599#issuecomment-908067817)だったり、ssh-agentとの協調がうまく行かなかったりと不具合が多いので、[Yubikeyの公式](https://developers.yubico.com/PGP/SSH_authentication/Windows.html)にも書かれている通り、GPG4WINを入れる事をおすすめします。

#### scoop

```sh
scoop install gpg4win
# gpg4winにもgpgコマンドは入っていますが、パスが自動で通らないのでgpgコマンドも別途足したほうが幸せかも
# scoop install gpg
```

#### chocolatey

```sh
choco install gpg4win
```

### Windows用のssh agentをインストール

Windows上ではWSL対応、OpenSSHの標準化、Windowsでサーバー作業する時に使われがちなMSYS2など、様々なチャネルが混在しておりカオスを極めています。この解説はこれも参考URLを貼る形になってしまうのですが、こちらを参照ください。

https://qiita.com/slotport/items/e1d5a5dbd3aa7c6a2a24

今回インストールするのは `wsl-ssh-pageant` で、本来はWSLの環境で使うためのものですが、これが無いと動きません。

[benpye/wsl-ssh-pageant](https://github.com/benpye/wsl-ssh-pageant)をダウンロード、インストールします。

パッケージマネージャー利用者は下記コマンドでinstall可能です。

※現在gnupg2.3.2以降のバージョンにディレクトリ指定周りのバグが存在するらしく、これを回避するにはgpgのバージョンを2.3.1以前のバージョンを指定する必要があります。参考URLに書かれた対処方法をする労力を掛けてもいい方以外はバージョン指定してインストールすることをおすすめします。
参考： https://github.com/ScoopInstaller/Main/issues/2599#issuecomment-908067817


#### scoop

```sh
scoop install wsl-ssh-pageant
```

#### chocolatey

```sh
# GUIで稼働させないとコンソールが残ったままになり鬱陶しい(scoopはデフォでGUI/CUI両方入ってます)
choco install wsl-ssh-pageant-gui
```

### 各種agentを自動起動させる

ファイル名を指定して実行(Windowsキー+R)で `taskschd.msc` を入力してタスクスケジューラーを起動します

![スクリーンショット 2021-12-05 024115.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104876/2c2abfd4-06d6-d794-58fc-8c7d84c51e4e.png)

`Microsoft > Windows` 辺りで新しいタスクを作成する。

トリガーはログオン時を指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104876/b3e17610-3789-bd4e-0a6d-610156881f9a.png)

起動するプログラムは下記を指定

プログラム `{wsl-ssh-pagent-gui.exeを指定}`
引数 `--systray -winssh openssh-ssh-agent`

プログラム `{gpg-connect-agent.exeを指定}`
引数 `/bye`

これにより、再起動するか、タスクを手動で実行すれば必要なアプリが自動で立ち上がるようになります。

### GPG鍵を生成・インポート

ここでは解説しないので、下記記事やその他記事を見て生成方法やバックアップしてください。

https://qiita.com/cocoabreak/items/d96cd0ba56cdcbf62d32#%E9%8D%B5%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B

既に鍵を生成済の方は、もし操作するPCのキーチェーンに入っていない場合はインポートしてください。

Yubikeyを使った鍵のかんたんお引越しの話は別記事で解説予定です。

### 自分のGPG鍵のフィンガープリントとキーグリップを確認する

鍵のフィンガープリントを確認しておきます。このあとの作業で使います。

キーグリップはSSHで使うのでAuthentication用のサブキーのキーグリップを控えておいてください。

```sh
# インポートした鍵のフィンガープリントとキーグリップを確認
gpg --list-keys --with-keygrip
--------------------------------------------------------
pub   nistp521 2021-12-05 [SC]
      {ここにフィンガープリント}
      Keygrip = {主鍵のキーグリップ}
uid           [  究極  ] mecaota <example@example.com>
uid           [  究極  ] [jpeg image of size 4096]
sub   nistp521 2021-12-05 [E]
      Keygrip = {↑のキーグリップ}
sub   nistp521 2021-12-05 [A]
      Keygrip = {↑のキーグリップ(AがAuthenticationで認証用なのでこれを控える)}
```

### 設定変更

`%APPDATA%\gnupg\gpg-agent.conf` に下記項目を書き足します。

```conf
enable-ssh-support
```


または、Kleopatraを起動して、メニューから `設定>Kleopatraの設定>GnuPG System>プライベート鍵` の `Sshサポートを有効にする` にチェックを入れて適用します。

これでSSHでGPG鍵を使って認証できるようになりました！

### SSH用の公開鍵を取得する

下記コマンドでssh用の公開鍵を入手します。

`gpg --export-ssh-key {ここにフィンガープリント}`

ここで出された公開鍵をgithub然りSSH先のサーバーに登録したりすることで、晴れてSSH via GPG鍵ができるようになります！

### 確認

下記コマンドを入力して、このような結果が出てくれば成功です。

```sh
ssh-add -L

# {鍵タイプ} {公開鍵の文字列} cardno:{カード番号}
```

### Git for WindowsのSSHクライアントをOpenSSHにする

そのままだとGit for Windowsに内蔵されたOpenSSHが使用されてしまいます。Windows内蔵のOpenSSHを使うよう修正します。

```sh
 git config --system core.sshCommand C:/Windows/System32/OpenSSH/ssh.exe
```

`\`や`¥`を使うと、うまくディレクトリパスとしてパース出来ないので、`/`を使ってディレクトリを切ります。

```sh
git config --system core.sshCommand
# C:/Windows/System32/OpenSSH/ssh.exe と出てくればOK
```

## 使い方

いつものようにsshするだけです。

途中で下記のような入力が出てきますが、これはYubikeyに登録しているGPGのPINです。初期設定では `123456` になってますが、変えている場合はそれを入力してください。

```shell
ssh git@github.com
# Hi mecaota! You've successfully authenticated, but GitHub does not provide shell access.
# Connection to github.com closed.
```

YubikeyのGPG用のPINは初期設定ではだれでもわかってしまうので変えてない方は変えておきましょう。


## あとがき

みなさんもぜひYubikeyを手に入れて、Yubikeyでなんでも完結させちゃいましょう！

~~そして、Windows特有の問題に苦労したく無い方はWindowsを消して任意のLinuxディストリビューションを入れましょう~~