LoginSignup
9
1

More than 3 years have passed since last update.

Dockerイメージとオレオレ証明書組み込みレシピ その2

Last updated at Posted at 2020-12-23

SSL 自己署名証明書と Docker レシピ その2

日立グループ OSS AdventCalendar #2 24日目は、OSSソリューションセンタ 神山 から投稿します。

前回記事(1枚目1日目)にて、Dockerイメージに証明書を組み込む方法を記載しました。今回は、その応用編をいくつか書いていきたいと思います。

応用編: マルチステージ・ビルドで組み込む

マルチステージ・ビルドとは、Docker 17.05 移行で導入された機能で、イメージのビルドを複数のステージに分けて実行できる機能です。マルチステージ・ビルド登場以前は、ビルド時のみ必要なパッケージもイメージに含まれてしまい、イメージの小容量化が難しかったのですが、マルチステージ・ビルドでは、多段階にビルドを分離することで、最終的に配布するイメージ(実行環境)からビルド時にのみ必要なパッケージを分離することが容易となります。

どのOSにしても、ca-certificates パッケージなど、何かしら インストールする必要があり、最小主義で環境を作りたい場合は、ちょっと気持ち悪い状態になります。

そんな時は、Docker のマルチステージ・ビルド を用いるときれいなイメージを作れます。

FROM ubuntu as certs
RUN apt-get update -y && apt-get install -y ca-certificates
COPY self-signed.cert /usr/local/share/ca-certificates/extra/self-signed.crt
RUN update-ca-certificates

FROM ubuntu
COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt

これは、1回目のビルドで通常通り証明書の登録ツール(update-ca-certificates)のインストールとオレオレ証明書のコピー及び登録をします。
そして2回目のビルドでは、update-ca-certificates の出力結果(/etc/ssl/certs/ca-certificates.crt) のみを新しいイメージに持ってきます。

最終的なイメージは、次のようなきれいなイメージになります。

  • オレオレ証明書を含む、システムが信頼する証明書(/etc/ssl/certs/ca-certificates.crt) は存在する
  • update-ca-certificates はインストールされていない
  • 登録のための一時ファイル(/usr/local/share/ca-certificates/extra/self-signed.crt) は存在しない

マルチステージ・ビルドはきれいなイメージを作りたいにはとても便利です。

応用編: 初見のイメージに証明書を登録する(Jenkins イメージ の例)

ここまでOSやミドルウェアをベースとする場合に、どうやって証明書を登録するかを扱ってきましたが…
実際は特定のサービス(Jenkinsなど…)で証明書を登録したいことも多いかと思います。
自己流なのでもしかしたら効率悪い・邪道な方法かもしれないです。もしもっと良い方法があればコメントでご指摘ください!

試しに Jenkins を例に、証明書を登録する方法を調べてみます。
証明書の登録は root 権限で行う必要がありますが、多くのイメージは、実行権限が root 以外になっています。

そこでまずはイメージの作りを見ていくのですが…
Docker Hub で Jenkins を見ると Dockerfile が公開されておりません。

こういうときは、Docker イメージ自体を調べてみます。

docker pull jenkins
docker history jenkins | grep "USER"

このように、jenkins イメージを取得し、history コマンドでどのようにイメージが作られたかを確認します。
この際、今回知りたいコンテナの実行ユーザーを設定している "USER" で絞り込みます。

すると、

<missing>   2 years ago   /bin/sh -c #(nop)  USER [jenkins]   0B

このような形で、"jenkins" ユーザーに設定されていることがわかります。

次にOSを特定したいのですが、Dockerfile が公開されていない場合、あたりを付けて調べてみるしかないです。
私はよく、

 docker run jenkins apt

といった具合に、パッケージマネージャをたたいてみて、コマンドの有無で調べています。
たまにパッケージマネージャすらも消してしまうような、ギリギリを攻めたイメージがあり、この方法で特定できないこともありますが…経験的にはこの方法でほぼ特定できました。

ここまでわかると、後は 次のような Dockerfile を書いて、ビルドしてあげればOKです。

FROM jenkins

USER root
COPY self-signed.cert /usr/local/share/ca-certificates/extra/self-signed.crt
RUN update-ca-certificates
USER jenkins
  1. ユーザをroot に戻す
  2. OSに合わせた方法で証明書をインストール(この場合は debian)
    • ここでは ca-certificates パッケージはインストールしていません(jenkins イメージではインストール済)
    • 多くの場合 ca-certificates パッケージが既にインストールされているため、まずは存在すること前提で呼び出すのがおすすめです。稀にインストールされていない場合がありエラーとなりますので、その場合は、 ca-certificates パッケージ のインストールも手順に組み込むと良いです
  3. ユーザを元に戻す
    • 元のイメージと使用感を合わせるために、実行ユーザは元に戻しておいた方が良いです

これで、正しくオレオレ証明書を認識するイメージが出来上がります。

さいごに

今回は、SSL証明書の登録を行う際に、イメージを小さくする方法や、初見イメージに対して組み込む流れを書いてみました。
この辺りは手探りな部分もあるので、もっと良い方法があれば、改善していきたいです。

9
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1