Wednesday, March 19, 2014

OpenStack中的Security Group

【注】
Security Group在openstack中起到很重要的作用,它直接保护租户的vm。但不恰当的配置也容易导致各种莫名其妙的问题。
理解Security Group的实现,有助于理解OpenStack的设计理念和解决各种网络问题。
最新版pdf也可以从这里下载。
--------------------------------------------------------------------------------
Security group的实现,目前是放在qbr***这样的Linux传统bridge上的,是基于iptables服务。
首先在控制节点上用neutron port-list命令列出虚拟机的端口id,例如:
# neutron port-list
+--------------------------------------+------+-------------------+----------------------------------------------------------------------------------------+
| id                                 | name | mac_address       | fixed_ips                                                                  |
+--------------------------------------+------+-------------------+----------------------------------------------------------------------------------------+
| 2a169bb4-4d8b-4c67-802c-a24bdafe1312 |      | fa:16:3e:2f:e9:72 | {"subnet_id": "a2456a2c-5eea-416d-8757-d10bc0aa2aaa", "ip_address": "192.168.0.1"}     |
583c7038-d341-41ec-a0d1-0cd2c33866ca |      | fa:16:3e:9c:dc:3a | {"subnet_id": "a2456a2c-5eea-416d-8757-d10bc0aa2aaa", "ip_address": "192.168.0.2"}     |
| 9b2db4ac-3145-401c-8dc6-486ca6e303b6 |      | fa:16:3e:4e:f1:b5 | {"subnet_id": "ea4ed31b-e05a-4735-8c3f-9b430e656b64", "ip_address": "192.168.122.200"} |
| c5a7d51b-9934-40bd-befa-adff840462d2 |      | fa:16:3e:21:1d:00 | {"subnet_id": "ea4ed31b-e05a-4735-8c3f-9b430e656b64", "ip_address": "192.168.122.201"} |
| db2f5a49-7c0d-45dd-acad-908931f9a654 |      | fa:16:3e:17:5c:36 | {"subnet_id": "a2456a2c-5eea-416d-8757-d10bc0aa2aaa", "ip_address": "192.168.0.3"}     |
+--------------------------------------+------+-------------------+----------------------------------------------------------------------------------------+
其中id的前10位数字被用作虚机对外连接的qbr(同时也是tap口)的idio加上前9位数字被用作安全组chainid
所有的规则默认都在filter表(默认表)中实现,分别来查看filter表的INPUTOUTPUTFORWARD三条链上的规则。
在计算节点上,可以用iptables --line-numbers -vnL [CHAIN]来获得filter表(可以指定某个链上的)规则。

INPUT

#iptables --line-numbers -vnL INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     360K   56M neutron-openvswi-INPUT  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
2    10583 2146K ACCEPT     tcp  --  *      *       192.168.122.100      0.0.0.0/0           multiport dports 5666 /* 001 nagios-nrpe incoming 192.168.122.100 */ 
3      846 50966 ACCEPT     tcp  --  *      *       192.168.122.100      0.0.0.0/0           multiport dports 5900:5999 /* 001 nova compute incoming 192.168.122.100 */ 
4    1033K  894M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
5      760 63840 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
6        1    60 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
7      977 58620 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22 
8     3899 1194K REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 
可以看到,跟安全组相关的规则被重定向到neutron-openvswi-INPUT
查看其规则,只有一条。
#iptables --line-numbers -vnL neutron-openvswi-INPUT
Chain neutron-openvswi-INPUT (1 references)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 neutron-openvswi-o583c7038-d  all  --  *      *       0.0.0.0/0            0.0.0.0/0           PHYSDEV match --physdev-in tap583c7038-d3 --physdev-is-bridged 
重定向到neutron-openvswi-o583c7038-d
#iptables --line-numbers -vnL neutron-openvswi-o583c7038-d
Chain neutron-openvswi-o583c7038-d (2 references)
num   pkts bytes target     prot opt in     out     source               destination         
1     3894 1199K RETURN     udp  --  *      *       0.0.0.0/0            0.0.0.0/0           udp spt:68 dpt:67 
2     4282 1536K neutron-openvswi-s583c7038-d  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
3        0     0 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0           udp spt:67 dpt:68 
4        0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           state INVALID 
5     3971 1510K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
6      311 25752 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           
7        0     0 neutron-openvswi-sg-fallback  all  --  *      *       0.0.0.0/0            0.0.0.0/0
如果是vm发出的dhcp请求,直接通过,否则转到neutron-openvswi-s583c7038-d
#iptables --line-numbers -vnL neutron-openvswi-s583c7038-d
Chain neutron-openvswi-s583c7038-d (1 references)
num   pkts bytes target     prot opt in     out     source               destination         
1     4284 1537K RETURN     all  --  *      *       192.168.0.2          0.0.0.0/0           MAC FA:16:3E:9C:DC:3A 
2        0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0
这条chain主要检查从vm发出来的网包,是否是openstack所分配的IPMAC,如果不匹配,则禁止通过。这将防止利用vm上进行一些伪装地址的攻击。

