学习 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 连接外网

前一篇文章介绍了使用 NAT 将 Linux network namespace 连接外网,但是这种模式有很大的局限,包括它使用的是内部IP,因此,外部计算机不能直接访问其IP,而需要通过访问其主机再通过 DNAT 才能访问它。它的应用场景通常是因为企业使用的公网IP地址一般都数量有限,在内部计算机需要访问公网时,往往采取 NAT 方式。本文将介绍使用 linux bridge 来将 linux network namespace 连接到外网。

1. 环境及配置

1.1 测试环境

(图1)

环境说明:

  • 计算机1(host1)是一个在 ESXi 上的 VMware 虚机,它拥有两块网卡,其中 eth0 用于与计算机2(host2)通信。
  • host1 的 IP 地址为 192.168.1.87. 实验使用的另一个机器 host2 的 IP 为 192.168.1.48. 它们的网关为 192.168.1.1
  • host1 上的 /proc/sys/net/ipv4/ip_forward 内容为0,也就是说 ip forwarding 是关闭的
  • host1 上的 iptables filter 表:
root@linuxkvm1:/etc# iptables -t filter -S
-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT

为了能从在 host1 上的 netns ns2 上能 ping 通 host2 ,你需要做的配置及说明:

步骤# 命令 说明
1 ip netns add ns2 创建名称为 ‘ns2’ 的 linux network namespace
2 ip link add veth1 type veth peer name veth2 创建一个 veth 设备,一头为 veth1,另一头为 veth2
3 ip link set veth2 netns ns2 将 veth2 加入 ns2 作为其一个 network interface
4

brctl addbr br1

brctl addif br1 eth0

ifconfig eth0 0.0.0.0

ifconfig br1 192.168.1.87/24 up

brctl addif br1 veth1

创建 liux bridge ‘br1’

删除 eth0 的 IP 地址,并将其地址设给 br1

将 eth0 加入 br1

将 veth1 加入 br1

5 ip netns exec ns2 ifconfig veth2 192.168.1.88/24 up 配置 veth2 的 IP 地址,它和 host1 和 host2 在同一个网段上
6 ip netns exec ns2 route add default gw 192.168.1.1 将 ns2 的默认路由设为 host1 和 host2 的网关地址
7

iptables -t filter  -A FORWARD -m physdev --physdev-in eth0 --physdev-out veth1 -j ACCEPT

iptables -t filter  -A FORWARD -m physdev --physdev-out eth0 --physdev-in veth1 -j ACCEPT

设置 FORWARD 规则

做了以上配置之后,

  • 从ns2 中可以ping 其它的计算机,无论是 192.168.1.0 网段还是其它网段
  • 从其他计算机上可以ping 192.168.1.88

备注:请确保所有 network interface 都是出于 up 状态,可以使用 ifconfig 命令查看其状态,如果是 down 的话可以使用 ip link set <interface> up 来设置。

2. 原理

2.1 linux bridge forwarding

当从外部计算机 ping veth2 的 IP 地址时的 iptables 统计:

Chain INPUT (policy ACCEPT  packets, 198K bytes)
pkts bytes target prot opt in out source destination Chain FORWARD (policy DROP packets, bytes)
pkts bytes target prot opt in out source destination
ACCEPT all -- * * 0.0.0.0/ 0.0.0.0/ PHYSDEV match --physdev-in ens9f0 --physdev-out veth1
ACCEPT all -- * * 0.0.0.0/ 0.0.0.0/ PHYSDEV match --physdev-in veth1 --physdev-out ens9f0 Chain OUTPUT (policy ACCEPT packets, 184K bytes)
pkts bytes target prot opt in out source destination

