Netruon 理解(11):使用 NAT 將 Linux network namespace 串連外網

來源:互聯網
上載者:User

標籤:

學習 Neutron 系列文章:

(1)Neutron 所實現的虛擬化網路

(2)Neutron OpenvSwitch + VLAN 虛擬網路

(3)Neutron OpenvSwitch + GRE/VxLAN 虛擬網路

(4)Neutron OVS OpenFlow 流表 和 L2 Population

(5)Neutron DHCP Agent

(6)Neutron L3 Agent  

(7)Neutron LBaas

(8)Neutron Security Group

(9)Neutron FWaas 和 Nova Security Group

(10)Neutron VPNaas

(11)Neutron DVR

(12)Neutron VRRP

(13)High Availability (HA)

(14)使用 NAT 將 Linux network namespace 串連外網

(15)使用 Linux bridge 將 Linux network namespace 串連外網

 

Linux network namespace 串連外網從大類上來講主要有兩種方法:網路位址轉譯(NAT) 和 橋接(bridging),而橋接根據使用的橋接器又可以分為使用 linux bridge 和 Open vSwitch 網路等。本文將說明 NAT 具體配置過程以及原理。

1. 環境及配置

我們可以把一個 linux network namespace 看作另一個電腦,這樣看起來會更加直觀:

節點 host1 的 IP 位址為 192.168.1.32. 實驗使用的另一個機器 host2 的 IP 為 192.168.1.15.

為了能從在 host1 上的 netns myspace 上能 ping 通 host2 ,你需要做的配置及說明:

步驟# 命令 說明
1 ip netns add myspace 建立名稱為 ‘myspace’ 的 linux network namespace
2 ip link add veth1 type veth peer name veth2 建立一個 veth 裝置,一頭為 veth1,另一頭為 veth2
3 ip link set veth2 netns myspace 將 veth2 加入 myspace 作為其一個 network interface
4 ifconfig veth1 192.168.45.2 netmask 255.255.255.0 up 配置 veth1 的 IP 位址
5 ip netns exec myspace ifconfig veth2 192.168.45.3 netmask 255.255.255.0 up 配置 veth2 的 IP 位址,它和 veth1 需要在同一個網段上
6 ip netns exec myspace route add default gw 192.168.45.2 將 myspace 的預設路由設為 veth1 的 IP 位址
7 echo 1 > /proc/sys/net/ipv4/ip_forward    開啟 linux kernel ip forwarding
8 iptables -t nat -A POSTROUTING -s 192.168.45.0/24 -o eth0 -j MASQUERADE 配置 SNAT,將從 myspace 發出的網路包的 soruce IP address 替換為 eth0 的 IP 位址
9 iptables -t filter -A FORWARD -i eth0 -o veth1 -j ACCEPT 在預設 FORWARD 規則為 DROP 時顯式地允許從 veth1 到 eth0 的 forwarding

這些配置之後,host 上的 route 表中自動添加了一條路由規則:

[email protected]:/home/s1# route -nKernel IP routing tableDestination     Gateway         Genmask         Flags Metric Ref    Use Iface0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 eth0192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0192.168.45.0    0.0.0.0         255.255.255.0   U     0      0        0 veth1

myspace 的路由表:

[email protected]:/home/s1# ip netns exec myspace route -nKernel IP routing tableDestination     Gateway         Genmask         Flags Metric Ref    Use Iface0.0.0.0         192.168.45.2    0.0.0.0         UG    0      0        0 veth2192.168.45.0    0.0.0.0         255.255.255.0   U     0      0        0 veth2

其中第一條是顯式地被建立的,第二條是自動被建立的。

現在你就可以從 myspace 中 ping 外網的地址了。

2 原理2.1 關於第八條 SNAT

如果沒有設定第八條 SNAT,那麼 ICMP Request 能夠到達對方電腦,但是 echo reply 訊息回不來,因為其目的地址為一個內部地址。

[email protected]:/home/s1# tcpdump -eni bridge1 -p icmp -vtcpdump: listening on bridge1, link-type EN10MB (Ethernet), capture size 65535 bytes07:40:03.827852 08:00:27:4f:56:17 > 08:00:27:c7:cf:ca, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 63, id 54069, offset 0, flags [DF], proto ICMP (1), length 84)    192.168.45.3 > 192.168.1.15: ICMP echo request, id 26569, seq 1, length 6407:40:04.829779 08:00:27:4f:56:17 > 08:00:27:c7:cf:ca, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 63, id 54194, offset 0, flags [DF], proto ICMP (1), length 84)

加上第八條之後,ping 能成功,也就是 ICMP echo request 能發出,echo reply 能返回。

在 host2 的網卡 eth0 上,能看到 ICMP echo request 網路包的源 IP 為 host1 的 IP:

07:44:19.360519 08:00:27:c7:cf:ca > 08:00:27:4f:56:17, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 54265, offset 0, flags [none], proto ICMP (1), length 84)    192.168.1.15 > 192.168.1.32: ICMP echo reply, id 28534, seq 7, length 6407:44:20.358360 08:00:27:4f:56:17 > 08:00:27:c7:cf:ca, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 63, id 21278, offset 0, flags [DF], proto ICMP (1), length 84)    192.168.1.32 > 192.168.1.15: ICMP echo request, id 28534, seq 8, length 64

在 host1 的網卡 eth0 上,能看到來回網路包使用的是 host1 和 host2 的 IP 位址:

