問題点
- Dockerコンテナのビルド時に、DockerfileからGitのプライベートリポジトリにアクセスしたり、SSHの公開鍵認証でサーバに接続したりしたくなることがある
- そのような場合、ホストマシンの
~/.ssh
以下を参照することになるが、以下のような問題が発生する- Dockerfileの
COPY
命令では~
や$HOME
が利用できず、絶対パスか相対パスで表現する必要があり、その場合にユーザによって~/.ssh
までのパスが変わってしまう - Dockerfileの
RUN
命令では--mount=type=bind
でファイルやディレクトリをマウントできるが、~
や$HOME
が利用できず、絶対パスか相対パスで表現する必要があり、その場合にユーザによって~/.ssh
までのパスが変わってしまう
- Dockerfileの
解決策
- 上記の問題を解決し、DockerfileからホストマシンのSSH秘密鍵をセキュアに参照するための仕組みが
docker build
コマンドの--ssh
オプションとRUN
命令の--mount=type=bind
である
検証
Dockerfile
FROM debian:stable-slim
# sshコマンドとssh-keyscanコマンドを使用できるようにする
RUN apt-get update
RUN apt-get install -y --no-install-recommends openssh-client
# Host Key CheckingをPASSするための設定
# Host Key CheckingはクライアントがサーバのSSH公開鍵を取得し、そのサーバが信頼できるサーバであることを確認するプロセスで、主に中間者攻撃(MITM)から守るための手順
# 通常は ~/.ssh/known_hosts に事前にサーバのSSH公開鍵を登録しておくことで、SSH接続時にここにあるSSH公開鍵と照合する
RUN mkdir ~/.ssh
RUN touch ~/.ssh/known_hosts
RUN chmod 700 ~/.ssh
RUN chmod 600 ~/.ssh/known_hosts
RUN ssh-keyscan 153.127.195.142 > ~/.ssh/known_hosts
# SSH接続する
# -T オプションを指定すると擬似端末(pseudo terminal; pty)が割り当てられなくなるため、非インタラクティブにsshコマンドを実行できる
RUN --mount=type=ssh ssh -T ubuntu@153.127.195.142
# --ssh オプションでホストマシンのSSH秘密鍵をDockerコンテナに渡す際にSSHエージェントを参照するため、事前にSSHエージェントにSSH秘密鍵を登録しておく
# ホストマシンの再起動時に登録したSSH秘密鍵は削除されるため注意
$ ssh-add /path/to/your_ssh_private_key
# SSHエージェントにSSH秘密鍵が登録されていれば表示される
$ ssh-add -l
# --ssh オプションの利用にはBuildKitの有効化が必須
# Docker 18.09以前のバージョンではBuildKitがデフォルトで有効化されていないため、以下の環境変数で有効化しておく必要がある
# BuildKitはDockerの新しいビルドエンジンで、ビルドの高速化や機能の拡張が行われている
$ DOCKER_BUILDKIT=1
# --ssh オプションに default を指定した場合、SSHエージェントが選定したSSH秘密鍵が使用される
# SSHエージェントは登録日が新しいものから順に参照する
$ docker build -t dockerfile-ssh-example --ssh default .