1Passwordで管理しているSSHの鍵をDocker for Mac上のdevcontainerでも使う

#1password
#docker
#vscode

背景

  • Mac では 1Password 上で SSH key を管理し、ssh-agent 機能 で Git の操作などに使っている
  • 普段 VSCode devcontainer での開発が多いので、Docker コンテナ内でも 1Password の SSH key を使いたい
  • Docker でホスト・ゲスト間の鍵共有には ssh-agent forwarding という仕組みが用意されているが、色々ハマりどころがあったので手順を整理した

Host マシン(Mac)側の設定

まず 公式ドキュメント通りに Mac 側で 1Password 上の鍵を使った SSH 接続が通るようにする。

# .zshrc # https://developer.1password.com/docs/ssh/get-started#step-4-configure-your-ssh-or-git-client if [[ "$OSTYPE" == "darwin"* ]]; then export SSH_AUTH_SOCK=~/Library/Group\ Containers/2BUA8C4S2C.com.1password/t/agent.sock fi

Mac 側で ssh -T git@github.com などで疎通が確認できれば OK。

Docker 側でも SSH_AUTH_SOCK に設定したソケットへアクセスし、コンテナ内から SSH の鍵を参照したい。これは環境変数が設定されているシェル内からopen -a Dockerすれば良い。

open -a Docker ps -Eww `pgrep -o Docker` PID TTY TIME CMD 26016 ?? 0:01.05 /Applications/Docker.app/Contents/MacOS/Docker PWD=/Users/horimislime SSH_AUTH_SOCK=/Users/horimislime/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock ...

SSH_AUTH_SOCK が Docker の起動時に渡せていればコンテナ側の設定(後述)でソケットにアクセスできる。

ちなみに OS 起動時に自動で Docker を立ち上げた場合などは当然変数を渡す方法がない。これは現状有効な workaround などもないようなので、Docker の起動については一手間かけるしかない。
/run/host-services/ssh-auth.sock doesn't work · Issue #6541 · docker/for-mac

devcontainer 側の設定

devcontainer では以下のようにして Mac 側で設定されたソケットを参照し鍵へアクセスできる。

// .vscode/devcontainer.json // https://docs.docker.com/desktop/networking/#ssh-agent-forwarding { "name": "Dev Environment", "image": "mcr.microsoft.com/vscode/devcontainers/base", "containerEnv": { "SSH_AUTH_SOCK": "/run/host-services/ssh-auth.sock" }, "mounts": [ "source=/run/host-services/ssh-auth.sock,target=/run/host-services/ssh-auth.sock,type=bind" ] }

/run/host-services/ssh-auth.sock という見覚えのないパスが登場するがお作法として書く。素直に Mac 側のソケットパスを指定してマウントすればいいのでは、という疑問が湧くけど、Unix domain socket は直接マウントできないという制約が関係しているようだ。
$SSH_AUTH_SOCK is not being forwarded to docker · Issue #410 · docker/for-mac

コンテナ内の SSH コマンドが参照する SSH_AUTH_SOCK も設定しておく。この時 remoteEnv ではなく containerEnv に変数定義する必要があるので注意する。containerEnv で指定したパスはコンテナの起動時に以下のように参照先が変更される。ここまで設定できたら SSH の疎通が取れるようになっているはず。

/workspaces/devcontainer ❯ echo $SSH_AUTH_SOCK /tmp/vscode-ssh-auth-60adbac5-8373-4f56-b933-84a6e8d19758.sock /workspaces/devcontainer ❯ ssh -T git@github.com Hi horimislime! You've successfully authenticated, but GitHub does not provide shell access.

TZ=Asia/Tokyo のようなコンテナ内のアプリケーション用設定には remoteEnv を使うクセがあったが、このケースのように Docker 側で変数の中身に手を加えるようなケースを考慮すると containerEnv を使う方が無難そうだ。公式でもこちらの方が推奨されているようだった。

We recommend using containerEnv (over remoteEnv) as much as possible since it allows all processes to see the variable and isn’t client-specific. Dev Container metadata reference

Tweet