学习 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

iptables -t filter -A FORWARD -o eth0 -i veth1 -j ACCEPT

在默认 FORWARD 规则为 DROP 时显式地允许 veth1 和 eth0 之间的 forwarding

这些配置之后,host 上的 route 表中自动添加了一条路由规则:

root@compute2:/home/s1# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG eth0
192.168.1.0 0.0.0.0 255.255.255.0 U eth0
192.168.45.0 0.0.0.0 255.255.255.0 U 0 0 0 veth1

myspace 的路由表:

root@compute2:/home/s1# ip netns exec myspace route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.45.2 0.0.0.0 UG veth2
192.168.45.0 0.0.0.0 255.255.255.0 U veth2

其中第一条是显式地被创建的,第二条是自动被创建的。

现在你就可以从 myspace 中 ping 外网的地址了。

2 原理

2.1 关于第八条 SNAT

如果没有设置第八条 SNAT,那么 ICMP Request 能够到达对方计算机,但是 echo reply 消息回不来,因为其目的地址为一个内部地址。

root@compute1:/home/s1# tcpdump -eni bridge1 -p icmp -v
tcpdump: listening on bridge1, link-type EN10MB (Ethernet), capture size bytes
::03.827852 :::4f:: > :::c7:cf:ca, ethertype IPv4 (0x0800), length : (tos 0x0, ttl , id , offset , flags [DF], proto ICMP (), length )
192.168.45.3 > 192.168.1.15: ICMP echo request, id , seq , length
::04.829779 :::4f:: > :::c7:cf:ca, ethertype IPv4 (0x0800), length : (tos 0x0, ttl , id , offset , flags [DF], proto ICMP (), length )

加上第八条之后,ping 能成功,也就是 ICMP echo request 能发出,echo reply 能返回。

在 host2 的网卡 eth0 上,能看到 ICMP echo request 网络包的源 IP 为 host1 的 IP:

::19.360519 :::c7:cf:ca > :::4f::, ethertype IPv4 (0x0800), length : (tos 0x0, ttl , id , offset , flags [none], proto ICMP (), length )
192.168.1.15 > 192.168.1.32: ICMP echo reply, id , seq , length
::20.358360 :::4f:: > :::c7:cf:ca, ethertype IPv4 (0x0800), length : (tos 0x0, ttl , id , offset , flags [DF], proto ICMP (), length )
192.168.1.32 > 192.168.1.15: ICMP echo request, id , seq , length

在 host1 的网卡 eth0 上,能看到来回网络包使用的是 host1 和 host2 的 IP 地址:

root@compute2:/home/s1# tcpdump -envi eth0 -p icmp -v
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size bytes
::27.285150 :::4f:: > :::c7:cf:ca, ethertype IPv4 (0x0800), length : (tos 0x0, ttl , id , offset , flags [DF], proto ICMP (), length )
192.168.1.32 > 192.168.1.15: ICMP echo request, id , seq , length
::27.285777 :::c7:cf:ca > :::4f::, ethertype IPv4 (0x0800), length : (tos 0x0, ttl , id , offset , flags [none], proto ICMP (), length )
192.168.1.15 > 192.168.1.32: ICMP echo reply, id , seq , length

在 host1 的 veth1 上,能看到发出的网络包的源 IP 和收到的网络包的目的 IP 皆为内部网段的 IP 地址:

root@compute2:/home/s1# tcpdump -envi veth1 -p icmp -v
tcpdump: listening on veth1, link-type EN10MB (Ethernet), capture size bytes
::13.355956 b2::7e:b6:e9:4e > ee::ae:dd:6f:7f, ethertype IPv4 (0x0800), length : (tos 0x0, ttl , id , offset , flags [DF], proto ICMP (), length )
192.168.45.3 > 192.168.1.15: ICMP echo request, id , seq , length
::13.356391 ee::ae:dd:6f:7f > b2::7e:b6:e9:4e, ethertype IPv4 (0x0800), length : (tos 0x0, ttl , id , offset , flags [none], proto ICMP (), length )
192.168.1.15 > 192.168.45.3: ICMP echo reply, id , seq , length

