情人节祝福语,根据 Linux 内核新特性的网关规划实践,华西村

依据 Linux 内核新特性的网关规划实践

咱们在不断盯梢 Linux 内核社区的新技能开展,并将之用于下一代外网网关的规划时发现,新特性存在不少缺点和 Bug,为此咱们向 Linux 内核社区回馈了 10 多个补丁,并融入到 Linux 内核 5.0 版别中,协助完善内核功用并进步稳定性。

-- 文旭

转自:UCloud http://blog.ucloud.cn/archives/4123

作者: 文旭

UCloud 外网网关是为了承载外网IP、负载均衡等产品的外网收支向流量,莫德里奇当时依据 Linux 内核的 OVS/GRE 地道/netns/iptabl石家庄地铁es 等完结,很好地支撑了现有事务。一同,咱们也在不断盯梢 Linux 内核社纪念碑谷攻略区的新技能开展,并将之用于下一代外网网关的规划。这些新特性可将体系功用和办理能力再提上一档,满意未来几年的需求。在计划规划研制进程中发现,新特性存在不少缺点和 B袁华ug,为此咱们向 Linux 内核社区回馈了 10 多个补丁,并融入到 Linux 内核 5.0 版别中,协助完善内核功用并进步李天佑稳定性。

当时业界的多租户外网网关许多都是依据 OpenFlow 的 OpenvSwitch(OVS)计划,可是跟着内核路由转发功用的不断完善,运用内核原生路由转发办法进行规划多租户外网网关体系成为一种或许。在这种办法下能有用的运用传统 iproute2 路由东西以及 iptables、nftables 等防火墙东西,而且跟着 SwitchDev 技能的鼓起,未来将网关体系迁移到 Linux Switch 上也成为一种或许。

现有 Linux 内核 3.x 的缺乏

当时广泛运用的内核版别为 3.x 系列,例如 CentOS 7 全系列规范支撑的内核为 3.10 版别,Fedora/Ubuntu 等 Linux 发行版也有很多运用。在 3.x 系列内核下存在着 IP 地道办理杂乱、租户阻隔功用损耗等问题。

  1. IP 地道办理杂乱
  2. Linux 内核创立 IP 地道设备来树立点对点的地道衔接,创立时需指定地道方针和地道密钥。因为宿主机之间两两树立衔接,面向宿主机的意图地址很多,这样就会导致网关节点上需求创立不计其数的地道设备,在大规模事务环境下,地道的办理将变得及其杂乱。
  3. 多租户阻隔导致的功用下降
  4. 公有云需求完结多租户阻隔以保证用户间的安全和隐私
  5. 因为 VPC 网络下不同租户的内网地址能够重合,导致路由也有重合的或许性,此刻需求经过很多的战略路由去阻隔租户的路由规矩,因为战略路由的链表特点,功用会跟着链表长度的添加而急剧下降。
  6. 因为防火墙和 NAT 的完结依据相同链式的 iptables,功用损耗相同可观。
  7. netns 带来功用开支
  8. 经过 netns 完结租户路由和防火墙规矩的阻隔,可是 netns 南京长江大桥会引进虚拟网卡和协议栈重入开支,使全体功用下降 20% 左右。

三项内核新技能

为了处理原有计划存在的困扰,咱们调研了很多职业干流计划和内核上游的新动向,发现 轻量级地道(Lightweight tunneling)(简称 lwtunnel)、 虚拟路由转发(Virtual Routing Forwarding)(简称 公公偏头痛mvVRF)以及 nftable & netfilter 流卸载(flow offload)三项内核新技能的特性,能够协助躲避原计划存在的缺点。

1、轻量级地道

Linux 内核在 4.3 版别中引进了轻量级地道,它供给了经过路由办法设置地道特点的办法,这样能够防止办理很多的地道设备。

创立地道设备时指定 external 形式,运用路由设置的轻量级地道经过 tun 设备发送报文。

# ip l add dev tun type gretap external

# ifconfig tun 1.1.1.7/24 up

