mfunaki's blog

CircleCI の Developer Advocate やってる mfunaki のブログです。

1Password の ssh-agent 機能を WSL/WSL2 でも利用する(2023/12版)

はじめに

1Password のバージョン8では、SSH Key の管理機能(接続先エントリごとに public key, fingerprint, 秘密鍵を管理)、および、ssh-agent 機能が導入されました。

これにより、例えば GitHubSSH 接続する際に、コマンドラインssh-keygen した後、ssh-add で生成された秘密鍵を追加、public key は GitHub のウェブ画面から追加といった一連の作業をしなくても、1Password がいい感じに管理してくれます。

この素晴らしい機能、WSL2上は、長らく「サポートしないけど、`npiperelay` コマンドと `socat` コマンドをインストール、設定すればできるよ」といった扱いでした。その時に書いた Qiita 記事がこちらです。

qiita.com

その後、自分でコマンドをインストール、設定しなくても設定できる WSL サポートがベータ提供されていましたが、2023年12月12日リリースのバージョン 8.10.22 で正式リリースされました! ということで、今回は2013/12版として、1Password の ssh-agent 機能を WSL/WSL2 で利用する方法をご紹介します。

なお、英語版のマニュアルはこちらです。

developer.1password.com

設定手順

それでは、英語版マニュアルの記述に沿って、設定手順を説明していきます。

1. 1Password にサインアップする

そもそも 1Password ユーザーでなければ、この先の各種設定もできないので、1Password にサインアップしましょう。

サインアップしてアカウントを設定しておけば、パスワードだけでなく、この後説明する SSH キーや、ほかにも開発に必要な API  アクセスキーなどをセキュアに保存し、WindowsMacAndroidiOS 間で同期することも可能です。

2. 1Password for Windows をインストールし、サインインする

1Password for WindowsMicrosoft Store からも 公式サイトからもダウンロード可能です。ダウンロード、インストールし、メールアドレス、シークレットキー、パスワードの3点セットでサインインしておきます。

3. 1Password 上で SSH キーを生成(またはインポート)する

1Passwordを起動して、最上部にある+新規アイテム をクリックすると、追加する項目を選択する画面になるので、SSHキーを選びます。

SSHキーを追加

新規アイテム画面が表示されるので、タイトルには GitHub SSH Key (アカウント名) など、わかりやすいタイトルを付けます。次に、+秘密鍵を追加 をクリックすると、 

が表示されるので、新しい鍵を生成、または(既存の鍵を登録するのであれば)キーファイルを読み込む をクリックします。今回は、新しい鍵を生成 を選びます。

秘密鍵を追加→新しい鍵を生成

鍵の種類には Ed25519 または RSA が指定可能です。画面上の説明では、

  • Ed25519: 最速かつ最新の規格です
  • RSA: RSAキーはEd25519キーよりも低速ですが、古いSSHサーバーでも動作します

とありますので、よほどのことがない限りは、Ed25519 でよいかと思います。鍵儒種類を選択して、生成 ボタンをクリックします。

Ed25519 を選択して生成

下のような感じで秘密鍵が生成されたら、保存 ボタンをクリックして、保存しておきます。

新規生成した秘密鍵を保存

4. GitHub に公開鍵を登録する

先ほど生成した秘密鍵に対応する公開鍵を GitHub に登録します。Web ブラウザで GitHub にアクセスしますが、ブラウザに 1Password プラグインがインストールしておくと、この後の作業が効率的です。

インストールが終わったら、GitHub サイトにアクセスし、SSH and GPG keys の設定画面にアクセスし、New SSH key ボタンをクリックします。

New SSH key

すると、add new SSH Key 画面が表示されます。Title 下のテキストボックスをクリックすると、先ほど設定した秘密鍵が表示されるので、クリックすることで、対応する公開鍵が自動入力されます。

秘密鍵を選択し、公開鍵を自動入力

公開鍵が自動入力されていることを確認したら、Add SSH key ボタンをクリックして、キーペアを保存しておきます。

GitHub に公開鍵を(認証目的で)追加

なお、上の画面では Key type が Authentication Key (認証用キー) となっていますが、同様のやり方で Key type に Signing Key を設定しておくことで、(GPGを使わない) SSH ベースでのコミット署名を行うことが可能になります。

4. Windows ホスト側で 1Password SSH エージェントをセットアップし、問題なく動作することを確認する

1Password が提供する ssh-agent を使用するため、Windows 標準の ssh-agent (OpenSSH Authentication Agent) を無効化します。Windows + R キーを押下し、services.msc コマンドを指定して OK ボタンをおし、サービス画面を表示します。

サービス (ローカル) の設定

サービスの一覧から OpenSSH Authentication Agent を探します。存在するのであれば、状態が実行中ではないことを確認してください。また、スタートアップの種類 も無効であることを確認します。そうでない場合は、OpenSSH Authentication Agent のプロパティ画面から、スタートアップの種類 を無効に、サービスの状態 を停止にしておきます。

OpenSSH Authentication Agent 設定