那为什么在 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 连接外网的更多相关文章

  1. Netruon 理解(12):使用 Linux bridge 将 Linux network namespace 连接外网

    学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...

  2. 【转】理解Docker容器网络之Linux Network Namespace

    原文:理解Docker容器网络之Linux Network Namespace 由于2016年年中调换工作的原因,对容器网络的研究中断过一段时间.随着当前项目对Kubernetes应用的深入,我感觉之 ...

  3. centos中NAT模式下静态IP连接外网

    使用linux虚拟机时,通常会用到yum命令来安装软件,然而这个命令需要连外网下载软件,用maven下载jar包也需要外网.虚拟机在内网可以互相ping通,然而ping不了外网,于是通过试验,终于找到 ...

  4. vmware 中Linux系统怎么连接外网?

    VMware虚拟机有三种网络模式,分别是Bridged(桥接模式).NAT(网络地址转换模式).Host-only(主机模式). VMware workstation安装好之后会多出两个网络连接,分别 ...

  5. linux: centos设置ip以及连接外网

    注明:我使用的的使centos 7,所有文件名是ifcfg-enp0s3, 一. 设置虚拟机中linux的ip,使本地能连通虚拟机的linux系统 1>.进入本地windows的cmd,输入ip ...

  6. 虚拟机NAT模式连接外网

    虚拟机三种联网方式: 一.NAT(推荐使用)                功能:①可以和外部网络连通    ②可以隔离外部网络 二.桥接模式                        功能:直接 ...

  7. NAT模式下VMware中CentOS7无法连接外网的解决方法

    故障现象 ----------------------------------------------------------------------------------------------- ...

  8. 虚拟机中的centos在nat模式下连不上外网

    这两天需要配置ftp服务器,可是虚拟机在nat模式下死活连不上外网,主机能够通过该ssh与虚拟机进行连接,虚拟机也能ping同一网段主机的IP地址,但就是ping不通外网, 开始我是这样配置的: 主机 ...

  9. windows,linux,cmd查看公网/外网IP

    1.linux(centos)查看公网/外网ip: curl ifconfig.me #inconfig.me是一个网站来的#或者,如果上面的无法访问curl icanhazip.com   2.Wi ...

随机推荐

  1. Visual Studio.NET单选题

     在Visual Studio.NET窗口中,在__________窗口中可以察看当前项目的类和类型的层次信息. A. 解决方案资源管理器 B. 类视图 C. 资源视图 D. 属性 在线答题:http ...

  2. Suggestion(搜索建议)产品和技术

    今天来简单聊聊Suggestion产品 什么是Suggestion服务? 一图胜千言: 当你想要搜索某个长词语或者一句话输入部分时,Suggestion服务预测你极大可能的候选项,并罗列出来,供你选择 ...

  3. Dom4j操作XML文件

    1. 创建并写入XML public static void writeXML(String filename){ try { Document document = DocumentHelper.c ...

  4. PHP正则表达式

    1.PHP中两个常用的正则函数 a.preg_match 正则函数,以perl语言为基础 语法:preg_match( mode,string subject,array matches) 说明:mo ...

  5. eclipse中怎么用cmd

    1:点击Run-----External tools------External tools configurations - 如果所示, name:就是工具配置的名字 location:cmd.ex ...

  6. C程序范例(2)——学生管理系统”链表“实现

    1.对于学生管理系统,能够实现的方法有许多,但是今天我们用链表的方法来实现.虽然初学者很可能看不懂,但是不要紧,这是要在整体的系统的学习完C语言之后,我才编写出的程序.所以大家不必要担心.在这里与大家 ...

  7. 【工业串口和网络软件通讯平台(SuperIO)教程】四.开发设备驱动

    SuperIO相关资料下载:http://pan.baidu.com/s/1pJ7lZWf 1.1    开发准备 把“开发包”内的所有文件复制到项目的“bin”目录下,或项目下的专用生成目录.开发包 ...

  8. 关于腾讯云ubuntu服务器tomcat访问慢问题

    在腾讯云上配了个一元的学生云,开始一切正常,直到配置tomcat开始出现各种莫名其妙的问题.最莫名其妙的是tomcat启动了,端口也 正常监听,安全组也放行端口了,然后问题来了. 用浏览器访问tomc ...

  9. JavaScript基本语法(四)

    一.     JavaScript 函数 1.函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块.我们可以将一些常用的代码封装成函数,待用到的时候就能直接调用使用.利用函数可以使代码的组织结构 ...

  10. arcgis for flex展示GIS基本功能

    1.地图框选搜索: 这是空间查询,在地图上框选一定的范围,然后搜索出在这个范围之内的所有信息,搜索到的详细信息在列表框显示出来 2.属性查询: 3.数据库展示: 4.绘制图形: 地图上绘制各种不同形状 ...