38
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

docker build --build-arg http_proxy=... で認証プロキシを設定すると危険だよ、という話

Posted at

はじめに

docker build --build-arg http_proxy=... で認証プロキシを設定すると危険だよ、という情報があまり広まっていない気がしたので書いておく。

なにが問題か?

Dockerのドキュメントより引用です。

Warning: It is not recommended to use build-time variables for passing secrets like github keys, user credentials etc. Build-time variable values are visible to any user of the image with the docker history command.

そう、--build-argで渡した環境変数はイメージには保存されていないから安全:smile:思ってはいけないdocker historyで参照できるメタデータにはバッチリ渡した環境変数が保存されているのである。
例えばdocker build --build-arg http_proxy=http://foo:bar@proxy.example.org のようにプロキシの認証情報を設定してビルドしていると、そのイメージをpullした環境でdocker historyするとプロキシ接続に利用したユーザID/パスワードが丸分かりになっちゃう、ということ。

この話、Qiitaで docker build-arg proxy で検索すると引っかかる記事では、触れられているものがなさそうで不安になった。
また、Qiita以外の日本語情報をググって探してみると、teratailに docker build で指定する http_proxy が履歴に残らないようにしたい というズバリそのものの質問があった。ぱっと目についたのはこの1件くらいと、気にしている人はかなり少なそうな印象。

で、どうすればいい?

いくつか対策はある。

対策1: Dockerをバージョンアップする

この問題、本家のISSUEでも扱われて実は新しめのDockerだと既に解決済みになっている。具体的には、Exclude “default” build-args from image historyというプルリクエストにより、下記のデフォルトのbuild-argsはhistoryから除外されるようになった。

  • HTTP_PROXY
  • http_proxy
  • HTTPS_PROXY
  • https_proxy
  • FTP_PROXY
  • ftp_proxy
  • NO_PROXY
  • no_proxy

Dockerのリリースノートを見ると、

ならこの修正が入っており大丈夫そう。ただし、リリースノートの下記記載のとおり、Dockerfileの中に ARG http_proxy みたいに書いてしまうと駄目なので注意。

The values of default build time arguments (e.g HTTP_PROXY) are no longer displayed in docker image history unless a corresponding ARG instruction is written in the Dockerfile. #31584

というわけで、新しいDockerに移行できるなら、これが一番簡単な対策方法。
(もちろんコンテナの再ビルドは必要。あと、過去のコンテナイメージはすでにpullされて広まっている可能性があるので、やってしまった方はパスワード変更をまず先にすべきでしょう)

対策:2 認証なしのプロキシを中継用に構築する

これは、teratailの回答 で示されていた方法の1つだが、認証なしのプロキシをDockerと認証プロキシの間に配置し、そこから認証プロキシに接続するようにするという方式。これだと、--build-argで渡すプロキシ情報には認証情報は入れなくて済む(プロキシを使っていることは分かってしまうが)。

自分は試していないが、認証ありHTTPプロキシを認証なしでプロキシするDockerfileでsquidを使って簡単にこのような中継プロキシを構築できるかも。

対策:3 透過プロキシを利用する

これも、teratailの回答 で示されていた方法の1つ。Dockerホスト側で透過プロキシを構築して、透過的に認証プロキシを経由させるという方法。これだと、--build-argでプロキシ情報は一切渡さなくて済む。Dockerのバージョンを上げれない場合はこの方法が個人的にはよいと思う。

なお、先日書いた プロキシとの戦いに疲れたのでgoで透過プロキシを作ってみた で紹介している透過プロキシを使うことで簡単に対応できる。

まとめ

  • Docker CE 17.05.0-ce未満を使っている場合、docker build --build-arg http_proxy=... で認証プロキシを設定するのは今すぐ止めよう (パスワード変更も忘れずに)。
  • Docker CE 17.05.0-ce以上にバージョンアップできる場合はそれでOK。コンテナの再ビルドは忘れずに。
  • バージョンアップできない場合は、透過プロキシ等を使って、少なくとも直接認証プロキシ情報を --build-argには設定しないようにすること。

おまけ

プロキシ関連で、Docker CE 17.07.0-ce (2017-08-29) 以上だと、下記のリリースノート内容のとおり、$HOME/.docker/config.json でプロキシ情報を設定できるようになっているので、--build-argで毎回渡す手間を省けるようになっている。

Add support for proxy configuration in config.json docker/cli#93

なお、この設定はdocker buildだけでなく、docker run時にも有効だそうで。設定方法はドキュメントに書かれているが、残念ながら実装と違うというISSUEが報告されており、正しくは以下のように設定する必要がある模様。

{
  "proxies":
  {
    "default":
    {
      "httpProxy": "http://127.0.0.1:3001",
      "noProxy": "*.test.example.com,.example2.com"
    }
  }
}
38
19
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
38
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?