次に、1Password の 設定 → 開発者 から SSHエージェントを使用 にチェックを入れます。それ以外は、以下の項目が設定可能です。

  • 新しいものごとに承認を求める: アプリケーションおよびターミナルセッション、アプリケーション
  • 重要な承認を覚えておいてください: 1Passwordがロックされるまで、4時間、12時間、24時間、1Passwordが終了するまで
  • 接続を承認するときにキー名を表示する: True/False
  • リッチ承認プロンプトを使用する: True/False

SSHエージェント の設定

5. Windows Subsystem for Linux (WSL) および必要な Linux ディストリビューションをインストールする

WSL2 と Linux ディストリビューションMicrosoft Store、または コマンドラインからインストールします。インストールが完了し(必要に応じ、Windows を再起動したら)、Windowsコマンドプロンプト(または Windows PowerShell)、および、Linux ディストリビューション上で、ssh-add.exe -l を実行し、同じ実行結果を得られるか、確認します。Linux ディストリビューション上で実行する際も、拡張子の .exe を忘れないようにしてください。

Windows PowerShell 上での ssh-add.exe -l 実行結果

Ubuntu 上での ssh-add.exe -l 実行結果

次に、(GitHubSSH 接続する人であれば何度も実行したことがあろう) ssh.exe -T git@github.com を実行し、正しく SSH 接続ができるかどうかを確認します(繰り返しになりますが、拡張子 .exe が重要です)。

初回の実行であれば、おなじみの Are you sure ou want to continue connecting (yes/no/[fingerprint])? が表示されるので、yes と答えると、1Password のプロンプトが表示されます。認証ボタンをクリックし、Windows Hello が求める認証を実行します(パスワード入力、顔認証、指紋認証など)。

Ubuntu 上での github.com への SSH 接続の確認

これで、(Linux ディストリビューション側で SSH 鍵管理をしなくても) Windows 側の 1Password を活用して、SSH 接続できることが確認できました。

ここまで問題がないようであれば、Linux ディストリビューション側の git コマンドがSSH コマンドに拡張子 .exe つきの ssh.exe を使用するように指定します。

$ git config --global core.sshCommand ssh.exe

6. SSH キーを使って Git のコミットに署名する

次に、Git のコミット時に SSH キーを使って署名する方法をご紹介します。1Password を使って鍵の管理をしないのであれば、git config --global user.signingkey /PATH/TO/.SSH/KEY.PUB で公開鍵のファイルを指定すればいいのですが、今回は、公開鍵の格納先が 1Password の中なので、違った指定が必要となります。

1Password の WSL 連携ドキュメントには、Sign Git commits with SSH という項目が用意されているので、ここでご紹介していきましょう。

署名に使いたい SSH キーを(Windows 上で)1Password で選択し、次のステップ: Gitのコミットに署名する 上の 設定する ボタンをクリックするか、右上の 縦3点をクリックし、コミットの署名を設定する... メニューを選択します。

コミットの署名を設定する

すると、Gitコミットの署名を設定する という画面が表示されます。下のほうに、LinuxWindowsサブシステム (WSL) の設定 というチェックボックスがありますので、このチェックボックスを選択します(選択時と未選択時で上のテキストボックスの内容が一部異なります)。

Gitコミットの署名を設定する

コードスニペット ボタンをクリックすると、テキストボックスの内容がクリップボードにコピーされるので、Linux ディストリビューション上で、~/.gitconfig ファイルにクリップボードの内容をペーストし保存します。

ここまで完了すると、WSL 上の Linux ディストリビューションで 1Password に SSH鍵管理を任せた状態で、GitHub への SSH 接続や SSH キーを使った署名ができるようになります。もちろん、(Windows 上にインストールした)VSCode からでも、WSL2 上の Linux ディストリビューションで git clone したリポジトリのコミットや署名つきプッシュも問題なく実行可能です。

さいごに

ここまでの説明で、WSL 上に GitHub からクローンしたリポジトリの操作は問題なく行えます。

1Password に SSH 鍵の管理を任せることのメリットは何でしょう? たとえば、WSL2 上で動作する複数の Linux ディストリビューションを活用している場合(異なる Linux 環境を活用したい場合)、Linux 環境の数は増えても、SSH 鍵の管理は 1Password で一元管理できるので、鍵を作りすぎて管理しきれなくなるということがなくなります。また、定期的に鍵のローテーションを行う場合のメンテナンス性は圧倒的に高まります。

その一方で、筆者(私)が解決できていない問題として、VSCode のDev Container(開発コンテナ) との相性が悪いという問題があります。クローンしたリポジトリをDev Container で開くと、~/.gitconfig の内容は引き継がれるのですが、その中の以下のエントリが、(コンテナ内部からみて)該当するファイルが存在しない状態のため、コミット時にエラーになってしまいます。

[gpg "ssh"]
  program = "/mnt/c/Users/mfunaki/AppData/Local/1Password/app/8/op-ssh-sign-wsl"

op-ssh-sign-wsl が見つからない

ここさえ解決できれば、コンテナ内のクリーンな開発環境に籠って仕事ができるのですが。解決方法をご存じの方はぜひ教えていただければと思います。