フィルターテーブルは、パケットをドロップするのに最適な場所であることが合意されています。
ただし、そのままでは、DockerはPREROUTINGを使用してINPUTフィルタールールをバイパスし、独自のFORWARDルールに変換して、Dockerコンテナーに世界中からアクセスできるようにします。 [〜#〜] docker [〜#〜]という名前のフィルターの挿入INPUT/FORWARDルールは、Dockerを再起動すると削除され、挿入される(追加されない)ため、失敗します。
私の最善の試みは、Dockerの前に別のPREROUTINGチェーンを挿入し、eth0(WAN)からブラックホールに不要なパケットを送信することです-0.0.0.1- natテーブルのDROP/REJECTはもうありません。
# Route anything but TCP 80,443 and ICMP to an IPv4 black hole
iptables -t nat -N BLACKHOLE
iptables -t nat -A BLACKHOLE ! -i eth0 -j RETURN
iptables -t nat -A BLACKHOLE -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
iptables -t nat -A BLACKHOLE -p tcp --dport 80 -j RETURN
iptables -t nat -A BLACKHOLE -p tcp --dport 443 -j RETURN
iptables -t nat -A BLACKHOLE -p icmp -j RETURN
iptables -t nat -A BLACKHOLE -p all -j DNAT --to 0.0.0.1
iptables -t nat -I PREROUTING -m addrtype --dst-type LOCAL -j BLACKHOLE
NATチェーンは、Dockerと1つのコンテナを実行した場合のようになります。
これはうまくいくようですが、他の事前ルーティングルールに到達する前にパケットを明示的に拒否する方法はありますか?
(Alpine Linux 3.6.2、Docker v17.05.0-ce)
アプリケーションを任意のアドレスにバインドしているコンテナーを誰かがデプロイする場合でも、ネットワークトラフィックを「強化」する必要があるという同様の問題がありました:0.0.0.0:port
。
DockerはDOCKER-USER
フィルターチェーンを提供しますが、DOCKER
で参照されるPREROUTING
natチェーンですべての魔法が発生するようです。
したがって、このnat
を回避する方法はありませんbeforeフィルタリングであり、Dockerのルールにあまり触れたくありません。
もう一度パケットを変更する必要があるのが嫌なので、デフォルトですべてを返し、PREROUTING
beforeDOCKER
内の別のチェーンにジャンプするスキームを思いつきました。
次に、トラフィックが良好であると判断した場合、選択的にDOCKER
に戻ります。
これがコードです:
iptables -t nat -N DOCKER-BLOCK
iptables -t nat -I PREROUTING -m addrtype --dst-type LOCAL -j RETURN
iptables -t nat -I PREROUTING -m addrtype --dst-type LOCAL -j DOCKER-BLOCK
それでおしまい!
パケットはDOCKER-BLOCK
チェーンにジャンプし、そのチェーンが空の場合、チェーンから出てPREROUTING
に進み、RETURN
にジャンプするとブロックされます。
ポートを有効にすると:
iptables -t nat -I DOCKER-BLOCK -p tcp -m tcp --dport 1234 -j DOCKER
これにより、パケットはDOCKER
チェーンに戻り、docker
によって管理されます。 Dockerはパケットを処理する必要があり、RETURN
のPREROUTING
には到達しないでください。
これの良い方法は、PREROUTING
テーブルに触れる必要がなくなることです。フラッシュする場合は、DOCKER-BLOCK
を直接フラッシュします。
DOCKER-BLOCKアプローチの問題は、ホストおよびコンテナへのトラフィックをブロックする場合、たとえばtcpポート50をブロックする場合、DOCKER-BLOCKチェーン(Dockerルールをバイパスするため)およびINPUTチェーンに追加する必要があることです。 (実際のドロップを実行するため)。