パケット遅延
tcpのport 53 synパケットのみを3秒遅延したい等 特定のパケットのみに遅延を適用させる方法。
条件設定にはtcを使って行う方法とiptablesのMARK経由で行う方法がある。 今回は遅延以外にもdropやreject(impパケットを返す)も別途行いたかったので 条件をまとめられるようiptablesを使用した。
TCの設定
tcで下記のようなキューを作成する
- キュー1 条件: MARK1 動作: 3秒遅延
- キュー2 条件: MARK2 動作: 5秒遅延
- キュー3 条件: MARK3 動作: 10秒遅延
- キュー4 条件: デフォルト 動作: 遅延しない
prioキュー設定
まずprioキューを作成する
tc qdisc add dev eth0 root handle 1: prio bands 4 priomap 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
bands
振り分けを行うクラスの数で今回は4個のクラスを作成する。
priomap
ipヘッダのTOSを見てどのクラスに振り分けるかの指定する設定だが、 今回パケットはTOSに関係なく全て4に送りたいので3を指定する。 (priomapのインデックスは0スタートなので3はクラス4の意味になる)
遅延用のキューを作成
prioキューの設定を行うと1:1 1:2 1:3 1:4の4つのクラスが出来てデフォルトでこれらは、 fifo qdiscと繋がっている。1:1 1:2 1:3の3つには遅延を行いたいのでnetemキューに繋ぎ直す
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 3s tc qdisc add dev eth0 parent 1:2 handle 20: netem delay 5s tc qdisc add dev eth0 parent 1:3 handle 30: netem delay 10s
handle
netemで作成したクラス名を指定。 下記のように連結される
- root=>1: => 1:1 => 10:
- root=>1: => 1:2 => 20:
- root=>1: => 1:3 => 30:
- root=>1: => 1:4 => デフォルトのfifo disc
delay
遅延させる秒数で3秒、5秒、10秒を選択
遅延用のキューに振り分けるフィルターの作成
遅延用のキューが作成できたのでそれらに振り分けるための条件を作成する
tc filter add dev eth0 parent 1: prio 1 handle 1 fw flowid 1:1 tc filter add dev eth0 parent 1: prio 1 handle 2 fw flowid 1:2 tc filter add dev eth0 parent 1: prio 1 handle 3 fw flowid 1:3
prio
優先度の設定でフィルターは優先度の高いものを上から順に実行していくが、 今回はMARK指定のみで複数の条件が同時に当てはまることがないので全てに1を指定
handle
MARK番号の指定でMARK1, 2, 3を使用する (netemの時指定したhandleではクラス指定だったがこちらはMARK番号となることに注意)
iptablesの設定
TCの設定ができたのであとはiptablesで条件を指定してMARKをつけることにより簡単に遅延が完了
例えばDNSのTCPフォールバックの3ウェイハンドシェイクのSYN,ACK応答のみ5秒遅延させたい場合は
iptables -A OUTPUT -p tcp --tcp-flags SYN,ACK SYN,ACK --sport 53 -j MARK --set-mark 2
テスト等で遅延させる秒数や条件が複数あり切り替えたい場合はユーザ定義チェインを作っておいて切り替えたり、 iptables-save&iptables-restoreでファイル経由にするほうがよい。