ホストの iptables INPUT チェーンにポートの allow ルールを追加したにもかかわらず、
Docker コンテナを -p host:container で公開したポートに接続できないケースがある。
結論から言うと、理由は明確である。
Docker のポート公開トラフィックは INPUT ではなく、FORWARD → DOCKER(-USER) チェーンで処理される。
そのため、INPUT にどれだけルールを追加しても、
Docker 系チェーンで DROP されていれば通信は遮断される。
なぜ INPUT が効かないのか
Docker のポート公開時のトラフィックフローは、通常以下のようになる。
外部 → DNAT → FORWARD → DOCKER-USER → DOCKER → コンテナ
つまり、コンテナ宛のトラフィックはホスト上のローカルプロセスではなく、
フォワーディングトラフィックとして扱われる。
したがって、許可/遮断の制御は DOCKER または DOCKER-USER で行う必要がある。
クイック診断
iptables -L DOCKER -n --line-numbers
iptables -L DOCKER-USER -n --line-numbers
以下のようなルールが存在する場合、実質的に「全遮断」状態である。
-p tcp --dport 0:65535 -j DROP- 条件なしの broad DROP ルール
最も危険な落とし穴(重要)
❌ DOCKER-USER で --dport だけを見て遮断してはいけない
次のようなルールはよく見かけるが、運用環境では危険である。
iptables -I DOCKER-USER -p tcp --dport 8080 -j DROP
理由
DOCKER-USER チェーンは DNAT 適用後 に評価される。
この時点での --dport 8080 は、外部ポートではなく「コンテナ内部ポート」 を指す。
その結果、以下のような状況が発生する。
- コンテナ A:
-p 9000:8080 - コンテナ B:
-p 8080:8080
意図: 「外部ポート 8080 だけを遮断したい」
現実: 内部ポート 8080 を使用するすべてのコンテナが同時に遮断される
これが本番環境で発生すると、
外部ポートだけで分離していたサービスが一斉に停止する。
安全なパターン(推奨)
原則
以下のルールは文法上 DOCKER に置き換えても動作するが、
運用環境では DOCKER-USER の使用を強く推奨する。
ESTABLISHED,RELATEDを最初に許可する- 遮断対象はポートではなく コンテナ IP に絞る
- 最後に
RETURNを入れる
例:特定コンテナのみ制御する場合
# 応答トラフィックを許可
iptables -I DOCKER-USER 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 特定コンテナ IP を対象
iptables -I DOCKER-USER 2 -d 172.17.0.10/32 -p tcp --dport 8080 -s 203.0.113.10/32 -j ACCEPT
iptables -I DOCKER-USER 3 -d 172.17.0.10/32 -p tcp --dport 8080 -j DROP
# Docker のデフォルトフローに戻す
iptables -A DOCKER-USER -j RETURN
ポイント
「外部ポート」基準で制御するのではなく、
「どのコンテナ宛のトラフィックか」 を基準に制御する。
これにより、DNAT 前提の構造でも副作用を回避できる。
Tip(運用上の考慮点)
コンテナの再生成やサーバー再起動により、
コンテナ内部 IP は変更される可能性がある。
運用環境では、以下のいずれかで安定性を確保することを推奨する。
- ユーザー定義 bridge ネットワーク + Static IP による固定(最も推奨)
- もしくは、外部ポート基準でのマッチングが必要な場合、
conntrack の original tuple(例:--ctorigdstport)を用いたルールを検討する
(※ conntrack エントリ、カーネルモジュール、ルールの適用位置により挙動が異なるため、事前テスト必須)
ルール保存(再起動対策)
DOCKER / DOCKER-USER のルールは再起動で消える可能性がある。
以下のコマンドで保存しておくこと。
netfilter-persistent save
一行まとめ
- Docker の公開ポートは
INPUTではなくDOCKER(-USER)で制御される DOCKER-USERにおける--dportは 内部ポート基準のため、必ずコンテナ単位に絞る
この二点を押さえておけば、Docker × iptables に起因する事故の 90% は回避できる。
🛠 마지막 수정일: 2025.12.29
💡 お困りですか?
Zabbix、Kubernetes、各種オープンソースインフラの構築・運用・最適化・障害解析が必要であれば、いつでもご連絡ください。
📧 メール: jikimy75@gmail.com
💼 サービス: 導入支援 | 性能チューニング | 障害解析コンサルティング