溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

基于Linux內(nèi)核新特性的網(wǎng)關(guān)設(shè)計方法是什么

發(fā)布時間:2022-01-07 16:24:31 來源:億速云 閱讀:180 作者:iii 欄目:系統(tǒng)運維

今天小編給大家分享一下基于Linux內(nèi)核新特性的網(wǎng)關(guān)設(shè)計方法是什么的相關(guān)知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

UCloud 外網(wǎng)網(wǎng)關(guān)是為了承載外網(wǎng)IP、負載均衡等產(chǎn)品的外網(wǎng)出入向流量,當前基于 Linux 內(nèi)核的 OVS/GRE  隧道/netns/iptables 等實現(xiàn),很好地支撐了現(xiàn)有業(yè)務(wù)。同時,我們也在不斷跟蹤 Linux  內(nèi)核社區(qū)的新技術(shù)發(fā)展,并將之用于下一代外網(wǎng)網(wǎng)關(guān)的設(shè)計。這些新特性可將系統(tǒng)性能和管理能力再提上一檔,滿足未來幾年的需求。在方案設(shè)計研發(fā)過程中發(fā)現(xiàn),新特性存在不少缺陷和  Bug,為此我們向 Linux 內(nèi)核社區(qū)回饋了 10 多個補丁,并融入到 Linux 內(nèi)核 5.0 版本中,幫助完善內(nèi)核功能并提升穩(wěn)定性。

當前業(yè)界的多租戶外網(wǎng)網(wǎng)關(guān)很多都是基于 OpenFlow 的  OpenvSwitch(OVS)方案,然而隨著內(nèi)核路由轉(zhuǎn)發(fā)功能的不斷完善,利用內(nèi)核原生路由轉(zhuǎn)發(fā)方式進行設(shè)計多租戶外網(wǎng)網(wǎng)關(guān)系統(tǒng)成為一種可能。在這種方式下能有效的使用傳統(tǒng)  iproute2 路由工具以及 iptables、nftables 等防火墻工具,并且隨著 SwitchDev  技術(shù)的興起,未來將網(wǎng)關(guān)系統(tǒng)遷移到 Linux Switch 上也成為一種可能。

現(xiàn)有 Linux 內(nèi)核 3.x 的不足

當前廣泛使用的內(nèi)核版本為 3.x 系列,例如 CentOS 7 全系列標準支持的內(nèi)核為 3.10 版本,F(xiàn)edora/Ubuntu 等 Linux 發(fā)行版也有大量使用。在 3.x 系列內(nèi)核下存在著 IP 隧道管理復雜、租戶隔離性能損耗等問題。

  1. IP 隧道管理復雜
    Linux 內(nèi)核創(chuàng)建 IP 隧道設(shè)備來建立點對點的隧道連接,創(chuàng)建時需指定隧道目標和隧道密鑰。因為宿主機之間兩兩建立連接,面向宿主機的目的地址眾多,這樣就會導致網(wǎng)關(guān)節(jié)點上需要創(chuàng)建成千上萬的隧道設(shè)備,在大規(guī)模業(yè)務(wù)環(huán)境下,隧道的管理將變得及其復雜。

  2. 多租戶隔離導致的性能下降

  3. 公有云需要實現(xiàn)多租戶隔離以確保用戶間的安全和隱私
    由于 VPC 網(wǎng)絡(luò)下不同租戶的內(nèi)網(wǎng)地址可以重合,導致路由也有重合的可能性,此時需要通過大量的策略路由去隔離租戶的路由規(guī)則,由于策略路由的鏈表屬性,性能會隨著鏈表長度的增加而急劇下降。

  4. 由于防火墻和 NAT 的實現(xiàn)基于同樣鏈式的 iptables,性能損耗同樣可觀。

  5. netns 帶來性能開銷
    通過 netns 實現(xiàn)租戶路由和防火墻規(guī)則的隔離,但是 netns 會引入虛擬網(wǎng)卡和協(xié)議棧重入開銷,使整體性能下降 20% 左右。

