VyOSでL2透過なNetwork Emulatorをつくる

VyOS で Network Emulator という話は前見ていたので記憶の片隅にあったわけです。

で。こういうのを見つけたわけですね。

思ったわけです。これ二つ組み合わせれば、L2透過 (L2 Transparent) な Network Emulator つくれるんじゃないのか? と。

はい。結論から言うとできました。まあそんなに機能追いかけて検証したわけじゃないけど、ちょっとしたテストくらいだったらこれで充分回せるじゃないだろうか。なお、VyOSのバックエンドで何をどう使っているのかとかを理解しているわけではないので、怪しげなことを書いているかもしれません。ツッコミどころがあったら教えてください。

環境構成

いきなり実機デプロイの図出だしますが、こんな感じでやりました。


はいわかりにくいですね。ごめんなさい。この図で言いたいことは

  • Internal セグメント (VLAN101) と Vyos Expr セグメント (VLAN701) を VyOS(vyos-expr) でブリッジしてひとつの L2 セグメント (192.168.1.0/24) としている。
  • ホスト vyexpr1 (192.168.1.99) に対する通信はかならず Vyos Expr Seg/vyos-expr を経由する。

というあたりです。自宅の環境でやる以上、どうしてもいまある機材の中でどうするかという話があってですね。こういう状態になっていますね。あ、VyOS は 1.1.7 を使っています。

テストに当たって、基本は vyexpr1/vyexpr2 間の通信がどうなるのか、というのが見えれば良いです。ただ、Win10 だと今ひとつだったツールがあったりしたので、DMZ セグメントにいる host1 というのを召喚していたりします。なので、host1 使うのは重要ではありません。新しく VM 立てたりするのが面倒だったから既存の VM を使い回しているだけです。

スイッチ(core2)側のポート設定はこんな感じです。

interface GigabitEthernet1/0/16
 switchport access vlan 701
 switchport mode access
!
interface GigabitEthernet1/0/17
 switchport access vlan 701
 switchport mode access
!
interface GigabitEthernet1/0/18
 switchport access vlan 101
 switchport mode access
!

なお、vyos-expr が接続している vSwitch (vSwitch2/3) は、L2で透過になってほしいので、プロミスキャスモードを有効にしてあります。

ブリッジ設定

まず、物理構成を確認した後、vyos-expr をブリッジとして設定し、vyexpr1 が vyos-expr 経由で(L2透過で)通信できることを確認しましょう。

vyos-exprの設定

  • eth0/1 を bridge-group 追加する、というだけで良いのですが、bridge 自体に IP を振っておくとデバッグ用に使えるのに IP も設定しましょう。(参照; User Guide - VyOS)
set interface bridge br0
set interface bridge br0 address 192.168.1.100/24
set interfaces ethernet eth0 bridge-group bridge br0
set interfaces ethernet eth1 bridge-group bridge br0

今回、br0 に設定した IP をつかって vyexpr2 から ssh していますが、当然このあとの delay/packet-loss 等の設定をすると ssh connection も影響を受けます。リモートアクセス用のパスは別にしておくのがベターだと思います。(面倒だったので今回はやっていませんが…)

スイッチ側の確認(物理接続: MACアドレステーブルの確認)

core2#show mac address-table | inc 1/0/1[6-8]
 101    000c.291a.d732    DYNAMIC     Gi1/0/18
 701    000c.291a.d73c    DYNAMIC     Gi1/0/17
 701    000c.2978.3848    DYNAMIC     Gi1/0/16
core2#

vyos-expr 側の確認

vyos@vyos# show interfaces
 bridge br0 {
     address 192.168.1.100/24
 }
 ethernet eth0 {
     bridge-group {
         bridge br0
     }
     hw-id 00:0c:29:1a:d7:32
 }
 ethernet eth1 {
     bridge-group {
         bridge br0
     }
     hw-id 00:0c:29:1a:d7:3c
 }
 loopback lo {
 }
[edit]
vyos@vyos#

vyos-expr に通信できることがわかったら ssh 接続も有効にしておきます。

set service ssh

遅延

通信遅延の設定。

