UDPフラッドを防ぐために、すべての着信UDPパケットを拒否するようにサーバーを設定しました。ただし、ネームサーバーには独自のドメインとサーバーを使用しているため、問題が発生する可能性があると言われました。どうすればそれを回避できますか?
私のファイアウォールはiptablesで、ディストリビューションはCentOS5.5です。
標準のセキュリティ慣行に従っている場合、デフォルトのファイアウォールポリシーはすべてをブロックすることです。着信DNS要求を許可する場合は、ポート53へのtcpおよびudpトラフィックを許可するルールを作成するだけです。
あなたが話しているトラフィックはUDPです。 UDPはステートレスです。つまり、接続を飽和させることに関心のある人は、パケットをドロップしただけでも、パケットをあなたのアドレスに送信できます。それでも、iptablesの最近の一致で半有用なことを実行して、限られた量のトラフィックのみが実際にシステムによって受け入れられ、処理されるようにすることができる場合があります。 Evanには、 SSHでのこれの使用 の例があります。追加する必要のあるルールを通知するために、ファイアウォールルールセット全体を確認する必要がある場合があります。
システムに対して深刻なDoSがある場合は、ほぼ確実にISPが支援する必要があります。VPS上のホストベースのファイアウォールでフラッドに対処しようとしても、あまり役に立ちません。
まだ持っていない場合は、完全に異なるネットワーク上のゾーンにいくつかのセカンダリDNSサーバーを設定することを検討する必要があります。
Iptablesで、ポート53への着信UDPトラフィックを受け入れ、エフェメラルポートのポート範囲内のすべてを拒否します。
上限が高すぎないようにしてください。高すぎると、サーバーはサーバー内部から外部ドメインを解決できなくなります(たとえば、「pinggoogle.com」を実行する場合)。 Linux OSでは、32768は61000までのソケットの最初のエフェメラルポート(別名ダイナミックポート)です。したがって、32767は静的に割り当てられたポートの最高のポートです。これは、サーバーをDNSリゾルバー(DNSキャッシュ)として使用しない場合にのみ当てはまります。/etc/resolv.confはネームサーバー127.0.0.1または:: 1を指します。
Tcpdumpの例を次に示します。
23:10:13.315832 IP b.b.b.b.34507 > a.a.a.a.53: 23674% [1au] A? whitehouse.gov. (38)
23:10:13.377619 IP a.a.a.a.53 > b.b.b.b.34507: 23674*- 1/2/3 A 172.230.122.69(122)
通常、UDPおよびTCP用のLinuxでローカルの動的(エフェメラルまたはプライベートとも呼ばれる)ポート範囲を見つけるには、次のようにします。
cat /proc/sys/net/ipv4/ip_local_port_range
ただし、DNSリゾルバーをホストしていないサーバーでのみ機能します(たとえば、/ etc/resolve.confが8.8.8.8を指している場合)。
サーバーはDNSリゾルバーではありません:
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p udp -m udp --dport 0:32767 -j DROP
サーバーはDNSリゾルバーです:
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p udp -m udp --dport 0:1023 -j DROP
独自のDNSリゾルバーをホストしてすべてのドメイン名を解決する場合は、これを考慮に入れる必要があります。
自分で確認するのが最善です。
を使用して送信ポートを監視できます
tcpdump udp and port 53 and not dst Host *yourserveripaddress*
次に、送信ポートを調べて、最小の数を見つけようとします。この最小数は、-dport 0:xxxxのポート番号xxxxより小さくすることはできません。小さくしないと、DNS要求がブロックまたは遅くなります。
インターネット上の見知らぬ人がサーバーに対してDNSクエリを実行できるようにする必要がありますか?ファイアウォールがサーバーに発信DNS要求を許可していることを確認する必要があると思います。
ファイアウォールを使用すると、すべてをブロックすることから始め、ポート/サービス/プロトコルの特定の組み合わせを開くことについて非常に正確/詳細になり、IPアドレス(範囲)で制限します。
DNSルックアップを除くすべての着信UDPパケットを拒否するにはどうすればよいですか?
これはもっと広義に言うことができます:Linux netfilterで開始しなかったすべてのトラフィックを拒否するにはどうすればよいですか?
答えは単純に2行です。
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j DROP
(一部のCPUサイクルを節約するためにループバックトラフィックをフィルタリングしたくないことを考慮して、例外を追加できます。)
OTOHが同じコンピューター上にDNSサーバーを持っていて、qnを「DNSサーバーへの外部クエリを除くすべての着信UDPトラフィックを拒否するにはどうすればよいですか?」とより正確に表すことができる場合、同じ2行ベースを使用しますDNSトラフィックを明示的に許可する別のものを追加します。
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT -m comment --comment "we serve DNS"
iptables -A INPUT -p tcp --dport 53 -j ACCEPT -m comment --comment "DNS uses TCP too sometimes"
iptables -A INPUT -j DROP
通常、最初の行以外には-m state
を指定する必要がないことに注意してください。最初の行はショートカットであるため、パイロットパケットに入る許可を得ても、正当なトラフィックを続行できます。
その他の通知
@Zoredacheのrecent
に関するアドバイスは、まったく当てはまりません。 recent
のユースケーススコープは非常に限られているため、効率的なデータ構造は使用されませんが、リストとハッシュが使用され、ツリーは使用されません。デフォルトでは、拡張可能なリストごとに100個のIPしか記憶できませんが、ハッシュはとにかくそれを検索するのにあまり効果的ではありません。