web-dev-qa-db-ja.com

iptablesでPREROUTINGを使用してパケットをドロップする

フィルターテーブルは、パケットをドロップするのに最適な場所であることが合意されています。

ただし、そのままでは、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つのコンテナを実行した場合のようになります。

Nat table rules

これはうまくいくようですが、他の事前ルーティングルールに到達する前にパケットを明示的に拒否する方法はありますか?

(Alpine Linux 3.6.2、Docker v17.05.0-ce)

2
Drakes

アプリケーションを任意のアドレスにバインドしているコンテナーを誰かがデプロイする場合でも、ネットワークトラフィックを「強化」する必要があるという同様の問題がありました:0.0.0.0:port

DockerはDOCKER-USERフィルターチェーンを提供しますが、DOCKERで参照されるPREROUTING natチェーンですべての魔法が発生するようです。

したがって、このnatを回避する方法はありませんbeforeフィルタリングであり、Dockerのルールにあまり触れたくありません。

もう一度パケットを変更する必要があるのが嫌なので、デフォルトですべてを返し、PREROUTINGbeforeDOCKER内の別のチェーンにジャンプするスキームを思いつきました。

次に、トラフィックが良好であると判断した場合、選択的に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はパケットを処理する必要があり、RETURNPREROUTINGには到達しないでください。

これの良い方法は、PREROUTINGテーブルに触れる必要がなくなることです。フラッシュする場合は、DOCKER-BLOCKを直接フラッシュします。

1
tehmoon

DOCKER-BLOCKアプローチの問題は、ホストおよびコンテナへのトラフィックをブロックする場合、たとえばtcpポート50をブロックする場合、DOCKER-BLOCKチェーン(Dockerルールをバイパスするため)およびINPUTチェーンに追加する必要があることです。 (実際のドロップを実行するため)。

0
kfir