DUICUO

SELinuxでコンテナを保護する


システムをハッキングし、コンテナ防御の第一線として SELinux を構成することがなぜ重要であるかを理解します。


Linux環境で何かが正常に動作しなくなった場合、最も簡単な方法はSecurity-Enhanced Linux(SELinux)を無効にすることです。しかし、突然正常に動作するようになった場合、無効化したことを忘れてしまう可能性があります。これはよくある落とし穴であり、非常に強力なセキュリティツールを失ってしまうことを意味します。

コンテナ、マイクロサービス、分散アーキテクチャの台頭に伴い、脅威も増加しています。これは、古くからよく知られている問題、つまりスピードに起因しています。コンテナの利点は、迅速な対応、より多くの処理、そして迅速な変更を可能にすることにあります。これは、コンテナの導入が急速に進んでいることを意味しますが、そのスピードは、より多くの問題や脆弱性に遭遇することを意味します。これは、より多くのことをより速く行うようになるにつれて、当然のことです。

脅威を軽減する方法

孫子の言葉に「戦わずして敵を征服することが、究極の勝利である」というものがあります。コンテナの基本的な防御においては、この言葉がまさに当てはまります。問題(戦闘)を回避し、コンテナホストのセキュリティを確保するには、SELinuxを第一の防御線として活用できます。

SELinuxは2000年にリリースされ、2003年にLinuxカーネルに統合されたオープンソースプロジェクトです。Red Hatによると、「SELinuxはLinuxシステム向けのセキュリティアーキテクチャであり、管理者がシステムへのアクセス権限をより詳細に制御できるようにします。SELinuxは元々米国国家安全保障局(NSA)によって開発され、Linuxセキュリティモジュール(LSM)を使用したLinuxカーネルへの一連のパッチです。」

さあ、始めましょう。

コンテナといえば、おそらくDockerが真っ先に思い浮かぶでしょう。Dockerは2013年の登場以来、コンテナ導入に革命をもたらしました。コンテナが爆発的に普及した主な理由の一つはDockerですが、前述のように、大量導入によってユーザーのセキュリティリスクに対する脆弱性が高まっています。

SELinux を使用して Docker コンテナを保護する前に、いくつかの設定を行う必要があります。

前提条件


  • CentOS 8/RHEL 8 がインストールおよび構成されました。
  • Docker CEのインストールと設定
  • ルート ユーザーと非ルート ユーザー (以下の例では​mcalizo​ ) の 2 つのアカウントを作成します。

RHEL 8/CentOS 8 サーバーに Docker をセットアップする必要がある場合は、こちらの手順に従ってください。RHEL 8 を使用している場合は、開始する前に、プリインストールされている Podman および runc パッケージを削除する必要があります。

まず、SELinux が有効になっていることを確認します。

 [mcalizo@Rhel82 ~] $ sestatus
SELinux ステータス: 有効
SELinuxfs マウント: /sys/fs/selinux
SELinux ルートディレクトリ: /etc/selinux
読み込まれたポリシー名: 対象
現在のモード: 強制
設定ファイルからのモード: 強制
ポリシーMLSステータス: 有効
ポリシーの deny_unknown ステータス: 許可
メモリ保護チェック: 実際 (安全)
最大カーネルポリシーバージョン: 31
[mcalizo@Rhel82 ~] $

次に、オペレーティングシステムのバージョンとDockerが実行中であることを確認します。rootとしてログインし、次のコマンドを実行します。

 [root@rhel82 ~] # cat /etc/redhat-release
Red Hat Enterprise Linux リリース8.2 (Ootpa)
[root@rhel82 ~] #

[root@rhel82 ~] # systemctl ステータス docker
● docker.service - Docker アプリケーションコンテナエンジン
ロード済み: ロード済み (/usr/lib/systemd/system/docker.service; 有効; ベンダープリセット: 無効)
アクティブ: 2020年10月28日(水) 19:10:14 EDT からアクティブ (実行中)、15秒前
ドキュメント: https://docs.docker.com
メインPID: 30768 (dockerd)
タスク: 8
メモリ: 39.0MB
Cグループ: /system.slice/docker.service
└─30768 /usr/bin/dockerd -H fd:// --containerd = /run/containerd/containerd.sock

