🚀

Docker起動時のiptables設定について調べてみた

2024/02/13に公開

Docker起動時のiptables設定について調べてみた内容をまとめました。

natテーブルしか書いてません。

テーブル

  • filter パケットの許可、破棄、拒否などのフィルタリングをする
  • nat 送信元、送信先のIPアドレスとポート番号の変換

その他はあまり使わないらしいので省略

テーブル

  • PREROUTING パケットがネットワークインターフェースで受信された直後に、宛先のIPアドレスとポート番号を変更する。外部からのトラフィックを内部の特定のIPアドレスにリダイレクトしたりする。
  • OUTPUT ローカルシステムから発信されるトラフィックに適用される。自分のシステムから外部へのリクエストのコントロールに用いられる。
  • POSTROUTING ルーティングの決定後、パケットがネットワークインターフェースから送信される直後に適用され、送信元のIPアドレスとポート番号を変更する。外部のシステムに対して自身のシステムがどのように見える化を制御する。

ターゲット

  • MASQUERADE 外部ネットワークにアクセスするときに、プライベートIPアドレスからパブリックIPアドレスへの変換(NAT)を行う技術。
  • DNAT 宛先のIPアドレスを別のIPアドレスに変換する処理。ファイアウォール、ルーター、プロキシサーバーなどで利用される。ssl(443)で受けて、アプリケーションサーバー(80)に転送するなどできる。

filterテーブルの設定内容

後日。

natテーブルの設定内容

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
PREROUTINGチェーンにルールを追加。宛先タイプ(--dst-type)がLOCALのパケットをDOCKERチェーンにジャンプ(-j)させる。
--dst-type LOCALとは、ローカルホストアドレス(127.0.0.0/8)宛のパケット、ネットワークインターフェースがeth0, wlan0などのパケットなどが当てはまる。

-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
OUTPUTチェーンにルールを追加。宛先が127.0.0.0/8でない、かつ宛先タイプ(--dst-type)がLOCALのパケットをDOCKERチェーンにジャンプ(-j)させる。
127.0.0.0/8とは、ローカルホストまたはループバックアドレスのこと。

-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
POSTROUTINGチェーンにルールを追加。ソースアドレスが172.17.0.0/16で、アウトバウンドインターフェースがdocker0でないパケットにMASQUERADEのアクションを適用する
=docker0インターフェースから出力されるトラフィックをマスクして、DockerホストのIPアドレスに変換する
172.17.0.0/16は、DockerのデフォルトブリッジネットワークのIPの範囲。
docker0は、デフォルトブリッジネットワークのインターフェースで、新しく作成されたコンテナはこのネットワークに接続される。
ブリッジネットワークとは、物理的に異なる2つ以上のネットワークセグメントを接続し、それらを1つのネットワークとして動作させる概念。Dockerの文脈ではコンテナ間の通信を可能にするため使用される。
アウトバウンドインターフェースとは、特定のコンテナから外部ネットワークへのトラフィック処理するネットワークインターフェース。

-A POSTROUTING -s 172.18.0.0/16 ! -o br-d9618c0af0c4 -j MASQUERADE
POSTROUTINGにルールを追加。ソースアドレスが172.18.0.0/16で、アウトバウンドインターフェースが br-d9618c0af0c4でないパケットにMASQUERADEのアクションを適用する。
172.18.0.0/16は、Dockerが追加で作成したブリッジネットワーク。

-A POSTROUTING -s 172.18.0.2/32 -d 172.18.0.2/32 -p tcp -m tcp --dport 5432 -j MASQUERADE
POSTROUTINGにルールを追加。送信元も宛先もIPが172.18.0.2/32で、宛先ポートが5432のパケットにMASQUERADEのアクションを適用する。コンテナ内部通信の変換。

-A DOCKER -i docker0 -j RETURN
-A DOCKER -i br-d9618c0af0c4 -j RETURN
アウトバウンドインターフェースがdocker0またはbr-d9618c0af0c4であるパケットをRETURNする(親のチェーンに戻す)アクション。

-A DOCKER ! -i br-805add1a2aac -p tcp -m tcp --dport 5432 -j DNAT --to-destination 172.18.0.2:5432
ネットワークインターフェースがbr-805add1a2aacでなく、宛先ポートが5432のTCPパケットに、DNATアクションを適用する。送信先のアドレスを172.18.0.2:5432に書き換える。

あとがき

何に使われているかわからない設定も多かったが、Dockerのネットワークの理解が少し深まった。

便利なコマンド

sudo systemctl restart docker
Dockerデーモンを再起動する。これでIPテーブルの設定が再設定される。

watch "sudo iptables -nvL"
filterテーブルの設定をリアルタイムで確認する。

watch "sudo iptables -nvL -t nat"
natテーブルの設定をリアルタイムで確認する。

sudo iptables -L --line-numbers
iptablesの設定を番号付きで確認する。削除するのに便利。

sudo iptables -D INPUT 1
INPUTチェーンの1番目のルールを削除する。番号は適切なのに変える。

sudo iptables -Z
パケットカウンタをリセットする。

sudo iptables-save > iptables.rule
iptablesの設定をファイルに保存する。

sudo iptables-restore < iptables.rule
iptablesの設定をファイルから読み込む。

Discussion