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