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, 往新链表中添加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
OpenStack为我们准备好了上面的包装链与非包装链,再添加添加防火墙规则的时候,就不要再往内置链上添加了,而是直接添加到包装链与非包装链上,我们来看一下怎么用吧
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 ACCEPT3,支持dhcp(67)和dns(53)
-A nova-network-INPUT -i br100 -p udp -m udp --dport 67 -j ACCEPT
相应的, 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 ACCEPTNeutron防火墙的定义位于:
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/ 中的内容。
关于上面的这个图,先要说一个很重要的说法,上图显示,netfilter实际上既可以在L2层过滤,也可以在L3层过滤的。
所以在网桥中一般会有下面的参数,即要求iptables不对bridge的数据进行处理:
# cat >> /etc/sysctl.conf <
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 ACCEPTphysdev是二层的东西,三层的接口用-i来匹配,但二层的需要用physdev模块的physdev-in这个match了。
下列配置抓取所有经过本机的ICMP包:
iptables -t raw -A OUTPUT -p icmp -j TRACE调试信息记录在/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