Looking for docker Answers? Try Ask4KnowledgeBase
Looking for docker Keywords? Try Ask4Keywords

Dockerドッカー付きのiptables


前書き

このトピックは、iptablesを使用して外部からのドッカーコンテナーへのアクセスを制限する方法についてです。

不本意な人のために、例を確認することができます。他の人にとっては、新しいルールを構築する方法を理解するために、コメントセクションを読んでください。

構文

  • iptables -I DOCKER [RULE ...] [ACCEPT | DROP] //ルールを追加するにはDOCKERテーブルの先頭
  • iptables -D DOCKER [RULE ...] [ACCEPT | DROP] // DOCKERテーブルからルールを削除するには
  • ipset restore </etc/ipfriends.conf // ipset ipfriendsを再設定するには

パラメーター

パラメーター詳細
ext_if Dockerホスト上の外部インターフェイス。
XXX.XXX.XXX.XXX Dockerコンテナがアクセスする特定のIPを指定する必要があります。
YYY.YYY.YYY.YYY Dockerコンテナがアクセスする別のIPを与える必要があります。
ipfriends DockerコンテナにアクセスできるIPを定義するipset名。

備考

問題

Dockerコンテナのiptablesルールを設定するのはちょっと難しいです。最初は、 "古典的な"ファイアウォールルールがこのトリックを行うべきだと思うでしょう。

たとえば、nginx-proxyコンテナ+いくつかのサービスコンテナを設定して、HTTPSを介していくつかのパーソナルWebサービスを公開しているとします。このようなルールでは、IP XXX.XXX.XXX.XXXのWebサービスにのみアクセスする必要があります。

$ iptables -A INPUT -i eth0 -p tcp -s XXX.XXX.XXX.XXX -j ACCEPT
$ iptables -P INPUT DROP

それは動作しません、あなたのコンテナは誰にとってもアクセス可能です。

実際、Dockerコンテナはホストサービスではありません。ホストの仮想ネットワークに依存し、ホストはこのネットワークのゲートウェイとして機能します。また、ゲートウェイに関しては、ルーティングされたトラフィックはINPUTテーブルで処理されず、FORWARDテーブルによって処理されます。

しかし、それはすべてではありません。実際、Dockerデーモンは、コンテナのネットワーク接続に関して魔法を発揮し始めると、多くのiptablesルールを作成します。特に、FORWARDテーブルからこの新しいテーブルにトラフィックを転送することによって、コンテナに関するルールを処理するDOCKERテーブルが作成されます。

$ iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-ISOLATION  all  --  anywhere             anywhere
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (2 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             172.18.0.4           tcp dpt:https
ACCEPT     tcp  --  anywhere             172.18.0.4           tcp dpt:http

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

ソリューション

公式の文書( https://docs.docker.com/v1.5/articles/networking/)をチェックすると、Dockerコンテナのアクセスを1つの特定のIPに制限するための最初の解決策が与えられます。

$ iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP

実際、DOCKERテーブルの一番上にルールを追加することは良い考えです。 Dockerによって自動的に設定されるルールに干渉することはなく、簡単です。しかし、2つの主要な欠点:

  • まず、2つのIPからアクセスする必要がある場合はどうすればよいでしょうか?ここでは1つのsrc IPだけを受け入れることができますが、他のものはそれを防ぐ手段を持たずに削除されます。
  • 第二に、ドッカーがインターネットにアクセスする必要がある場合はどうすればよいですか?サーバー8.8.8.8だけが応答することができるので、リクエストは正常に処理されません。
  • 最後に、他のロジックを追加したい場合はどうしますか?たとえば、HTTPプロトコルを使用しているWebサーバーにアクセスするすべてのユーザーにアクセスできますが、その他すべてのアクセスを特定のIPに制限します。

最初の観測では、 ipsetを使うことができます。上記のルールで1つのIPを許可する代わりに、事前定義済みのIPセットからすべてのIPを許可します。ボーナスとして、ipsetはiptableルールを再定義する必要なしに更新することができます。

$ iptables -I DOCKER -i ext_if -m set ! --match-set my-ipset src -j DROP

第2の観察では、これはファイアウォールの標準的な問題です。ファイアウォールを介してサーバーに接続することが許可されている場合、ファイアウォールはサーバーがユーザーの要求に応答するように許可する必要があります。これは、確立された接続に関連するパケットを認可することによって行うことができる。ドッカーロジックの場合、次のようになります。

$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT

最後の観察は1つのポイントに焦点を当てます:iptablesのルールは不可欠です。実際に、いくつかの接続(ESTABLISHED接続に関するものを含む)を受け入れるための追加ロジックは、DROPルールの前にDOCKERテーブルの最上位に置かなければなりません。

テーブルの先頭にルールを挿入するiptableの-Iオプションを使用するので、以前のiptablesルールは逆の順序で挿入する必要があります。

// Drop rule for non matching IPs
$ iptables -I DOCKER -i ext_if -m set ! --match-set my-ipset src -j DROP
// Then Accept rules for established connections
$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT 
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 3rd custom accept rule
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 2nd custom accept rule
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 1st custom accept rule

これを念頭に置いて、この設定を示す例を確認することができます。

ドッカー付きのiptables 関連する例