10月28日19:10:13 rhel82.home.labs.com dockerd[30768]: 時間= "2020-10-28T19:10:13.889602941-04:00" レベル=エラーメッセージ= ">
10月28日 19:10:13 rhel82.home.labs.com dockerd[30768]: time=" 2020 -10 -28T19 :10:13.903413613-04:00 " level=警告メッセージ>
10月28日 19:10:13 rhel82.home.labs.com dockerd[30768]: time=" 2020 -10 -28T19 :10:13.903427451-04:00 " level=警告メッセージ>
10月28日 19:10:13 rhel82.home.labs.com dockerd[30768]: time=" 2020 -10 -28T19 :10:13.903538271-04:00 " level=info msg=" L>
10月28日19:10:14 rhel82.home.labs.com dockerd[30768]: 時間= "2020-10-28T19:10:14.132060506-04:00" レベル=情報メッセージ= "D>
10月28日 19:10:14 rhel82.home.labs.com dockerd[30768]: time=" 2020 -10 -28T19 :10:14.308943088-04:00 " level=info msg=" L>
10月28日19:10:14 rhel82.home.labs.com dockerd[30768]: 時間= "2020-10-28T19:10:14.319438549-04:00" レベル=情報メッセージ= "D>
10月28日 19:10:14 rhel82.home.labs.com dockerd[30768]: time=" 2020 -10 -28T19 :10:14.319570298-04:00 " level=info msg=" D>
10月28日19:10:14 rhel82.home.labs.com dockerd[30768]: 時間= "2020-10-28T19:10:14.333419209-04:00" レベル=情報メッセージ= "A>
10月28日 19:10:14 rhel82.home.labs.com systemd[1]: Dockerアプリケーションコンテナエンジンを起動しました

Docker のバージョンを確認してください:

 [root@rhel82 ~] # docker --version
Docker バージョン19.03.13 、ビルド 4484c46d9d

ホストをハッキングする

問題を理解する最良の方法の一つは、実際に体験してみることです。そこで、セキュリティ設定が不十分だと、Dockerホストに悪意のあるコードが簡単に挿入されてしまうことをお伝えします。

Docker ホスト上で不正行為を行うには、「悪意のある」非 root ユーザー (このチュートリアルでは​mcalizo​ ) が Docker コンテナをインスタンス化できるグループのメンバーである必要があります。

まず、ユーザー​mcalizo​がどのグループに属しているかを確認します。

 [root@Rhel82 ~] # グループ mcalizo
mcalizo : mcalizo

出力を見ると、 ​mcalizo​自身のグループにのみ属していることがわかります。つまり、 ​mcalizo​ Docker コンテナをインスタンス化できず、インスタンス化しようとすると以下のエラーが発生します。

 [mcalizo@Rhel82 ~] $ docker run -it --rm centos:latest /bin/sh
docker: unix:///var/run/docker.sock の Docker デーモン ソケットに接続しようとしたときにアクセスが拒否されました: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/create: dial unix /var/run/docker.sock: connect: アクセスが拒否されました。
「docker run --help」を参照してください。

​mcalizo​コンテナをインスタンス化できるようにするには、ユーザーを​docker​グループに追加します。

 [root@Rhel82 ~] # usermod -G docker -a mcalizo
[root@Rhel82 ~] # グループ mcalizo
mcalizo : mcalizo ドッカー

次に、 ​fedora:latest​コンテナをデプロイし、インスタンス化されたコンテナにログインして探索します。

 [mcalizo@Rhel82 ~] $ docker run -it --rm fedora:latest /bin/sh
ローカルでイメージ'fedora:latest'見つかりません
最新: library/fedora からプル
ee7e89337106: プル完了
ダイジェスト: sha256:b9ec86d36fca7b1d3de39cd7c258e8d90c377d312c21a7748071ce49069b8db4
ステータス: fedora:latest 新しいイメージをダウンロードしました
sh-5.0 # cat /etc/redhat-release
Fedora リリース33 (三十三)