说明网络流量确实经过了 linux bridge 做 forwarding。关于 linux bridge 上的 iptables 设置的说明的更详细内容,请参考 ebtables/iptables interaction on a Linux-based bridge。要点包括:

    • 跟 linux bridge 相关的有 iptables 和 ebtables 过滤表
    • linux 内核 2.6 版本包含了 ebtables 和 br-nf 的代码,其中 br-nf 代码使得被 bridge 的网络帧/包会经过 iptables 过滤表;ebtables 表工作在网络二层(Ethernet),iptables 表工作在上层(IP)。
    • 当一个 IP 包进入了一个 bridge/router interface 后,它将网络包发给另一个 bridge interface的情形如下:
    • (图2)
    • 当一个 IP 包进入了一个 bridge/router interface 后,它将网络包发给一个非 bridge interface的情形如下:
      • (图3)

基于上面的原理,就本文中的案例的要求,

(1)如果使用 physdev 模块的话,可以使用下面两条规则进行精准的控制:

iptables -t filter  -A FORWARD -m physdev --physdev-in eth0 --physdev-out veth1 -j ACCEPT
iptables -t filter -A FORWARD -m physdev --physdev-out eth0 --physdev-in veth1 -j ACCEPT

备注:

  • physdev-in 指定的是网络包进入的 bridge 的端口
  • physdev-out 指定的是网络包离开的 bridge 的端口

(2)也可以使用常规规则来控制是否允许 br1 进行 forwarding

iptables -t filter -A FORWARD -i br1 -j ACCEPT

(3)linux 内核的 ip forwrading 不需要启用,它主要针对的是 NAT 情形。

2.2 linux bridge 的转发行为

Linux bridge 根据收到的帧的目的 MAC 地址来决定其行为:

  • 如果帧的目的 MAC 地址是已知的在 bridge 的另一头,会做 bridging (转发)
  • 如果帧的目的 MAC 地址是未知的,会做 flooding (泛洪)
  • 如果帧的目的 MAC 地址是 bridge 自身或者它的某个端口的 MAC 地址(local),则发往上层 IP 层
  • 如果目的 MAC 地址是已知的而且在 bridge 的源侧,则丢弃

linux bridge 自身维护了 mac 地址和输入端口的映射表:

root@linuxkvm1:/home/s1# brctl showmacs br-ens9f0
port no mac addr is local? ageing timer
:0e:d5:c6:: no 224.96
7e:::bb:: yes 0.00
7e:::bb:: yes 0.00
a0::9f:5c::f8 no 58.07
a0::9f::b1: yes 0.00
a0::9f::b1: yes 0.00
ee:::cc:: no 0.29
  • 当从 ns2 中 ping 外部计算机时,因为 bridge 发现其目的 mac 地址不是 local 的,它对该 IP 包执行 linux bridging,这就会触发 2.1 中讨论过的过滤规则。
  • 当从 ns2 中 ping host1 时,因为目的 mac 地址是 local 的,它会直接把它发给 IP 层,此时,前面讨论的 FORWARD 链的 filter 表的两条过滤规则对它不起作用,这也就是为什么即使不添加这两天规则,ping host1 也是会成功的。

2.3 网络接口的混杂模式(Promiscuous mode, 简称 Promisc mode)

根据 wikipedia 的定义,Promisc 模式是指一个 NIC 会把它接受的所有网络流量都交给 CPU,而不是只是把它想转交的部分交给 CPU。在 IEEE 802 网络中,每个网络帧都有一个目的 MAC 地址。在 non-promiscuous 模式下,NIC 只会接受目的 MAC 地址是它自己的 MAC 地址的单播帧,以及多播及广播帧。在混杂模式下,NIC 会接受经过它的所有帧。

简单地,你可以使用 ifconfig 命令或者 netstat -i 命令来查看一个 network interface 上的混杂模式是否打开了:

  • ifconfig eth0, 查看 eth0 的配置,包括混杂模式。当输出包含 PRMISC 时,表明该网络接口处于混杂模式。但是也有特殊情况,参见下面的 2.3.2 部分。
root@linuxkvm1:/home/s1# ifconfig eth0
eth0 Link encap:Ethernet HWaddr a0::9f::b1:
inet6 addr: fe80::a236:9fff:fe97:b168/ Scope:Link
UP BROADCAST RUNNING PROMISC MULTICAST MTU: Metric:
  • ifconfig eth0 promisc  //使 eth0 进入混杂模式
  • ifconfig eth0 -promisc //使 eth0 退出混杂模式

