皆様どうも、こんにちは!
こまりの情報処理技術者、桑木です。
WSL2はただ単にWindowsから使えるLinux環境と言うだけでなく、とてもシームレスにコマンド実行やファイルの参照ができるので、WindowsにLinuxが融合したかのような使い心地を得ることができます。
しかし、アプリケーションレベルではやっぱり別環境なので、SSHの設定などはそれぞれ個別にする必要があります。とはいえ、複数の鍵を作ったり、同じ鍵をコピーしたりはしたくありません。
そこで、今回の記事ではWindowsにssh-agent
を設定することで、WSL2でSSH接続するときの認証をWindows側に転送して肩代わりさせる方法を説明します。
この記事の内容
手順
ひとまず先に手順だけ載せます。
Chocolateyをインストールしていない場合は、手順に従ってインストールしてください。色々書かれていますが、Step2.2のコマンドを管理者権限のpowershellにコピペして実行するだけです。Chocolateyはnpiperelay
をインストールするために使うだけなので、npiperelay
を他の方法でインストールできるならChocolateyは不要です。
管理者権限のpowershellで以下のコマンドを実行します。
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
choco install -y npiperelay
ssh-add
WSL2の~/.bash_profile
に次の記述を追加します。
export SSH_AUTH_SOCK=$HOME/.ssh/agent.sock
ss -a | grep -q $SSH_AUTH_SOCK
if [ $? -ne 0 ]; then
rm -f $SSH_AUTH_SOCK
( setsid socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork EXEC:"npiperelay.exe -ei -s //./pipe/openssh-ssh-agent",nofork & ) >/dev/null 2>&1
fi
上記の.bash_profile
がなければ作成します。
その場合は上の記述とは別に、次の行を先頭に記述します。既に.bash_profile
が存在する場合は、同じ意味の記述がしてあるはずなので不要です。
test -r ~/.bashrc && . ~/.bashrc
WSL2で次のコマンドを実行します。
sudo apt install -y socat
WSL2再起動後に次のコマンドを実行してWindows側と同じものが表示されればOKです。
ssh-add -l
解説(Windows側)
SSHエージェントとはなんぞや、ということに関してはqiitaの記事なんかが詳しいので参考にしてください。
ここでは前述の手順の意味を解説をします。
OpenSSHサービス(SSHエージェント)の常駐
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
Windowsに登録されている「OpenSSH Authentication Agent」サービスの「スタートアップの種類」が初期状態では「無効」になっているので、「自動」に設定してWindows起動時に自動的に起動するようにしています。
これはWindows起動時の動作を設定しただけなので、今回に限り手動でも起動してやります。
このサービスが起動すると、Windowsについてくるssh-agent.exe
が常駐して名前付きパイプ\\.\pipe\openssh-ssh-agent
がオープンされます。
SSHエージェントにSSHキーの登録
ssh-add
SSHエージェントにSSHキーを登録します。id_rsa
的なファイルをパラメータで指定すれば、それが登録されます。省略した場合は、ユーザディレクトリ/.ssh/
にあるid_rsa, id_dsa, id_ecdsa, id_ecdsa_sk, id_ed25519, id_ed25519_sk
などが登録されるようです。
手順前後しますが、
ssh-add -l
SSHエージェントに登録されているSSHキーの一覧を表示します。WindowsとWSL2の両方で、このコマンドで同じものが表示されればSSHエージェントが正しく機能していることが確認できます。
名前付きパイプのリレーに使うコマンドのインストール
choco install -y npiperelay
WSL2からWindowsの名前付きパイプを参照するために後で必要になるnpiperelay.exe
をインストールします。chocoでインストールすればPATHも通るようなので、インストール先を気にする必要もなさそうです。
解説(WSL2側)
UNIXドメインソケットのリレーに使うコマンドのインストール
sudo apt install -y socat
WSL2側にも、UNIXドメインソケットをリレーするために必要になるsocat
をインストールします。
.bash_profile
, .bashrc
ログイン時に自動的に実行されるファイルです。今回の場合は.bash_profile
に後で説明するコマンドを記述して、ログイン時に自動実行させます。WSL2のUbuntuは、初期状態では.bash_profile
が存在しないので作成しますが、.bash_profile
が存在する場合は.bashrc
が実行されません。
.bashrc
は初期状態でも存在していて、シェルを色々ユーザフレンドリーにしてくれるスクリプトが記述されています。これが実行されないとユーザフレンドみが足りなくなります。
test -r ~/.bashrc && . ~/.bashrc
そこで.bash_profile
の中から.bashrc
を実行するコマンドを記述しておきます。
UNIXドメインソケットと連携
export SSH_AUTH_SOCK=$HOME/.ssh/agent.sock
環境変数SSH_AUTH_SOCK
に適当なパスを指定します。WSL2側のssh
コマンドはSSH_AUTH_SOCK
が設定されていれば、そこに指定されたUNIXドメインソケットを通してSSHエージェントとやりとりします。
ss -a | grep -q $SSH_AUTH_SOCK
if [ $? -ne 0 ]; then
rm -f $SSH_AUTH_SOCK
( setsid socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork EXEC:"npiperelay.exe -ei -s //./pipe/openssh-ssh-agent",nofork & ) >/dev/null 2>&1
fi
SSH_AUTH_SOCK
で指定したUNIXドメインソケットが存在するかどうか判定して、存在しなければsocat
を実行して作成します。
このソケットに接続があればnpiperelay
が起動されて、その標準入出力とUNIXドメインソケットの入出力がリレーされます。npiperelay
は、Windowsの名前付きパイプと標準入出力をリレーするコマンドですが、結果的にこれでWindowsの名前付きパイプとWSL2のUNIXドメインソケットが接続されている状態になります。
まとめ
- WindowsにUNIXドメインソケットはないが、ほとんど同じ機能の名前付きパイプ(named pipe)がある
ssh-agent
をWindowsに移植する際に名前付きパイプを使用するように変更された- WindowsとWSL2の連携は良くできているものの、残念ながらWSL2から直接名前付きパイプを参照する方法がない
- 標準入出力ならシームレスに連携できる
- よって、UNIXドメインソケットと名前付きパイプを標準入出力経由で接続すればOK