AuthZ& AuthN - Docker Access Authorization Plugin
Dockerのデフォルトの認可モデルはすべてまたは何もです。Dockerデーモンにアクセス権限を持つ任意のユーザーは任意のDockerクライアントコマンドを実行できます。同じことが、DockerのEngine APIを使用してデーモンに連絡する呼び出し元にも当てはまります。より細かいアクセス制御が必要な場合、認可プラグインを作成し、Dockerデーモン構成に追加できます。認可プラグインを使用すると、Docker管理者はDockerデーモンへのアクセスを管理するための細かいアクセスポリシーを構成できます。
基本的なアーキテクチャ
Docker Authプラグインは外部のプラグインであり、Dockerデーモンに要求されたアクションを許可/拒否するために使用できます。これは、要求したユーザーと要求されたアクションに応じて、Dockerデーモンに要求されたアクションを許可/拒否することができます。
CLIを介してまたはEngine APIを介してDockerデーモンにHTTPリクエストが行われると、認証サブシステムはインストールされた認証プラグインにリクエストを渡します。リクエストにはユーザー(呼び出し元)とコマンドコンテキストが含まれます。プラグインは、リクエストを許可または拒否するかを決定する責任があります。
以下のシーケンス図は、許可および拒否の認可フローを示しています:
プラグインに送信される各リクエストには、認証されたユーザー、HTTPヘッダー、およびリクエスト/レスポンスボディが含まれます。プラグインに渡されるのはユーザー名と使用された認証方法だけです。最も重要なのは、ユーザーの資格情報やトークンは渡されないことです。最後に、認可プラグインに送信されるのは、Content-Type
がtext/*
またはapplication/json
であるリクエスト/レスポンスボディのみです。
exec
などのHTTP接続を乗っ取る可能性のあるコマンドに対して(HTTPアップグレード
など)、認可プラグインは最初のHTTPリクエストのみに対して呼び出されます。プラグインがコマンドを承認すると、残りのフローには認可が適用されません。具体的には、ストリーミングデータは認可プラグインに渡されません。logs
やevents
などのチャンク化されたHTTPレスポンスを返すコマンドに対しては、HTTPリクエストのみが認可プラグインに送信されます。
リクエスト/レスポンス処理中、一部の認可フローではDockerデーモンへの追加のクエリが必要になる場合があります。このようなフローを完了するために、プラグインは通常のユーザーと同様にデーモンAPIを呼び出すことができます。これらの追加のクエリを有効にするには、プラグインは管理者が適切な認証およびセキュリティポリシーを構成できる手段を提供する必要があります。
複数のプラグイン
Dockerデーモンの起動の一部として、プラグインを登録する責任があります。複数のプラグインをインストールし、それらを連結することができます。このチェーンは順序付けられることができます。デーモンへの各リクエストは、チェーンを通過して順番に処理されます。リソースへのアクセスがすべてのプラグインによって許可される場合のみ、アクセスが許可されます。
プラグインの例
Twistlock AuthZ Broker
プラグインauthzを使用すると、JSONファイルを作成して、リクエストを承認するためにプラグインが読み取ることができます。したがって、各ユーザーがどのAPIエンドポイントに到達できるかを非常に簡単に制御できます。
以下は、AliceとBobが新しいコンテナを作成できるようにする例です:{"name":"policy_3","users":["alice","bob"],"actions":["container_create"]}
ページroute_parser.goでは、要求されたURLとアクションの関係を見つけることができます。ページtypes.goでは、アクション名とアクションの関係を見つけることができます
シンプルプラグインチュートリアル
インストールとデバッグに関する詳細な情報を含む理解しやすいプラグインをこちらで見つけることができます:https://github.com/carlospolop-forks/authobot
README
とplugin.go
のコードを読んで、どのように動作するかを理解してください。
Docker Authプラグインのバイパス
アクセスの列挙
確認する主なポイントは許可されているエンドポイントと許可されているHostConfigの値です。
この列挙を実行するには、https://github.com/carlospolop/docker_auth_profilerというツールを使用できます。
許可されていない run --privileged
run --privileged
最小権限
コンテナを実行して特権セッションを取得する
この場合、システム管理者はユーザーがボリュームをマウントしたり、--privileged
フラグを使用してコンテナを実行したり、コンテナに追加の権限を与えることを禁止しています。
しかし、ユーザーは実行中のコンテナ内でシェルを作成し、追加の特権を与えることができます:
今、ユーザーは以前に議論されたテクニックのいずれかを使用してコンテナから脱出し、ホスト内で特権を昇格することができます。
書き込み可能フォルダのマウント
この場合、システム管理者はユーザーに--privileged
フラグを使用してコンテナを実行することを禁止し、コンテナに追加の権限を与えることを許可せず、/tmp
フォルダのみをマウントすることを許可しました。
/tmp
フォルダをマウントできない場合がありますが、別の書き込み可能なフォルダをマウントすることができます。書き込み可能なディレクトリを見つけるには、次のコマンドを使用できます:find / -writable -type d 2>/dev/null
Linuxマシンのすべてのディレクトリがsuidビットをサポートするわけではありません! suidビットをサポートするディレクトリを確認するには、mount | grep -v "nosuid"
を実行します。たとえば、通常、/dev/shm
、/run
、/proc
、/sys/fs/cgroup
、/var/lib/lxcfs
はsuidビットをサポートしていません。
また、/etc
をマウントしたり、構成ファイルを含む他のフォルダをマウントした場合、それらをdockerコンテナ内でrootとして変更してホストで悪用し、特権を昇格させることができます(たとえば、/etc/shadow
を変更することができます)
未チェックのAPIエンドポイント
このプラグインを構成するシステム管理者の責任は、各ユーザーがどのアクションをどの特権で実行できるかを制御することです。したがって、管理者がエンドポイントと属性にブラックリストアプローチを取る場合、攻撃者が特権を昇格させる可能性のあるいくつかのエンドポイントを見落とす可能性があります。
Docker APIはhttps://docs.docker.com/engine/api/v1.40/#で確認できます。
未チェックのJSON構造
ルートでのバインド
システム管理者がDockerファイアウォールを構成する際に、APIの重要なパラメータである「Binds」を見落とした可能性があります。 次の例では、この構成ミスを悪用して、ホストのルート(/)フォルダをマウントするコンテナを作成および実行することが可能です:
この例では、JSON内のルートレベルのキーとして Binds
パラメータを使用していますが、APIでは HostConfig
キーの下に表示されていることに注意してください。
HostConfig内のBinds
ルート内のBinds と同じ手順に従い、Docker APIにこの リクエスト を実行してください:
ルートでのマウント
ルートでのバインドと同じ手順に従い、このDocker APIに対してリクエストを実行します:
HostConfig内のマウント
Docker APIにこのリクエストを実行する際に、rootでのバインドと同じ手順に従ってください:
未チェックのJSON属性
システム管理者がDockerファイアウォールを設定する際に、APIのHostConfig内のCapabilitiesなどの重要なパラメータの属性を見落としてしまった可能性があります。次の例では、この設定ミスを悪用して、SYS_MODULE機能を持つコンテナを作成および実行することが可能です。
HostConfig
は通常、コンテナから脱出するための興味深い権限を含んでいるキーです。ただし、以前に議論したように、それ以外の場所でBindsを使用することも機能し、制限をバイパスすることができる可能性があります。
プラグインの無効化
システム管理者がプラグインの無効化を禁止するのを忘れていた場合、これを完全に無効化するためにこれを利用することができます!
認証プラグインのバイパスに関する解説
参考文献
Last updated