本例中,经过 eth0 的网络流量,既包括发给它的,也包括发给 ns2 的,此时帧的目的 MAC 地址不再是 eth0 自己的MAC地址,因此,eth0 的混杂模式必须打开。但是,在测试过程中,发现两个有意思的事情。

2.3.1 VMware 虚机的 NIC 的混杂模式

根据 How promiscuous mode works at the virtual switch and portgroup levels 这篇文章,VMware 虚机的 NIC 需要启用混杂模式时,VMware vSwitch 以及它的 Virtual group 中的 vPort 也需要开启混杂模式。当 vSwitch 启用了混杂模式时,它上面的所有端口组(portgroup)也默认开启了混杂模式。好吧,在我的测试中,为了找到这个问题,花了我不少时间。

(1)开启 vSwitch 的混杂模式

(2)端口组的混杂模式,默认是随 vSwitch 的混杂模式,但是你也可以显式地打开或者关闭

2.3.2 VirtualBox 虚机网卡的混杂模式

2.3.3 linux bridge 及其接口的混杂模式

测试过程发现,当一个网络接口被加入了 linux bridge 之后,它的混杂模式就会被自动开启,而且无法关闭,直到把它从 bridge 上删除。

(1)当 veth 设备离开 linux bridge 后,自动退出混杂模式

brctl delif br-ens9f0 veth40
dmesg | grep promiscuous
[498665.637647] device veth40 left promiscuous mode

此时可以手工设置其 promisc 模式了:

root@linuxkvm1:/home/s1# netstat -i | grep veth40
veth40 BMRU
root@linuxkvm1:/home/s1# ifconfig veth40 promisc
root@linuxkvm1:/home/s1# netstat -i | grep veth40
veth40 BMPRU
[498822.803260] device veth40 entered promiscuous mode

(2)当 veth 设备被加入 linux bridge 后,自动进入 promisc 模式

brctl addif br-ens9f0 veth40
dmesg | grep promiscuous
[498681.199680] device veth40 entered promiscuous mode

此时即使通过ifconfig 将其设置为非 promisc 模式,netstat -i 也显示其处于非 promis 模式,但是其实此时它仍然处于 promisc 模式:


dmesg没有记录
root@linuxkvm1:/home/s1# ifconfig veth40 -promisc 
root@linuxkvm1:/home/s1# netstat -i | grep veth40
veth40 BMRU

结论:

  • 网络设备被加入 linux bridge 后,自动进入混杂模式,而且无法退出。应该说这种做法也简化了 linux bridge 环境中的网络配置。
  • 网络设备从 linux bridge 移出后,自动退出混杂模式,而且可以修改
  • linux bridge 自身也是一种二层网络设备,但是它没有混杂模式的说法,它会根据情况来转发或者泛洪网络帧

备注:本文所涉及的 linux bridge 以及 iptables 的相关知识比较复杂,本文作者仅确认本文中的测试过程及结果,原理分析部分可能存在错误。本文会保持持续更新。