# ip r r 2.2.2.11 via 1.1.1.11 dev tun encap ip id 1000 dst 172.168.0.1 key

2、虚拟路由转发

Linux 内核在 4.3 版别中引进了 VRF 的开始支撑,并在 4.8 版别构成齐备版别。虚拟路由转发能够将一台 Linux Box 的物理路由器当多台虚拟路由器运用,能很好的处理租户路由阻隔问题,防止直接运用战略路由。因而,能够将不同租户的网卡参加租户所属的虚拟路由器中来完结多租户的虚拟路由。


依据 Linux 内核新特性的网关规划实践


# ip link add user1 type vrf table1

# ip link add user1 type vrf table2

# ip l set user1 up

# ip l set user2 up

# ip l set dev eth1 master user1

# ip l set dev eth1 master user2

# ip r a default via 192.168.0.1 dev eth1 table 1 onlink

# ip r a default via 192.168.0.1 dev eth1 table 2 onlink

3、流卸载

nftables 是一种新的数据包分类结构,旨在代替现存的 {ip,ip6,arp,eb}_tables。在 nftables 中,大部分作业是在用户态完结的,内核只知道一些根本指令(过滤是用伪状态机完结的)。nftables 的一个高档特性便是映射,能够运用不同类型的数据并映射它们。例如,咱们能够映射 iif 设备到专用的规矩调集(之前创立的存储在一个链中)。因为是哈希映射的办法,能够完美的防止链式规矩跳转的功用开支。

Linux 内核在版别 4.16 引进了流卸载功用,它为 IP 转发供给了依据流的卸载功用。当一条新建衔接完结首回合原方向和反方向的报文时,完结路由,防火墙和 NA调查T 作业后,在处理反方向首报文的 forward 钩子,依据报文路由、NAT 等信息创立可卸载流到接纳网卡 ingress 钩子上。后续的报文能够在接纳 ingress 钩子上直接转发,不需求再进入 IP 栈处理。此外,将来流卸载还将支撑硬件卸载形式,这将极大进步体系转发功用。



# nft add table firewa火影忍者hentaill

#北京市委书记 nft add flowtable f fb1 { hook ingress priority 0 \; devices = { eth0, eth1 } \; }

# nft add chain f ftb-all {type filter hook forward priority 0 \; policy accept \; }

# nft add rule f ftb-all ct zone 1 ip protocol tcp flow offload @fb1

计划规划与优化实践

经过对上述三项新技能的研讨,咱们发现能够测验规划一套依据路由的办法,完结多租户层叠网络的外网网关。在计划规划进程中,咱们也碰到了比如 lwtunnel 和流卸载功用缺乏,以及 VRF 和流卸载不能一同有用的作业等问题。终究咱们都设法处理了,并针对这些内核的缺乏提交补丁给 Linux 内核社区。

1、lwtunnel 发送报文 tunnel_key 丢掉

问题描绘:咱们运用 lwtunnel 路由办法发送报文时,创立了一个 external 类型的 gretap 地道,咱们将指令设置了 id 为 1000,可是发送成功报文中没有 t山东临沂unnel_key 字段。

# ip l add dev tun type gretap

# ifconfig tun 1.1.1.7/24 up

# ip r r 2.2.2.11 via 1.1.1.11 dev tun encap ip id情人节祝福语,依据 Linux 内核新特性的网关规划实践,华西村 1000 dst 172.168.0.1

问题定位:咱们研讨 iproute2 代码,发现因为 TUNNEL_KEY 的标志并没有开放给用户态,所以 iproute2 东西并没有对 lwtunnel 路由设置 TUNNEL_KEY,导致报文不会创立 tunnel_key 字段。

提交补丁:咱们给内核和用户态 iproute2 别离提交补丁来处理这一问题:

  • iptunnel: make TUNNEL_FLAGS available in uapi
  • iproute: Set女性的逼 ip/ip6 lwtunnel f新年好简谱lags

提交补丁后,能够经过以下办法设置路由:

