このメッセージは、マルチキャスト・パケットが NAT テーブルを通る際に NAT のコードにより出力されるもので、今のところコネクション追跡部が マルチキャスト・パケットをうまく処理できないのが原因です。 マルチキャストが何であるか分からないか、 またはマルチキャストをまったく必要としないなら、 以下のようにしてください:
iptables -t mangle -I PREROUTING -j DROP -d 224.0.0.0/8
syslog かコンソールに以下のメッセージが表示されます:
NAT: X dropping untracked packet Y Z aaa.aaa.aaa.aaa -> bbb.bbb.bbb.bbb
このメッセージは、NAT のコードにより表示されます。 NAT を行うには、有効なコネクション追跡情報がないといけないので、 パケットを破棄しているのです。コネクション追跡部が conntrack 情報を決定できなかったパケットすべてに対し、このメッセージが表示されます。
考えられる理由としては:
こうしたパケットのもっと詳細なログを取りたいなら(つまり、 リモート・プローブやスキャニング・パケットだと疑うなら)、 以下のルールを利用してください:
iptables -t mangle -A PREROUTING -j LOG -m state --state INVALID
そうです、パケットはフィルタ・テーブルに到達する前に、NAT のコードによって破棄されてしまうので、このルールを mangle テーブルに設定しなくてはなりません。
つまり、完全な透過型ファイアウォールを構築したいわけですね? 素晴らしい考えですね! カーネル 2.4.16 の時点でもなお、それを動かすには追加パッチを カーネルにあてる必要があります。そのパッチは、 http://bridge.sourceforge.net/ で入手できます。
そうですね、それは半分本当のことです。NAT モジュールだけでは 処理できません。NAT 抜きでファイアウォールを利用すれば、 それはうまくいきます。
netfilter は、できる限りパケットに手を加えないように努めます。 ですので、我々のところにリブートしたてのマシンがあり、 SNAT ボックスの背後にいる誰かがローカル・ポート 1234 番でコネクションを開いた場合、netfilter ボックスは IP アドレスだけに手を加え、ポート番号はそのままにしておきます。
SNAT 用の IP アドレスが一個しかない場合、誰かが同じ送信元ポート番号 で別のコネクションを開くと同時に、netfilter は IP アドレスとポート番号の両方に手を加えなくてはならなくなります。
しかし、使用可能な IP アドレスが一個以上あるなら、 この場合も IP 部に手を加えるだけですみます。
このメッセージが syslog の中にあるのに気付いたら、ご利用の環境下では、 どうやら conntrack データベースが十分な数のエントリを持ってないようです。 デフォルトでは、コネクション追跡部の処理できる同時接続数には、 ある一定の上限があります。 この数は、ご利用のシステムのメモリ・サイズの上限に依ります (メモリが 64MB でしたら 4096 個、128MB でしたら 8192 個 ...)。
追跡するコネクションの数の上限を増やすことは簡単にできますが、 追跡するコネクション数ひとつあたり、swap できないカーネル・メモリを約 350 バイト食うことをお忘れなく!
上限を例えば 8192 に増やすには、以下のように入力してください:
echo "8192" > /proc/sys/net/ipv4/ip_conntrack_max
proc ファイルシステム中に、/proc/net/ip_conntrack
という名前のファイルがあります。以下のようにすれば、
このファイルを出力して表示できます。
cat /proc/net/ip_conntrack
有効なすべての IP テーブルは、以下のようにしてリスト表示されます。
cat /proc/net/ip_tables_names
既知のバグです。できるだけ速やかに、最新の CVS のソースか、 1.2.1 以降の iptables にアップグレードしてください。
これは iptables が IP アドレス毎に DNS 検索を行っているためです。 各ルール 2 つのアドレスから構成されますので、最悪の場合、 ルール毎に 2 回 DNS 検索が入ります。
問題となるのは、プライベート IP アドレス(10.x.x.x や 192.168.x.x など) を使っている場合で、DNS はホスト名を解決できず、タイムアウトします。 こうしたタイムアウトの合計が、ご利用のルールセットによっては、 とても長い時間になるかもしれません。
DNS の逆引きを行わないようにするには、-n (numeric)オプションを入れて、 iptables をお使いください。
syslogd や klogd を適切に設定しなくてはなりません - LOG ターゲットは、プライオリティ値 warning(4) で、ファシリティ値 kern のロギングを行います。 ファシリティ値とプライオリティ値についての詳細は、 syslogd.conf の man ページを参照してください。
デフォルトでは、プライオリティ値が debug(7) より重要なカーネルのメッセージがすべてコンソールに送られます。 この値を 7 から 4 まで上げれば、コンソール上に LOG メッセージが表示されることはありません。
こうすると、他の重要なメッセージもコンソールに表示されなく なるかも知れません。気をつけてください (syslog ファイルには影響しません)。
まず第一に、当然ながら、適切な DNAT か REDIRECT のルールが必要となります。 squid が NAT ボックス自身の上で動くなら、REDIRECT のみ使ってください。 例えば:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to 192.168.22.33:3128
その後、squid を正しく設定しなくてはなりません。 我々がここで提供できる情報は限られていますので、 更に詳しい情報については、squid のドキュメントを参照ください。
Squid 2.3 での squid.conf に、以下のような設定が必要です:
http_port 3128
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
Squid 2.4 になると、さらに設定行が必要になります:
httpd_accel_single_host off
LOG ターゲットは、いわゆる「終了しないターゲット」です。 つまりそれは、パケットがルールに適合しても、そこで終了しません。 LOG ターゲットを利用すると、パケットはロギングされ、 ルール適合の検索が次のルールに引き継がれます。
では、ログを取り、同時に破棄するにはどうすればよいのでしょう? 最も簡単なのは、二つのルールを含むチェインをあつらえることです:
iptables -N logdrop
iptables -A logdrop -j LOG
iptables -A logdrop -j DROP
今後パケットをログに記録してから破棄したい場合は、 "-j logdrop" を使うだけですみます。
netfilter では確実に止めることはできない、というのが端的な回答になります。 大部分のワームは、正規の高レベルのプロトコル(つまり、HTTP や SMTP (電子メールに VB スクリプトが添付される)や、そうしたプロトコルを 処理するデーモンに見つかった脆弱性を突くプログラム)を利用したものです。 ここでいう高レベルのプロトコルとは、TCP/IP よりも上の層にあるプロトコル のことです。iptables はそうした高レベルのプロトコルを見ないので、 適切にフィルタリングするのはほとんど不可能です。それを行うには、 アプリケーション・プロキシ・フィルタリングが必要になります。
アプリケーション・プロキシ・フィルタリングを行うかわりに、patch-o-matic にある string ターゲットを使うのは止めて下さい。それだと、 フラグメントされたパケット(HTTP リクエストが二つの TCP パケットに分割されるような場合)がきたり、IDS すり抜け技術をやられたり、 その他もろもろの場合に失敗してしまいます。警告はしましたよ! string マッチは有用ですが、別の用途のためにあるのです。
あなたは patch-o-matic から tcp-window-tracking パッチを適用しています。 そのコードは、パケットのシーケンス/確認応答番号、 セグメント・サイズなどにより、許可された TCP ストリームに関して、 条件を満たしているパケットを追跡し続けます。 パケットの一つが条件を満たしていない(範囲外)のを検出すると、 そのパケットが無効であるとみなし、上記のメッセージを表示します。
新バージョンから、そのパケットと、その不適合の原因を正確に 記録するようにしています。
また新バージョンでは、sysctl によりそのロギングを完全 に止めることも可能です。
echo 0 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_log_out_of_window
あなたは /proc/net/ip_conntrack を見て、UNREPLIED エントリに非常に大きな タイマ値(最高で5日)が割り当てられているのに気付き、どうして我々が (明らかにコネクションではない) UNREPLIED エントリに無駄に conntrack エントリを使おうとするのかと不思議に思われたのですね?
その答えは簡単です: UNREPLIED エントリは、テンポラリなエントリだからです。 つまり、コネクション追跡エントリが限界まで来たらすぐに、古い UNREPLIED エントリを削除します。言いかえると、conntrack を何も持たないよりは、 UNREPLIED エントリの中の有用かもしれない情報を、それが実際に必要 とするまで保持しておくのがよいだろうというわけです。
えーと、つまるところ我々が怠惰だからです;) はっきり言って、 ステートフルなファイヤウォーリングを始めた時点で、 チェックオプションを実装するのがほとんど不可能になります。 伝統的なステートレスなファイヤウォーリングの場合、 フィルタリングを行うかどうかは、パケットヘッダにのっている情報 だけで決まります。しかし、コネクション追跡(や '-m state' ベースのルール) を行う場合、フィルタリングを行うかどうかは、そのパケットのヘッダと ペイロードの内容だけでなく、そのコネクションに以前流れたパケットの ヘッダとペイロードの内容によっても変わります。