三項內(nèi)核新技術(shù)

為了解決原有方案存在的困擾,我們調(diào)研了大量行業(yè)主流方案和內(nèi)核上游的新動向,發(fā)現(xiàn)輕量級隧道Lightweight tunneling(簡稱 lwtunnel)、虛擬路由轉(zhuǎn)發(fā)Virtual Routing Forwarding(簡稱 VRF)以及 nftable & netfilter流卸載flow offload三項內(nèi)核新技術(shù)的特性,可以幫助規(guī)避原方案存在的缺陷。

1、輕量級隧道

Linux 內(nèi)核在 4.3 版本中引入了輕量級隧道,它提供了通過路由方式設(shè)置隧道屬性的方法,這樣可以避免管理大量的隧道設(shè)備。
創(chuàng)建隧道設(shè)備時指定 external 模式,利用路由設(shè)置的輕量級隧道通過 tun 設(shè)備發(fā)送報文。

# 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、虛擬路由轉(zhuǎn)發(fā)

Linux 內(nèi)核在 4.3 版本中引入了 VRF 的初步支持,并在 4.8 版本形成完備版本。虛擬路由轉(zhuǎn)發(fā)可以將一臺 Linux Box  的物理路由器當多臺虛擬路由器使用,能很好的解決租戶路由隔離問題,避免直接使用策略路由。因此,可以將不同租戶的網(wǎng)卡加入租戶所屬的虛擬路由器中來實現(xiàn)多租戶的虛擬路由。

基于Linux內(nèi)核新特性的網(wǎng)關(guān)設(shè)計方法是什么

# 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 eth2 master user1# ip l set dev eth2 master user2# ip r a default via 192.168.0.1 dev eth2 table 1 onlink# ip r a default via 192.168.0.1 dev eth2 table 2 onlink

3、流卸載

nftables 是一種新的數(shù)據(jù)包分類框架,旨在替代現(xiàn)存的 {ip,ip6,arp,eb}_tables。在 nftables  中,大部分工作是在用戶態(tài)完成的,內(nèi)核只知道一些基本指令(過濾是用偽狀態(tài)機實現(xiàn)的)。nftables  的一個高級特性就是映射,可以使用不同類型的數(shù)據(jù)并映射它們。例如,我們可以映射 iif  設(shè)備到專用的規(guī)則集合(之前創(chuàng)建的存儲在一個鏈中)。由于是哈希映射的方式,可以***的避免鏈式規(guī)則跳轉(zhuǎn)的性能開銷。

Linux 內(nèi)核在版本 4.16 引入了流卸載功能,它為 IP 轉(zhuǎn)發(fā)提供了基于流的卸載功能。當一條新建連接完成首回合原方向和反方向的報文時,完成路由,防火墻和 NAT 工作后,在處理反方向首報文的 forward 鉤子,根據(jù)報文路由、NAT 等信息創(chuàng)建可卸載流到接收網(wǎng)卡 ingress 鉤子上。后續(xù)的報文可以在接收 ingress 鉤子上直接轉(zhuǎn)發(fā),不需要再進入 IP 棧處理。此外,將來流卸載還將支持硬件卸載模式,這將極大提高系統(tǒng)轉(zhuǎn)發(fā)性能。

基于Linux內(nèi)核新特性的網(wǎng)關(guān)設(shè)計方法是什么

# nft add table firewall# nft add flowtable f fb1 { hook ingress priority 0 \; devices = { eth0, eth2 } \; }# 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

方案設(shè)計與優(yōu)化實踐

通過對上述三項新技術(shù)的研究,我們發(fā)現(xiàn)可以嘗試設(shè)計一套基于路由的方式,實現(xiàn)多租戶層疊網(wǎng)絡(luò)的外網(wǎng)網(wǎng)關(guān)。在方案設(shè)計過程中,我們也碰到了諸如  lwtunnel 和流卸載功能不足,以及 VRF 和流卸載不能一起有效的工作等問題。最終我們都設(shè)法解決了,并針對這些內(nèi)核的不足提交補丁給  Linux 內(nèi)核社區(qū)。

