Neutron印象8: OpenStack中的防火墙

来源:互联网 发布:天使与魔鬼 知乎 编辑:程序博客网 时间:2024/06/14 00:06

作者:张华  发表于:2012-4-10
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明

( http://blog.csdn.net/quqi99 )

iptables提供了全面的协议状态跟踪、数据包的应用层检查、速率限制、过滤策略。

iptables策略是由一组有序的规则建立的,它告诉内核该如何处理数据包。而规则应用于表中的一个链,链是一个规则集。

iptable 的概念从大到小是:iptables > tables > chains > rules

表,表描述了iptables的功用大类,共有4个内置表:filter,nat, mangle,raw

filter, 默认表,有三个重要的内置链:INPUT, OUTPUT, FORWARD

nat,网络地址转换表,三个链,PREROUTING (DNAT), POSTROUTING(SNAT),OUTPUT(用于本地包的NAT)

mangle, 用于包的修改, PREOUTING, OUTPUT, FORWARD, INPUT, POSTROUTING

raw, 用于配置免除, PREROUTING, OUTPUT

下图显示了这些内置链的关系:




例如:openstack中的floating-ips就是根据SNAT与DNAT规则实现的:

iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -o eth0 -j SNAT --to-source 9.123.25.13
iptables -t nat -A PREROUTING -d 9.123.25.13 -j DNAT --to-destination 172.16.1.2

http://blog.csdn.net/bill_lee_sh_cn/article/details/4401896


匹配,即条件,每个iptables规则都包含一级匹配以及一个目标,后者告诉ipatables对于符合规则的数据包应该采取什么动作。最重要的iptables匹配如下:

--source (-s ), 配置源IP地址或网络

--destination (-d), 匹配目标IP或网络

--protocol (-p), 匹配IP

--in-interface (-i), 流入接口(如,eth0)

--out-interface (-o), 输出接口

--state,匹配一组连接状态

--string, 匹配应用层数据字节序列

--comment,在内核内存中为一个规则关联多达256个节字的注释数据

目标,即动作,它们用于在数据包匹配一条规则时触发的一个动作。如下:

ACCEPT, 充许数据包通过

DROP,丢弃数据包,不响应报文

REJECT, 丢弃数据包,响应报文

LOG,记录数据包信息到syslog

RETURN,在调用链中继续处理数据包


除了内置链以外,还可以自定义链表,自定义链表的一般过程是:

1, 创建一个新链表,iptables-t filter -N newchain

2, 往新链表中添加rulesiptables-t filter -A newchain -s 192.168.75.129 -j DROP

3, 通过-j参数使用自定义的链,iptables-A INPUT -j newchain


Neutron使用了自定义链,分包装链与非包装链两类,区别在于是否对链表添加组件名重新包装

(这样定名的目的是为了不和系统中其他应用设置的防火墙规则混淆

1)包装链,链名需要通过组件名重新包装,如neutron-l3-agent组件定义的OUTPUT链叫neutron-l3-agent-OUTPUT,也意味着,Neutron不会用内置链OUTPUT,它必须跳转到对应的包装链(iptables-t filter OUTPUT -j neutron-l3-agent-OUTPUT

2)非包装链,链名没有用组件名包装,例如,neutron-filter-top就是位于FOWARDOUTPUT顶部的非包装链,用于在不同OpenStack组件共享的链,

neutron-filter-top链的内容是:

iptables -t filter -N neutron-filter-top

iptables -t filter -A FORWARD -jneutron-filter-top

iptables -t filter -A OUTPUT -j neutron-filter-top


再添加一个包装链neutron-l3-agent-local,接管非包装链neutron-filter-top

iptables -t filter -N neutron-l3-agent-local

iptables -t filter -A neutron-filter-top -jneutron-l3-agent-local

对于IPv4,IPv6Neutronfilternat两张表里的INPUT,FORWARD, OUTPUT三个内置链都定义了相应的包装链:

iptables -t filter -A INPUT -jneutron-l3-agent-INPUT

iptables -t filter -A FORWARD -jneutron-l3-agent-FORWARD

iptables -t filter -A OUTPUT -jneutron-l3-agent-OUTPUT

iptables -t nat -A INPUT -j neutron-l3-agent-INPUT

iptables -t nat -A FORWARD -jneutron-l3-agent-FORWARD

iptables -t nat -A OUTPUT -jneutron-l3-agent-OUTPUT


还定义了一个名为neutron-postrouting-bottom的非包装类,用于POSTOURING链之后:

iptables -t filter -N neutron-postrouting-bottom

iptables -t filter -A POSTROUTING -jneutron-postrouting-bottom

neutron-postrouting-bottom链后再定义两个snat(neutron-l3-agent-snat)的包装类:

iptables -t filter -N neutron-l3-agent-snat

iptables -t filter -A neutron-postrouting-bottom-j neutron-l3-agent-snat

iptables -t filter -N neutron-l3-agent-float-snat

iptables -t filter -A neutron-postrouting-bottom-j neutron-l3-agent-float-snat


最后定义sg-fallback包装链

iptables -t filter -N neutron-l3-agent-sg-fallback

iptables -t filter -Aneutron-l3-agent-sg-fallback -j DROP


所以这些初始化链的关系是:



OpenStack为我们准备好了上面的包装链与非包装链,再添加添加防火墙规则的时候,就不要再往内置链上添加了,而是直接添加到包装链与非包装链上,我们来看一下怎么用吧(这些内容来自永生的博客,写得真不错,做笔记到这里了,http://www.ibm.com/developerworks/cn/cloud/library/cl-openstack-network/index.html )

1)元数据,

VM首先访问l3-agent节点上的网关,而l3-agent节点(dhcp-agent节点也会干这事)会在9697端口上启动neutron-ns-metadata-proxy代理,下面的iptables rules保证包通过(注意: 如果存在命名空间这些规则就在命名空间里)。

-A neutron-l3-agent-PREROUTING -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 9697 

-A neutron-l3-agent-INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 9697 -j ACCEPT

然后neutron-ns-metadata-proxy代理会通过http协议访问neutron metadata-agent,所以169.254.169.254应该是配置在metadata-agent节点的lo口上。neutron metadata-agent的机器上应该将169.254.169.254 DNAT实际布置metadata service的机器metadata_host上,如172.16.1.122 。(所以当nova-api与metadata agent不在同一机器上时,在metadata agent机器上应该配置metadata_host配置)

ip addr add169.254.169.254/32 scope link dev lo

-A nova-network-PREROUTING -d 169.254.169.254/32 -p tcp -m tcp --dport80 -j DNAT --to-destination 172.16.1.122:8775

同时,在nova-api机器上要放行这类包。

-A nova-network-POSTROUTING -s 10.0.0.0/8 -d 172.16.1.122/32 -j ACCEPT




2)访问dmz规则,FLAGS.dmz_cidr定义了一个dmz列表,虚机应该能访问它,例本例的dmz列表为:10.0.128.0/24

    -Anova-network-POSTROUTING -s 10.0.0.0/8 -d 10.0.128.0/24 -j ACCEPT

