1.防火墙有什么用?
2.什么是IP地址欺骗?
3.Neutron 防火墙的相关说明?
1. 基础知识
1.1 防火墙(firewall)
![](http://www.aboutyun.com/data/attachment/forum/201512/23/152523bdixmssrwlmmdrwq.jpg)
与负载均衡器类似,按照其工作的网络层次,防火墙可以分为:
- 网络层防火墙(四层):网络层防火墙可视为一种 IP 封包过滤器,运作在底层的TCP/IP协议堆栈上。我们可以以枚举的方式,只允许符合特定规则的封包通过,其余的一概禁止穿越防火墙(病毒除外,防火墙不能防止病毒侵入)。这些规则通常可以经由管理员定义或修改,不过某些防火墙设备可能只能套用内置的规则。 我们也能以另一种较宽松的角度来制定防火墙规则,只要封包不符合任何一项“否定规则”就予以放行。操作系统及网络设备大多已内置防火墙功能。较新的防火墙能利用封包的多样属性来进行过滤,例如:来源 IP地址、来源端口号、目的 IP 地址或端口号、服务类型(如 HTTP 或是 FTP)。也能经由通信协议、TTL 值、来源的网域名称或网段...等属性来进行过滤。
- <ignore_js_op>
- 应用层防火墙(七层):应用层防火墙是在 TCP/IP 堆栈的“应用层”上运作,您使用浏览器时所产生的数据流或是使用 FTP 时的数据流都是属于这一层。应用层防火墙可以拦截进出某应用程序的所有封包,并且封锁其他的封包(通常是直接将封包丢弃)。理论上,这一类的防火墙可以完全阻绝外部的数据流进到受保护的机器里。
- <ignore_js_op>
- 主防火墙:如上面图1所示,主防火墙位于网络边界,控制进出网络的网络包。Neutron FWaas 是一种主防火墙,安装在网络节点上。
- 分布式防火墙:分布式防火墙位于内部网络节点上,比如终端计算机上,控制进出该计算机的网络包。Neutron 安全组(Security Group)是一种分布式防火墙,安装在计算节点上。
-
内部网络和外部网络之间的所有网络数据流都必须经过防火墙。防火墙适用于用户网络系统的边界,属于用户网络边界的安全保护设备。
-
只有符合安全策略的数据流才能通过防火墙。防火墙是一个类似于桥接或路由器的、多端口的(网络接口>=2)转发设备,它跨接于多个分离的物理网段之间,并在报文转发过程之中完成对报文的审查工作。
-
应用层防火墙具备更细致的防护能力。下一代防火墙具备应用层分析的能力,能够基于不同的应用特征,实现应用层的攻击过滤,在具备传统防火墙、IPS、防毒等功能的同时,还能够对用户和内容进行识别管理,兼具了应用层的高性能和智能联动两大特性,能够更好的针对应用层攻击进行防护。
- 规则:只有符合所制定的规则的网络包才能通过防火墙。
- 策略:规则的逻辑集合。
1.2 IP 地址欺骗 (IP Spoofing)
![](http://www.aboutyun.com/data/attachment/forum/201512/23/153146gaaj2unaaou6wk2v.jpg)
![](http://www.aboutyun.com/data/attachment/forum/201512/23/153243wl7lhh1l7u7xfnhh.jpg)
- 任何进入网络的数据包不能把网络内部的地址作为源地址。
- 任何进入网络的数据包必须把网络内部的地址作为目的地址。
- 任何离开网络的数据包必须把网络内部的地址作为源地址。
- 任何离开网络的数据包不能把网络内部的地址作为目的地址。
- 任何进入或离开网络的数据包不能把一个私有地址(Private Address)或在RFC1918中列出的属于保留空间(包括10.x.x.x/8、172.16.x.x/12 或192.168.x.x/16 和网络回送地址127.0.0.0/8.)的地址作为源或目的地址。
- 阻塞任意源路由包或任何设置了IP选项的包。
1.3 iptables bridge (在 linux 桥上做防火墙)
![](http://www.aboutyun.com/data/attachment/forum/201512/23/152524od7mnzt4lt4ixnb9.jpg)
(引用自 https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg)
bridge/netfilter 在内核(代码模块成为 br-nf,在这里 可以看到代码)被启用后,iptables 链的 Hook 函数也被注册到桥处理代码(bridging code)中。然而,这并不意味着它们不再被注册到标准的 IP协议栈代码中。对于被桥代码处理的网络包来说,br-nf 会判断 iptables 哪些链会在网络栈的什么位置被遍历。显然,它会保证同一个包不会被链处理两次,因此所有没有被桥代码处理的包会被标准的IP包处理方式来处理。但是,如果一个计算机既有 bridge 也有 router,那么进入该计算机的网络包,有些会被 bridge code 中 netfiler Hook 方法处理,有些会被 IP code 中的 netfilter hook 方法处理,这点需要在定义 iptables rules 时加以注意。
再来谈谈关键的 ”Bridging Decision“ 部分,其代码在(http://lxr.free-electrons.com/source/net/bridge/br_input.c#L226 rx_handler_result_t br_handle_frame(struct sk_buff **pskb))。它会基于目的MAC地址做出如下判断:
- bridge 网络帧,如果帧的目的 MAC 地址是在桥的另一侧的某个网络设备上。
- 泛洪该网络帧,如果帧的目的 MAC 对网桥是不认识的。
- 转到更高一层的三层IP协议栈代码处理,如果帧的目的地址是桥本身的或者它的某个端口的。
- 忽略它,如果帧的目的地址是位于它来自的桥的方向的同一侧。
-
Linux 内核支持 bridge (CONFIG_BRIDGE=m or CONFIG_BRIDGE=y).
-
Linux 内核支持 bridge/netfilter (CONFIG_BRIDGE_NETFILTER=y).
-
Linux 内核需要包含 Netfilter physdev match 支持 (CONFIG_IP_NF_MATCH_PHYSDEV=m or CONFIG_IP_NF_MATCH_PHYSDEV=y). 它在 2.6 版本的内核中开始作为标准模块。
-
你的 iptables 工具需要支持 physdev match,以及支持在一条规则中使用多个 '-m physdev'. iptables 从 1.3.6 版本开始支持。
-
你需要安装 bridge-utils 包。
1
2
|
sysctl
-
w net.bridge.bridge
-
nf
-
call
-
arptables
=
1
sysctl
-
w net.bridge.bridge
-
nf
-
call
-
iptables
=
1
|
参数 | 说明 |
-m physdev | 匹配桥端口的进入和出去的设备。这只在内核版本 2.5.44 以上有效 (This module matches on the bridge port input and output devices enslaved to a bridge device. This module is a part of the infrastructure that enables a transparent bridging IP firewall and is only useful for kernel versions above version 2.5.44.) |
--physdev-in [!] name | Name of a bridge port via which a packet is received。(收到数据包的 bridge port 的名字,只对 INPUT, FORWARD and PREROUTING 链有效)。可以添加 ”+“ 来做头部部分匹配。如果数据包不是从桥设备接收到的,则匹配不成功。 |
--physdev-out [!] name | Name of a bridge port via which a packet is going to be sent.(数据包要发到的 bridge port name,只对 FORWARD, OUTPUT and POSTROUTING 有效) |
[!] --physdev-is-in | Matches if the packet has entered through a bridge interface (在数据包是通过一个桥interface进入的时候会匹配成功) |
[!] --physdev-is-out | Matches if the packet will leave through a bridge interface. (在数据包将要通过一个桥的interface出去时匹配成功) |
[!] --physdev-is-bridged | Matches if the packet is being bridged and therefore is not being routed (在数据包是正被桥接的而不是正被路由时匹配成功。它只对 FORWARD and POSTROUTING 有效。) |
1
2
3
4
|
# brctl addbr br0
# brctl addif br0 eth0
# brctl addif br0 eth1
# ifconfig br0 netmask 255.255.255.0 192.168.32.1 up
|
![](http://www.aboutyun.com/data/attachment/forum/201512/23/152525guryuri88ciy5zr5.jpg)
- 作为内网和外网之间的路由器,这些数据包经过 br0 时会被 iptables 的 filter 表的 FORWARD 链处理;
- 作为可以访问外网的终端机,外网的数据包通过 eth1 直接进出该计算机,进来的包会被 iptables 的 filter 表的 INPUT 链过滤,出去的包被 OUTPUT 链过滤。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#允许本机通过访问外网,但是将进来的 udp,tcp 和 icmp 的网络包写日志(INPUT 规则的 physdev-in 肯定是 eth1 了)
iptables
-
A INPUT
-
p udp
-
m physdev
--physdev-in eth1 -j LOG
iptables
-
A INPUT
-
p tcp
-
m physdev
--physdev-in eth1 -j LOG
iptables
-
A INPUT
-
p icmp
-
m physdev
--physdev-in eth1 -j LOG
# 允许 ssh, smtp and http 到 br0(INPUT!)
iptables
-
A INPUT
-
p tcp
--dport 22 -m physdev --physdev-in eth1 -j ACCEPT
iptables
-
A INPUT
-
p tcp
--dport 25 -m physdev --physdev-in eth1 -j ACCEPT
iptables
-
A INPUT
-
p tcp
--dport 80 -m physdev --physdev-in eth1 -j ACCEPT
# 拒绝到 br0 的别的网络包
iptables
-
A INPUT
-
p tcp
--syn -m physdev --physdev-in eth1 -J REJECT
# 允许通过 tcp 端口 22(ssh),25 (smtp),80(http)到内网
iptables
-
A FORWARD
-
p tcp
--dport 22 -m physdev --physdev-in eth1 --physdev-out eth0 -j ACCEPT
iptables
-
A FORWARD
-
p tcp
--dport 25 -m physdev --physdev-in eth1 --physdev-out eth0 -j ACCEPT
iptables
-
A FORWARD
-
p tcp
--dport 80 -m physdev --physdev-in eth1 --physdev-out eth0 -j ACCEPT
# 禁止 tcp 端口 6667 (IRC)
iptables
-
A FORWARD
-
p tcp
--dport 6667 -m physdev --physdev-in eth1 -j REJECT
# 禁止其它连接到内网
iptables
-
A FORWARD
-
p tcp
--syn -m physdev --physdev-in eth1 --physdev-out eth0 -j REJECT
|
1.4 ipset 和在 iptables 规则中使用 ipset
(1). 首先 ipset 里面好多的命令是和 iptables 一样的,比如 -F ,-X, -A, -nL等等。
(2). 用户如果什么都没有添加的话,这个时候 ipset list 就会发现都是空的。
(3) 这个时候我们试着添加一个 set,如:ipset -N test_policy ipmap --network 192.168.100.1/24。该命令:
- test_policy:自定义set;
- ipmap:自定义set的类型,表示是 IP 地址; bitmap:ip,mac 表示是 IP 或者 MAC 地址。
- network 192.168.100.1/24:代表一个网段
- ipset -A test_policy 192.168.100.1
- ipset -A test_policy 192.168.100.2
- ipset -A test_policy 192.168.100.3
- ipset -A test_policy 192.168.100.4
01
02
03
04
05
06
07
08
09
10
11
12
|
root@compute
1
:
/
home
/
s
1
# ipset list
Name
:
test_policy
Type
:
bitmap
:
ip
Revision
:
2
Header
:
range
192.1
68.1
00.0
-192.1
68.1
00.2
55
Size
in
memory
:
160
References
:
0
Members
:
192.1
68.1
00.1
192.1
68.1
00.2
192.1
68.1
00.3
192.1
68.1
00.4
|
- src:也就是只是匹配的源地址,如果你需要匹配目的地址的话那么就写成 dst
以上部分资料来自 来源。更详细的信息,请 man ipset。
2. Neutron 防火墙和安全组概述
- Nova Security Group:Nova 项目提供给虚机的安全组。
- Neutron Security Group:Neutorn 项目提供给虚机的安全组。
- Neutron FWaas:基于 Neutron L3 Agent 实现的虚机防火墙的一个参考实现。
这三个组件底层都通过控制 Linux iptables 来控制进出虚机或者租户网络的网络包,但是在不同的位置使用不同的方法来实现不同的目的。三者之间的比较如下:
Nova Security Group | Neutron Security Group | Neutron FWaas | |
作用 | 控制进入虚机的网络包 | 控制进出虚机的网络包 | 控制进出租户网络的网络包。对不经过 Virutal Router 的网络包不起作用。 |
防火墙节点 | Nova 计算节点 | Nova 计算节点(L2 Agent 节点) | L3 Agent 节点上该 firewall 所在的租户的所有 router 的 namespace 中 |
IPV6 支持 | 支持。通过配置项 use_ipv6 来指定是否使用 IPV6,默认值为 false。 | 判断 /proc/sys/net/ipv6/conf/default/disable_ipv6 文件的内容。如果是 ”0“,表示支持 ipv6,否则不支持。如果支持的话,则同时往 iptables 和 ip6tables 中添加链和规则。 | 支持,同时往 iptables 和 ip6tables 中添加链和规则,但是似乎没有判断系统是否支持 IPV6. |
控制粒度 | 虚机 | Neutron port | 租户的所有 virtual router 的所有 Interface |
控制实施者 | Nova 计算节点的 IP 栈 | Nova 计算节点的 qbr 桥 | router 的 namespace 的 IP 栈 |
控制的网络流量方向 | ingress only (进入虚机的网络包) | ingress 和 egress (进出虚机的网络包) | ingress 和 egress (进出租户网络的网络包) |
匹配的数据项 | 协议、源 IP 网段、目的端口号 | 协议、端口、网段、方向 | 协议、源端口、目的端口、源 IP 网段、目的 IP、方向 |
匹配的结果行为 | 允许(allow) | 允许(allow) | 允许(allow)和拒绝(deny) |
使用 | 启动虚机时指定安全组,不指定的话使用默认安全组。虚机启动后,对所使用的安全组的变更会实时应用到虚机。可以向虚机添加和删除安全组。 | 动态(随时,启动虚机时和启动后)使用 neutron port-update 命令更新指定 port 的安全组。 | 动态(随时)应用到租户的所有虚拟路由器。 |
没有显式配置安全组时的默认行为 | 使用默认安全组(Default Security Group ),它允许使用同一个安全组的虚机访问该虚机 | 禁止该机器的网络访问,除了允许它访问 DHCP 服务 | 没有默认防火墙,防火墙没有默认规则。配置了 firewall 但是没添加规则的话,禁止所有网络进出数据网络。 |
允许的数目 | 多个,Security Group 数目(默认10)和 Security Group Rules 数目(默认100)受租户的 quota 限制 | 最多一个,不允许多个。 | |
CLI |
#列表,增加,删除 虚机的安全组
add-secgroup: Add a Security Group to a server
list-secgroup: List Security Group(s) of a server. remove-secgroup: Remove a Security Group from a server.
#操作安全组
secgroup-add-group-rule secgroup-add-rule secgroup-create secgroup-delete secgroup-delete-group-rule secgroup-delete-rule secgroup-list secgroup-list-rules secgroup-update
#启动虚机时指定安全组
nova boot --flavor FLAVOR_ID --image IMAGE_ID --security-groups SEC_GROUP
|
#操作安全组
neutron security-group-create
neutron security-group-list neutron security-group-rule-create neutron security-group-rule-list neutron security-group-rule-delete neutron security-group-delete
#创建 port 时指定安全组:
neutron port-create --security-group SECURITY_GROUP_ID1 --security-group SECURITY_GROUP_ID2 NETWORK_ID
#显示 port 的安全组
neutron port-list -c security_groups -c id -c mac_address -c fixed_ips -c device_id
#删除 port 的安全组
neutron port-update --no-security-groups PORT_ID
#使用带安全组的 port 启动虚机
nova boot vm1 --flavor 6 --nic port-id= |
#防火墙操作
firewall-create
firewall-delete firewall-list firewall-show firewall-update #防火墙策略操作 firewall-policy-create firewall-policy-delete firewall-policy-insert-rule firewall-policy-list firewall-policy-remove-rule firewall-policy-show firewall-policy-update #防火墙规则操作 firewall-rule-create firewall-rule-delete firewall-rule-list firewall-rule-show firewall-rule-update |
配置 | 见下文 | ||
底层实现 | 见下文 |