1、lwtunnel 發(fā)送報文 tunnel_key 丟失

問題描述:我們利用 lwtunnel 路由方式發(fā)送報文時,創(chuàng)建了一個 external 類型的 gretap 隧道,我們將命令設(shè)置了 id 為 1000,但是發(fā)送成功報文中沒有 tunnel_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 1000 dst 172.168.0.1

問題定位:我們研究 iproute2 代碼,發(fā)現(xiàn)由于 TUNNEL_KEY 的標志并沒有開放給用戶態(tài),所以 iproute2 工具并沒有對 lwtunnel 路由設(shè)置 TUNNEL_KEY,導致報文不會創(chuàng)建 tunnel_key 字段。

提交補?。何覀兘o內(nèi)核和用戶態(tài) iproute2 分別提交補丁來解決這一問題:

  • iptunnel: make TUNNEL_FLAGS available in uapi

  • iproute: Set ip/ip6 lwtunnel flags

提交補丁后,可以通過以下方式設(shè)置路由:

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 隧道無效

問題發(fā)現(xiàn):為了能有效隔離租戶路由,我們給每個租戶創(chuàng)建一個基于 tunnel_key 的 gretap 隧道設(shè)備。如下圖,創(chuàng)建一個 tunnel_key 1000 的 gretap 隧道設(shè)備,把隧道設(shè)備加入租戶所屬 VRF,隧道設(shè)備能有效地接收報文,但并不能發(fā)送報文。

# ip l add dev tun type gretap key 1000# 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

問題定位:研究內(nèi)核發(fā)現(xiàn),IP 隧道在非外部模式下即使指定了輕量級隧道路由,發(fā)送報文也沒有使用它,導致報文路由錯誤被丟棄。

提交補丁:

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

提交補丁后,在未指定 tunnel_dst 的非外部模式 IP 隧道下,能使用輕量級隧道路由進行發(fā)送報文。

3、外部 IP 隧道 ARP 無法正常運行

問題描述:鄰居 IP 隧道進行了 ARP 請求,但是本端的 ARP 回應(yīng)報文的隧道頭中并沒帶 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

問題定位:研究代碼發(fā)現(xiàn),隧道收到了對端的 ARP 請求,在發(fā)送報文 ARP 回復的時候會復制請求報文的隧道信息,但是遺漏了所有 tun_flags。

提交補?。?/p>

  • iptunnel: Set tun_flags in the iptunnel_metadata_reply from src

4、流卸載不能與 DNAT 有效工作

問題描述:防火墻創(chuàng)建規(guī)則從 eth0 收到目的地址 2.2.2.11 的報文,DNAT 為 10.0.0.7, 流卸載無法工作。

問題定位:分析發(fā)現(xiàn),客戶端 1.1.1.7 -> 2.2.2.7 DNAT 到服務(wù)器 10.0.0.7,***個回復的反向報文(syc+ack)使用了錯的目的地址獲取反向路由。

daddr = ct->tuplehash[!dir].tuple.dst.u3.ip

此時 dir 為反方向,所以 daddr 獲取為原方向的目的地址,這個值是 2.2.2.7,但是由于被 DNAT過,真正的路由不應(yīng)該通過 2.2.2.7 去獲取,而是應(yīng)該根據(jù) 10.0.0.7 這個值去獲取。

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

提交補丁:

  • netfilter: nft_flow_offload: Fix reverse route lookup

5、流卸載不能與 VRF 有效工作

問題描述:將網(wǎng)卡 eth0 和 eth2 加入 VFR 后,流卸載不起作用。

# ip addr add dev eth0 1.1.1.1/24# ip addr add dev eth2 1.1.1.1/24# ip link add user1 type vrf table 1# ip l set user1 up# ip l set dev eth0 master user1# ip l set dev eth2 master user1

