本文介绍了OpenStack如何通过iptables,链和规则处理网络,这与其他系统非常相似。 但是首先,让我们看一下iptables的结构,作为本文中使用的技术的更新。
iptable结构
iptable是一个用户空间应用程序,它使系统管理员可以配置Linux内核防火墙提供的表。 iptable专门指IPv4。
要设置Linux防火墙,将使用规则,每个规则都指定一个数据包中要匹配的内容以及如何处理该数据包。 链是规则列表。
iptables的前身ipchains添加了规则链的概念。 iptables将其进一步扩展到表中。 因此,iptables的结构为:iptables>表>链>规则。
iptable有四个内置表:
- 过滤器表 :具有以下链的默认表:
- 输入到本地服务器的数据包。
- OUTPUT,用于本地生成并从本地服务器输出的数据包。
- FORWARD用于通过本地服务器路由的数据包。
- NAT表 (网络地址转换):
- PREROUTING:用于目标NAT,它将在路由之前更改数据包的IP地址。
- POSTROUTING:用于源NAT,它在路由后更改数据包的IP地址。
- 输出:防火墙上本地生成的数据包的NAT。
- 乱码表 :对于专用数据包更改:
- 展示
- 输出值
- 前锋
- 输入
- 后伸
- 原始表 :对于配置豁免:
- 展示
- 输出值
OpenStack中的iptable
在OpenStack中,您将主要在Cloud Compute-Nova模块中找到iptable链和规则,Cloud Compute-Nova模块是使用Python编写的使用许多外部库的云计算结构控制器(IaaS系统的主要部分)。 本文详细介绍了联网任务所需的nova-network FlatDHCPManager组件以及其他OpenStack组件。
启动时,OpenStack会定义一些OpenStack链。 这些链与Linux的内置链形成链结构。 启动时的另一项任务是为固定网络范围和元数据服务定义一些规则。 创建并使用网络后,nova-network会设置一些规则。 创建一个实例(也称为服务器和VM)后,nova-compute将创建一个特定于实例的链,并在该链下设置规则以确保实例的连接性。 关于浮动IP,OpenStack还使用一些规则使其工作。 此外,OpenStack的安全组及其规则由iptables规则体现。
OpenStack入门
OpenStack是开发人员和云计算技术人员的全球合作,为公共云和私有云提供开放标准的云操作系统,它是根据Apache许可条款发布的免费开源软件。 云服务提供商,企业和政府组织可以利用免费的,Apache许可的软件来构建可大规模扩展的云环境。
OpenStack当前包含六个核心软件项目:
- 云计算新手
- 云存储快速
- 图像服务概览(交付和注册)
- 身份服务重点
- 仪表盘-地平线
- 网络连接-量子
这些项目以及充满活力的技术提供商生态系统和未来的项目,为公共云和私有云提供了可插拔的框架和操作系统。
Nova项目中有10多个二进制文件,其中3个与VM连接有关:
- nova-api为VM提供元数据服务。
- nova-compute为虚拟机设置网络环境。
- nova-network为整个云生态系统设置网络环境,并执行IP分配,DHCP设置等任务。
Nova模块主要由一组Python守护程序组成,尽管它需要并与许多本机系统组件集成,以实现数据库,消息传递和虚拟化功能。 它使用特殊的元数据服务使虚拟机实例能够检索特定于实例的数据。 实例访问位于http://169.254.169.254的元数据服务。
元数据包括公共SSH密钥(在用户请求新实例时由密钥/对名称标识),用户数据(在API调用中作为user_data
参数传递或在Nova boot命令中通过--user_data
标志--user_data
)。 二进制nova-api实现元数据服务。
OpenStack是一组复杂的组件。 要了解有关系统以及其他组件之一如何工作的更多信息,请遵循“ 相关主题”部分中大量的OpenStack资源。
在介绍Nova中的规则和链之前,让我们看一下IP寻址模式。
Nova中的IP寻址
每个可用的新星网络都会为每个VM自动分配一个专用IP地址。 这些IP地址称为固定IP 。 您可以选择将公共IP地址分配给实例。 OpenStack使用术语浮动IP来指代可以动态添加到正在运行的虚拟实例中的IP地址(通常是公共IP)。
有多种策略可用于实现固定IP:
- 平板模式
- 固定DHCP模式
- VLAN DHCP模式
- 量子模式的Nova网络
平板模式
平面模式是最简单的联网模式。 每个实例从池中接收一个固定IP。 默认情况下,所有实例都连接到同一网桥(br100)。 网桥必须手动配置。 网络配置将在启动之前注入实例。 在此模式下,没有浮动IP功能。
固定DHCP模式
这与平面模式相似,因为所有实例都连接到同一网桥。 在这种模式下,Nova会进行更多配置。 它将尝试桥接到以太网设备(默认为eth0)。 它还将在作为网桥的dhcpserver上运行dnsmasq
。 实例通过执行dhcpdiscover
接收其固定IP。 此外,还提供了浮动IP功能。
VLAN DHCP模式
这是默认的联网模式,并且支持大多数功能。 对于多台计算机安装,它需要支持主机管理的VLAN标记的交换机。 在这种模式下,Nova将为每个项目创建VLAN和网桥(与租户相同)。 该项目获得了一系列只能从VLAN内部访问的专用IP。 为了使用户访问其项目中的实例,需要创建一个特殊的VPN实例(代号为“ cloudpipe”)。 Nova为用户生成证书和密钥以访问VPN并自动启动VPN。
量子模式的Nova网络
在这种模式下,DHCP服务器也可以自动启动,但是不支持浮动IP。 每个计算主机上都运行一个量子代理,以将虚拟实例连接到量子网络。 网络拓扑可能非常复杂。
在Nova中,安全组是网络访问规则(如防火墙策略)的命名集合。 这些访问规则指定应将哪些传入网络流量传递到组中的所有VM实例; 所有其他传入流量都将被丢弃。 用户可以随时修改组的规则。 新规则将针对所有正在运行的实例以及此后启动的实例自动执行。 安全组可以被视为安全配置文件或安全角色,例如“ webappserver”。
iptables的规则和链
如前所述,iptable是一个用户空间应用程序,它使系统管理员可以配置Linux内核防火墙提供的表以及它存储的链和规则。
前面也提到过,可以定义几个不同的表。 在OpenStack中使用的是过滤器和NAT。 每个表包含许多内置链,也可以包含用户定义的链。 每个链都是可以匹配一组数据包的规则列表。 每个规则都指定如何处理匹配的数据包-这称为target ,它可能是跳转到同一表中用户定义的链的过程。
从这里开始,我将讨论各种密钥链和规则。
nova-network启动时创建的链
图1. NetworkManager类连接其他类
如图1所示, NetworkManager
是一个大型类,它与许多其他类或模块连接。 在这些类或模块中, linux_net
是其中之一。 linux_net
包含一个IptablesManager
对象,该对象的__init__()
方法初始化OpenStack系统中定义的链。
图2.初始化链
Linux内核中的IPv4数据包过滤器规则表具有一些内置链,如前所述:PREROUTING,INPUT,FORWARD,OUTPUT和POSTROUTING。 通常,到达Linux主机的数据包进入PREROUTING链。 传递完后,内核会做出路由决策。 如果数据包用于Linux主机,则转到INPUT链,如果被接受,则转到目标进程。 如果该数据包不是用于Linux主机的,则转到FORWARD链,然后转到POSTROUTING链,然后离开主机。 由本地进程生成的数据包首先进入OUTPUT链,然后如果被接受,则进入POSTROUTING链。
除了这些内置链之外,OpenStack系统还会创建其他一些链接到链系统中的链。 OpenStack链包括两种类型:未包装链和包装链。
解开链的示例包括nova-filter-top和nova-postrouting-bottom。 nova-filter-top添加在FORWARD和OUTPUT链的顶部。 它的名称没有包装,因此它是由Nova的各个工人共享的。 它适用于需要位于FORWARD和OUTPUT链顶部的规则。 它在IPv4和IPv6表集中。
缠绕链的例子包括绿色链。 这些链的名称以进程名称作为后缀。 例如,nova-network创建nova-network-PREROUTING链。
对于IPv4和IPv6,包装了内置的INPUT,OUTPUT和FORWARD过滤器链,这意味着“真实的” INPUT链具有跳转到包装的INPUT链等的规则。此外,还有一个名为local的包装链从nova-filter-top跳到。
对于IPv4,以与内置过滤器链相同的方式包装内置的PREROUTING,OUTPUT和POSTROUTING NAT链。 另外,在POSTROUTING链之后应用了sNAT链和float-sNAT链。
新星网络启动的规则
图3显示了FlatDHCPManager启动过程的一部分。 前面已经描述了__init__()
方法,该方法构造一个IptableManager
对象以创建许多OpenStack链。 因此,让我们关注init_host()
。 init_host()
方法调用init_host()
的initialize()
方法,该方法调用linux_net
方法以在NAT表中设置一些iptables规则。
图3. FlatDHCPManager的启动过程
( 图3的放大图 。)
让我们看看这些规则。
元数据托管规则
在由创建规则init_host()
的linux_net
,一个规则是允许下的IP FLAGS.fixed_range
访问metadata_host(这是在这种情况下,192.168.1.90)。
-A nova-network-POSTROUTING -s 10.0.0.0/8 -d 192.168.1.90/32 -j ACCEPT
ensure_metadata_ip()
使用以下命令将169.254.169.254/32添加到lo
设备:
# ip addr add 169.254.169.254/32 scope link dev lo
然后metadata_forward()
添加dNAT规则以将数据包从169.254.169.254/32路由到meta_host:
-A nova-network-PREROUTING -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT
--to-destination 192.168.1.90:8775
如果nova-network和nova-api不在同一主机上运行,则必须在nova-network主机上定义meta_host,以指向nova-api主机。
访问dmz的规则
FLAGS.dmz_cidr
定义dmz(外围网络)CIDR(无类域间路由)列表。 默认情况下,它是一个空列表。 在这种情况下,它是10.128.0.0/24。 因此,规则是:
-A nova-network-POSTROUTING -s 10.0.0.0/8 -d 10.128.0.0/24 -j ACCEPT
虚拟机相互连接的规则
另一个规则是确保具有两个固定IP的VM可以相互通信:
-A nova-network-POSTROUTING -s 10.0.0.0/8 -d 10.0.0.0/8 -m conntrack ! --ctstate DNAT
-j ACCEPT
固定子网之外的访问规则
add_snat_rule()
方法将sNAT规则添加到NAT表的包装链sNAT中。 您可以在图3中看到ip_range
和FLAGS.routing_source_ip
。 ip_range
的值由FLAGS.fixed_range
定义。 在这种情况下,它是10.0.0.0/8。 默认情况下, FLAGS.routing_source_ip
是FLAGS.my_ip
,默认情况下是函数flags._get_my_ip()
。 在这种情况下, FLAGS.my_ip
为192.168.1.90。 之后,您将获得如下规则:
-A nova-network-snat -s 10.0.0.0/8 -j SNAT --to-source 192.168.1.90
为了使固定IP能够在外部访问,您必须创建一个网络,该网络是FLAGS.fixed_range
的子网。 这样,通过将默认网关指向nova-network计算机上的br100的一个IP,具有该子网IP的VM便可以访问外部网络。
每个网络的规则
要建立网络,nova-network在过滤器表中创建一些规则。 要在给定网络上触发nova-network的操作,请运行以下命令:
- 创建一个网络并设置主机:
# ./bin/nova-manage network create mynet 10.10.10.0/24
- 引导服务器:
nova boot --image a3fb743d-42df-49ba-b9c4-8042ebbd344e --flavor 1 myserver
执行以下命令后,您将具有以下规则:
- 允许转发的流量通过网桥,以便br100上的IP可以用作网关:
-A nova-network-FORWARD -i br100 -j ACCEPT -A nova-network-FORWARD -o br100 -j ACCEPT
- 允许DHCP和DNS流量进入本地
dnsmasq
进程:-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
注意:67是DHCP端口,53是DNS端口。
nova-compute主机规则
nova-compute模块还创建包裹的链。 在这些链上,它在过滤器表中创建一些规则。 让我们看看那些。
允许转发流量通过桥的规则
nova-compute主机上的这些规则允许VM与nova-network主机以及其他计算主机上的VM连接。
-A nova-compute-FORWARD -i br100 -j ACCEPT
-A nova-compute-FORWARD -o br100 -j ACCEPT
每个实例的链和规则
对于每个实例,它都会在过滤器表中创建一个链和一些规则(图4)。
图4.每个实例的链和规则
您可以看到:
- nova-compute为每个实例创建一个链。 在图4中,该链的名称为nova-compute-inst-1。
- 所有针对此实例的流量,无论是转发还是从本地进程生成,都进入该实例的特定链。
- 允许来自实例所在子网的IP的所有流量。
- 允许来自指定DHCP服务器的所有DHCP通信。
- 所有其他流量都被丢弃。
新API
开始时,nova-api在过滤器表中创建一个规则,以允许其他人访问nova-api服务。
-A nova-api-INPUT -d 192.168.1.90/32 -p tcp -m tcp --dport 8775 -j ACCEPT
浮动IP
要查看如何实现浮动IP,请首先将浮动IP与实例的固定IP相关联。 先前创建的实例的固定IP为10.10.1.0.2。
在默认池中创建浮动IP
要在默认池中创建浮动IP:
# nova-manage floating create --ip_range=192.168.1.232/30
要从该池分配浮动IP:
# Nova floating-ip-create
您的IP为192.168.1.233。 现在将其分配给ID为8f773639-c04f-4885-9349-ac7d6a799843的实例:
# nova add-floating-ip 8f773639-c04f-4885-9349-ac7d6a799843 192.168.1.233
将浮动IP绑定到公共接口
FLAGS.public_interface
用于绑定浮动IP。 运行nova add-floating-ip
命令后,可以看到在public_interface
下有以下浮动IP:
# ip addr list dev wlan0
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 08:11:96:75:91:54 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.90/16 brd 192.168.255.255 scope global wlan0
inet 192.168.1.233/32 scope global wlan0
inet6 fe80::a11:96ff:fe75:9154/64 scope link
valid_lft forever preferred_lft forever
NAT表中用于浮动IP的规则
实例在nova-network主机上获得浮动IP后,将应用以下规则:
-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.233
您会看到dNAT规则用于将浮动IP转换为实例的固定IP。 如果以浮动IP作为目标IP的数据包到达nova-network主机,则转换目标IP。 然后,您有一个sNAT规则,可将流量从实例的固定IP转换为浮动IP。 由于所有从VM到固定网络外部的流量都指向网关,而该网关是由nova-network的dnsmasq
进程设置的,因此使用此sNAT规则,可以将来自VM的流量成功屏蔽为来自浮动IP。 此外,您在打包的OUTPUT链中有一个dNAT规则,该规则允许nova-network上的本地进程访问具有浮动IP的VM。
使用浮动IP对VM进行Ping
要对具有浮动IP的VM进行ping操作,还需要更多规则。 请记住,在nova-compute主机上,每个实例都有特定的链。 其中的规则仅允许来自固定子网中IP的流量。 如果您对浮动IP进行ping操作,则这些规则将丢弃流量,因为ping数据包的源IP不在固定子网内。 显然,您需要添加一条规则以允许icmp通信。
要添加允许ping的规则,请使用OpenStack的安全组规则概念:
# nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0
之后,您会看到在该实例的特定链下又创建了一个规则:
-A nova-compute-inst-1 -p icmp -j ACCEPT
以相同的方式,您可以对具有浮动IP的VM启用SSH。
结论
iptables的规则被OpenStack网络广泛使用。 它的安全组和浮动IP概念只是使用iptables规则的开始。 深入研究后续资源,以了解有关使用OpenStack的IaaS环境的更多信息。
翻译自: https://www.ibm.com/developerworks/cloud/library/cl-openstack-network/index.html