遅延設定を入れる前に、何もしないときの通信遅延を見ておきます。おおむね 1ms 弱というところですね。なお、最初 vyexpr2 (Windows10) の ping (Cygwin package の ping) でやったんですけど、出力が小数点以下切り捨てになるんですよね。有効数字桁数がちゃんと出てくれた方がなんとなくうれしいので host1 を使っています。

stereocat@host1:/tftpboot$ ping -c 10 192.168.1.99
PING 192.168.1.99 (192.168.1.99) 56(84) bytes of data.
64 bytes from 192.168.1.99: icmp_req=1 ttl=63 time=0.615 ms
64 bytes from 192.168.1.99: icmp_req=2 ttl=63 time=0.713 ms
64 bytes from 192.168.1.99: icmp_req=3 ttl=63 time=0.657 ms
64 bytes from 192.168.1.99: icmp_req=4 ttl=63 time=0.726 ms
64 bytes from 192.168.1.99: icmp_req=5 ttl=63 time=3.03 ms
64 bytes from 192.168.1.99: icmp_req=6 ttl=63 time=1.04 ms
64 bytes from 192.168.1.99: icmp_req=7 ttl=63 time=0.547 ms
64 bytes from 192.168.1.99: icmp_req=8 ttl=63 time=0.610 ms
64 bytes from 192.168.1.99: icmp_req=9 ttl=63 time=0.565 ms
64 bytes from 192.168.1.99: icmp_req=10 ttl=63 time=0.578 ms

--- 192.168.1.99 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 8999ms
rtt min/avg/max/mdev = 0.547/0.909/3.032/0.721 ms
stereocat@host1:/tftpboot$

vyos-expr に遅延設定を入れます。
VyOS でネットワーク遅延やロスを発生させるには の丸パクでそのままやります。この後のもだいたいそうです。あと、network-emulator 設定は interface outbound にのみ設定…などの話はこのリンク先を参照してください。

set traffic-policy network-emulator DELAY-100 network-delay 100
set interfaces ethernet eth1 traffic-policy out DELAY-100
vyos@vyos# compare
[edit interfaces ethernet eth1]
+traffic-policy {
+ out DELAY-100
+}
[edit]
+traffic-policy {
+ network-emulator DELAY-100 {
+ burst 15k
+ network-delay 100
+ }
+}
[edit]
vyos@vyos#

再度 ping 実行しましょう。

stereocat@host1:/tftpboot$ ping -c 10 192.168.1.99
PING 192.168.1.99 (192.168.1.99) 56(84) bytes of data.
64 bytes from 192.168.1.99: icmp_req=1 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=2 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=3 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=4 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=5 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=6 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=7 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=8 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=9 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=10 ttl=63 time=100 ms

--- 192.168.1.99 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9014ms
rtt min/avg/max/mdev = 100.581/100.677/100.762/0.207 ms
stereocat@host1:/tftpboot$

ちゃんと host1-vyexpr1 間の通信に設定した遅延が乗っかっていることがわかります。

いま eth1 の outbound で設定したので、eth0 の outbound にも同じポリシを設定してみると、当然 200ms の遅延が発生します。

set interfaces ethernet eth0 traffic-policy out DELAY-100
stereocat@host1:/tftpboot$ ping -c 10 192.168.1.99
PING 192.168.1.99 (192.168.1.99) 56(84) bytes of data.
64 bytes from 192.168.1.99: icmp_req=1 ttl=63 time=200 ms
64 bytes from 192.168.1.99: icmp_req=2 ttl=63 time=200 ms
64 bytes from 192.168.1.99: icmp_req=3 ttl=63 time=200 ms
64 bytes from 192.168.1.99: icmp_req=4 ttl=63 time=200 ms
64 bytes from 192.168.1.99: icmp_req=5 ttl=63 time=200 ms
64 bytes from 192.168.1.99: icmp_req=6 ttl=63 time=200 ms
64 bytes from 192.168.1.99: icmp_req=7 ttl=63 time=200 ms
64 bytes from 192.168.1.99: icmp_req=8 ttl=63 time=200 ms
64 bytes from 192.168.1.99: icmp_req=9 ttl=63 time=200 ms
64 bytes from 192.168.1.99: icmp_req=10 ttl=63 time=200 ms