問題定位:查看代碼發(fā)現(xiàn),原方向和反方向首報文進入?yún)f(xié)議堆棧后 skb->dev 會設(shè)置為 vrf device user1,創(chuàng)建流卸載規(guī)則的 iif 就是 user1。但是卸載規(guī)則下發(fā)在 eth0 和 eth2 的 ingress 鉤子上,所以后續(xù)報文在 eth0 和 eth2 的 ingress 鉤子上不能匹配流規(guī)則規(guī)則。

提交補?。?/p>

  • netfilter: nft_flow_offload: fix interaction with vrf slave device

最終,我們根據(jù)兩個方向查找路由的結(jié)果,設(shè)置流卸載規(guī)則的 iifoif 信息來解決此問題。

6、VRF PREROUTING 鉤子重入問題

問題描述:配置網(wǎng)卡加入 VRF,防火墻 ingress 方向規(guī)則為接收目的地址 2.2.2.11 、TCP 目的端口 22  的報文,egress 方向規(guī)則為丟棄 TCP 目的端口 22 的報文。出現(xiàn)異常結(jié)果: 收到目的地址 2.2.2.11 TCP 22  目的端口的報文卻被丟棄。

問題定位:研究發(fā)現(xiàn)網(wǎng)卡加入 VRF 后收到的報文會兩次進入 PREROUTING 鉤子,因為在進入 IP  棧時會進***次PREROUTING 鉤子,然后被 VRF 設(shè)備接管后會再次進入 PREROUTING 鉤子。上述規(guī)則***次在  rule-1000-ingress chain中 dst nat 為 10.0.0.7,第二次由于報文被 DNAT 后會錯誤的進入  rule-1000-egress,導致報文被丟棄。

提交補丁:我們給內(nèi)核加了一個支持判斷網(wǎng)卡類型的 match 項目,讓用戶態(tài)避免可知的第二次無效重入,內(nèi)核態(tài)和用戶態(tài) 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 和流卸載實現(xiàn)多租戶外網(wǎng)網(wǎng)關(guān)的原型驗證。驗證過程如下:

1、首先創(chuàng)建原型環(huán)境

a. netns cl 模擬外網(wǎng)客戶端,地址為 1.1.1.7,隧道源地址 172.168.0.7,配置發(fā)送路由;
b. netns ns1 模擬租戶 1,內(nèi)網(wǎng)地址為 10.0.0.7,外網(wǎng)地址為 2.2.2.11,隧道源地址 172.168.0.11 tunnel_key 1000,配置發(fā)送路由;
c. netns ns2 模擬租戶 2,內(nèi)網(wǎng)地址為 10.0.0.7,外網(wǎng)地址為 2.2.2.12,隧道源地址 172.168.0.12 tunnel_key 2000,配置發(fā)送路由;
d. Host 模擬外網(wǎng)網(wǎng)關(guān),隧道源地址 172.168.0.1,創(chuàng)建租戶 VRF user1 和 use2,創(chuàng)建租戶 IP 隧道 tun1 和 tun2,配置轉(zhuǎn)發(fā)路由。

原型環(huán)境圖如下:

基于Linux內(nèi)核新特性的網(wǎng)關(guān)設(shè)計方法是什么

2、創(chuàng)建防火墻規(guī)則

a. 租戶 1 入向允許 TCP 目的端口 22 和 ICMP 訪問,出向禁止訪問外部 TCP 22 目的端口;
b. 租戶 2 入向允許 TCP 端口 23 和 ICMP 訪問,出向禁止訪問外部 TCP 23 目的端口;
c. 在租戶 tun1 和 tun2 設(shè)備上支持流卸載。

最終,客戶端可以通過 2.2.2.11 成功訪問 user1 tcp 22 端口服務(wù),user1 不能訪問客戶端 tcp 22  端口服務(wù);客戶端可以通過 2.2.2.12 成功訪問 user2 tcp 23 端口服務(wù),user1 不能訪問客戶端 tcp 23 端口服務(wù)。

在后續(xù)硬件功能完善以及網(wǎng)卡廠商支持后,我們還會做進一步的開發(fā)驗證。

以上就是“基于Linux內(nèi)核新特性的網(wǎng)關(guān)設(shè)計方法是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI