参考:
- http://openvswitch.org/
- http://tomocha.net/diary/?20110928 (flow ruleとか)
- git clone git://openvswitch.org/openvswitch
source最新版にopenvswitch-1.2.2.tar.gz があるけど、redhat用の起動スクリプトにBRCOMPAT(linux互換のブリッジモード)の設定が入っていなかったり,他にも何か怪しいのでgitの最新使ったほうがよい。
Scientific Linux 6.1 + libvirt 0.8.7で実験。仮想化のホストサーバになるのでブリッジを利用。
目的
(VLANを分けたりせずに同一のネットワークで仮想マシンを構築して)仮想マシンにroot権限付きで渡した場合に、任意にIPを変えられると重複したりするので困る。そこで仮想マシン(正確には、それに割り当てるNICのMACアドレス)とIPアドレスをホストOS側で管理したい。
結論
とりあえず結論を先に書くと、やりたいことは一応できたけど仮想マシンの起動/停止の際のflowの自動適用をどうやればいいかわからないので実用できず。さくらはどうやってんだろう。。。
install
autoconf 2.64以上のinstall
openvswitch 1.3以上の場合はautoconf 2.64以上が必要。しかしSL 6.1はautoconf 2.63 なのでこれもsourceから最新を入れる。
展開して普通にconfigure && make && make install
openvswitch install
linuxのbridgeの設定が入っているとinstallできないので、入れている場合は外しておく。
SL6.1なのでINSTALL.RHEL を参考にしてrpmパッケージ作る方法でやった。他のdistriの場合はINSTALL.Linuxを参考に、make, make install, insmod をするぐらいなのでほとんど同じなはず。
- rpmファイル完成
$ git clone git://openvswitch.org/openvswitch #### boot.shのautoreconfのPATHをあらかじめinstallした最新版の場所に変更 $ perl -pi -e 's!autoreconf!/usr/local/bin/autoreconf!' boot.sh $ ./configure --with-linux=/lib/modules/`uname -r`/build $ make dist $ rpmbuild -bb rhel/openvswitch.spec $ rpmbuild -bb rhel/openvswitch-kmod-rhel6.spec $ ls -1 ~/rpmbuild/RPMS/x86_64/ kmod-openvswitch-1.4.90-1.el6.x86_64.rpm openvswitch-1.4.90-1.x86_64.rpm openvswitch-debuginfo-1.4.90-1.x86_64.rpm
- install
$ cd ~/rpmbuild/RPMS/x86_64/ $ su - # rpm -ivh *rpm # ovs-vsctl -V ovs-vsctl (Open vSwitch) 1.4.90 # chkconfig openvswitch on # vim /etc/sysconfig/openvswitch ##### BRCOMPAT=yes に変更 # /etc/init.d/openvswitch start ##### /etc/openvswitch/conf.db 等は勝手に作ってくれる # ovs-vsctl show ##### version, interface等が出てくればOK
bridgeの設定
bridgeに割り当てる時に一旦NICが切れるので、コンソールで作業するか複数NICがある場合には作業しないNICからログインして1つずつ作業する。
eth0をbr0に割り当てる
# ifdown eth0 # ovs-vsctl add-br br0 # ovs-vsctl add-port br0 eth0
ifcfg configの設定
通常のbridge設定とほとんど同じ。1つ違うのは"eth0をbr0に割り当てる"というところはovs-vsctlで設定しているので(実態はovsdb-serverがもっている/etc/openvswitch/conf.db)
ifcfg-eth0にBRIDGE=br0 という設定は"書かない"。
# cd /etc/sysconfig/network-scripts/ # vi ifcfg-eth0 DEVICE="eth0" BOOTPROTO="none" IPV6INIT="yes" ONBOOT="yes" # vi ifcfg-br0 DEVICE="br0" BOOTPROTO="none" ONBOOT="yes" TYPE="Bridge" IPADDR=192.168.0.10 NETMASK=255.255.255.0
network restartでbridge deviceにIPがつくことを確認
IP/ARP 偽装対策
初めにも書いたけど一番やりたかったのはこれ。仮想OSでroot権限を渡していると同じネットワークの他のIPを偽装(偽装というかこっちが想定していない他のIPを勝手に割り振る)
出来てしまうのでそれを制限する。
ex: 仮想マシンAのeth0 52:54:00:11:22:33 (ホストOS上でvnet0のFE:54:00:11:22:33)を192.168.0.100 に制限するflowを適用する
ovs-ofctlの最後の引数はスペースを入れないのだったらクォート不要。
flowの適用
- MAC-IPの組み合わせが一致するものはnormal => 許可
- それ以外はdrop => 拒否 というflow
このときpriorityを書いておかないと、問答無用でdropされてしまうようなので、
- 明示的にpriorityを設定し、dropするflowを一番低いpriorityにする
- dropするflowのpriority=0 に設定し、他にはpriorityを設定しない
などの設定が必要になる。
# ovs-ofctl show br0 | grep vnet0 2(vnet0): addr:fe:54:00:11:22:33 #### => id 2 が割り当てられている # ovs-ofctl add-flow br0 'in_port=2, dl_src=52:54:00:11:22:33, \ priority=100, ip, nw_src=192.168.0.100, actions=normal' # ovs-ofctl add-flow br0 'in_port=2, dl_src=52:54:00:11:22:33, \ priority=100, arp, nw_src=192.168.0.100, actions=normal' # ovs-ofctl add-flow br0 'in_port=2, dl_src=52:54:00:11:22:33, \ udp, nw_src=0.0.0.0,tp_src=68, nw_dst=255.255.255.255, tp_dst=67, actions=normal' # ovs-ofctl add-flow br0 'in_port=2, priority=0, action=drop'
これで完了。
flowの削除
特定の仮想NICのflowを消す場合はin_portを指定する。
# ovs-ofctl del-flows br0 in_port=2
in_port=2 を指定しないとbr0の全flowが削除されてしまう == defaultで用意されているactions=normalのflowも消えてしまってbr0の全通信が拒否されてしまうので注意。
flowの保存
dump-flowsでflowの内容がテキストに出てくるのでファイルに保存
# ovs-ofctl dump-flows br0 NXST_FLOW reply (xid=0x4): cookie=0x0, duration=11.052s, table=0, n_packets=49, n_bytes=5908, priority=0 actions=NORMAL # ovs-ofctl dump-flows br0 | grep -v NXST_FLOW > br0.flow
cookie=.. からはじまる部分がflowルールの本体。これをadd-flowsの引数に与えれば
保存していたflowを追加できる。
# ovs-ofctl add-flows br0 br0.flow