ip r 奇经八脉r 2.2.2.11 via 1.1.1.11 dev tun encap ip id 1000 dst 172.168.0.1 key

2、lwtunnel 对指定密钥的 IP 地道无效

问题发现:为了能有用阻隔租户路由,咱们给每个租户创立一个依据 tunnel_key 的 gretap 地道设备。如下图,创立一个 tunnel_key 1000 的 gretap 地道设备,把地道设备参加租户所属 VRF,地道设备能有用地接纳报文,但并不能发送报文。

# ip l add dev tun type gretap key 1000

# ifconfig tun 1.1.1.7/24 upstop

# ip r r 2.2.2.11 via情人节祝福语,依据 Linux 内核新特性的网关规划实践,华西村 1.1.1.11 dev tun encap ip id 1000 dst 172.168.0.1 key

问题定位:研讨内核发现,IP 地道在非外部形式下即便指定了轻量级地道路由,发送报文也没有运用它,导致报文路由过错被丢掉。

提交补丁:

  • ip_tunnel: Make none-tunnel-dst tunnel port work with lwtunnel

提交补丁后,在未指定 tunnel_dst 的非外部形式 IP 地道下,能运用轻量级地道路由进行发送报文。

3、外部 IP 地道 ARP 无法正常运转

问题描绘:街坊 IP 地道进行了 ARP 恳求,可是本端的 ARP 回应报文的地道头中并没带 tunnel_key 字段。

# ip l add dev tun type gretap external

# ifconfig tun 1.1.1.7/24 up

# ip r r 2.2.2.11 via 1.1.1.11 dev tun encap ip id 1000 dst 172.168.0.1 key

问题定位:研讨代码发现,地道收到了对端的 ARP 恳求,在发送报文 ARP 回复的时分会仿制恳求报文的地道信息,可是遗漏了一切 tun_flags。

提交补丁:

  • iptunnel: Set tun_flags in the iptunnel_metadata_reply from src

4、流卸载不能与 DNAT 有用作业

问题描绘:防火墙创立规矩从 eth0 收到意图地址 2.2.2.11 的报文,DNAT 为 10.0.0.7, 流卸载无法作业。

问题定位:剖析发现,客户端 1.1.1.7 -> 2.2.2.7 DNAT 到效劳器 10.0.0.7,第一个回复的反向报文(syc+ack)运用了错的意图地址获取反向路由。

daddr = ct->tuplehash[!dir].情人节祝福语,依据 Linux 内核新特性的网关规划实践,华西村tuple.dst.u3.ip

此刻 dir 为反方向,所以 daddr 获取为原方向的意图地址,这个值是 2.2.2.7,可是因为被 DNAT过,真实的路由不应该经过 2.2.2.7 去获取,而是应该依据 10.0.0.7 这个值去获取。

addr = ct->tuplehash[dir].tuple.src.u3.ip

提交补丁:

  • netfilter: nft_flow_offload: Fix reverse route lookup

5、流卸载不能与 VRF 有用作业

问题描绘:将网卡 eth0 和 eth1 参加 VFR 后,流卸载不起作用。

# ip a情人节祝福语,依据 Linux 内核新特性的网关规划实践,华西村ddr add dev eth0 1.1.1.1/24

# ip addr add dev eth1 1.1.1.1/24

# ip link add user1 type vrf table 1

# ip 情人节祝福语,依据 Linux 内核新特性的网关规划实践,华西村l set user1 up

# ip l set dev eth0 master user1

# ip l set dev eth1 master user1

问题定位:检查代码发现,原方向和反方向首报文进入协议仓库后 skb->dev 会设置为 vrf device user1,创立流卸载规矩的 iif 便是 user情人节祝福语,依据 Linux 内核新特性的网关规划实践,华西村1。可是卸载规矩下发在 eth0 和 eth1 的 ingress 钩子上,所以后续报文在 eth0 和 eth1 的 ingress 钩子上不能匹配流规矩规矩。

