conntrackの値を監視しようとしてスクリプトを作っている最中にこんなことに気づきました。
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_count 53424
いくらなんでも多すぎじゃね、っていうか実際こんなにコネクションが残ってたらポートが枯渇するかどうかっていう話になってしまいます。
さっそく内容を確認してみました。conntrackコマンドでもprocfsでもどちらでも確認することができます。
5万行でてくるのでheadで一部だけ見ます。
$ sudo head -n 3 /proc/net/ip_conntrack tcp 6 180817 ESTABLISHED src=10.x.x.xx dst=1.xx.x.xx sport=80 dport=52843 [UNREPLIED] src=1.xx.x.xx dst=xxx.xx.x.xxx sport=52843 dport=80 mark=0 use=2 tcp 6 88234 ESTABLISHED src=10.x.x.xx dst=1.xx.xxx.xxx sport=80 dport=64778 [UNREPLIED] src=1.x.xxx.xxx dst=xxx.xx.x.xxx sport=64778 dport=80 mark=0 use=2 tcp 6 329583 ESTABLISHED src=10.x.x.xx dst=1.x.x.x sport=80 dport=63624 [UNREPLIED] src=1.x.x.xx dst=xxx.xx.x.xxx sport=63624 dport=9 mark=0 use=2
3個目のカラムはタイムアウトです。ESTABLISHEDなTCPだとデフォルト値の5日間残ります。この時点で慌ててタイムアウトの値を小さくしたのですが、テーブルをFLUSHするのも怖いので、5日間かけて消えてなくなるのをじっくり待つことにしました。
しかし[UNREPLIED]ってなんぞやと思い調べてみたところ、公式に回答がのっていました。
http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#THECONNTRACKENTRIES
通信が双方から行われていないと[UNREPLIED]になるようです。TCPのセッションとしては残っていないけど、conntrackのテーブルに記憶されている状態なのかな。
[ASSURED]は破棄されないと書いてあるので、実際は[ASSURED]の数が上限値という感じでしょうか。こちらは全体で100ちょっとでした。
さらにこんなものをみつけました。
http://archive.linux.or.jp/JF/JFdocs/netfilter-faq-3.html#ss3.16
あなたは /proc/net/ip_conntrack を見て、UNREPLIED エントリに非常に大きな タイマ値(最高で5日)が割り当てられているのに気付き、どうして我々が (明らかにコネクションではない) UNREPLIED エントリに無駄に conntrack エントリを使おうとするのかと不思議に思われたのですね? その答えは簡単です: UNREPLIED エントリは、テンポラリなエントリだからです。 つまり、コネクション追跡エントリが限界まで来たらすぐに、古い UNREPLIED エントリを削除します。言いかえると、conntrack を何も持たないよりは、 UNREPLIED エントリの中の有用かもしれない情報を、それが実際に必要 とするまで保持しておくのがよいだろうというわけです。
「何度もトラッキングしなおすよりメモリにおいといたほうがいいだろwww」
ってことですかね。
しかし、メモリにたくさんとっておいてスキャンするコストと、少ない件数をメモリに残しておいて新しくトラッキングさせるのは、どっちがコストが安いんでしょうね。
もう少し調べる必要がありそうです。