3)两个虚机互通,从一个子网且不是DNAT的连接放行。

-Anova-network-POSTROUTING -s 10.0.0.0/8 -d 10.0.0.0/8 -m conntrack !--ctstate DNAT

-j ACCEPT

4)SNAT规则,例如从10.0.0.0/8虚机内网网络出去的包将源目址修改为外网IP9.123.1.12

-A nova-network-snat -s10.0.0.0/8 -j SNAT --to-source 9.123.1.122

5)创建网桥要做的事

1,网络节点,转发流量,充当网关

-A nova-network-FORWARD -i br100 -j ACCEPT-A nova-network-FORWARD -o br100 -j ACCEPT2, <span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">若是计算节点要允许虚机与网络节点以及其他计算节点上的虚机相连</span></span>-A nova-compute-FORWARD -i br100 -j ACCEPT -A nova-compute-FORWARD -o br100 -j ACCEPT

,支持dhcp(67)dns(53)

-A nova-network-INPUT -i br100 -p udp -m udp --dport 67 -j ACCEPT -A nova-network-INPUT -i br100 -p tcp -m tcp --dport 67 -j ACCEPT-A nova-network-INPUT -i br100 -p udp -m udp --dport 53 -j ACCEPT-A nova-network-INPUT -i br100 -p tcp -m tcp --dport 53 -j ACCEPT<span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">4,所以每个虚机的链和规则如下图:</span></span>



相应的, neutron l2 agent上的规则如下:

neutron l2 agent上的iptables设置,当它发现有新增tap设备时,就会从DB中取出和tap设备关联的port信息来设置vlan及security group(调用plugin的security_group_rules_for_devices方法获取port的安全组规则信息,规则信息里面已经考虑了允许dhcp, address_pair等)相关设置。每个port对应两条链(iX-XXXX和oX-XXXX), 下面只显示iX-XXXX的作为例子,oX-XXXX的依此类推:
(physdev是二层的东西,三层的接口用-i来匹配,但二层的需要用physdev模块的physdev-in这个match了。)
:neutron-l2-agent-sg-chain
-A neutron-l2-agent-FORWARD -m physdev --physdev-out tap1334c522-14 --physdev-is-bridged -j neutron-l2-agent-sg-chain

-A neutron-l2-agent-sg-chain -m physdev --physdev-out tap1334c522-14 --physdev-is-bridged -j neutron-l2-agent-i1334c522-1
-A neutron-l2-agent-sg-chain -j ACCEPT
-A neutron-l2-agent-sg-fallback -j DROP
-A neutron-l2-agent-i1334c522-1 -m state --state INVALID -j DROP
-A neutron-l2-agent-i1334c522-1 -m state --state RELATED,ESTABLISHED -j RETURN
-A neutron-l2-agent-i1334c522-1 -s 10.0.0.7/32 -j RETURN
-A neutron-l2-agent-i1334c522-1 -s 10.0.0.2/32 -p udp -m udp --sport 67 --dport 68 -j RETURN
-A neutron-l2-agent-i1334c522-1 -j neutron-l2-agent-sg-fallback


l3-agent 上FWaaS 相关设置

-A neutron-l3-agent-iv4XXXXXXXX-XXXX -m state --state INVALID -j DROP  
-A neutron-l3-agent-iv4XXXXXXXX-XXXX -m state --state ESTABLISHED,RELATED -j ACCEPT  
-A neutron-l3-agent-iv4XXXXXXXX-XXXX … -j ACCEPT/DROP

-A neutron-l3-agent-ov4XXXXXXXX-XXXX -m state --state INVALID -j DROP  
-A neutron-l3-agent-ov4XXXXXXXX-XXXX -m state --state ESTABLISHED,RELATED -j ACCEPT  
-A neutron-l3-agent-ov4XXXXXXXX-XXXX … -j ACCEPT/DROP

-A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-iv4XXXXXXXX-XXXX  
-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-ov4XXXXXXXX-XXXX  
-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-fwaas-default-policy  
-A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-fwaas-default-policy

5,nova-api一开始会在filter表内创建一个规则允许他人能访问它(如nova-apiip是: 172.16.1.122)

-A nova-api-INPUT -d 172.16.1.122/32 -p tcp -m tcp --dport 8775 -j ACCEPT6, <span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">浮动</span></span>ip<span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">即外网</span></span>ip<span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">设置在网络节点的外网网卡上</span></span>nova-manage floating create --ip_range=192.168.1.232/30Nova floating-ip-createnova add-floating-ip 8f773639-c04f-4885-9349-ac7d6a799843 192.168.1.233-A nova-network-OUTPUT -d 192.168.1.233/32 -j DNAT --to-destination 10.10.10.2-A nova-network-PREROUTING -d 192.168.1.233/32 -j DNAT --to-destination 10.10.10.2 -A nova-network-float-snat -s 10.10.10.2/32 -j SNAT --to-source 192.168.1.2336<span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">,如果想</span></span>ping<span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">一个虚机的话,需设置一个安全组规则(</span></span>nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0<span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">),它将产生如下防炎墙</span></span>rules. <span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">请记住,在此 </span></span>nova-compute <span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">主机上,针对每个实例必须有一个特定链;其内的规则只允许来自固定子集内的 </span></span>IP <span style="font-family:WenQuanYi Zen Hei Sharp,monospace;"><span lang="zh-CN">的流量。</span></span>-A nova-compute-inst-1 -p icmp -j ACCEPT


Neutron防火墙的定义位于:

vi/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini

[securitygroup]

firewall_driver =neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

既然neutronOVSHybridIptablesFirewallDriver接管了计算节点上的防火墙,所以应该确保nova-computenova.conf配置:

[DEFAULT]

firewall_driver =nova.virt.firewall.NoopFirewallDriver


查看Neutron中定义防火墙信息命令如下:

[hua@laptop devstack]$ ip netns list

qrouter-a4a3f113-4c61-4f74-adb6-ea3b6855a7e7

qdhcp-8779fa7c-d8ea-4827-a15d-3c7f56cb3ac0

[hua@laptop devstack]$ sudo ip netns execqrouter-a4a3f113-4c61-4f74-adb6-ea3b6855a7e7 iptables-save

[hua@laptop devstack]$ sudo ip netns execqrouter-a4a3f113-4c61-4f74-adb6-ea3b6855a7e7 iptables-restore


下面是这篇文章《利用raw表实现iptables调试》http://blog.youlingman.info/debugging-iptables-with-raw-table/ 中的内容。



关于上面的这个图,先要说一个很重要的说法,上图显示,netfilter实际上既可以在L2层过滤,也可以在L3层过滤的。

所以在网桥中一般会有下面的参数,即要求iptables不对bridge的数据进行处理:

# cat >> /etc/sysctl.conf <<EOF
  net.bridge.bridge-nf-call-ip6tables = 0
  net.bridge.bridge-nf-call-iptables = 0
  net.bridge.bridge-nf-call-arptables = 0
  EOF
# sysctl -p /etc/sysctl.conf

或者改用下面的方法解决:

 iptables -t raw -I PREROUTING -i BRIDGE -s x.x.x.x -j NOTRACK.

如果net.bridge.bridge-nf-call-iptables=1,也就意味着二层的网桥在转发包时也会被iptables的FORWARD规则所过滤,这样就会出现L3层的iptables rules去过滤L2的帧的问题(packets don't cross nat table twice, In the bridging process, you don’t know the outgoing interface so the previous rule doesn’t work. He needs the interface because he’s using MASQUERADE. In the routing process, the packets go to iptables but they never cross NAT tables because the packet already crossed the table in the bridging process.http://www.woitasen.com.ar/2011/09/confusion-using-iptables-nat-and-bridge/),所以涉及一些dnat, snat就不生效了,举个例子,具体表现在openstack中就是metadata服务不好使了。这个说法可参见:https://bugzilla.redhat.com/show_bug.cgi?id=512206

所以这样下面的规则也就失效了,所以http://blog.youlingman.info/debugging-iptables-with-raw-table/这个文章上的作者调试iptables的方法挺好,但实际上网络为什么不通的问题实质没有找准。

-A quantum-l3-agent-POSTROUTING ! -i qg-91757ded-c4 ! -o qg-91757ded-c4 -m conntrack ! --ctstate DNAT -j ACCEPT

还有一种等价于上面bridge-nf-call-iptables的做法,即iptables允许bridge上的数据直接转发
# iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT# service iptables save# service iptables restart

physdev是二层的东西,三层的接口用-i来匹配,但二层的需要用physdev模块的physdev-in这个match了


下列配置抓取所有经过本机的ICMP包:

iptables -t raw -A OUTPUT -p icmp -j TRACEiptables -t raw -A PREROUTING -p icmp -j TRACE
modprobe ipt_LOG

调试信息记录在/var/log/message文件中


其他:

打开一个端口:

iptables -I INPUT -i eth0 -p tcp --dport 16509 -j ACCEPT
iptables  -I OUTPUT -o eth0 -p tcp --sport 16509 -j ACCEPT 
sudo iptables-save > /tmp/ipt.save
cat /tmp/ipt.save | sudo iptables-restore
lsof -i:16509


2014-04-25添加:

如果使用neutron中的security group的话,配置如下:

1, /etc/nova/nova.conf:
libvirt_vif_driver = nova.virt.libvirt.vif.LibvirtHybridOVSBridgeDriver
linuxnet_interface_driver =nova.network.linux_net.LinuxOVSInterfaceDriver
security_group_api = neutron
firewall_driver = nova.virt.firewall.NoopFirewallDriver
2, /etc/neutron/ovs_neutron_plugin.ini:
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver


资料:

Linux网络路由表处理及钩子(Iptables and Ebtables) http://blog.chinaunix.net/uid-23741326-id-3573470.html


声明:

本博客欢迎转发,但请保留原作者信息!

新浪微博:@孔令贤HW

博客地址:http://blog.csdn.net/lynn_kong

内容系本人及本人团队学习、研究和总结,如有雷同,实属荣幸!


写在前面:

因为目前的时间和精力都有限,每天团队里有很多杂事需要处理,博客更新的速度明显慢了许多。好在公司为我们提供了宽松、自由的办公环境,访问外网更加方便,并且因为跟内网隔离,也因此少了不少打扰。记得我在之前的博客中有提到,我不知道我还能坚持多久,但我会尽力。一方面是我促使自己不断学习的过程,另一方面,也希望能给初学者一些帮助,高手,尽量绕行吧,我不敢班门弄斧,但如果能提供一些建议和指正,定当感激不尽!OpenStack目前的形式仍然是如火如荼,各种新的组件,各种培训,各种交流,各种教程,大家的技能水平都有了明显提升,我的教程,也许受众会越来越少,呵呵,这是好事,当大家都是高手的时候,也许交流会更加高效。另外,那些加我QQ或微博咨询问题的朋友,实在抱歉,我来不及一一回答,因为有些问题确实需要登录环境排错,有些问题Google之就会找到比我说出来更加合适的答案,希望你们见谅,也希望你们学会如何自己解决问题,早日修成正果!


作为OpenStack中的网络组件,Neutron提供了面向租户的,L2-L7层的各种服务。作为一种实现原型,Neutron中的linuxbridge和openvswitch(两种plugin),以及其他一些高级服务,都尽可能借用了Linux自身的一些特性,来实现一些复杂的网络模型。其中,iptables功不可没。

 

iptables模型

下面是一张iptables的模型图,关于iptables的知识不属于本文的讲解范畴,请自行google之。



l3-agent

Provides L3/NAT forwarding to provide external network access for VMs on tenant networks。l3 agent接收来自plugin(H版中默认已经使用router service plugin)的RPC消息,来构建3层功能模型,主要处理Router和Floatingip资源对象模型。

 

当系统中的namespace打开时,一个l3 agent可以同时处理多个router,但需要注意的是,一个l3 agent只能处理一个external net上的routers。l3 agent在处理router时,会初始化一些iptables的配置。具体步骤如下:

1、针对ipv4和ipv6分别都有对应的表,但只有ipv4中有nat表,也说明了目前neutron中高级服务不支持ipv6;

2、对filter表,增加一个链neutron-filter-top,规则:

  1. -A FORWARD -j neutron-filter-top  
  2. -A OUTPUT -j neutron-filter-top  

   增加一个链neutron-l3-agent-local,规则:

  1. -A neutron-filter-top -j neutron-l3-agent-local  

3、对系统中的内置链进行包装:

filter表中的三个链:INPUT, OUTPUT, FORWARD

nat表中的三个链:PREROUTING, OUTPUT, POSTROUTING

   将到达原链的数据包转发到包装链。

4、对ipv4的nat表,增加一个链neutron-postrouting-bottom,规则:

  1. -A POSTROUTING -j neutron-postrouting-bottom  

   增加一个链neutron-l3-agent-snat,规则:

  1. -A neutron-postrouting-bottom -j neutron-l3-agent-snat  

   增加一个链neutron-l3-agent-float-snat,规则:

  1. -A neutron-l3-agent-snat -j neutron-l3-agent-float-snat  

5、metadata proxy:

   在ipv4的filter表增加规则:

  1. -A neutron-l3-agent-INPUT -s 0.0.0.0/0 -d 127.0.0.1 -p tcp -m tcp --dport 9697 -j ACCEPT  

   在ipv4的nat表增加规则:

  1. -A neutron-l3-agent-PREROUTING -s 0.0.0.0/0 -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j REDIRECT --to-port 9697  

6、根据router中enable_snat属性,看是否有必要设置snat规则:

   首先将neutron-l3-agent-POSTROUTING和neutron-l3-agent-snat链的规则清空,恢复如下规则:

  1. -A neutron-l3-agent-snat -j neutron-l3-agent-float-snat  

   对IPv4的nat表设置:

  1. -A neutron-l3-agent-POSTROUTING ! -i qg-XXX ! -o qg-XXX -m conntrack ! --ctstate DNAT -j ACCEPT  
  2. -A neutron-l3-agent-snat -s XXX.XXX.XXX.XXX/XX -j SNAT --to-source XXX.XXX.XXX.XXX  

7、处理floatingip

    在IPv4的nat表中增加规则:

  1. -A neutron-l3-agent-PREROUTING -d <floatingip> -j DNAT --to <fixedip>  
  2. -A neutron-l3-agent-OUTPUT -d <floatingip> -j DNAT --to <fixedip>  
  3. -A neutron-l3-agent-float-snat -s <fixedip> -j SNAT --to <floatingip>  

8、应用规则

    iptables-save -c,获取当前所有iptables信息;

    iptables-restore -c <new_input>,应用最新的iptables配置;

 

初始化之后,l3 agent节点上的iptables配置如下:


security group

目前在neutron中,实现安全组功能的plugin有:Nicira NVP, Open vSwitch, Linux Bridge, NEC, and Ryu。其中,linux bridge和ovs都使用了iptables来实现底层的安全组模型。

 

创建一个port时,可以指定port所属的安全组(若不指定,则加入默认的安全组),此时,因为系统中某个安全组有成员变化,所以需要通知到各个节点,传递这样一个信息:一些安全组中的成员有变化,如果你有对这些安全组的引用,请更新对应的iptables规则。对于linux bridge和ovs来说,需要由neutron l2 agent处理更新请求。

 

首先,l2 agent初始化时,在加载IptablesFirewallDriver时就会初始化一些iptables的配置。

在v4和v6都会增加自定义链,很多链的命名规则与l3 agent节点相似,此外会新增:

neutron-l2-agent-sg-fallback,默认丢弃所有包;

其次,l2 agent发现有新增设备(port)时,会调用plugin的security_group_rules_for_devices方法获取port的安全组规则信息(规则信息里面已经考虑了允许dhcp, address_pair, ),然后重新配置本节点的iptables的filter表,主要关注INPUT和FORWARD链:

1、增加neutron-l2-agent-sg-chain链

2、每个port对应两条链(iX-XXXX和oX-XXXX),同时:

  1. -A neutron-l2-agent-FORWARD -m physdev --physdev-out <port-id> --physdev-is-bridged -j neutron-l2-agent-sg-chain  
  2. -A neutron-l2-agent-sg-chain -m physdev --physdev-out <port-id> --physdev-is-bridged -j iX-XXXX  
  3. -A neutron-l2-agent-FORWARD -m physdev --physdev-in <port-id> --physdev-is-bridged -j neutron-l2-agent-sg-chain  
  4. -A neutron-l2-agent-sg-chain -m physdev --physdev-in <port-id> --physdev-is-bridged -j oX-XXXX  
  5. -A neutron-l2-agent-INPUT -m physdev --physdev-in <port-id> --physdev-is-bridged -j oX-XXXX  
  6. -A iX-XXXX … -j RETURN  
  7. -A iX-XXXX -j neutron-l2-agent-sg-fallback  
  8. -A oX-XXXX … -j RETURN  
  9. -A oX-XXXX -j neutron-l2-agent-sg-fallback  
  10. -A neutron-l2-agent-sg-chain -j ACCEPT<span style="font-family:Arial,Helvetica,sans-serif; background-color:rgb(255,255,255)"> </span>  

引用《Iptables Security Group Implementation》中的截图:


firewall as a service

既然有了安全组的功能,为什么还要firewall呢?下面引用自fwaas-spec-v0.1:

  1. the security group rules lack the ability to express application characteristics which some of the next generation firewalls do. The Security Groups feature also does not support a workflow that allows providers to publish a collection of audited rules, and which a tenant can choose to apply in his network (say for security compliance reasons). In general, the Security Groups feature is Quantum port-centric which does not address the need to manage and leverage the richer security features provided by an edge Firewall service.  

firewall功能借用了l3 agent来实现,当前firewall有两种实现:Linux Iptables和varmour,这里仅关注Linux。创建firewall时,会对租户的所有router关联的iptables规则进行配置,firewall在接口和操作上同时支持IPv4和IPv6。

1、首先移除与firewall相关联的链;

2、在filter表增加链neutron-l3-agent-fwaas-default-policy及规则:

-A neutron-l3-agent-fwaas-default-policy -j DROP

3、操作filter表

增加链:neutron-l3-agent-iv4XXXXXXXX-XXXX(XXX为firewall的ID),和规则:

  1. -A neutron-l3-agent-iv4XXXXXXXX-XXXX -m state --state INVALID -j DROP  
  2. -A neutron-l3-agent-iv4XXXXXXXX-XXXX -m state --state ESTABLISHED,RELATED -j ACCEPT  
  3. -A neutron-l3-agent-iv4XXXXXXXX-XXXX … -j ACCEPT/DROP  

 增加链:neutron-l3-agent-ov4XXXXXXXX-XXXX,和规则:

  1. -A neutron-l3-agent-ov4XXXXXXXX-XXXX -m state --state INVALID -j DROP  
  2. -A neutron-l3-agent-ov4XXXXXXXX-XXXX -m state --state ESTABLISHED,RELATED -j ACCEPT  
  3. -A neutron-l3-agent-ov4XXXXXXXX-XXXX … -j ACCEPT/DROP  

4、设置其他规则

  1. -A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-iv4XXXXXXXX-XXXX  
  2. -A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-ov4XXXXXXXX-XXXX  
  3. -A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-fwaas-default-policy  
  4. -A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-fwaas-default-policy  

可见,目前firewall的实现是在每个租户所拥有的路由的边缘进行iptables配置,关注filter表的FORWARD链,后续的I版可能会推出Zone的概念。

 

总结

随着Neutron中的高级服务越来越多,也许每个节点(特别是网络节点)上的iptables规则会越来越复杂,定位一个网络问题的时间成本也会随之增加。但iptables作为Linux内核默认提供的功能,是可以满足一些简单场景的要求的,同时也对快速部署提供了可能性。当然,我想这是大部分网络厂商的机会,大家可以在自有产品之上提供自己的实现,借助OpenStack,来带动自身产品的销售,甚至可以提供Neutron没有的功能作为差异化特性,提升自己的竞争力。Linux bridge和openvSwitch(乃至后面的ML2)其实是提供一种参考实现,大家在实现自己Plugin或Driver的同时,其实是有大把的现成的代码可以拷贝的,:)