Netruon 理解(12):使用 Linux bridge 将 Linux network namespace 连接外网的更多相关文章

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

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

  2. vmware中linux虚拟机使用NAT模式不能连接外网解决

    linux虚拟机一直配置的桥接模式,今天改成NAT模式发现不能上外网 环境:VMware12,CentOS 6.8,NAT模式 ①电脑实际ip:192.168.1.100 ②NAT使用虚拟网卡网关: ...

  3. Linux 设置IP地址,并能连接外网

    1,如果是 centos6,请修改  vi /etc/sysconfig/network-scripts/ifcfg-eth0 2,如果是 centos7,请修改 => vi /etc/sysc ...

  4. linux 网络虚拟化: network namespace 简介

    linux 网络虚拟化: network namespace 简介 network namespace 是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自的网络栈信息.不管是虚拟机还是 ...

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

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

  6. 为虚机Linux系统设置静态IP,ping通外网并解决相关问题

    在虚机中安装完Linux系统后,虚机是ping不通外网的,而默认的动态IP会为之后的Hadoop应用造成不少麻烦,为了减少这些不必要的麻烦,我们把系统的IP设置为静态. 步骤: 修改系统配置文件 命令 ...

  7. VM中Linux网络设置(固定ip、连接外网开发环境)

      在开发过程中,我们经常需要在linux中进行操作.毕竟服务器的系统大多数都是Linux,所以在dev环境需要配置好一台Linux系统配合开发.   在VMWare Workstation Pro中 ...

  8. vm虚拟机中linux无法连接外网?

    问题出现的环境? vm虚拟机中安装了linux系统,vm设置了NAT方式共享主机ip,但还是没法访问外网?在linux系统中查询ip地址,没有ipv4地址,就是配置了自动获取,但是还是没有获取? 问题 ...

  9. Linux连接外网

    1.给linux配置ip 进行远程管理 如果网络不同的话需要配置网卡,命令如下: vi /etc/sysconfig/network-scripts/ifcfg-enp0s3   回车 就出现网络的环 ...

随机推荐

  1. iOS阶段学习第32天笔记(页面传值方法介绍)

    iOS学习(UI)知识点整理 一.界面传值方法 1.方法一  Block传值  通过SubView视图的Block向View视图传值改变View视图的背景色 实例代码: 1)SubViewContro ...

  2. Asp.net 面向接口可扩展框架之类型转化基础服务

    新框架正在逐步完善,可喜可贺的是基础服务部分初具模样了,给大家分享一下 由于基础服务涉及面太广,也没开发完,这篇只介绍其中的类型转化部分,命名为类型转化基础服务,其实就是基础服务模块的类型转化子模块 ...

  3. 关于在aspx前台使用后台变量的问题

    我们经常会在后台定义一个变量,然后在用<%=变量名%>这种方式去获取,但是有时候<head></head>里面获取变量的时候,有时候会获取不到是怎么回事呢 前台: ...

  4. 排列组和在c语言中的应用

    排列组和在c中很常见,但是这个排列组和是通过循环来实现的,和数学中的还是有一点区别的,而且c中的方法也不尽相同,而且我遇到c中的数学问题总会纠结于数学上是怎么实现的但是我自己又不会,所以就没了兴趣,例 ...

  5. Java Web 学习路线

    实际上,如果时间安排合理的话,大概需要六个月左右,有些基础好,自学能力强的朋友,甚至在四个月左右就开始找工作了.大三的时候,我萌生了放弃本专业的念头,断断续续学 Java Web 累计一年半左右,总算 ...

  6. 转移博客到xinqiyang.freeflare.com了,这里会继续更新.

    hi.... 欢迎大家来到这里,这里将转移到github page搭建的博客 http://xinqiyang.freeflare.com 了,现在习惯于实用markdown来写东西了,这样可以脱离浏 ...

  7. ul ol di三者区别

    1.ul是无序列表,也就是说没有排列限制可以随意加li: <ul> <li>可以随意放置</li> <li>可以随意放置</li> < ...

  8. H5与CS3权威上.5 绘制图形(1)

    1.canvas元素基础知识 (1)在页面上放置canvas元素,相当于在页面上放置一块"画布",可以用Javascript编写在其中进行绘画的脚本. (2)在页面中放置canva ...

  9. 记jQuery.fn.show的一次踩坑和问题排查

    最近很少已经很少用jQuery,因为主攻移动端,常用Zepto,其实很多细节和jQuery并不一样.最近又无意中接触到了PC的需求和IE6, 使用了jQuery,刚好踩坑了,特意记录一下. 本文内容如 ...

  10. [SharePoint]SharePoint Claim base Authentication的一个比较好的介绍

    User identity in AD DS is based on a user account. For successful authentication, the user provides ...