分享

OpenStack中的防火墙简介

pig2 发表于 2014-2-25 23:23:16 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 0 19753
本帖最后由 pig2 于 2014-4-4 23:52 编辑

可以带着下面问题来阅读本文:

1.iptables的作用是什么?

2.iptables有几个内助链?

3.openstack中的floating-ips是根据什么规则实现的?

4.neutron-filter-top与openstack的关系?



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

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

1.jpg



例如: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, 往新链表中添加rules,iptables-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就是位于FOWARD和OUTPUT顶部的非包装链,用于在不同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,IPv6,Neutron为filter和nat两张表里的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


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

2.jpg


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

1)元数据,

当虚机通过169.254.169.254来访问metadata service时,布署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-destination172.16.1.122:8775

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

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


所以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代理会访问neutron metadata-agent,就和上面的串起来了,所以169.254.169.254应该是配置在metadata-agent节点的lo口上。

可能dhcp-agent和neutron-ns-metadata-proxy都会有自己的命名空间,如上,在L3层,通过iptables导通,DNAT时类似。在L2层,namespace是不起作用的。



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, 若是计算节点要允许虚机与网络节点以及其他计算节点上的虚机相连-A nova-compute-FORWARD -i br100 -j ACCEPT -A nova-compute-FORWARD -o br100 -j ACCEPT

3,支持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 ACCEPT4,所以每个虚机的链和规则如下图:

3.jpg


相应的, 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-api的ip是: 172.16.1.122)

-A nova-api-INPUT -d 172.16.1.122/32 -p tcp -m tcp --dport 8775 -j ACCEPT6, 浮动ip即外网ip设置在网络节点的外网网卡上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,如果想ping一个虚机的话,需设置一个安全组规则(nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0),它将产生如下防炎墙rules. 请记住,在此 nova-compute 主机上,针对每个实例必须有一个特定链;其内的规则只允许来自固定子集内的 IP 的流量。-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

既然neutron的OVSHybridIptablesFirewallDriver接管了计算节点上的防火墙,所以应该确保nova-compute的nova.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/中的内容。

4.jpg


关于上面的这个图,先要说一个很重要的说法,上图显示,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



看文章写心得,一起交流,共同进步


来自群组: openstack技术组

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条