提交补丁:

  • netfilter: nft_flow_offload: fix interaction with vrf slave device

终究,咱们依据两个方向查找路由的成果,设置流卸载规矩的 iif 和 oif 信息来处理此问题。

6、VRF PREROUTING 钩子重入问题

问题描绘:装备网卡参加 VRF,防火墙 ingress 方向规矩为接纳意图地址 2.2.2.11 、TCP 意图端口 22 的报文,egress 方向规矩为丢掉 TCP 意图端口 22 的报文。出现异常成果: 收到意图地址 2.2.2.11 TCP 22 意图端口的报文却被丢掉。

问题定位:研讨发现网卡参加 VRF 后收到的报文会两次进入 PREROUTING 钩子,因为在进入 IP 栈时会进第一次PREROUTING 钩子,然后被 VRF 设备接收后会再次进入 PREROUTING 钩子。上述规矩第一次在 rule-1000-ingress chain中 dst nat 为 10.0.0.7,第2次因为报文被 DNAT 后会过错的进入 rule-1000-egress,导致报文被丢掉。

提交补丁:咱们给内核加了一个支撑判别网卡类型的 match 项目,让用户态防止可知的第2次无效重入,内核态和用户态 nftables 别离提交了如下的补丁:

  • netfilter: nft_meta: Add NFT_META_I/OIFKIND meta type
  • meta: add iifkind 脊髓复元汤and oifkind support

运用办法:

nft add rule firewall rules-all meta iifkind "vrf" counter accept

原型验证

终究,咱们成功地运用 lwtunnel、水真多VRF 和流卸载完结多租户外网网关的原型验证。验证进程如下:

1、首要创立原型环境

a. netns cl 模仿外网客户端,地址为 1.1.1.7,地道源地址 172.168.0.7,装备发送路由;

b. netns ns1 模仿租户 1,内网地址为 10.0.0.7,外网玉兰地址为 2.2.2.11,地道源地址 172.168.0.11 tunnel_key 1000,装备发送路由;

c. netns ns2 模仿租户 2,内网地址为 10.0.0.7,外网地址为 2.2.2.12,地道源地址 172.168.0.12 tunnel_key 2000,装备发送路由;

d. Host 模仿外网网关,地道源地址 172.168.0.1,创立租户 VRF user1 和 use2,创立租户 IP 地道 tun1 和 tun2,装备转发路由。

原型环境图如下:



2、创立防火墙规矩

a. 租户 1 入向答应 TCP 意图端口 22 和 ICMP 拜访,出向制止拜访外部 TCP 22 意图端口;

b. 租户 2 入向答应 TCP 端口 23 和 ICMP 拜访,出向制止拜访外部 TCP 23 意图端口;

c. 在租户 tun1 和 tun2 设备上支撑流卸载。

终究,客户端能够经过 2.2.2.11 成功拜访 user1 tcp 22 端口效劳,user1 不能拜访刘云天客户端 tcp 22 端口效劳;客户端能够经过 情人节祝福语,依据 Linux 内核新特性的网关规划实践,华西村2.2.2.12 成功拜访 user2 tcp 23 端口效劳,user1 不能拜访客户端 tcp 23 端口效劳。

在后续硬件功用完善以及网卡厂商支撑后,咱们还会做进一步的开发验证。

写在最终

以上是本项目触及的部分核心问题,这些补丁特性都能够在 Linux 内核 5.0 版别里获取。咱们把这期间为 Linux 内核社区奉献的补丁收拾成了 一份列表 ,期望能为开发者供给协助,读者能够点击阅读。

Linux 作为老练的开源套件,一向是云厂商运用的干流操作体系,但在技能的更新迭代进程中,一些新特性在实践应用上也会存在稳定性、兼容性等方面的问题。咱们在研讨运用上游技能的一同,也一向积极探索、丰厚开源技能功用,协助进步开源技能稳定性。并将产出继续回馈给社区,与社区一起构建一个昌盛的开源生态。

点击“了解更多”可拜访文内链接