SNSでシェアされてきたので、早速確認しました。
もう少しくわしい話が以下で公開されていました。
ちなみにこの件は最近報告された問題ではなく、結構前から言われていたことです。設定の不備から外部から無認証でコンテナーを実行されてマイニングに使われるみたいな話です。
Dockerやべえ。早くほかのコンテナランタイムにしないと
...ではなく、「お前のDockerの設定、やべえから」...という話なのです。
早速確認してみました。
実験開始
最初の記事によると、2375/tcpポートが狙われる対象だそうです。そんなポート、普通は空いていたっけ? 最後の記事によると、2376/tcp、2377/tcp、4243/tcpなんかもスキャン対象のポートみたいですね。
ポート番号「2375/tcp」で調べたら、このドキュメントを見つけました。
「Docker Remote API」を使ってリモートのDockerでコンテナーを実行する事ができる機能ですね。便利だったので私も一時期使っていました。 ちなみにこの設定はデフォルトでは無効のはずです。
[root@docker-demo ~]# systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled) Active: active (running) since 火 2020-08-25 10:42:16 JST; 11min ago Docs: https://docs.docker.com Main PID: 2958 (dockerd) Tasks: 8 Memory: 40.3M CGroup: /system.slice/docker.service └─2958 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock [root@docker-demo ~]# ss -natu |egrep "2375|2376" [root@docker-demo ~]#
systemctl status docker
コマンドなどを実行して、dockerdのオプションに問題のあるような設定が書かれていない場合はおそらく問題ないです。
しかし「Docker Remote API」とかで検索してブログの記事の方法で設定を書き換えてポートまで開放してしまった場合、設定が不適切であると悪用される可能性があります。 以下に実施しては本当にだめな設定例を書きます。絶対にDockerホストでこのような設定はしないでください。
# vi /usr/lib/systemd/system/docker.service ... [Service] ... ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H fd:// --containerd=/run/containerd/containerd.sock # systemctl daemon-reload # systemctl restart docker # firewall-cmd --add-port=2375/tcp --zone=public --permanent # firewall-cmd --reload
0.0.0.0:2375で待ち受けするように設定し、かつpublic zoneでポート2375を開放しています。 かなりセキュリティ的にだめな設定例です。
例示したような設定を行うと、リモートからコンテナー基盤へのアクセスが無認証で行えてしまいます(下記例はデーモンとしてNGINXサーバーを起動した例)。
$ docker -H tcp://192.168.56.126:2375 container run --name=nginx1 -d -p 8080:80 -it nginx:alpine Unable to find image 'nginx:alpine' locally Trying to pull repository docker.io/library/nginx ... alpine: Pulling from docker.io/library/nginx df20fa9351a1: Pull complete 3db268b1fe8f: Pull complete f682f0660e7a: Pull complete 7eb0e8838bc0: Pull complete e8bf1226cc17: Pull complete Digest: sha256:a97eb9ecc708c8aa715ccfb5e9338f5456e4b65575daf304f108301f3b497314 Status: Downloaded newer image for nginx:alpine c561de3a7819fedb3c69285a790e6181fb24f7945bd2b987931dba7487291f5c
こんな脆弱な設定のDockerホストがパブリッククラウド上で動いていて、かつ固定のグローバルIPアドレスなんかが割り当てられてポートも空いていたら、あっという間に悪用されそうですね。
アクセスを許可するホストをファイアウォールなどで絞ったりすればいくらか軽減できるかもしれませんが、この用途ならKubernetesやDocker swarmなどでコンテナクラスターを構築して使うほうが良いと思います。あとはむやみに外部に開放しないということも...。
どうしても「Docker Remote API」を使わなければならない場合は次を参考に、利用に証明書が必要な構成を取るべきでしょう。
ここも目を通すべきでしょう。
Dockerを使っている場合、Kubernetesのようなコンテナー基盤のエンジンとしてDockerを使っている場合は、一度Dockerの設定を確認したほうが良いと思います。Dockerの基本的な設定は /etc/docker/daemon.json
とか、 /etc/default/docker
、 /etc/sysconfig/docker
などに記述されていると思いますが、ディストリビューションやバージョンによって別のパスに書いている場合もあるので、 ps aux|grep docker
などで確認するなど、よく調べたほうが良いと思います。
また、ホストに不審なコンテナーやシェルスクリプトがないかも確認したほうが良いと思います。