--- 192.168.1.99 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9011ms
rtt min/avg/max/mdev = 200.620/200.704/200.761/0.531 ms
stereocat@host1:/tftpboot$

パケットロス

続いてパケットロスの設定にいきます。

set traffic-policy network-emulator LOSS-50 packet-loss 50
set interfaces ethernet eth1 traffic-policy out LOSS-50

遅延設定に続けてやったので

  • eth0 out: delay 100ms
  • eth1 out: loss 50%

となっている点に注意です。

vyos@vyos# show interfaces
 bridge br0 {
     address 192.168.1.100/24
 }
 ethernet eth0 {
     bridge-group {
         bridge br0
     }
     hw-id 00:0c:29:1a:d7:32
     traffic-policy {
         out DELAY-100
     }
 }
 ethernet eth1 {
     bridge-group {
         bridge br0
     }
     hw-id 00:0c:29:1a:d7:3c
     traffic-policy {
         out LOSS-50
     }
 }
 loopback lo {
 }
[edit]
vyos@vyos#

再度 ping 実行してみます。

stereocat@host1:/tftpboot$ ping -c 100 192.168.1.99
PING 192.168.1.99 (192.168.1.99) 56(84) bytes of data.
64 bytes from 192.168.1.99: icmp_req=1 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=4 ttl=63 time=100 ms
(省略)
64 bytes from 192.168.1.99: icmp_req=89 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=91 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=92 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=94 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=95 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=96 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=97 ttl=63 time=100 ms
64 bytes from 192.168.1.99: icmp_req=99 ttl=63 time=101 ms
64 bytes from 192.168.1.99: icmp_req=100 ttl=63 time=100 ms

--- 192.168.1.99 ping statistics ---
100 packets transmitted, 51 received, 49% packet loss, time 99322ms
rtt min/avg/max/mdev = 100.560/100.734/101.324/0.341 ms
stereocat@host1:/tftpboot$

100 発なげてほぼ 50% のパケットロスでした + 片側でのこした遅延の設定もそのまま有効になっていることがわかります。

帯域制御

いったん遅延やパケロスの設定は外します。

帯域測定については、今回は iperf を使いました。

  • vyexpr2 (Win10): iperf 2.0.5 on Cygwin (iperf client)
  • vyexpr1 (ubuntu): iperf 2.0.5-3 (iperf server)

という組み合わせで行きます。

まずは何も設定しない状態での測定。

stereocat@vyexpr2 ~
$ iperf -c 192.168.1.99
------------------------------------------------------------
Client connecting to 192.168.1.99, TCP port 5001
TCP window size: 208 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.1.20 port 56689 connected with 192.168.1.99 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 1.09 GBytes 939 Mbits/sec

stereocat@vyexpr2 ~
$

1Gbps近く出ました。いやまあ、間のリンク全部 1Gbps だからなのですが、でも VyOS Bridge とか挟んだ割にはそれなりに出ましたね…。

帯域制御設定を入れてみます。

set traffic-policy network-emulator BANDWIDTH-100mbps bandwidth 100mbit
set interfaces ethernet eth1 traffic-policy out BANDWIDTH-100mbps

設定や単位についてはこの辺も参照してみてください。

再度帯域測定を実行してみます。

stereocat@vyexpr2 ~
$ iperf -c 192.168.1.99
------------------------------------------------------------
Client connecting to 192.168.1.99, TCP port 5001
TCP window size: 208 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.1.20 port 56814 connected with 192.168.1.99 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 115 MBytes 96.6 Mbits/sec

stereocat@vyexpr2 ~
$

ちゃんと 100Mbps 弱くらいの値になりました。

まとめ

VyOS で L2 Transparent なネットワークエミュレータが作れました。まあ精度とか性能とかでどこまで保証できるのか、というのはともかく、ちょっとした実験であればすぐ使えるんじゃないかと思います。これ、思いつきでちょっと試してみようと思って数時間ですよ…凄いお手軽。このお手軽さでこれだけできるんだからありがたいことです。