另一篇和防火墙相关的文章,OpenStack中的防火墙 ( by quqi99 ) http://blog.csdn.net/quqi99/article/details/7447233

      OpenStack的网络组件已经从Quantum更名为Neutron了。之前Quantum就有一个安全组的实现,它运行在每一个计算节点上,能够做到:

1)过滤进入到计算节点上虚机的流量

2)过滤从虚机出来的流量(nova-network并不能实现这一点)

3)过滤虚机之间的流量

        安全组的一般用法及实现框图如下:

$nova secgroup-create mygroup description

$nova secgroup-add-rule mygroup tcp 22 22 192.168.1.0/24

$nova boot --flavor 1 --image f16f1d2d-71d6-41b7-98a5-319f142d61f5--security_groups mygroup i1




         上述一个安全组由一系列的iptable rule组成,rule都是针对soure/dest ip及tcp port的,它不能像下一代的防火墙一样来表达应用特性像audited rules,也不能提供边缘防火墙的特性。所以在Neutron提供L4/L7层框架之际,也将推出了FWaaS服务(https://docs.google.com/document/d/1PJaKvsX2MzMRlLGfR0fBkrMraHYF0flvl0sqyZ704tA/edit?pli=1)

         在FWaaS中,tenant可以创建多个Firewall instances,而每一个virtual firewall instance和多个Firewall Policies关联,每个firewall policies由多个Firewall rules按序组成。不能直接应用一个rule,它必须先加入到一个policy中,因为它需要先审计。如下图:


         多层防火墙的应用场景如下图:





       Neutron L3 agent运行在gateway host上,它通过linux的namespace特性实例化多个neutron router,一个tenant能用多个router。见下图,router中的qr-XXX虚拟接口用于和tenant网络相连,qg-XXX虚拟接口用于跟外部网络相连,防火墙服务应该是过滤出入tenant网络的所有流量,所以firewallpolicy应该是应用在qr-XXX虚拟接口上(iptables出口rule中添加”-oqr-+” a即可,入口规则添加”-iqr-+”即可),如果对所以tenant网络都适用的话可以运用在qg-XXX接口上(havana的这一版本不会实现这一点,并且也不会实现Zones的概念,一组像上面的qr-XXX接口可以组成一个Zone,也不会检查address sppofing)。所以防火墙规则不仅应该像之前的安全组那个运用到计算节点上,也应该运用在相应的tenant'srouter的主机相应的namespace下(这即是所谓的边缘防火墙规则).

参考实现将会有4个chains,出和入各一个,ipv4和ipv6各一个。:




        所以相应地在FWaaSAgent中会有几个方法:

  1. create_firewall(apply_list, fireall),fireall是指一组上面的防火墙规则,apply_list指一些networknamespace

  2. update_firewall(apply_list, fireall)

  3. delete_firewall(apply_list, fireall)


      关于将上面的firewallinstance在哪里应用到VM应涉及到L4/L7服务框架了。以前Neutron只有一级插件结构(像OVS插件,像LinuxBridge插件),但现在引入了L4/L7层服务框架之后变成了两层,即实现了在一个核心插件(像OVS插件)下再能添加若干个服务(像LBaaS,像FWaaS)。可参见:https://docs.google.com/document/d/1iLzieNKxM7xip_lRidmalAhF_6-Yf1b_cePF4yeAnkQ/edit?pli=1,



       相关进阶的代码和BP:

1)Firewallas a Service (FWaaS) APIs and DB Model,https://review.openstack.org/29004

