Dockerのポート開放がufwの制限を受けなくて焦った件について

前提としてufwを使ってConohaにVPS立ててみた 第2回 FW設定 - 24時のような設定をしているとします。たとえばNginxのプロセスをコンテナではなくホストで動かす場合、外部からホストの80番ポートにアクセスしようとしてもフィルタリングされてアクセスができません。

でもでも、docker run -p 80:80 nginxでコンテナを作成して、ホストの80番ポートにアクセスすると普通にNginxのページが見えちゃうんですよね。なんでだろうと思っていたら、どうやらDocker側で勝手にiptablesにルールを追加するのが原因だったみたいです。

Dockerによるiptablesへのルールの追加

めちゃくちゃ参考にさせていただきました

qiita.com

デフォルトの設定だとDockerが勝手にiptablesにルールを追加してどっからでもアクセスできるようになっちゃうみたいですね。ルールを追加するのは

  • Dockerデーモン起動時
  • docker run -pでコンテナのポートをパブリックに晒す時

この2つのタイミングのようです。

iptablesについてはまだ勉強不足なんですが、とりあえずNginxのコンテナにどっからでもアクセスできるようになっちゃうのは、後者のタイミングに追加されるルールがアカンみたいです。docker run -pの裏では以下のようなルールが追加されていたと。

  • filter table
    • 全てのアクセス元からコンテナへの接続を許可
  • nat table
    • ダイナミックNATによってホストへのアクセスをコンテナへ転送

ちなみにこれらのルールはdocker killなどでコンテナを停止させると自動的に削除されます。

natテーブルの設定はまぁ良いとして、問題はfilterテーブルの設定ですね。

コンテナへのアクセスに制限をかける

$ sudo iptables -L DOCKER -n -v
Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
   22  2294 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.2           tcp dpt:80

この設定を上書きして、Nginxのコンテナにアクセスできるのは接続元IPがXXX.XXX.XXX.XXXだけにします。

$ sudo iptables -I DOCKER ! -i docker0 -o docker0 -j DROP ! -s XXX.XXX.XXX.XXX -d 172.17.0.2 -p tcp --dport 80
$ sudo iptables -L DOCKER -n -v
Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       tcp  --  !docker0 docker0 !XXX.XXX.XXX.XXX        172.17.0.2           tcp dpt:80
   24  1922 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.2           tcp dpt:80

ここで追加したルールは簡単に言うと送信元IPアドレスがXXX.XXX.XXX.XXX以外の接続を拒否するものです。接続先ポートとかインタフェースの細かい設定も一応やっています。

このルールと2番目のACCEPTのルールを組み合わせることで、Nginxのコンテナにアクセスできるのは接続元IPがXXX.XXX.XXX.XXXだけにしました。

ホストネットワークの場合

Dockerには3種類のコンテナネットワーク機能が備わっています。さっきNginxのコンテナが使ってたのはDockerデフォルトのブリッジネットワークで、docker0という仮想的なブリッジに接続するタイプです。

ネットワークのタイプをホストネットワークにしてコンテナを作成する場合、このようにします。

$ docker run -d -p 80:80 --name nginx --net=host nginx
7163c9585f33197081b7a7c3bb31036633e5c113fd8dff5d062ee278d566fd7e

ホストネットワークでコンテナを作成した場合はiptablesに新しいルールは追加されません。そんなわけでいちいちiptablesの設定をいじくるのがめんどうくさい時はホストネットワークでコンテナを作成するといい(のかな?)

うーん。コンテナのパケットフィルタリングは奥が深そうです。それと、ufwだけじゃなくてiptablesについてもちゃんと勉強しなきゃダメですね。

参考

全体的に

iptables周り