[email protected]:/home/s1# tcpdump -envi eth0 -p icmp -vtcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes06:31:27.285150 08:00:27:4f:56:17 > 08:00:27:c7:cf:ca, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 63, id 58781, offset 0, flags [DF], proto ICMP (1), length 84)    192.168.1.32 > 192.168.1.15: ICMP echo request, id 29610, seq 158, length 6406:31:27.285777 08:00:27:c7:cf:ca > 08:00:27:4f:56:17, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 23662, offset 0, flags [none], proto ICMP (1), length 84)    192.168.1.15 > 192.168.1.32: ICMP echo reply, id 29610, seq 158, length 64

在 host1 的 veth1 上,能看到發出的網路包的源 IP 和收到的網路包的目的 IP 皆為內部網段的 IP 位址:

[email protected]:/home/s1# tcpdump -envi veth1 -p icmp -vtcpdump: listening on veth1, link-type EN10MB (Ethernet), capture size 65535 bytes06:33:13.355956 b2:52:7e:b6:e9:4e > ee:53:ae:dd:6f:7f, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 6989, offset 0, flags [DF], proto ICMP (1), length 84)    192.168.45.3 > 192.168.1.15: ICMP echo request, id 29610, seq 264, length 6406:33:13.356391 ee:53:ae:dd:6f:7f > b2:52:7e:b6:e9:4e, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 63, id 36067, offset 0, flags [none], proto ICMP (1), length 84)    192.168.1.15 > 192.168.45.3: ICMP echo reply, id 29610, seq 264, length 64

那為什麼在 forwarding 發生之前,在 iptables nat 表中並沒有顯式做 DNAT 的情況下 veth1 和 eth0 之間有了 DNAT 呢? 

原因是 ICMP 使用了 Query ID,而 NAT 會自動根據 ICMP Query ID 對 ICMP echo reply 做 DNAT。根據 https://tools.ietf.org/html/rfc5508 的 3.1. ICMP Query Mapping 章節,當內部的 host1 發一個 ICMP Query 給外部 host2 時,linux 核心的 NAT 模組會針對 NAT 的外部地址分配一個匹配的 query ID(上面例子中的 id 29610);然後當收到 ICMP echo reply 時,NAT模組會根據 ICMP Query ID 以及 ICMP header checksum 將外部 IP 轉化為內部 IP,然後再做 forwarding。也可以看出,ICMP Query ID 類似於 TCP 和 UDP 使用的連接埠號碼(port number),兩者的區別在於 NAT 為 ICMP 自動做了 DNAT,而 TCP 和 UDP 則需要顯式添加 DNAT 規則。

2.2 關於 IP forwarding

 (圖片來源)

Linux 核心在從 veth1 上收到 myspace 發過來的 ICMP 包以後,

  1. 執行 PREROTING 規則,本例不需要此配置此規則。
  2. 執行 Routing decision。它會檢查網路包的目的IP地址,發現它不在本機上,說明需要進行 routing (FORWARD)。因為 Linux 上預設的 IP forwarding 是關閉的,因此需要執行第七條命令來開啟它;然後再檢查 iptable 規則中的這種 forwarding (ICMP 包從veth1 出再進入 eth0)。通常為了安全起見,管理員會將 FORWARD 的預設規則設定為 DROP,此時則需要執行第九條命令顯式地允許(ACCEPT)所需要的 forwarding。
  3. 執行 ip forwarding。尋找 host1 上的路由表,網路包會被路由到 eth0。
  4. 執行 POSTROUTING 規則。因為此時的網路包的源 IP 位址仍然為內部地址,為了避免 ICMP 網路包有去無回,需要通過 SNAT 將內部地址轉換為外部地址。這就是第八條的作用。
  5. 從 eth0 發出

(3)關於 myspace 的預設路由

因為 myspace 只有一根網線(veth)串連到 veth1,因此,必須將預設的路由器地址設定為 veth1 的 IP 位址。

2.3 DNAT

  上面的配置只是為了能從 myspace 中訪問外網。要使得外面網路能訪問 myspace 中的應用的話,則需要在 host1 上添加 DNAT 規則,比如將 8080 連接埠受到的 TCP 轉到內部 IP 上的 80 連接埠;同時還需要配置 forward 規則,允許從 eth0 出到 veth1 進。基本過程為:

對方電腦使用 host1 的 IP 位址和特定連接埠訪問 mysapce 中的 TCP 應用 (192.168.1.32:8080),

  1. Linux 核心在從 eth0 上收到發過來的TCP包(IP 為 192.168.1.32,連接埠為 8080)
  2. 執行 PREROTING 規則,將目的 IP 及連接埠修改為 192.168.45.3 和 80
  3. 執行 Routing decision。它會檢查網路包的目的IP地址,發現它不在本機上,說明需要進行 routing (FORWARD)。檢查 Linux 的 IP forwarding 是否開啟;然後再檢查 iptable 規則中的這種 forwarding (TCP 包從 eth0 出再進入 veth1)。通常為了安全起見,管理員會將 FORWARD 的預設規則設定為 DROP,此時則需要執行類似第九條命令顯式地允許(ACCEPT)所需要的 forwarding。
  4. 執行 ip forwarding。尋找 host1 上的路由表,網路包會被路由到 veth1。
  5. 執行 POSTROUTING 規則。儘管有第八條規則,但是它要求源地址在內部網段,因此不會執行。
  6. 從 veth1 發出的包通過 veth 裝置進入 myspace 的 veth0 網卡。
  7. 被 80 連接埠上的應用接收到。

 

 

Netruon 理解(11):使用 NAT 將 Linux network namespace 串連外網

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.