2)  FwaaS agent,https://blueprints.launchpad.net/quantum/+spec/quantum-fwaas-agent

3)  FwaaS Plugin, https://blueprints.launchpad.net/quantum/+spec/quantum-fwaas-plugin  4)  FwaaS ip tables driver https://blueprints.launchpad.net/quantum/+spec/quantum-fwaas-iptables-driver  

OpenStack neutron floatingips 与 iptables 深入分析


1. 简介neutron-l3-agent

OpenStack neutron-l3-agent 主要负责实现网络三层协议,为虚拟机完成SNAT,DNAT等地址的转换与伪装,提供安全弹性隔离的云网络环境,

下面详细叙述了OpenStack如何使用iptables链与规则完成复杂的neutron-l3-agent 的网络地址转换(NAT)功能,虚拟机floating ip与fixed ip绑定的工作原理。


2. iptables 简介

    2.1 iptables 链拓扑结构


  2.2 iptables 表结构

           Table filter: 

                Chain INPUT

                Chain FORWARD

                Chain OUTPUT

            filter 表用于一般的信息包过滤,它包含 INPUT 、 OUTPUT 和 FORWARD 链。

          Table nat:

                Chain PREROUTING

                Chain OUTPUT

                Chain POSTROUTING

           PREROUTING 链由指定信息包一到达防火墙就改变它们的规则所组成,而 POSTROUTING 链由指定正当信息包打算离开防火墙时改变它们的规则所组成。 


3. iptables command

# 添加一条规则到 INPUT 链的末尾,ACCEPT 来自源地址 10.9.1.141 的包

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# iptables -A INPUT -s 10.9.1.141  -j ACCEPT  

#允许protocol为TCP 、 UDP 、 ICMP 的包通过

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# iptables -A INPUT -p TCP, UDP  
# 从INPUT链中删除掉规则“Drop 到端口80的包”
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# iptables -D INPUT --dport 80 -j DROP  
# 将 INPUT 链的缺省规则指定为 DROP 
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# iptables -P INPUT DROP  

# 创建一个新链new-chain

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# iptables -N new-chain  

# 删除Table filter 中的所有规则

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# iptables -F  

# 列出INPUT链中的所有规则

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# iptables -L INPUT  

# 删除链
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# iptables -X  

4. 配置neutron-l3-agent 

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# neutron router-create router1  
  2. +--------------------------------------+---------+-----------------------+  
  3. | id                                   | name    | external_gateway_info |  
  4. +--------------------------------------+---------+-----------------------+  
  5. |c36b384e-b1f5-45e5-bb4f-c3ed32885142 | router1 | null |  
  6. +--------------------------------------+---------+-----------------------+  
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# vi /etc/neutron/l3_agent.ini  
  2. interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver   
  3. # OS is RHEL6.4, not support namespace  
  4. use_namespaces = False  
  5. # This is done by setting the specific router_id.  
  6. router_id = c36b384e-b1f5-45e5-bb4f-c3ed32885142  
  7. # Name of bridge used for external network traffic. This should be set to  
  8. # empty value for the linux bridge  
  9. external_network_bridge = br-eth1  
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]# service neutron-l3-agent restart  

启用转发功能

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@xianghui-10-9-1-141 ~]#  echo 1 > /proc/sys/net/ipv4/ip_forward  

5. neutron 利用iptables 实现 NAT 原理

iptables 中neutron l3 agent自定义的链:
neutron-l3-agent-PREROUTING
neutron-l3-agent-OUTPUT

neutron-l3-agent-POSTROUTING




一.iptables简介

1.iptables数据包处理流程

tables_traverse

以本机为目的的包,由上至下,走左边的路
本机产生的包,从local process开始走左边的路
本机转发的包,由上至下走右边的路

简化流程如下:

 

2.iptables表结构

在neutron中主要用到filter表和nat表
filter表:
Chain INPUT
Chain FORWARD
Chain OUTPUT
filter表用于信息包过滤,它包含INPUT、OUTPUT和FORWARD 链。

nat表:
Chain PREROUTING
Chain OUTPUT
Chain POSTROUTING
nat表用于网络地址转换,PREROUTING链由指定信息包一到达防火墙就改变它们的规则所组成,而 POSTROUTING 链由指定正当信息包打算离开防火墙时改变它们的规则所组成。

More:
Traversing of tables and chains
Linux Firewalls Using iptables

二.l3 agent消息处理

复制代码
_rpc_loop  ---  _process_router            ---  _router_added                                            ---  process_router                                                                            ---  _router_removed                      ---  _process_router_delete     ---  _router_removed
复制代码
 

在上面几个方法中,会涉及到iptables的处理。

三.iptables_manager初始化

iptables_manager的初始化是在class IptablesManager中完成的,它对iptables的链进行了包装。

源码目录:neutron/neutron/agent/linux/iptables_manager.py

主要操作:

新建一个neutron-filter-top链,这个是没有包装的,加在原生的FORWARD和OUTPUT链上。
对filter表的INPUT,OUTPUT,FORWARD链进行包装,将到达原链的数据包转发到包装链,还增加一个包装的local链。
对于nat表,PREROUTING,OUTPUT,POSTROUTING链进行包装,另外在POSTROUTING链之后加了snat链。

代码分析:

对于l3 agent,binary_name是neturon-l3-agent。

