web-dev-qa-db-ja.com

DOCKERFILEのARGがシークレットの受け渡しに推奨されないのはなぜですか?

http://docs.docker.com/engine/reference/builder/#arg では、ARGSを介してシークレットを渡さないことをお勧めします。

注:githubキー、ユーザー資格情報などの秘密を渡すためにビルド時変数を使用することはお勧めしません。

危険なビルド時変数を通過する秘密はどの時点ですか?

26
Roger Lam

2018年8月の更新:

これで、ドッカーbuild --secret id=mysecret,src=/secret/file
Dockerでビルド時引数を使用する安全な方法 」を参照してください。

2017年1月の更新:

Docker(swarm)1.13には docker secret

ただし、 commented by Steve Hoffman(bacoboy

[...] secretコマンドは、swarmユーザーがより一般的なソリューションではないことを支援するだけです(永続的なボリュームをアタッチする場合のように)。
シークレットの管理方法(それらが何であり、誰がそれらにアクセスできるか)は、システムに大きく依存し、「プラットフォーム」を作るために組み合わせた有料またはOSSのビットに依存します。
プラットフォームの提供に移行しているDockerでは、HashicorpがVaultをAtlasに統合しているように、最初の実装がスウォームベースであることは驚くことではありません。

秘密がどのように渡されるかは、docker run
AWSはロールとポリシーを使用してこの種のことを行い、アクセス許可とSDKを許可/拒否します。
Chefは、暗号化されたデータバッグと暗号化された「ブートストラップ」を使用して認証します。
K8Sには、1.13でリリースされたばかりのバージョンがあります。
mesosが同様の実装をやがて追加すると確信しています。

これらの実装は2つのキャンプに分類されるようです。

  • 「プラットフォーム」が提供するボリュームマウント経由でシークレットを渡すか、(chef/docker secret/k8s
  • ブート時に情報を取得するために外部サービスと通信するための資格情報を渡します(iam/credstash/etc)

元の回答:2015年11月

これは commit 54240f8 (docker 1.9、2015年11月)で導入されました PR 15182

ビルド環境は、キャッシュルックアップを支援するために、中間コンテナのコマンド文字列の前に追加されます。
ビルドのトレーサビリティにも役立ちます。しかし、これにより、ビルド時の秘密を渡すという観点から、この機能の安全性が低下します。

問題1349 繰り返します:

ビルド時環境変数:ビルド時環境変数は、秘密を処理するように設計されていません。他のオプションがないため、人々はこれを使用することを計画しています。それらが秘密に適しているという印象を与えることを防ぐために、プロセスでそれらの変数を意図的に暗号化しないことが決定されました。

9176comments で述べたように:

env変数は、秘密を渡す間違った方法です。車輪を再発明して、すぐに障害のあるセキュリティ配布メカニズムを提供しようとするべきではありません。

環境に秘密鍵を保存すると、誤って公開する傾向があります。まさに避けたいことです。

  • 環境がプロセスで暗黙的に利用可能であることを考えると、アクセスとコンテンツの公開方法を追跡することは、不可能ではないにしても、非常に困難です。
  • デバッグに役立ち、エラーレポートの一部として送信することもあるため、アプリケーションが環境全体を取得して印刷することは非常に一般的です。非常に多くの秘密がPagerDutyに漏洩しているため、インフラストラクチャからそれらをスクラブする内部プロセスが十分にグリース化されています。
  • 環境変数は子プロセスに渡されるため、意図しないアクセスが許可され、最小特権の原則が破られます。アプリケーションの一部として、サードパーティのツールを呼び出して何らかのアクションを実行すると、サードパーティのツールが突然環境にアクセスし、それがどうなるかを神が知っていると想像してください。
  • クラッシュするアプリケーションでは、後でデバッグするために環境変数をログファイルに保存することが非常に一般的です。これは、ディスク上の平文の秘密を意味します。
  • Env変数に秘密を入れると、すぐに部族の知識に変わります。新しいエンジニアは、それらが存在することを知らず、環境変数を処理する際に注意する必要があることを認識していません(サブプロセスへのフィルタリングなど)。

全体として、env変数のシークレットは最も驚きの原則を破り、悪い習慣であり、シークレットの最終的な漏洩につながります。

31
VonC

単純な理由は、historyを実行するだけで、秘密の値が画像を持つすべてのユーザーに表示されるためです。

このサンプルdockerファイルをご覧ください。

FROM Alpine

ARG secret

RUN echo "${secret}"

(素敵でシンプル、秘密をどのように使うかを説明するためだけに。)

それからビルドします$ docker build --build-arg secret=S3CR3T - < Dockerfile

Sending build context to Docker daemon 2.048 kB
Step 1 : FROM Alpine
 ---> 13e1761bf172
Step 2 : ARG secret
 ---> Running in 695b7a931445
 ---> 5414c15a1cb6
Removing intermediate container 695b7a931445
Step 3 : RUN echo "${secret}"
 ---> Running in c90cf0d1414b
s3cr3t
 ---> f2bcff49ac09
Removing intermediate container c90cf0d1414b
Successfully built f2bcff49ac09

そして、「秘密」を取り戻す方法の例(|1 secret=最初の行で):

$ docker history f2bcff49ac09
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
f2bcff49ac09        8 seconds ago       |1 secret=S3CR3T /bin/sh -c echo "${secret}"    0 B
5414c15a1cb6        8 seconds ago       /bin/sh -c #(nop) ARG secret                    0 B
13e1761bf172        6 months ago        /bin/sh -c #(nop) ADD file:614a9122187935fccf   4.797 MB

これは、イメージをローカルで構築した場合、またはレジストリから取得した場合です。

実行中のコンテナからビルド時の秘密を守ることが目的の場合は、ARGを使用すると役立ちます。これを検討してください。

$ docker run --rm -ti f2bcff49ac09 sh
/ # env
HOSTNAME=7bc772fd0f56
SHLVL=1
HOME=/root
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
$ # Note no secret in the above output
9

新しい(17.05)ドッカー機能のマルチステージビルド( https://docs.docker.com/engine/userguide/eng-image/multistage-build/ )はこれらの(有効な)懸念を軽減すると思います--build-argを使用するだけです。

FROM mybuildertools
ADD my-git-creds /root/.ssh
RUN git clone [email protected]:example/foo /src
FROM mybuildertools
COPY --from=0 /src /src
RUN ...build /src with no git credentials ending up in final image...

残念ながら、「my-git-creds」ディレクトリがない限り、後続の再構築(Dockerfileのビルドステップの変更など)を許可する簡単な方法はないようです。

3
jamshid

https://github.com/abourget/secrets-bridge と書いて、ビルド時の秘密の問題に対処しました。

これは、ビルドプロセス中にビルド引数として渡すことができるスローアウェイ構成を作成し、ホストに接続してシークレットを取得して使用し、ホストブリッジを強制終了できます。 build-argsがどこかに保存されていても、サーバーが終了するとすぐに使用できなくなります。

サーバーは、TLS Websocket通信を介してトンネリングされるSSHエージェント転送をサポートします。 Windowsでも動作します!

お役に立てれば。

2
abourget