[连载型] Neutron 系列 (13): Neutron 是如何实现虚机防火墙的 【上】

1.防火墙有什么用?
2.什么是IP地址欺骗?
3.Neutron 防火墙的相关说明?






1. 基础知识

1.1 防火墙(firewall)

    防火墙是依照特定的规则来控制进出它的网络流量的网络安全系统。一个典型的场景是在一个受信任的内网和不受信任的外网比如 Internet 之间建立一个屏障。防火墙可以是电脑上运行的软件,也可以是独立的硬件设备。

 

<ignore_js_op>



与负载均衡器类似,按照其工作的网络层次,防火墙可以分为:

  • 网络层防火墙(四层):网络层防火墙可视为一种 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)

    正常情况下,二层数据帧的源IP 地址就是发出数据的机器的 IP 地址,对方计算机接收到以后,向该 IP 地址发出回复数据帧:

 

<ignore_js_op>

 

(该例子中,node1 发往 node2 的帧的 IP 地址就是 node1 的地址,因此 node2 能够通过  ARP 获取 node1 的 MAC,并将回复将发回到它)

 

如果源计算机的数据帧的源 IP 地址不是它自己的IP地址而是一个不存在的地址或者另外一台机器的地址,目的计算机接受到数据帧后,它就会一直不停的发出 ARP 广播,最终也无法获取到MAC地址,或者发送返回帧到另一台的计算机。这就是所谓的(源) IP 地址欺骗。

 

<ignore_js_op>

 

(该例子中,node1 将它发往 node2 的数据帧的源IP设置为 node3 的IP,导致 node2 的回复发到了node3)

 

如果大量的计算机使用另外一台计算机的 IP 作为源 IP 向很多的计算机发出 ping 命令,那么那一台计算机将会收到很多的 ping 回复。这将导致它的网络带宽被塞满而不能对外提供网络服务。



常见的防止IP地址欺骗的方法:

 

  • 任何进入网络的数据包不能把网络内部的地址作为源地址。
  • 任何进入网络的数据包必须把网络内部的地址作为目的地址。
  • 任何离开网络的数据包必须把网络内部的地址作为源地址。
  • 任何离开网络的数据包不能把网络内部的地址作为目的地址。
  • 任何进入或离开网络的数据包不能把一个私有地址(Private Address)或在RFC1918中列出的属于保留空间(包括10.x.x.x/8、172.16.x.x/12 或192.168.x.x/16 和网络回送地址127.0.0.0/8.)的地址作为源或目的地址。
  • 阻塞任意源路由包或任何设置了IP选项的包。

 

Neutron 安全组针对 IP 地址欺骗,特别设置了相应的防火墙规则。


1.3 iptables bridge (在 linux 桥上做防火墙)

    首先说说 bridge。这篇文章 详细解释了 bridge 的工作原理。简单地说,brige 是 linux 上的一个虚机(逻辑)设备,它依赖于从设备,并将从设备虚拟化为端口(port),从设备的 IP 及 MAC 都不再可用,且被设置为接收任何包,最终由 bridge 设备来决定数据包的去向:接收到本机、转发、丢弃。

 

   上一篇文章 介绍了 iptables 是如何处理三层网络包的。显然,普通的 Linux 内核 IP 栈代码和 netfilter 无法处理经过网桥的数据包,因为网桥是属于网络二层,对于 IP 栈来说是透明的。因此,Linux 内核和 iptables 增加了处理经过二层网桥的数据包的功能。下面是增加了网桥处理能力的 netfilter 的数据包处理过程:

 

<ignore_js_op>