filter表的操作:
增加一个链neutron-filter-top,增加规则:
-A FORWARD -j neutron-filter-top
-A OUTPUT -j neutron-filter-top

增加一个包装链neutron-l3-agent-local,增加规则:
-A neutron-filter-top -j neutron-l3-agent-local

复制代码
        # Add a neutron-filter-top chain. It's intended to be shared        # among the various nova components. It sits at the very top        # of FORWARD and OUTPUT.        for tables in [self.ipv4, self.ipv6]:            tables['filter'].add_chain('neutron-filter-top', wrap=False)            tables['filter'].add_rule('FORWARD', '-j neutron-filter-top',                                      wrap=False, top=True)            tables['filter'].add_rule('OUTPUT', '-j neutron-filter-top',                                      wrap=False, top=True)            tables['filter'].add_chain('local')            tables['filter'].add_rule('neutron-filter-top', '-j $local',                                      wrap=False)
复制代码
 

包装IPv4和IPv6 filter表的INPUT,OUTPUT,FORWARD链,以及IPv4 nat表的PREROUTING,OUTPUT,POSTROUTING链。

将到达原链的数据包转发到包装链:

复制代码
        # Wrap the built-in chains        builtin_chains = {4: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']},                          6: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}}        if not state_less:            self.ipv4.update(                {'nat': IptablesTable(binary_name=self.wrap_name)})            builtin_chains[4].update({'nat': ['PREROUTING',                                      'OUTPUT', 'POSTROUTING']})        for ip_version in builtin_chains:            if ip_version == 4:                tables = self.ipv4            elif ip_version == 6:                tables = self.ipv6            for table, chains in builtin_chains[ip_version].iteritems():                for chain in chains:                    tables[table].add_chain(chain)                    tables[table].add_rule(chain, '-j $%s' %                                           (chain), wrap=False)
复制代码
 

包装链neutron-l3-agent-INPUT,neutron-l3-agent-OUTPUT,neutron-l3-agent-FORWARD,添加规则:
-A INPUT -j neutron-l3-agent-INPUT
-A OUTPUT -j neutron-l3-agent-OUTPUT
-A FORWARD -j neutron-l3-agent-FORWARD

nat表的操作:
(承上面的代码)
包装链neutron-l3-agent-PREROUTING,neutron-l3-agent-OUTPUT,neutron-l3-agent-POSTROUTING,添加规则:
-A PREROUTING -j neutron-l3-agent-PREROUTING
-A OUTPUT -j neutron-l3-agent-OUTPUT
-A POSTROUTING -j neutron-l3-agent-POSTROUTING

nat表中添加neutron-postrouting-bottom链,增加规则:
-A POSTROUTING -j neutron-postrouting-bottom

nat表中添加包装链neutron-l3-agent-snat,增加规则:
-A neutron-postrouting-bottom -j neutron-l3-agent-snat

nat表中添加包装链neutron-l3-agent-float-snat,增加规则:
-A neutron-l3-agent-snat -j neutron-l3-agent-float-snat

代码如下:

复制代码
        if not state_less:            # Add a neutron-postrouting-bottom chain. It's intended to be            # shared among the various nova components. We set it as the last            # chain of POSTROUTING chain.            self.ipv4['nat'].add_chain('neutron-postrouting-bottom',                                       wrap=False)            self.ipv4['nat'].add_rule('POSTROUTING',                                      '-j neutron-postrouting-bottom',                                      wrap=False)            # We add a snat chain to the shared neutron-postrouting-bottom            # chain so that it's applied last.            self.ipv4['nat'].add_chain('snat')            self.ipv4['nat'].add_rule('neutron-postrouting-bottom',                                      '-j $snat', wrap=False)            # And then we add a float-snat chain and jump to first thing in            # the snat chain.            self.ipv4['nat'].add_chain('float-snat')            self.ipv4['nat'].add_rule('snat', '-j $float-snat')
复制代码
 

四.l3 agent代码中关于iptables的处理

1._router_added

_router_added方法,创建和metadata相关的iptables规则:

复制代码
    def _router_added(self, router_id, router):        ri = RouterInfo(router_id, self.root_helper,                        self.conf.use_namespaces, router)        self.router_info[router_id] = ri        if self.conf.use_namespaces:            self._create_router_namespace(ri)        for c, r in self.metadata_filter_rules():            ri.iptables_manager.ipv4['filter'].add_rule(c, r)        for c, r in self.metadata_nat_rules():            ri.iptables_manager.ipv4['nat'].add_rule(c, r)        ri.iptables_manager.apply()        super(L3NATAgent, self).process_router_add(ri)        if self.conf.enable_metadata_proxy:            self._spawn_metadata_proxy(ri.router_id, ri.ns_name)
复制代码
 

1.metadata_filter_rules方法中,如果enable_metadata_proxy为True,增加规则

复制代码
    def metadata_filter_rules(self):        rules = []        if self.conf.enable_metadata_proxy:            rules.append(('INPUT', '-s 0.0.0.0/0 -d 127.0.0.1 '                          '-p tcp -m tcp --dport %s '                          '-j ACCEPT' % self.conf.metadata_port))        return rules
复制代码
 

然后在filter表中增加这条规则,接受所有从外面进来到达metadata_port端口的数据包:
-A neutron-l3-agent-INPUT -s 0.0.0.0/0 -d 127.0.0.1 -p tcp -m tcp –dport 9697 -j ACCEPT

2.metadata_nat_rules方法,如果enable_metadata_proxy为True,增加规则

复制代码
    def metadata_nat_rules(self):        rules = []        if self.conf.enable_metadata_proxy:            rules.append(('PREROUTING', '-s 0.0.0.0/0 -d 169.254.169.254/32 '                          '-p tcp -m tcp --dport 80 -j REDIRECT '                          '--to-port %s' % self.conf.metadata_port))        return rules
复制代码
 

然后在nat表中增加这条规则做DNAT转换,在route之前,将虚拟机访问169.254.169.254端口80的数据包重定向到metadat_port端口:
-A neutron-l3-agent-PREROUTING -s 0.0.0.0/0 -d 169.254.169.254/32 -p tcp -m tcp –dport 80 -j REDIRECT –to-port 9697

