今更だけどDockerコンテナの脆弱性をRancher経由で利用されroot権を渡してしまった話

「脆弱性」というほど大げさなものではなく、Dockerが普及した頃から注意喚起されていた内容ですが、仲間内の環境ということもあり油断していました。今回は戒めの意味も込めて記事を書かせていただきます。

# 使用していた環境
-   VPS（2コア/8GB Ubuntu 18.04） *2台
    -   VPS1台は Docker + Kubernetes を管理するためRancherマスターとして使用
    -   残りの1台はRancher管理下のホストとしてKubernetesを構成…デプロイ用
-   権限の状況（どちらもログインできるのは私のみ）
    -   VPS/Rancherマスター…sudo, docker グループに所属するユーザー1個。公開鍵でのみssh可能
    -   VPS/ホスト…sudo, docker グループに所属するユーザー1個。公開鍵でのみssh可能
-   環境を使用する人
    -   私
    -   趣味で一緒にコードを書いている友達
        -   環境構築が面倒なのでRancherの構築などは私に投げている
        -   こいつが今回の犯人
        
# 脆弱性への攻撃内容
dockerコンテナをrunする際に「-v」オプションでVPSマシンの "/" と、コンテナの指定ディレクトリを関連付け、 "chroot"を実行。
コンテナ上からVPSマシンに対してroot権限であらゆる書き換えを実行。（sshd_config  書き換えなど）

情報はこちらを参考にさせていただきました。
-   [Don't expose the Docker socket (not even to a container)](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container.html)
-   [コンテナ・セキュリティ入門 と Kubernetes(qiita記事)](https://qiita.com/MahoTakara/items/b3baafe3a6ea9a26fef4)

**上記をdocker コマンド で実行した場合の手順** ※説明のために記載します。実際に実行はしないでください。

```bash
docker run -it -v /:/root debian /bin/bash
#ローカルマシンのロートディレクトリ"/"をdebianコンテナの"/root"ディレクトリと同期させた状態で実行

root@{コンテナID}:/# cat /etc/hostname
{コンテナID}
#コンテナ上でbashを実行していますので、当然コンテナの名前が返ってきます。

root@{コンテナID}:/# chroot /root
:# /bin/bash
#ローカルマシンの"/"と関連付けている"/root"に対してchrootを実行して"/"の操作が可能に。試しにbashを起動してみる..

root@{コンテナID}:/# cat /etc/hostname
{ローカルマシンのホスト名}
#同じコマンドを実行しましたが、今度はローカルマシンの名前が出てきました。あとはやりたい放題です。

root@{コンテナID}:/# vi /etc/ssh/sshd_config
root@{コンテナID}:/# ps aux
root@{コンテナID}:/# lsof -i -P
#などなど..
```

# Rancher で実行された内容
1.  adminユーザー（私）が新規ユーザー（犯人）を作成。
2.  作成したユーザーに最低限の権利を付与。
3.  新規ユーザーがログイン。
4.  プロジェクトの作成権限があるクラスターでコンテナを作成。
5.  以降は上記のdockerコマンド実行内容と同様。

以下Rancherの操作画面を使って説明いたします。

## 1.adminユーザー（私）が新規ユーザー（犯人）を作成。
adminでログインし、「グローバル」タブの「ユーザー」を選択しユーザーを追加する。
![図１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332187/9aa96aaa-9e7c-015b-3f22-a167e77172df.png)


ユーザーの内容は以下で作りました。
ユーザー名： waruihito
パスワード： waruihito
表示名： waruihito
グローバル権限： 一般ユーザー
![図２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332187/2560e226-df8b-210e-74c2-555677a15d26.png)


## 2.作成したユーザーに最低限の権利を付与。
クラスターのメンバーにも新規ユーザーを追加。（今回のクラスタ名は「sandbox」）
今回は最低限の権限として「Create Project」のみを付与します。
![図４.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332187/b3096f6b-4fe0-521b-268a-2561a1d3561f.png)


## 3.新規ユーザーでログイン。
作成したユーザーでログインし直すと、権限が振られているクラスターのみが表示されます。
![図５.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332187/d1cbbf84-2704-858f-8d54-ff22f0a79f59.png)


「Create Project」権限を持っているので、新規プロジェクト「warudakumi」を作成します。
![図６.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332187/fa76c511-98b1-06ce-20f6-5d2b2834711c.png)


## 4.クラスターでコンテナを作成。
先程の「warudakumi」プロジェクトで、「ワークロード」から乗っ取り用のコンテナをデプロイしていきます。
![図７.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332187/73916013-a212-70ee-b90a-868ef1e36f0c.png)


## 5.以降は上記のdockerコマンド実行内容と同様。
ボリュームにノード上の "/" パスを指定します。
![図８.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332187/613425c2-56c1-f3f2-54e2-28bc5f469cfe.png)


作成したコンテナ（ポッド）でシェルを実行します。（Rancherではプルダウンから選択して起動できます。）
![図９.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332187/814ffdcc-8044-32fd-c6af-054b095f28b6.png)


コマンドを実行して乗っ取りができました。
![図１０.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332187/3d7d320b-c471-d3c8-df3e-911a75c8a2bf.png)

![図１１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332187/5a8c6f61-598d-6395-75c1-50bb02878714.png)



# 学んだこと
Docker単体で運用するときには結構気を使っている部分ですし、公式のリファレンスにも「ここに気をつけて！」みたいな文言は書いてあります。
しかしk8sやRancherなどで運用する際には「それは知ってて当然だよね？」という暗黙のルールのもと構築をしてしまうことで、このような初歩的な脆弱性を疲れることになりました。（いや口で言ってくれたら分かるよ？わざわざsshd_config書き換える必要ある？印象には残ったけどね！）

基本大事！効率的にするためであって、横着してもいいわけではないということだと思います。