新しく作成されたコンテナにログインすると、自動的に root としてログインしていることがわかります。

 sh-5.0 # だれだ

sh-5.0 #

​root​ユーザーはコンテナ内でほぼすべての操作を実行できるため、コンテナホストを悪用して甚大な被害を与えることが可能です。コンテナをインスタンス化できるため、ホストのsudoersアカウントに属していなくても、ホストに対して操作を実行できます。

作成したコンテナを終了し、この脆弱性を証明するための新しいコンテナを作成します。

 [mcalizo@Rhel82 ~] $ docker run -it --rm -v /:/exploit fedora:latest /bin/bash
[ルート@131043f2e306 /] #

-v オプションは、Docker ホスト上の​/​ディレクトリを​/exploit​ディレクトリの下のコンテナにマウントします。

 [root@131043f2e306 /] #ls エクスプロイト/
bin boot dev etc home lib lib64 media mnt opt ​​proc root run sbin srv sys tmp usr var

マウントされているため、Dockerホスト上でほぼ何でも実行できます。例えば、ファイルを削除したり、特定の設定を編集してシステムを侵害したり、トロイの木馬などのマルウェアをインストールして重要な情報を盗んだりすることも可能です。

なぜこんなことが起きたのでしょうか?

SELinux が強制モードになっているのに、なぜこのようなことが起こるのか疑問に思うかもしれません。SELinux を詳しく調べて、問題がどこにあるのかを見てみましょう。

SELinux に Docker コンテキストがあるかどうかを確認します。

 [mcalizo@Rhel82 ~] $ ps -eZ | grepドッカー
system_u:system_r:container_runtime_t:s0 30768 ? 00:00:04 dockerd
[mcalizo@Rhel82 ~] $

予想通り、有効になっています。これは、SELinuxがDockerデーモンを管理していることを意味します。DockerデーモンでSELinuxがデフォルトで有効になっているかどうかを確認します。

 [mcalizo@Rhel82 ~] $ docker info | grepセキュリティ-A3
セキュリティ オプション:
seccomp
プロフィール: デフォルト
カーネルバージョン: 4.18.0-193.el8.x86_64

DockerデーモンのSELinuxはデフォルトで無効になっています。これが問題です!ドキュメントに記載されているように、 ​/etc/docker/daemon.json​ daemon.json`ファイルを更新または作成して、SELinuxによるDockerの制御と管理を有効にしてください(この操作にはroot権限が必要です)。

 [root@Rhel82 ~] # cat /etc/docker/daemon.json
{
"selinux-enabled" : true
}
[root@Rhel82 ~] #
[root@Rhel82 ~] # systemctl dockerを再起動します

このファイルを作成または更新して Docker を再起動すると、Docker デーモンで SELinux サポートが有効になっていることがわかります。

 [root@Rhel82 ~] # systemctl dockerを再起動します
[mcalizo@Rhel82 ルート] $ docker info | grepセキュリティ-A3
セキュリティ オプション:
seccomp
プロフィール: デフォルト
SELinux
[mcalizo@Rhel82 ルート] $

特定のファイル システムを Docker ホストから Docker コンテナーにマウントすることは引き続き可能ですが、それらのファイルの更新やアクセスは許可されなくなりました。

 [mcalizo@Rhel82 ルート] $ docker run -it --rm -v /:/exploit fedora:latest /bin/bash
[root@ecb5836da1f6 /] # /exploit/etc/shadow.sh をタッチ
touch : '/exploit/etc/shadow.sh' にアクセスできません: 権限が拒否されました
[root@ecb5836da1f6 /] #

もっと詳しく知る

コンテナ環境における第一の防御線は、コンテナホストのオペレーティングシステムの設定がどれだけ強固であるかにかかっています。Linuxのセキュリティを強化する方法は数多くあり、セキュリティ体制を強化するための市販ソリューションもその一つです。

SELinuxは、Linuxディストリビューションにデフォルトで組み込まれている追加のセキュリティレイヤーです。システムを侵害から保護するには、SELinuxが有効になっていることを確認してください。