前提と問題点
複数の仮想マシンで仮想ネットワークを作成し、webサーバマシンにて以下のプログラムを実行し、クライアントからwebサーバマシンにhttperfでアクセスする。ルーティングテーブルはメイン=rt1,rt2の二つあり、クライアントからwebサーバまでの経路は一本道だが、webサーバからクライアントまでの経路はrt1,rt2の二つの経路がある。
本来はrt1を参照するが、プログラムを実行している間に送信されるパケットはrt2を参照したい。
しかし、実際にプログラムを動かすと一つ目のコネクション
のパケットはrt1を参照して、二つ目以降のコネクションのパケットはrt2を参照する。
実現したいこと
- iptables -A PREROUTING -i eth3 -p tcp -j MARK --set-mark $mark をプログラム内で実行した瞬間から適用されてほしい
- 適用されてほしいというのは一つ目のコネクションのパケットからちゃんとrt2を参照してほしいということです。
該当のソースコード
perl
1#!/usr/bin/perl -sw 2 3$count = 0; 4$debug = 1; 5 6#ループ回数が指定されていないときは10回とする。 7unless ($n) { 8 $n = 10; 9} 10 11# コマンドの出力をパイプでファイルハンドルへ渡す 12$pid = open (PKT, "tcpdump -l -i eth3 -tt -nn '((host 192.168.X.XX) and (tcp) and (src port 80) and (tcp[tcpflags] & (tcp-syn|tcp-fin) != 0))'|"); 13 14# ファイルハンドルからtcpdumpの結果を読み込む 15while (<PKT>) { 16 17 # 時刻(秒)を$1,送信先アドレスを $2,送信先ポートを$3,フラグ[S]or[S.]を$4,シーケンス番号を$5とする 18 if (/^(\d+\.\d+).*> (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).(\d+).*(Flags \[S\.?\]).*seq (\d+)/) { 19 20 print "---------flag[S]------------\n"; 21 if($debug == 1){ 22 print "\$_ = $_\n"; 23 print "match[S] = $&\n"; 24 } 25 26 #マークは2とする。ip rule によってマーク2はルーティングテーブルrt2を参照する。 27 $mark = 2; 28 print "\$count = $count and \$mark = $mark\n"; 29 30 # iptablesでマークをつける。rt2にルーティングされるようになる(はず) 31 $cmd = "iptables -A PREROUTING -i eth3 -p tcp -t mangle -j MARK --set-mark $mark "; 32 if ($debug == 1) { 33 print "\$cmd = $cmd\n"; 34 } 35 system $cmd; 36 $cmd_3 = "iptables -tmangle -L"; 37 system $cmd_3; 38 # $cmd_restart = "service iptables restart"; 39 # system $cmd_restart; 40 41 #フラグが[F]or[F.]の場合 42 } elsif (/^(\d+\.\d+).*> (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).(\d+).*(Flags \[F\.?\]).*seq (\d+)/) { 43 44 print "---------------flag[F]---------------\n"; 45 if($debug == 1) { 46 print "\$_ = $_\n"; 47 print "match[F] = $&\n"; 48 } 49 50 $count++; 51 52 #n回読み込んだら終了させる。 53 if ($count == $n) { 54 last; 55 } 56 } 57} 58 59#マーク付けした内容を全て削除する 60$cmd_2 = "iptables -F PREROUTING -t mangle"; 61system $cmd_2; 62 63#クローズする前にプロセスを終了させる。 64kill(15,$pid); 65#使ったらちゃんと閉じる 66close (PKT); 67
試したこと
- 手動でiptables を設定してマーク付け=ルーティングの変更ができるか
-> できた。予め設定しておく分にはできて、プログラム内のwhileループ内で行おうとするとすぐに適用されなかった。
- whileより前にiptablesを行うsystemコマンドをかく
-> この方法はできるし、解決にはなりますが、今後の目的のためipttablesは「SYNパケットを読み込んでから、対応したFINパケットを読み込むまでの間」に実行する必要があります。
お願い
説明で不十分な点や不明な点が多いとは思いますが、聞いていただければ捕捉しますのでご協力お願いします。
回答1件
あなたの回答
tips
プレビュー