Dockerでマストドンやってたら、遮断したはずのポートが丸見えだった件

みんなマストドンをやっているだろうか?

僕はやっている。
インスタンス管理をやっている。

こんなふうに運用していた

conoHaのVPS
CentOS7.3
Dockerで運用している
ちなみにDockerは今回が初めて本格的に触った。

マストドンは裏側では3000ポートと4000ポートで待ち受けている。
3000の方は普通のWEB
4000の方はAPIを担当している。

HTTPサーバーであるnginxが、httpの80とhttpsの443で受け取ったら、
それぞれ3000と4000に送りつけている
リバースプロキシという技だ。

通常、公開用のhttpとhttpsのポートだけ開けておく。

もちろん僕もそのようにしていた。
CentOS7以降はiptablesではなくfirewalldというファイアウォールのソフトウェアでポートの開け閉めを管理している。

firewalldで、許可するポートはhttpとhttpsなど自分が必要と認めたポートだけを開けていた。

ところが自分のPCからcurlで3000と4000宛にアクセスしてみたら、なんと繋がってしまったのだ。

スポンサードリンク

何故繋がったのだ!!

はじめfirewalldが起動していないのかと思って、確認したがバッチリ動いていた。
適当なエコーサーバーを立ててみて、自分のPCからアクセスしてみたが遮断されている。

ちなみにfirewalldってのは実は裏側ではiptablesが動いていて、firewalldの定義を自動で設定してくれるようなものっぽい。
というわけでiptables -nvLコマンドを使い、ちゃんと遮断されるのか確認したが、3000と4000ポートが入り込む余地はなかった。

Dockerが原因だった

https://teratail.com/questions/60817

同じようなことで悩む人が見つかった。

Dockerのことを調べててこのようなことがわかった
http://qiita.com/Arturias/items/b538e6bbf05dd3364397

Dockerコンテナは、独自にIPが振られている。
その独自のIPというのは、仮想ブリッジを使って実現している。

Dockerコンテナが開いている3000ポートなどは、
アプリがLISTENしているようなものではなく、
ルーティングによってフォワーディングされている。

iptablesでは、PREROUTINGチェーンでFORWARDかINPUTかを判別してる。
3000宛に来た通信は、INPUTじゃない
iptables的にはFORWARDで、仮想のIP当てに転送する通信なんだ。
http://qiita.com/kawaz/items/ed0030cb29c7d0497b63

だから、3000と4000はfirewalldで遮断されずに、どんどん受け入れちゃっていたというわけだ

どうしよう

DockerがiptablesのNATとかの設定を勝手にやっているみたいなので、
iptablesとfirewalldで何とかしようとするのは難しそうだ。

それにDockerがやっているんだからDockerの方で責任をもたせたい。

マストドンではDocker-composeというのを使っている。
これはDockerのコンテナをまとめて起動したりビルドしたり、全体の構成をやってくれる便利なやつだ。

docker-compose.ymlファイルにマストドンのdockerコンテナたちの構成やプロパティが書かれている。

ポイントはwebとstreamingという2つのコンテナだ。
この2つがそれぞれ3000と4000を開けている。

portsという項目が、ポートを開けているところだ。
“3000:3000″と書かれていれば、左側がホスト側つまりCentOS側が受け付けるポート
右側がDockerコンテナのIPが開いているポートだ。

これのホスト側のポートのIPを指定できるようだ。
“127.0.0.1:3000:3000” とかけば、ホスト側の3000ポートはループバックに対してのみ開く。
つまりルーティングされない。
iptablesのINPUTチェーンで最終的に遮断される。
と思う。

こんなふうに設定をした。
webとstreamingだ

他にもexposeとかを使うとかの技も見聞きしたけれども、
どうも上手くいかなかったので、上記の設定にしてみた。

設定し、docker-compose buildをしたら、
繋がらなくなった。

 

スポンサードリンク

関連コンテンツ