2007年4月17日火曜日

ポリシング

ingress の qdisc 例を探していたところホストを SYN フラッドから守るなるものがあった。filter を理解していないので、すっごい adhoc だけど eth0 の ingress ポリシングは
tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: protocol ip prio 20 u32 match u8 0 0 police rate 1Mbit buffer 20Kb drop flowid :1
みたいな感じで OK っぽい。ただ最後の flowid :1 って何かわからん。
結局何が言いたいかと言うと、先日の TBF って頑張らなくても filter - police - action drop で同じことができるのでは? とゆー話。

有益そうなリンク。以前 netdev でアナウンスされたことがあった記憶が...で IFB って使うとデバイスにヒモ付かなくても qdisc 使えるの?

2007年4月16日月曜日

conntrackd のテストケース

2.6.18 から netfilter の state について netlink 経由でやり取りできるようになったらしい。このやり取りを multicast 使ってクラスタ組むデーモン conntrackdテストケースの意訳。ベタな上にちょっと長いけど。


Test Case

このドキュメントではシンプルなプライマリ/バックアップ設定に基づく、とてもシンプルな高可用性の設定について述べます。

Description

テストケースではファイアウォールとして動作する二つのホスト FW1 と FW2、またデスクトップとして動作する A と B から構成されます。ネットワーク概要については下図に詳述されています。

初めに、FW1 は図中赤色で強調された仮想 IP を保持していると見なします。このように配備された設定は FW1 がアクティブ FW2 がアクティブホストが落ちるのを待つという古典的なプライマリ/バックアップとなります。仮想IP を受け継ぐ過程を自動化するソフトウェアはkeepalived です。

Ruleset

FW1 と FW2 で実装されているフィルタリングポリシは以下の通りです。

[1] iptables -P FORWARD DROP
[2] iptables -A FORWARD -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
[3] iptables -A FORWARD -i eth1 -p tcp --syn -m state --state NEW -j ACCEPT
[4] iptables -A FORWARD -i eth1 -p tcp -m state --state ESTABLISHED -j ACCEPT
[5] iptables -I FORWARD -j LOG
[6] iptables -I POSTROUTING -t nat -s 192.168.0.3 -j SNAT --to 192.168.1.100
見た通り、転送するデフォルトのポリシは 破棄 [1]。ファイアウォールクラスタはホスト A から開始されるホスト B への新規 TCP 接続を 許可 [3,4] して逆方向は確立されたもののみ [2]。加えて、このクラスタはホスト A から B に向かう接続の 送信元 NATを行う。この転送ポリシに合致しないパケットは全てログに残される [5]。

Generating traffic

テストのため、ホスト A から B への SSH セッションを開始します。

Failure and Takeover

FW1 を落としてみると、すぐに FW2 が仮想 IP を受け継ぎます。

Problems

理屈では SSH 接続は FW2 にて転送されるべきですが、新たにアクティブとなったホストは、そのような接続については何も知らないため、これを新規接続と見なします。あいにく、この接続は実際は 確立されており、パケットを通過させるルール [2] に該当しません。このパケットの破棄はログに残されます。

Solution: Conntrackd

この問題を克服するためには FW1 と FW3 に conntrackd を配備しなければなりません。このデーモンはアクティブノードによって転送された接続の状態を複製するのでバックアップは適宜この接続を引き継ぐことができます。アクティブノードによって転送された接続の状態をダンプさせることができます。

(shell FW1)# conntrackd -i
tcp 6 ESTABLISHED src=192.168.0.3 dst=192.168.0.100 sport=51356
dport=22 src=192.168.0.100 dst=192.168.1.3 sport=22 dport=51356
[ASSURED] mark=0 [active since 5s]
バックアップノードでは複製された接続を観測することができます。
(shell FW2)# conntrackd -e
tcp 6 ESTABLISHED
src=192.168.0.3 dst=192.168.0.100 sport=51356 dport=22
src=192.168.0.100 dst=192.168.1.3 sport=22 dport=51356 [ASSURED] mark=0
[active since 2s]

2007年4月9日月曜日

TBF

ポリシングとシェーピングあたりが違いがわかりやすかった。加えて Linux 特化な部分があるけど このあたりにある
Other info: very good paper about tbf (6 pages, 17 May 2001)
からの図もわかりやすい。意訳すると...

バケツがトラフィックフローの平均送信レートを表すトークンによって補充されるレートである rate。トークンバケツが貯めることができるトークン数である bucket size あるいは burst size。limit はバケツのサイズとキューのサイズの合計。これによって TBF がポリシングするかシェーピングするか決める。limit が bucket size と同じならばキューのサイズは 0 となり、(descipline に) 従わないパケットはドロップされる。つまりポリシング。limit が bucket size より大きいならば...

で、ポリシングの場合は
tc qdisc add dev eth1 root tbf rate 1Mbit burst 20Kb limit 20Kb
で iperf 使って測ると見事ソレらしい数値になった。
もう一回。limit と burst が同じならばポリシング、limit が burst より大きくなると、それなりにシェーピング。