iptables ルールは AWS NLB および Elastic IP では機能しませんが、EC2 インスタンスのパブリック IP を使用すると機能します。

iptables ルールは AWS NLB および Elastic IP では機能しませんが、EC2 インスタンスのパブリック IP を使用すると機能します。

ちょっと困惑しています。

まず背景を説明します。NLB の背後に AWS EC2 インスタンスがあります。NLB は Elastic IP を使用しています。EC2 インスタンスは DNS サーバーを実行し、UDP と TCP 53 をリッスンしています。NLB は TCP と UDP ポート 53 に設定されています。インスタンスはターゲット グループ内にあり、NLB から見て正常です (そして、期待どおりにリクエストを処理しています)。

ANY解決しようとしている問題: レコード タイプのすべての DNS クエリ(およびレート制限とフィルタリングのその他のいくつかのルール) を確実にドロップしたいので、次のiptablesルールを追加しました。

$ iptables -t raw -I PREROUTING -p udp --dport 53 -m string \
    --hex-string "|0000FF0001|" --algo bm --from 40 -j DROP

$ iptables -t raw -I PREROUTING -p tcp --dport 53 -m string \
    --hex-string "|0000FF0001|" --algo bm --from 52 -j DROP

$ iptables -t raw -I PREROUTING -p udp --dport 53 -m string \
    --hex-string "|0000FF0001|" --algo bm --from 40 -j LOG \
    --log-prefix "BLOCKED ANY: "

$ iptables -t raw -I PREROUTING -p tcp --dport 53 -m string \
    --hex-string "|0000FF0001|" --algo bm --from 52 -j LOG \
    --log-prefix "BLOCKED ANY: "

さて、問題は…

試してみると、dig some.domain -t any @public.ip.of.instanceクエリがブロックされ、/var/log/kern.log期待どおりにログ エントリが表示されます。

試してみると、dig some.domain -t any @elastic.ip.on.nlbリクエストはブロックされず、応答が返されます。 にログ エントリはありませんkern.log

私にとって最も奇妙な部分は、NLB を除外して、同じ Elastic IP をインスタンスに直接割り当てようとしたことです。結果は同じで、 にANY送信されたクエリは、EIP上記のルールが適用されていてもドロップされません。の代わりにプライベート IP を使用して別のインスタンスから送信されたiptables同じクエリは、予想どおりドロップされます。ANYEIP

nat(チェーンも使用PREROUTING) テーブルとfilter(チェーンを使用) テーブルで同じルールを試しましたINPUT。ルールに明らかな何かが欠けているのでしょうかiptables?

他に何かアイデアはありますか?

答え1

ServerFaultを調べてみると、この答えが見つかりました -iptables は 16 進文字列の一致によりパケットをドロップします16 進数値の間にスペースが表示されるので、以下を試してみることをお勧めします。

その質問からの例:

$ iptables --append INPUT --match string --algo kmp \
    --hex-string '|f4 6d 04 25 b2 02 00 0a|' --jump ACCEPT

したがって、例を次のように変更します。

$ iptables -t raw -I PREROUTING -p udp --dport 53 -m string \
    --hex-string "|00 00 FF 00 01|" --algo bm --from 40 -j DROP

答え2

さて、その後多くの何時間もトラブルシューティングを行った結果、簡単に言えば、ずっと動作していたということのようです...

NLB の背後にある EC2 インスタンスで tcpdump を実行しました ( tcpdump udp port 53 -X -nn)。次に、Macbook (Catalina 10.15.2) から実行しましたdig some.domain -t any @elastic.ip.on.nlbが、応答が返されただけでなく、EC2 インスタンスのパケット キャプチャにクエリが表示されませんでした。dig クエリで使用した Elastic IP を使用している NLB の背後にある EC2 インスタンスは 1 つだけです。完全に奇妙に感じたので、Ubuntu マシンと Windows 10 コンピューターで同じ dig コマンドを実行しました。これらのクエリは両方ともタイムアウトし (iptables によって適切にフィルター処理されました)、tcpdump で確認でき、ログ メッセージは予想どおり /var/log/kern.log にありました。Macbook に戻って同じ dig コマンドを実行しましたが、まだ回答が返され、tcpdump には何も返されません... 何てこった!

私は Macbook を再起動し、正しい IP と同じクエリを使用していることを 100 万回目に確認し、別のドメインを試し、おそらく他の 100 のことも試しました。Macbook からのパケット キャプチャに何もない応答が返される理由がまったくわかりません。

結局、これは奇妙に孤立した問題 (おそらく Apple の不手際が原因) のようで、私が最初に考えたような AWS による奇妙なパケット操作や iptables ルールの破綻ではないようです。したがって、本当の答えは、StackExchange に投稿する前に複数のマシンで試してみることです。

編集: 明確にするために。インスタンスのパブリック IP を使用し、EIP を使用しない場合、Macbook からの tcpdump でクエリが表示されます (予想どおりにタイムアウトします)。クエリが表示されず、応答が返されるのは EIP の場合のみです...

また、これは回答投稿であるべきなのか、それとも最初の投稿を修正するだけでよかったのか、私にはわかりません。モデレーターの皆さんは、これをどう扱うかはあなた次第です!

関連情報