(引用自 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协议栈代码处理,如果帧的目的地址是桥本身的或者它的某个端口的。
  • 忽略它,如果帧的目的地址是位于它来自的桥的方向的同一侧。

 

    对 (1)和 (2)来说,接下来该数据帧被 filter 的 FORWARD 链处理。对(3)来说,它会被 filter 的 INPUT 链处理。发生这种情况时,该 bridge 其实是被用作一个路由器(一个对比例子是现实世界中的带路由的交换机设备)。包含 IP 包的以太帧的目的 MAC 地址是桥的MAC地址,但是目的 IP 地址不是桥的IP地址。  这篇文章 ebtables/iptables interaction on a Linux-based bridge 详细分析了其处理过程。   

 

    要在 Linux bridge 上做防火墙(firewall packets as they are being bridged,或者说在 linux bridge 上应用 iptables 规则),必须满足以下条件:

 

  • 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 包。
    需要注意的,各个 Linux 发行版并不是都默认启用了 netfilter for bridge,比如 Ubuntu 默认启用了, 而 RedHat 默认没启用。Neutron 会执行下面的命令来启用它:

 

[AppleScript]  纯文本查看 复制代码
?
1
2
sysctl - w net.bridge.bridge - nf - call - arptables = 1
sysctl - w net.bridge.bridge - nf - call - iptables = 1



    从Linux 2.6 内核版本上,iptables 1.3.6 版本以后就能够过滤 Linux bridge 上的网络包了。它使用如下参数:

 

参数说明
-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 [!] nameName 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-inMatches if the packet has entered through a bridge interface (在数据包是通过一个桥interface进入的时候会匹配成功)
[!] --physdev-is-outMatches if the packet will leave through a bridge interface. (在数据包将要通过一个桥的interface出去时匹配成功)
[!] --physdev-is-bridgedMatches if the packet is being bridged and therefore is not being routed (在数据包是正被桥接的而不是正被路由时匹配成功。它只对 FORWARD and POSTROUTING 有效。)
举例:

 

在一台 linux 机器上创建 linux bridge br0,连接 eth0 和 eth1.其中 eth0 是内网端口,eth1和 eth2是外网端口。
[AppleScript]  纯文本查看 复制代码
?
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



<ignore_js_op>

 

实际上,在将 eth1 的 IP 设置给 br0 以后,该机器可以通过 br0/eth1 访问外网(这篇文章 详细地阐述了该原理),这样,该 linux 机器是同时作为一台路由器和一台终端机:

 

  • 作为内网和外网之间的路由器,这些数据包经过 br0 时会被 iptables 的 filter 表的 FORWARD 链处理;
  • 作为可以访问外网的终端机,外网的数据包通过 eth1 直接进出该计算机,进来的包会被 iptables 的 filter 表的 INPUT 链过滤,出去的包被 OUTPUT 链过滤。

 

可以创建如下的 iptables 规则来实现经过 br0 的网络包:

 

[AppleScript]  纯文本查看 复制代码
?
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

  在 iptables 中,如果去匹配多个 IP 地址的话,就会写入多条 iptables 的规则(这些 IP 都是无规律性的),当如果需要匹配几百甚至上千个 IP 地址的话,那么性能就会受到严重的影响。使用 ipset 的话,这种情况可以有很大的改善,其最主要是的在结构和规则的查找上面做了很大的改善。当出现上面的情况的时候,ipset 对性能就始终稳定在一个相对值上。根据提供的测试结果表明,当规则在300-1500之间的时候其对性能的影响基本是水平线。所以当你的防火墙规则过多的时候不妨试试看。

 

安装:http://ipset.netfilter.org/下载然后安装。

 

使用:

(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:代表一个网段

 

(4) 自定义 set 创建好了后就需要在上面添加一些IP了,如:

 

  • 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

 

(5)这个时候你ipset -nL就会看到该 set 以及它的 members:
[AppleScript]  纯文本查看 复制代码
?
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

 

(6)把它加到 iptables 链里面,比如说加到 FORWARD 链里面。比如要拒绝该 ipset 中计算机的访问,则添加规则 iptables -A FORWARD -m set --match-set test_policy src -j DROP。其中:

 

  • src:也就是只是匹配的源地址,如果你需要匹配目的地址的话那么就写成 dst


以上部分资料来自 来源。更详细的信息,请 man ipset。

2. Neutron 防火墙和安全组概述

    为了虚机和网络安全,Neutron 提供安全组和 FWaas(firewall-as-a-service)。两者的概念非常类似。一个安全组定义了哪些进入的网络流量能被转发给虚机。安全组包含一组防火墙策略,称为安全组规则(Security Group Rule)。可以定义n个安全组,每个安全组可以有n个规则,可以给每个实例绑定n个安全组。FWaas 则作用于虚拟路由器上,对进出租户网络的网络流量进行过滤。OpenStack 的相关的组件为:

 

  • Nova Security Group:Nova 项目提供给虚机的安全组。
  • Neutron Security Group:Neutorn 项目提供给虚机的安全组。
  • Neutron FWaas:基于 Neutron L3 Agent 实现的虚机防火墙的一个参考实现。


这三个组件底层都通过控制 Linux iptables 来控制进出虚机或者租户网络的网络包,但是在不同的位置使用不同的方法来实现不同的目的。三者之间的比较如下:

 Nova Security GroupNeutron Security GroupNeutron 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
配置见下文  
底层实现见下文

转载于:https://www.cnblogs.com/liuhongru/p/11098248.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值