ふぃーるどのーつ

技術系ブログ「ふぃーるどのーつ」

リモートLinuxの開発コンテナー(Dev Container)上でgit認証のためにssh agentを共有する

簡単に言うと、VS CodeのDevContainers(以下開発コンテナー)でSSHのForward Agentを有効にする方法です。

VS Codeのリモート開発では、ssh接続したLinux上で開発コンテナーを起動して開発をおこなうことができます。Gitレポジトリーへの認証は、GitHubであればVS Code上でGitHub認証すればそれで済むのですが、色々な事情でGitレポジトリーからsshの公開鍵認証を使用してgit cloneしている場合を考えます。

サーバー・コンテナーおよびソフトウェア等のコンポーネントの関係は以下の通りです。

その際に、Gitの認証情報の扱いについては以下の様な前提を考えます。

このため、コンテナー上でsshのDocker側で .sshディレクトリーをマウントする方法は取れず、デスクトップ環境上の認証情報をssh-agentを使用してLinuxサーバー上→Dockerコンテナーと多段で転送することになります。

その方法についてです。

SSHエージェント転送の設定

GitHubSSHエージェント転送の利用 に従ってSSHのエージェント転送の設定を行います。

基本的には、 ~/.ssh/config のホスト設定に ForwardAgent yes を設定します。

Host pi.local
  ForwardAgent yes

エージェント転送するデスクトップ環境と、Linuxの環境上で、ssh -T git@github.com を実行して、それぞれ、GitHubへの公開鍵での認証が成功していることを確認します。

また、Linuxのサーバー上で、ssh-agent -s を実行して、エージェント転送によってサーバー上でssh-agentの設定が有効になっていることを確認します。

デスクトップ環境上での確認

-> % ssh -T git@github.com
Hi azusa! You've successfully authenticated, but GitHub does not provide shell access.

Linuxの環境上での確認

-> % ssh -T git@github.com 
Hi azusa! You've successfully authenticated, but GitHub does not provide shell access.
% ssh-agent -s
SSH_AUTH_SOCK=/tmp/ssh-hUY7HhVFv08Q/agent.335449; export SSH_AUTH_SOCK;
SSH_AGENT_PID=335450; export SSH_AGENT_PID;
echo Agent pid 335450;

なお、VS Code上においては、設定の「Enable Agent Forwarding」(remote.SSH.enableAgentForwarding) を true に設定すれば、 ForwardAgent yes の設定は必要ないです。ただし、ターミナル(コマンドライン) からssh接続した場合とVS Code上で挙動がかわってしまうため、~/.ssh/config 上でForwardAgentの 設定をすることをおすすめします。

開発コンテナー上でのssh-agentの共有

開発コンテナーのビルドはdocker compose を使用して docker-compose.yml に記述するものとして説明します。

以下のサイトの記述に従ってLinuxサーバー上の環境変数 SSH_AUTH_SOCK をコンテナー上でマウントします。

SSH_AUTH_SOCK が2回出てきますが、

  • ホスト(Linuxサーバー)上の SSH_AUTH_SOCK が差しているファイルをコンテナー上で /tmp/ssh-agent.sock としてマウントして、
  • コンテナー内で /tmp/ssh-agent.sockSSH_AUTH_SOCK環境変数として指定する

という意味になります。

services:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      SSH_AUTH_SOCK: "/tmp/ssh-agent.sock"
    volumes:
      - .:/app
      - "$SSH_AUTH_SOCK:/tmp/ssh-agent.sock"
    working_dir: /app

ここまで設定すればSSHでリモート接続したVS Code上でGitからクローンしたレポジトリーから開発コンテナーを起動した場合に、公開鍵のパスフレーズ入力なしでGit操作ができるようになっているはずです。

サンプルコードは以下で公開しています。

github.com

実際にはDocker Desktop上とちがい、Linuxサーバー上で開発コンテナーを動かすにはホスト上とコンテナー上でUID/GIDを同じにする必要があり、その方法を調べるのが大変だったのですが、それはまた次の話にします。