OUTPUT

#iptables --line-numbers -vnLables --line-numbers -vnL OUTPUT
Chain OUTPUT (policy ACCEPT 965K packets, 149M bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     481K  107M neutron-filter-top  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
2     481K  107M neutron-openvswi-OUTPUT  all  --  *      *       0.0.0.0/0            0.0.0.0/0
分别跳转到neutron-filter-topneutron-openvswi-OUTPUT
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-filter-top
Chain neutron-filter-top (2 references)
num   pkts bytes target     prot opt in     out     source               destination         
1     497K  112M neutron-openvswi-local  all  --  *      *       0.0.0.0/0            0.0.0.0/0
跳转到neutron-openvswi-local
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-OUTPUT
Chain neutron-openvswi-OUTPUT (1 references)
num   pkts bytes target     prot opt in     out     source               destination         
chain目前无规则。
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-local
Chain neutron-openvswi-local (1 references)
num   pkts bytes target     prot opt in     out     source               destination
chain目前也无规则。

FORWARD

FORWARD chain上主要实现安全组的功能。用户在配置缺省安全规则时候(例如允许sshvm,允许pingvm),影响该chain
#iptables --line-numbers -vnLables --line-numbers -vnL FORWARD
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1    16203 5342K neutron-filter-top  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
2    16203 5342K neutron-openvswi-FORWARD  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
3        0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited
同样跳转到neutron-filter-top,无规则。跳转到neutron-openvswi-FORWARD
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-FORWARD
Chain neutron-openvswi-FORWARD (1 references)
num   pkts bytes target     prot opt in     out     source               destination         
1     8170 2630K neutron-openvswi-sg-chain  all  --  *      *       0.0.0.0/0            0.0.0.0/0           PHYSDEV match --physdev-out tap583c7038-d3 --physdev-is-bridged 
2     8156 2729K neutron-openvswi-sg-chain  all  --  *      *       0.0.0.0/0            0.0.0.0/0           PHYSDEV match --physdev-in tap583c7038-d3 --physdev-is-bridged
neutron-openvswi-FORWARD将匹配所有进出tap-XXX端口的流量。
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-sg-chain
Chain neutron-openvswi-sg-chain (2 references)
num   pkts bytes target     prot opt in     out     source               destination         
1     8170 2630K neutron-openvswi-i583c7038-d  all  --  *      *       0.0.0.0/0            0.0.0.0/0           PHYSDEV match --physdev-out tap583c7038-d3 --physdev-is-bridged 
2     8156 2729K neutron-openvswi-o583c7038-d  all  --  *      *       0.0.0.0/0            0.0.0.0/0           PHYSDEV match --physdev-in tap583c7038-d3 --physdev-is-bridged 
3    12442 4163K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0
如果是网桥从tap-XXX端口发出到VM的流量,则跳转到neutron-openvswi-i9LETTERID;如果是从tap-XXX端口进入到网桥的(即vm发出来的)流量,则跳转到neutron-openvswi-o9LETTERID
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-i583c7038-d
Chain neutron-openvswi-i583c7038-d (1 references)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           state INVALID 
2      400 43350 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
3        1    60 RETURN     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:22 
4        1    84 RETURN     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
5     3885 1391K RETURN     udp  --  *      *       192.168.0.3          0.0.0.0/0           udp spt:67 dpt:68 
6     3885 1197K neutron-openvswi-sg-fallback  all  --  *      *       0.0.0.0/0            0.0.0.0/0
neutron-openvswi-i9LETTERID允许安全组中配置的策略(允许sshping等)和dhcp reply通过。默认的neutron-openvswi-sg-fallbackdrop所有流量。
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-o583c7038-d
Chain neutron-openvswi-o583c7038-d (2 references)
num   pkts bytes target     prot opt in     out     source               destination         
1     3886 1197K RETURN     udp  --  *      *       0.0.0.0/0            0.0.0.0/0           udp spt:68 dpt:67 
2     4274 1533K neutron-openvswi-s583c7038-d  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
3        0     0 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0           udp spt:67 dpt:68 
4        0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           state INVALID 
5     3963 1507K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
6      311 25752 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           
7        0     0 neutron-openvswi-sg-fallback  all  --  *      *       0.0.0.0/0            0.0.0.0/0
neutron-openvswi-o9LETTERID将跳转到neutron-openvswi-s583c7038-d,允许DHCP Request和匹配VM的源IP和源MAC的流量通过。

整体逻辑

整体逻辑如图表所示。
 
图表 OpenStack相关iptables规则的整体逻辑

快速查找安全组规则

从前面分析可以看出,某个vm的安全组相关规则的chain的名字,跟vmid的前9个字符有关。
因此,要快速查找qbr-XXX上相关的iptables规则,可以用iptables -S列出(默认是filter表)所有链上的规则,其中含有id的链即为虚拟机相关的安全组规则。其中--physdev-in表示即将进入某个网桥的端口,--physdev-out表示即将从某个网桥端口发出。
#iptables -S |grep tap583c7038-d3
-A neutron-openvswi-FORWARD -m physdev --physdev-out tap583c7038-d3 --physdev-is-bridged -j neutron-openvswi-sg-chain 
-A neutron-openvswi-FORWARD -m physdev --physdev-in tap583c7038-d3 --physdev-is-bridged -j neutron-openvswi-sg-chain 
-A neutron-openvswi-INPUT -m physdev --physdev-in tap583c7038-d3 --physdev-is-bridged -j neutron-openvswi-o583c7038-d 
-A neutron-openvswi-sg-chain -m physdev --physdev-out tap583c7038-d3 --physdev-is-bridged -j neutron-openvswi-i583c7038-d 
-A neutron-openvswi-sg-chain -m physdev --physdev-in tap583c7038-d3 --physdev-is-bridged -j neutron-openvswi-o583c7038-d



可以看出,进出tap-XXX口的FORWARD链上的流量都被扔到了neutron-openvswi-sg-chain这个链,neutron-openvswi-sg-chain上是security group具体的实现(两条规则,访问虚拟机的流量扔给neutron-openvswi-i583c7038-d;从虚拟机出来的扔给neutron-openvswi-o583c7038-d)。

Sunday, March 09, 2014

用rdo安装OpenStack多节点时的注意事项

RDO是Redhat的OpenStack社区,所设计的packstack工具,可以提供在redhat/centos环境下一键式的openstack安装部署方案,目前已经较为成熟。
基本过程可以参考http://openstack.redhat.com/Quickstart,迅速创建一个单机版安装的openstack环境(单节点版基本上不会出现任何问题)。

在创建多节点环境时,有一些注意事项总结如下:
1、packstack理论上可以重复运行,而不需要清除之前操作的修改。如果运行时出现难以解释的问题,建议将环境清除(参考http://openstack.redhat.com/Uninstalling_RDO)后再试。必要时,请清除环境后重启节点。

2、虚拟机启动后默认不支持用户指定管理员的密码,需要手动修改/etc/nova/nova.conf文件让libvirt_inject_password=true,然后重启nova服务。

3、如果是基于Vlan,则需要数据网的交换机支持vlan转发,并且端口为trunk模式。

4、网卡配置文件在/etc/sysconfig/network-scripts/ifcfg-*,确认数据网网卡的mac地址已经写入,并且gre模式下要配置IP地址,例如
eth0为数据网网卡
DEVICE=eth0
ONBOOT=yes
HWADDR=00:14:5E:F5:3C:82
TYPE=Ethernet
BOOTPROTO=none
IPADDR=10.0.0.100
NETMASK=255.255.255.0

对于控制节点,外部网桥也需要确保配置正确
br-ex为
DEVICE=br-ex
ONBOOT=yes
DEVICETYPE=ovs
TYPE=OVSBridge
BOOTPROTO=static
IPADDR=111.111.111.12
NETMASK=255.255.255.0
DNS1=8.8.8.8

5、在计算节点上可以提前yum update; yum makecache来加速安装过程中对软件的部署。

6、可以用packstack --gen-answer-file=xxxx.txt文件生成默认的配置文件,之后自行进行修改,修改时候要注意不需要配置的地方不要改动,目前packstack还没有提供一致性检查的保障,只会逐条进行解释执行。

7、尽量用国内的mirror,比如CentOS6-Base-163,官方源因为网络问题不太稳定。

Monday, February 17, 2014

理解OpenStack中OpenvSwitch的几个要点

OpenvSwitch是实现虚拟化网络的重要基础组件,在OpenStack中利用OpenvSwitch作为底层部件来完成虚拟网络提供和租户网络管理。
在部署和应用OpenStack的过程中,可能会碰到网络相关的一些问题,能够准确的理解OpenStack中OpenvSwitch的角色和网络的理念,会有助于解决问题和快速部署。

OpenvSwitch可以认为是一种Linux Bridge的实现,只不过功能更多一些。因此,它完全可以替代Bridge。原先Bridge可以实现的功能在OpenvSwitch中都可以实现。

OpenvSwitch不等于OpenFlow Switch,恰恰相反,支持OpenFlow只是它的一个feature而已,可能还没有支持OvsDB协议更重要。因此,它在实现上自定义了很多地方,只是兼容OpenFlow协议。比如在OpenvSwitch中用户态的vswitchd和内核态的datapath。vswitchd会总管流表,而datapath中有精确匹配的部分流表,类似cache架构。

正因为OpenvSwitch不仅仅是一个OpenFlow Switch,它的流表组成除了of流表外,还有其他一些(隐藏)流表。这些隐藏流表是由于默认交换机和控制器在同一网络中(in-band),因此要保证两者互通。要关闭默认的inband可以通过“ovs-vsctl set controller br0 connection-mode=out-of-band”。

检查所有流表信息可以通过ovs-appctl bridge/dump-flows br0,这往往要比ovs-vsctl dump-flows br0打印出更多的信息来。ovs-dpctl dump-flows [dp]可以打印出datapath的流表信息。ovs-appctl dpif/dump-flows <br>可以打印出指定bridge上的datapath流。

OpenvSwitch可以实现访问控制功能,通过转发规则,可以实现简单的安全行为,包括通过、禁止等。现在OpenStack中的安全组是由iptables实现的,造成在节点上多了好几级的Bridge。理论上,以后都可以统一由OpenvSwitch来管理。

支持VLan(eth0为trunk口,创建vlan 1的tap0口):
ovs-vsctl add-br br0
ovs-vsctl add-port br0 eth0
ovs-vsctl add-port br0 tap0 tag=1

OpenvSwitch 在无法连接到控制器时候(fail mode)可以选择两种fail状态,一种是standalone,一种是secure状态。如果是配置了standalone(或者未设置fail mode)mode,在三次探测控制器连接不成功后,此时ovs-vswitchd将会接管转发逻辑(后台仍然尝试连接到控制器,一旦连接则退出fail状态),OpenvSwitch将作为一个正常的mac 学习的二层交换机。如果是配置了secure mode,则ovs-vswitchd将不会自动配置新的转发流表,OpenvSwitch将按照原先有的流表转发。可以通过下面命令进行管理。
ovs-vsctl get-fail-mode bridge
ovs-vsctl del-fail-mode bridge
ovs-vsctl set-fail-mode bridge standalone|secure

Friday, February 14, 2014

LSO, TSO, GSO和网络虚拟化

先来看三个缩写到底具体代表什么:Large Segment Offload (LSO),TCP segmentation offload (TSO), 以及Generic Segmentation Offload (GSO)。

首先来看LSO。我们知道计算机网络上传输的数据基本单位是离散的网包,既然是网包,就有大小限制,这个限制就是MTU(Maximum Transmission Unit)的大小,一般是1518字节。比如我们想发送很多数据出去,经过os协议栈的时候,会自动帮你拆分成几个不超过MTU的网包。然而,这个拆分是比较费计算资源的(比如很多时候还要计算分别的checksum),由CPU来做的话,往往会造成使用率过高。那可不可以把这些简单重复的操作offload到网卡上呢?

于是就有了LSO,在发送数据超过MTU限制的时候(太容易发生了),os只需要提交一次传输请求给网卡,网卡会自动的把数据拿过来,然后进行切,并封包发出,发出的网包不超过MTU限制。

反过来,当网卡收到很多碎片包的时候,也可以辅助自动组合成一段较大的数据,一次性提交给os处理。

很典型的,TCP协议中就考虑了分片存在的情况,往往是切分TCP的数据包,叫做TSO。而一般的情况,则称为LSO或者GSO。
对于其他不支持切片的协议例如UDP,则只能进行IP层上的切片。

这样做,一方面大大降低了CPU利用率,又增强了网卡等转发设备的feature,所以说有时候适当的进行offload很重要!

那么,这三个SO,跟虚拟化有什么联系呢?

在网络虚拟化中,一个最常见的技术就是隧道,这是实现overlay的通用手段。而实现隧道无非就两种思路,一种是把转发信息放到包头上,即封装/解封装(无论VXLAN还是STT都是这个思路);另外一种是由额外的数据库管理,转发时候进行查询。这两种思路各有利弊,这里不细说,如果我们采用封装/解封装的作法,那么可能原来网包并没有超过MTU限制,加上封装包头就超了,这就需要进行切片了。

所以VMware在其旗舰产品NVP中强调可以通过TSO来提高转发性能。

但是显然,前提是网卡能够支持,并且在os中配置打开。
可以通过ethtool -k eth0来查看当前状态
通过ethtool -K eth0 gso off/on 这样的命令来开关

Sunday, December 22, 2013

2014——SDN控制平面的关键一年

作为SDN整个技术体系中最复杂,也是最为核心的部分,控制器近些年已经逐渐成为业界追逐的首要目标。
从整个SDN的发展历程来看,跟Internet的发展历程惊人的相似,都是自底向上;都是从campus推广到业界;也都是利用事实标准发展起来。
最开始的三年(07-10),大家所关注的热点还是在于数据平面以及如何与控制平面的交互,包括制定各种南向标准,包括支持SDN的软件交换机项目(包括ovs,linc等)。这一阶段,热点还是集中在学术界居多,业界也在有限度的开始观察和尝试部署sdn。同时,学术界中提出了不少的控制器初步模型和解决方案(nox,pox,floodlight等)。
接下来的三年(11-13),数据平面已经被证实足够成熟,可以用了。那么,要充分发掘sdn的巨大潜力,一个好用的控制器就成为了关键。这一阶段,业界的投入明显加大,sdn的讨论重心明显从学术界到业界转移。这一点符合基本规律。毕竟业界的开发效率和产品质量还是有保障的,而且sdn的需求根本是要落在企业头上。这一阶段中,各个企业尝试了学术界的控制器方案,但很快就纷纷采取不同的路子。

Cisco,作为事实的网络老大,最为霸气,自己内部先后并行推出多个控制器项目,包括XNC、ONE PK、ACI等。而这些项目也延续了Cisco一贯的作风,名义上开放,实际上封装自身的私有协议和产品。
Vmware,作为虚拟届的一哥,借助收购Nirica,推出NSX产品方案,其内部的控制器可以通过ovsdb来管理底下的物理或虚拟交换机。
NEC,作为很早就开始研究sdn的公司,推出了PNC,成功部署在多个实际应用案例中。
Juniper,印度哥做事情,确实喜欢剑走偏锋,在很短时间内,虚晃一枪后默默搞了个OpenContrial,也是打着open的名义来推自身的产品。
显然的是,任何一家推出的控制器都不足以让大家无条件的接受,这个时候,开源社区再次展露了它独到的魅力。
由多家IT巨头共同发起了OpenDaylight项目,现在已经吸引了越来越多的vendor参加,借助开源的力量,发出了越来越大的声音。包括Cisco在内不少家企业也基于OpenDaylight项目开发自己的内部版本。

如果sdn后续的发展路程仍然保持与internet的惊人一致,那么,控制器就跟tcp/ip一样,将成为整个行业的生死之争。
而实际上,随着OpenDaylight项目第一个release的走近,关键的2014马上就要到来了,这一年,必将不那么平静。
或许,明年此时,整个sdn控制平面行业的重新布局将尘埃落定。