Docker と iptables¶
Linux 上では、 Docker は iptables
ルールを操作します。これは実装の詳細であり、 Docker が追加する iptables
ポリシーを変更すべきではありません。しかしながら、 Docker によって管理されている追加されたポリシーを、自分自身で変更したい場合には、いくつかの影響が発生する可能性があります。
Docker を実行しているホストをインターネット上に公開している場合、コンテナやホスト上で実行しているサービスに対する許可のない接続を防ぐように、おそらく何らかの iptables ポリシーを追加しようとするでしょう。これをどのようにして行うか、そして、気を付けるべき警告について、このページで扱います。
iptables ポリシーは Docker 用ルールの前に追加¶
Docker は2つのカスタム iptables DOCKER-USER
と DOCKER
です。そして、常に入力側のパケットは、これら2つのチェインによるチェックが第一に行われます。
Docker の iptables
全ルールは DOCKER
チェインに追加されます。このチェインは手動で操作しないでください。Docker のルールを読み込む前にルールの追加が必要な場合は、 DOCKER-USER
チェインにルールを追加します。これらのルールは Docker が自動的に作成するルールより前に適用されます。
ルールは FORWARD
チェインにも追加されます。手動で、あるいは他の ipables をベースとするファイアウォールによって追加されたものは、これらの( Docker が追加した)チェインの後で処理されます。つまり、Docker を通してポートを公開している場合、ファイアウォールによってどのようなルールが追加されていても、ポート公開に何ら問題ありません。Docker を通して公開しているポートに対し、何らかのルールを適用したい場合は、 DOCKER-USER
チェインに「必ず」追加する必要があります。
Docker ホストに対する接続を制限¶
デフォルトでは、全ての外部ソース IP アドレスから Docker ホストに接続できます。コンテナに対して特定の IP アドレスもしくはネットワークからのみ許可するには、 DOCKER-USER
フィルタ チェインの一番上に 192.168.1.1
を除く全ての外部アクセスを制限します。
$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.1 -j DROP
注意点として、 ext_if
をホスト上での実際の外部インターフェースと一致するように変更が必要です。(IPアドレスの代わりに)ソース となるサブネットでも指定できます。以下の例はサブネット 192.168.1.0/24
からのアクセスを許可するルールです。
$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.0/24 -j DROP
最後に、 --src-range
を使って IP アドレス範囲を指定できます( --src-range
や --dst-range
を使う場合も、 -m iprange
が追加されますので、覚えておいてください)。
$ iptables -I DOCKER-USER -m iprange -i ext_if ! --src-range 192.168.1.1-192.168.1.3 -j DROP
-s
または --src-range
と -d
または --dst-range
を一緒に使えます。たとえば、 Docker デーモンが 192.168.1.99
と 10.1.2.3
の両方をリッスンする場合、 10.1.2.3
に対してルールを追加するものの、 192.168.1.99
は開いたままにできます。
iptables
は複雑であり、より複雑なルールは、このトピックの範囲外です。更なる詳しい情報は Netfilter.org HOWTO をご覧ください。
ルータ上の Docker¶
Docker は FORWARD
チェインに DROP
するポリシーも追加出来ます。Docker ホストがルータとしても機能している場合は、このポリシーを追加した結果、あらゆるトラフィックが転送されなくなる可能性があります。システムがルータとしても機能し続けたい場合は、 DOCKER-USER
チェインで ACCEPT
ルールを追加し、許可を明示する必要があります。
$ iptables -I DOCKER-USER -i src_if -o dst_if -j ACCEPT
Docker からの iptables 操作を回避するには¶
Docker エンジンの /etc/docker/daemon.json
設定ファイルで、 iptables
キーを false
に設定できます。ですが、このオプションは大部分のユーザにとって適切ではありません。Docker によって作成された iptables
ルールを完全に回避できないだけでなく、作成後のルールは、極めて複雑かつ命令範囲が広まってしまう懸念があります。 iptables
を false
にする設定とは、Docker Engine のコンテナネットワークへ通信を遮断するような場合に使います。
Docker ランタイムを他のアプリケーションと構築し、システム統合したい場合には、 moby プロジェクト をお探しください。
コンテナ用のデフォルト バインド アドレスを指定¶
デフォルトでは、 Docker デーモンは 0.0.0.0
アドレス上、つまり、ホスト上のあらゆるアドレスにポートを公開します。もしもこの挙動を変更し、特定の内部 IP アドレスだけ公開したい場合には、 --ip
オプションを使って別の IP アドレスが指定可能です。一方で、 --ip
が変更できるのは「デフォルト」だけであり、サービスごとの IP アドレスは制限できません。
Firewalld との統合¶
Docker バージョン 20.10.0 以上を実行中で、 --iptables
を有効にし、システム上で firewalld を使っている場合、 Docker は自動的に docker
という名称の firewalld
ゾーンを作成し、作成されている全てのネットワークインタフェース(例: docker0
)を docker
ゾーン内に追加し、シームレスなネットワーク通信を可能にします。
docker インタフェースを zone から削除するには、以下の firewalld
コマンドの実行を考えます。
# 適切な zone や docker インタフェースに置き換えてください
$ firewall-cmd --zone=trusted --remove-interface=docker0 --permanent
$ firewall-cmd --reload
参考
- Docker and iptables