再调用iptables_manager.apply()方法,应用规则:
iptables-save -c ,获取当前所有iptables信息;
iptables-restore -c ,应用最新的iptables配置;

2.process_router

process_router方法:

1.perform_snat_action,为external gateway处理SNAT规则

复制代码
    def _handle_router_snat_rules(self, ri, ex_gw_port, internal_cidrs,                                  interface_name, action):        # Remove all the rules        # This is safe because if use_namespaces is set as False        # then the agent can only configure one router, otherwise        # each router's SNAT rules will be in their own namespace        ri.iptables_manager.ipv4['nat'].empty_chain('POSTROUTING')        ri.iptables_manager.ipv4['nat'].empty_chain('snat')        # Add back the jump to float-snat        ri.iptables_manager.ipv4['nat'].add_rule('snat', '-j $float-snat')        # And add them back if the action if add_rules        if action == 'add_rules' and ex_gw_port:            # ex_gw_port should not be None in this case            # NAT rules are added only if ex_gw_port has an IPv4 address            for ip_addr in ex_gw_port['fixed_ips']:                ex_gw_ip = ip_addr['ip_address']                if netaddr.IPAddress(ex_gw_ip).version == 4:                    rules = self.external_gateway_nat_rules(ex_gw_ip,                                                            internal_cidrs,                                                            interface_name)                    for rule in rules:                        ri.iptables_manager.ipv4['nat'].add_rule(*rule)                    break        ri.iptables_manager.apply()
复制代码
 

先清空nat表的neutron-l3-agent-POSTROUTING链和neutron-l3-agent-snat链;

再在nat表的neutron-l3-agent-snat链添加规则:

-A neutron-l3-agent-snat -j neutron-l3-agent-float-snat

然后对应add_rules操作,则处理external_gateway_nat_rules,处理完后在nat表中添加规则:

复制代码
    def external_gateway_nat_rules(self, ex_gw_ip, internal_cidrs,                                   interface_name):        rules = [('POSTROUTING', '! -i %(interface_name)s '                  '! -o %(interface_name)s -m conntrack ! '                  '--ctstate DNAT -j ACCEPT' %                  {'interface_name': interface_name})]        for cidr in internal_cidrs:            rules.extend(self.internal_network_nat_rules(ex_gw_ip, cidr))        return rules
复制代码
 

规则命令如下:

-A neutron-l3-agent-POSTROUTING ! -i qg-XXX ! -o qg-XXX -m conntrack ! –ctstate DNAT -j ACCEPT

这条命令的意思是除了出口和入口都为qg-XXX,(qg即是router上的外部网关接口)匹配除了DNAT之外的其他状态。

然后处理internal_network_nat_rules:

    def internal_network_nat_rules(self, ex_gw_ip, internal_cidr):        rules = [('snat', '-s %s -j SNAT --to-source %s' %                 (internal_cidr, ex_gw_ip))]        return rules
 

规则命令如下:

-A neutron-l3-agent-snat -s internal_cidr -j SNAT –to-source ex_gw_ip

2.process_router_floating_ip_nat_rules方法,处理floating ip,作SNAT/DNAT转换。

复制代码
    def process_router_floating_ip_nat_rules(self, ri):        """Configure NAT rules for the router's floating IPs.        Configures iptables rules for the floating ips of the given router        """        # Clear out all iptables rules for floating ips        ri.iptables_manager.ipv4['nat'].clear_rules_by_tag('floating_ip')        # Loop once to ensure that floating ips are configured.        for fip in ri.router.get(l3_constants.FLOATINGIP_KEY, []):            # Rebuild iptables rules for the floating ip.            fixed = fip['fixed_ip_address']            fip_ip = fip['floating_ip_address']            for chain, rule in self.floating_forward_rules(fip_ip, fixed):                ri.iptables_manager.ipv4['nat'].add_rule(chain, rule,                                                         tag='floating_ip')        ri.iptables_manager.apply()   def floating_forward_rules(self, floating_ip, fixed_ip):        return [('PREROUTING', '-d %s -j DNAT --to %s' %                 (floating_ip, fixed_ip)),                ('OUTPUT', '-d %s -j DNAT --to %s' %                 (floating_ip, fixed_ip)),                ('float-snat', '-s %s -j SNAT --to %s' %                 (fixed_ip, floating_ip))]
复制代码
 

先清理nat表所有的floationg ip规则;然后floating_forward_rules方法,在nat表中处理floating ip和fixed ip的NAT转换:

 

具体规则如下:
-A neutron-l3-agent-PREROUTING -d floating_ip -j DNAT –to fixed_ip
-A neutron-l3-agent-OUTPUT -d floating_ip -j DNAT –to fixed_ip
-A neutron-l3-agent-float-snat -s fixed_ip -j SNAT –to floating_ip

3._router_removed

_router_removed方法,删除和metadata相关的规则:

复制代码
    def _router_removed(self, router_id):        ri = self.router_info.get(router_id)        if ri is None:            LOG.warn(_("Info for router %s were not found. "                       "Skipping router removal"), router_id)            return        ri.router['gw_port'] = None        ri.router[l3_constants.INTERFACE_KEY] = []        ri.router[l3_constants.FLOATINGIP_KEY] = []        self.process_router(ri)        for c, r in self.metadata_filter_rules():            ri.iptables_manager.ipv4['filter'].remove_rule(c, r)        for c, r in self.metadata_nat_rules():            ri.iptables_manager.ipv4['nat'].remove_rule(c, r)        ri.iptables_manager.apply()        if self.conf.enable_metadata_proxy:            self._destroy_metadata_proxy(ri.router_id, ri.ns_name)        del self.router_info[router_id]        self._destroy_router_namespace(ri.ns_name)
复制代码

 

五.总结

l3 agent初始化完成后,iptables处理流程如下:

感谢春祥提供图片!

Reference:
Neutron中的iptables

本文转自http://squarey.me/cloud-virtualization/iptables_usage_in_l3_agent.html



0 0
原创粉丝点击