精华内容
下载资源
问答
  • 计算机网络安全虚拟网络技术分析计算机网络安全防火墙技术研究网络安全入侵检测系统设计思路 摘要近些年计算机网络技术飞速发展已经广泛应用在人们的学习生活以及工作过程当中计算机的网络安全问题也受到人们的高度...
  • Linux虚拟网络技术

    2019-07-29 11:54:30
    近几年,Docker、Kubernetes等容器化技术和容器编排工具的兴起使技术人员从应用部署和维护的泥淖中解脱出来,同时也...今天就把近期的对Linux虚拟网络技术的学习成果分享出来,希望能和大家一起交流学习。 Networ...

    近几年,Docker、Kubernetes等容器化技术和容器编排工具的兴起使技术人员从应用部署和维护的泥淖中解脱出来,同时也改变了很多很多互联网公司的技术架构。笔者近期也在学习Docker和Kubernetes,对这些新技术所带来的便捷性和安全性非常着迷,其中尤其对容器化技术的网络实现方式更为好奇。今天就把近期的对Linux虚拟网络技术的学习成果分享出来,希望能和大家一起交流学习。

    Network Namespace

    Network Namespace 是 Linux 内核提供的功能,是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自网络栈信息。不管是虚拟机还是容器,运行的时候仿佛自己都在独立的网络中。而且不同Network Namespace的资源相互不可见,彼此之间无法通信。如下图所示:

    ip netns命令

    可以借助 ip netns命令来完成对 Network Namespace 的各种操作。 ip netns命令来自于 iproute2安装包,一般系统会默认安装,如果没有的话,读者自行安装。

    注意: ip netns命令修改网络配置时需要 sudo 权限。

    可以通过 ip netns命令完成对Network Namespace 的相关操作,可以通过 ip netns help查看命令帮助信息:

    
     
    1. $ ip netns help

    2. Usage: ip netns list

    3. ip netns add NAME

    4. ip netns set NAME NETNSID

    5. ip [-all] netns delete [NAME]

    6. ip netns identify [PID]

    7. ip netns pids NAME

    8. ip [-all] netns exec [NAME] cmd ...

    9. ip netns monitor

    10. ip netns list-id

    默认情况下,Linux系统中是没有任何 Network Namespace的,所以 ip netns list命令不会返回任何信息。

    创建Network Namespace

    下面,我们通过命令创建一个名为 ns0的命名空间:

    
     
    1. $ ip netns add ns0

    2. $ ip netns list

    3. ns0

    新创建的 Network Namespace 会出现在 /var/run/netns/目录下。如果相同名字的 namespace 已经存在,命令会报 Cannotcreatenamespacefile"/var/run/netns/ns0":Fileexists的错误。

    对于每个 Network Namespace 来说,它会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源。

    操作Network Namespace

    ip命令提供了 ip netnsexec子命令可以在对应的 Network Namespace 中执行命令。

    1. 查看新创建 Network Namespace 的网卡信息

    
     
    1. $ ip netns exec ns0 ip addr

    2. 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000

    3. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    可以看到,新创建的Network Namespace中会默认创建一个 lo回环网卡,此时网卡处于 关闭状态。此时,尝试去 ping 该 lo回环网卡,会提示 Networkisunreachable

    
     
    1. $ ip netns exec ns0 ping 127.0.0.1

    2. connect: Network is unreachable

    通过下面的命令启用 lo回环网卡:

    
     
    1. ip netns exec ns0 ip link set lo up

    然后再次尝试去 ping 该 lo回环网卡:

    
     
    1. $ ip netns exec ns0 ping -c 3 127.0.0.1

    2. PING 127.0.0.1 (127.0.0.1) 56(84) bytes of >.

    3. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.048 ms

    4. 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.031 ms

    5. 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.029 ms

    6.  

    7. --- 127.0.0.1 ping statistics ---

    8. 3 packets transmitted, 3 received, 0% packet loss, time 1999ms

    9. rtt min/avg/max/mdev = 0.029/0.036/0.048/0.008 ms

    转移设备

    我们可以在不同的 Network Namespace 之间转移设备(如veth)。由于一个设备只能属于一个 Network Namespace ,所以转移后在这个 Network Namespace 内就看不到这个设备了。

    其中,veth设备属于可转移设备,而很多其它设备(如lo、vxlan、ppp、bridge等)是不可以转移的。

    veth pair

    veth pair 全称是 Virtual Ethernet Pair,是一个成对的端口,所有从这对端口一 端进入的数据包都将从另一端出来,反之也是一样。引入veth pair是为了在不同的 Network Namespace 直接进行通信,利用它可以直接将两个 Network Namespace 连接起来。整个veth的实现非常简单,有兴趣的读者可以参考源代码 drivers/net/veth.c的实现。

    创建veth pair

    
     
    1. $ sudo ip link add type veth

    2. $ ip addr

    3. 61: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000

    4. link/ether e6:39:e1:e0:3a:a0 brd ff:ff:ff:ff:ff:ff

    5. 62: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000

    6. link/ether be:41:49:42:23:6a brd ff:ff:ff:ff:ff:ff

    可以看到,此时系统中新增了一对veth pair,将veth0和veth1两个虚拟网卡连接了起来,此时这对 veth pair 处于”未启用“状态。

    如果我们想指定 veth pair 两个端点的名称,可以使用下面的命令:

    
     
    1. ip link add vethfoo type veth peer name vethbar

    实现Network Namespace间通信

    下面我们利用veth pair实现两个不同的 Network Namespace 之间的通信。刚才我们已经创建了一个名为 ns0的 Network Namespace,下面再创建一个信息Network Namespace,命名为 ns1

    
     
    1. $ ip netns add ns1

    2. $ ip netns list

    3. ns1

    4. ns0

    然后我们将veth0加入到ns0,将veth1加入到ns1,如下所示:

    
     
    1. $ ip link set veth0 netns ns0

    2. $ ip link set veth1 netns ns1

    然后我们分别为这对veth pair配置上ip地址,并启用它们:

    
     
    1. $ ip netns exec ns0 iplink set veth0 up

    2. $ ip netns exec ns0 ip addr add 10.0.1.1/24 dev veth0

    3. $ ip netns exec ns1 iplink set veth1 up

    4. $ ip netns exec ns1 ip addr add 10.0.1.2/24 dev veth1

    查看这对veth pair的状态

    
     
    1. $ ip netns exec ns0 ip addr

    2. 61: veth0@if62: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000

    3. link/ether e6:39:e1:e0:3a:a0 brd ff:ff:ff:ff:ff:ff link-netnsid 1

    4. inet 10.0.1.1/24 scope global veth0

    5. valid_lft forever preferred_lft forever

    6. inet6 fe80::e439:e1ff:fee0:3aa0/64 scope link

    7. valid_lft forever preferred_lft forever

    8.  

    9. $ ip netns exec ns1 ip addr

    10. 62: veth1@if61: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000

    11. link/ether be:41:49:42:23:6a brd ff:ff:ff:ff:ff:ff link-netnsid 0

    12. inet 10.0.1.2/24 scope global veth1

    13. valid_lft forever preferred_lft forever

    14. inet6 fe80::bc41:49ff:fe42:236a/64 scope link

    15. valid_lft forever preferred_lft forever

    从上面可以看出,我们已经成功启用了这个veth pair,并为每个veth设备分配了对应的ip地址。我们尝试在 ns1中访问 ns0中的ip地址:

    
     
    1. $ ip netns exec ns1 ping -c 3 10.0.1.1

    2. sudo: unable to resolve host zormshogu

    3. PING 10.0.1.1 (10.0.1.1) 56(84) bytes of >.

    4. 64 bytes from 10.0.1.1: icmp_seq=1 ttl=64 time=0.091 ms

    5. 64 bytes from 10.0.1.1: icmp_seq=2 ttl=64 time=0.035 ms

    6. 64 bytes from 10.0.1.1: icmp_seq=3 ttl=64 time=0.037 ms

    7.  

    8. --- 10.0.1.1 ping statistics ---

    9. 3 packets transmitted, 3 received, 0% packet loss, time 1999ms

    10. rtt min/avg/max/mdev = 0.035/0.054/0.091/0.026 ms

    可以看到,veth pair成功实现了两个不同Network Namespace之间的网络交互。

    veth查看对端

    一旦将veth pair的peer段放入另一个Network Namespace,我们在当前Namespace中就看不到它了。那么,我们怎么才能知道这个veth pair的对端在哪里呢?可以通过 ethtool工具来查看(当Network Namespace很多时,操作会比较麻烦):

    
     
    1. $ ip netns exec ns1 ethtool -S veth1

    2. NIC statistics:

    3. peer_ifindex: 5

    得知另一端的接口设备序列号是5,我们再到另一个命名空间中查看序列号5代表什么设备:

    
     
    1. $ ip netns exec ns0 ip link | grep 5

    2. veth0

    网桥

    veth pair打破了 Network Namespace 的限制,实现了不同 Network Namespace 之间的通信。但veth pair有一个明显的缺陷,就是只能实现两个网络接口之间的通信。如果我们想实现多个网络接口之间的通信,就可以使用下面介绍的网桥(Bridge)技术。简单来说,网桥就是把一台机器上的若干个网络接口“连接”起来。其结果是,其中一个网口收到的报文会被复制给其他网口并发送出去。以使得网口之间的报文能够互相转发。

    网桥的工作原理

    网桥对报文的转发基于MAC地址。网桥能够解析收发的报文,读取目标MAC地址的信息,和自己记录的MAC表结合,来决策报文的转发目标网口。

    为了实现这些功能,网桥会学习源MAC地址,在转发报文时,网桥只需要向特定的网口进行转发,从而避免不必要的网络交互。

    如果它遇到一个自己从未学习到的地址,就无法知道这个报文应该向哪个网口转发,就将报文广播给所有的网口(报文来源的网口除外)。

    网桥的实现

    Linux内核是通过一个虚拟的网桥设备(Net Device)来实现桥接的。这个虚拟设备可以绑定若干个以太网接口设备,从而将它们桥接起来。如下图所示:

    如上图所示,网桥设备 br0 绑定了 eth0 和 eth1。

    对于网络协议栈的上层来说,只看得到 br0,上层协议栈需要发送的报文被送到 br0,网桥设备的处理代码判断报文该被转发到 eth0 还是 eth1,或者两者皆转发;反过来,从eth0 或 eth1 接收到的报文被提交给网桥的处理代码,在这里会判断报文应该被转发、丢弃还是提交到协议栈上层。

    而有时eth0、eth1 也可能会作为报文的源地址或目的地址,直接参与报文的发送与接收,从而绕过网桥。

    brctl

    和网桥有关的操作可以使用命令 brctl,这个命令来自 bridge-utils 这个包。

    1. 创建网桥

    
     
    1. # 创建网桥

    2. brctl addbr br0

    1. 删除网桥

    
     
    1. # 删除网桥

    2. brctl delbr br0

    1. 绑定网口 建立一个逻辑网段之后,我们还需要为这个网段分配特定的端口。在Linux 中,一个端口实际上就是一个物理或虚拟网卡。而每个网卡的名称则分别为eth0 ,eth1 ,eth2 。我们需要把每个网卡一一和br0 这个网段联系起来,作为br0 中的一个端口。

    
     
    1. # 让eth0 成为br0 的一个端口

    2. brctl addif br0 eth0

    3. # 让eth1 成为br0 的一个端口

    4. brctl addif br0 eth1

    5. # 让eth2 成为br0 的一个端口

    6. brctl addif br0 eth2

    iptables/netfilter

    iptables是Linux实现的软件防火墙,用户可以通过iptables设置请求准入和拒绝规则,从而保护系统的安全。我们也可以把iptables理解成一个客户端代理,用户通过iptables这个代理,将用户安全设定执行到对应的安全框架中,这个“安全框架”才是真正的防火墙,这个框架的名字叫 netfilter。iptables其实是一个命令行工具,位于用户空间。

    iptables/netfilter(以下简称iptables)组成了Linux平台下的包过滤防火墙,可以完成封包过滤、封包重定向和网络地址转换(NAT)等功能。

    消息处理链

    iptables不仅要处理本机接收到的消息,也要处理本机发出的消息。这些消息需要经过一系列的”关卡“才能被本机应用层接收,或者从本机发出,每个”关卡“担负着不同的工作。这里的”关卡“被称为”链“。

    • INPUT:进来的数据包应用此规则链中的策规则;

    • OUTPUT:外出的数据包应用此规则链中的规则;

    • FORWARD:转发数据包时应用此规则链中的规则;

    • PREROUTING:对数据包作路由选择前应用此链中的规则(所有的数据包进来的时侯都先由这个链处理);

    • POSTROUTING:对数据包作路由选择后应用此链中的规则(所有的数据包出来的时侯都先由这个链处理);

    数据包经过各个链的处理过程大致如下图所示:

    规则表

    从上面我们知道,iptables是按照规则来办事的,这些规则就是网络管理员预定义的条件。规则一般的定义为:如果数据包头符合这样的条件,就这样处理“。这些规则并不是严格按照添加顺序排列在一张规则表中,而是按照功能进行分类,存储在不同的表中,每个表存储一类规则:

    • Filter 主要用来过滤数据,用来控制让哪些数据可以通过,哪些数据不能通过,它是最常用的表。

    • NAT 用来处理网络地址转换的,控制要不要进行地址转换,以及怎样修改源地址或目的地址,从而影响数据包的路由,达到连通的目的。

    • Mangle 主要用来修改IP数据包头,比如修改TTL值,同时也用于给数据包添加一些标记,从而便于后续其它模块对数据包进行处理(这里的添加标记是指往内核skb结构中添加标记,而不是往真正的IP数据包上加东西)。

    • Raw 在Netfilter里面有一个叫做链接跟踪的功能,主要用来追踪所有的连接,而raw表里的rule的功能是给数据包打标记,从而控制哪些数据包不做链接跟踪处理,从而提高性能; 优先级最高

    表和链的关系

    表和链共同完成了iptables对数据包的处理。但并不是每个链都包含所有类型的表,所以,有些链是天生不具备某些功能的。就像我们去车站乘车的时候,”关卡A“只负责检查身份证,”B关卡”只负责检查行李,而“C关卡”功能比较齐全,即负责检查身份证,又负责检查行李。二者的关系如下图所示:

    总结

    今天我们共同学习了一些常见的Linux虚拟网络技术。其中,Linux通过Network Namespace实现了网络的隔离,使网络协议栈之间互不干扰;并通过veth pair和网桥实现了相同主机上多个Network Namespace之间的数据通信;iptables则可以帮助我们实现网络安全和数据包的路由转发功能,从而使主机和主机、容器与容器、容器和宿主机之间可以相互收发消息。在这些技术的共同协作下,才有了现在安全、稳定的虚拟网络。

    品略图书馆 http://www.pinlue.com/

     

     

     

     

    展开全文
  • 在教学过程提出了一种基于VMware虚拟网络技术实现DHCP中继代理的设计方案。使用VMware构建虚拟网络环境,然后在Windows Server 2003 中安装DHCP服务,配置路由和远程访问服务来实现不同子网之间的路由,并能为不同...
  • 本文首发于我的公众号码农之屋(id:Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。 导读:Bond技术即bonding,它是Linux Kernel...

    本文首发于我的公众号码农之屋(id: Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。

    导读:Bond技术即bonding,它是Linux Kernel的一个模块,能将多块物理网卡绑定到一块虚拟网卡上,并通过修改网口驱动让多块网卡看起来是一个单独的以太网接口设备(对外只有一个IP),一般用于解决网卡的单点故障或网卡负载较高的场景。


    一、Bond简介

    Bond技术即bonding,它是Linux Kernel的一个模块,能将多块物理网卡绑定到一块虚拟网卡上,并通过修改网口驱动让多块网卡看起来是一个单独的以太网接口设备,外界看到的只有一个IP,一般用于解决网卡的单点故障或网卡负载较高的场景。

    二、Bond技术原理

    Bond技术需要物理网卡开启混杂模式才能正常工作。在混杂模式下,网卡不只接收目的MAC地址为自身的以太网帧,而是接收网络上所有的数据帧。为了实现多块网卡的协同工作,Bond将自己的MAC地址复制到各个物理网卡上,让所有的网卡共享同一个MAC地址。这个方式就要求所有的网卡都要支持BIOS,这样才能够让操作系统将MAC地址写到网卡上。

    对于单物理网卡的Bond网卡来说,Bond网卡的MAC地址和物理网卡的物理地址是一致的。而对于多物理网卡的Bond网卡而言,其中一块物理网卡会被设置为 Master,其他的网卡则都是Slave,Bond网卡的MAC地址取自标志为Master的物理网卡,然后再将这个MAC地址复制到其他物理网卡上。所以在安装网卡时,我们需要指定Bond网卡,以及Bond网卡所对应的标志为Master的物理网卡。

    三、网卡Bond模式

    网卡Bond模式总共有7种,最常用的是负载模式(模式0)和主备模式(模式1),在网络流量较大的场景下推荐使用负载模式,而在可靠性要求较高的场景下则推荐使用主备模式。接下来将对这7种模式进行简单的介绍以及优缺点对比。

    1)模式0

    此模式使用轮询策略,即顺序的在每一个被bond的网卡上发送数据包,这种模式提供负载均衡和容错能力。Bond0可以保证bond虚拟网卡和被bond的两张或多张物理网卡拥有相同的MAC地址,其中bond虚拟网卡的MAC地址是其中一张物理网卡的MAC地址,而bond虚拟网卡的MAC地址是根据bond自己实现的一个算法来选择的。

    在bond0模式下,如果一个连接或者会话的数据包从不同的网口发出,途中再经过不同的链路,则在客户端很有可能会出现数据包无序到达的现象,而无序到达的数据包一般需要重新发送,这样网络的吞吐量就会下降。另外,如果做bond0的两张或多张网卡接到了同一交换机上,还需对交换机配置聚合模式。

    2)模式1

    此模式使用主备策略,在所有做bond1的物理网卡中,同一时刻只有一张网卡被激活,当且仅当活动网卡失效时才会激活其他的网卡。这种模式下做bond的两张或多张网卡的MAC地址和Bond虚拟网卡的MAC地址相同,而Bond的MAC地址是Bond创建启动后活动网卡的MAC地址。

    这种模式要求主被网卡能快速的切换,即当主网卡出现故障后能迅速地切换至备用网卡。切换过程中,上层的应用几乎不受影响,因为Bond的驱动程序会临时接管上层应用的数据包,存放至数据缓冲区,等待备用网卡启动后再发送出去。但是如果切换时间过长,则会引起缓冲区的溢出,导致丢包。

    3)模式2

    此模式的默认选择策略是:选择网卡的序号=(源MAC地址 XOR 目标MAC地址) % Slave网卡(从网卡)的数量。其他的传输策略可以通过xmit_hash_policy配置项指定。

    4)模式3

    模式3使用广播策略,数据包会被广播至所有Slave网卡进行传送。

    5)模式4

    模式4使用动态链接聚合策略,启动时会创建一个聚合组,所有Slave网卡共享同样的速率和双工设定,需要交换机支持IEEE 802.3ad动态链路聚合模式。支持使用ethtool工具获取每个slave网卡的速率和双工设定。

    6)模式5

    模式5基于每个slave网卡的速率选择传输网卡,支持使用ethtool工具获取每个slave网卡的速率。

    7)模式6

    模式6包含了bond5模式,同时还支持对IPV4流量接收时的负载均衡策略,而且不需要任何交换机的支持,支持只是用ethtool获取每个Slave的速率,要求底层驱动支持设置某个网卡设备的硬件地址。

    介绍完这7种模式之后,我们简单对这7种模式的优缺点进行简单的对比,具体的内容请参考以下图1所示。

    图1 Bond网卡7种模式优缺点对比

     

     

    我的公众号「码农之屋」(id: Spider1818) ,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。

    展开全文
  • 目前国内校园网络一般是在以IP 为核心,结合虚拟网络技术的交换式以太网上运行校园网的交换技术,当前作为校园网络主干的网络交换技术主要有两类, 一是ATM 技术, 二是千兆以太网技术。大家请下载
  • 本文首发于我的公众号码农之屋(id:Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。 导读:云化场景到处都是虚拟机和容器,它们...

    本文首发于我的公众号码农之屋(id: Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。

    导读:云化场景到处都是虚拟机和容器,它们背后的网络管理都离不开虚拟网络设备,了解虚拟网络设备将有助于我们更好地理解云化场景的网络架构。本篇文章将对Linux的TUN进行介绍。


    一、虚拟网络设备和物理网络设备的区别

    网络设备就像是一个管道,从其中任意一端收到的数据将从另一端发送出去。比如物理网卡,它的两端分别是内核协议栈和物理网络,从物理网络收到的数据,会转发给内核协议栈,而应用程序从协议栈发过来的数据将会通过物理网络发送出去。

    对于Linux内核网络设备管理模块来说,虚拟设备和物理设备没什么区别,都是网络设备,都能配置IP,从网络设备来的数据,都会转发给内核协议栈,而从协议栈过来的数据,也会交由网络设备发送出去(怎么发送出去的,发到哪里去,那是设备驱动的事情,跟Linux内核没关系)。所以说虚拟网络设备的一端也是协议栈,而另一端是什么则取决于虚拟网络设备的驱动实现。


    二、TUN是什么?它的另一端是什么?

    TUNLinux内核的一种虚拟三层网络设备,纯软件实现,通过此设备可以处理来自网络层的数据。

    从上图可以看出TUN设备和物理设备eth0之间的差别,它们的一端虽然都连着协议栈,但另一端却不一样,eth0连接的是物理网络,而TUN设备的另一端是一个用户态程序,协议栈发给TUN设备的数据包能被这个应用程序读取到,并且应用程序能直接向TUN设备写数据。

    这里列举一个典型的TUN设备的应用场景,host1的进程A跟host2的进程B通信,利用TUN驱动进程,实现隧道封装,从而实现以VPN方式进行通信。

    这里假设host1的eth0 IP为10.10.10.1/24,TUN设备IP为172.168.1.1,而host2的eth0 IP为10.100.10.1/24,TUN设备IP为192.168.1.1。host1和host2网络是互通的。

    下面来我们先来看看在host1上,数据包的发包流程:

    1、host1的应用程序A通过socket发送了一个数据包,目的IP地址是172.168.1.100

    2、socket将这个数据包丢给内核协议栈处理

    3、协议栈根据数据包的目的IP地址,匹配本地路由规则,知道这个数据包应该由TUN虚拟设备出去,于是将数据包交给TUN设备

    4、TUN设备收到数据包之后,发现另一端被TUN驱动进程打开了,于是将数据包丢给了TUN驱动进程

    5、TUN驱动进程收到数据包之后,做一些跟业务相关的处理,然后构造一个新的数据包,将原来的数据包嵌入在新的数据包中,最后通过socke将数据包转发出去,这时候新数据包的源地址变成了eth0的地址,而目的IP地址变成了host2的eth0的IP

    6、socket将数据包丢给内核协议栈

    7、协议栈根据本地路由,发现这个数据包应该要通过eth0发送出去,于是将数据包交给eth0

    8、eth0通过物理网络将数据包发送出去

    接下来我们看下在host2上,数据包的收包流程:

    1、eth0收到数据包之后,把数据包丢给了内核协议栈处理

    2、协议栈进行拆包(仅拆除了外层封装,内层封装由TUN驱动进程处理),根据目的端口号把数据包发给了TUN驱动进程(两主机的TUN驱动进程都是监听同个端口号)

    3、TUN驱动进程拿到数据包后进行解包处理,然后把解出来的包发给TUN设备

    4、TUN设备收到包之后移交给内核协议栈处理

    5、协议栈根据目的IP,发现是送给应用程序B的,于是将数据包交给程序B,最终程序B就收到了程序A给它发的数据包

    从上面的流程中可以看出,数据包选择走哪个网络设备完全由路由表控制,所以如果我们想让某些网络流量走隧道封装的转发流程,就需要配置路由表让这部分数据走TUN设备。


    三、TUN设备有什么用?

    从上面介绍过的流程可以看出来,TUN设备的用处是将协议栈中的部分数据包转发给用户空间的应用程序,给用户空间的程序一个处理数据包的机会。于是比较常用的数据压缩,加密等功能就可以在TUN设备驱动程序实现,TUN设备最常用的场景是VPN,包括tunnel以及应用层的IPSec。


    四、示例程序

    这里写了一个程序,它收到TUN设备的数据包之后,只打印出收到了多少字节的数据包,其它的什么都不做。

    #include <net/if.h>
    #include <sys/ioctl.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <sys/types.h>
    #include <linux/if_tun.h>
    #include<stdlib.h>
    #include<stdio.h>
    
    int tun_alloc(int flags)
    {
    
        struct ifreq ifr;
        int fd, err;
        char *clonedev = "/dev/net/tun";
    
        if ((fd = open(clonedev, O_RDWR)) < 0) {
            return fd;
        }
    
        memset(&ifr, 0, sizeof(ifr));
        ifr.ifr_flags = flags;
    
        if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) {
            close(fd);
            return err;
        }
    
        printf("Open tun/tap device: %s for reading...\n", ifr.ifr_name);
    
        return fd;
    }
    
    int main()
    {
    
        int tun_fd, nread;
        char buffer[1500];
    
        /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
         *        IFF_TAP   - TAP device
         *        IFF_NO_PI - Do not provide packet information
         */
        tun_fd = tun_alloc(IFF_TUN | IFF_NO_PI);
    
        if (tun_fd < 0) {
            perror("Allocating interface");
            exit(1);
        }
    
        while (1) {
            nread = read(tun_fd, buffer, sizeof(buffer));
            if (nread < 0) {
                perror("Reading from interface");
                close(tun_fd);
                exit(1);
            }
    
            printf("Read %d bytes from tun/tap device\n", nread);
        }
    
        return 0;
    }

    我的公众号「码农之屋」(id: Spider1818) ,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。

    展开全文
  • 虚拟网络技术:macvlan

    2019-09-07 13:18:40
    本文首发于我的公众号码农之屋(id:Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。 导读:macvlan是linux kernel提供的网络虚拟...

    本文首发于我的公众号码农之屋(id: Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。

    导读:macvlan是linux kernel提供的网络虚拟化技术之一,它将物理网卡虚拟出多块虚拟网卡,每块虚拟网卡都有自己的mac地址和IP地址,相当于物理网卡施展了多重影分身之术,由一块变成多块。


    一、macvlan简介

    有时我们可能需要一块物理网卡绑定多个IP以及多个MAC地址,虽然绑定多个IP很容易,但是这些IP会共享物理网卡的MAC地址,无法满足我们的设计需求,所以才有了macvlan虚拟网络技术。macvlan是linux kernel v3.9才开始支持的新特性,它一般是以内核模块的形式存在,当前比较稳定的版本是4.0+。

    macvlan听起来有点像vlan,但它们的实现机制是完全不一样的。macvlan子接口和主接口是完全独立的,可以单独配置MAC地址和IP地址,而VLAN子接口和主接口是共用相同的MAC地址。从功能上看,vlan是用来划分广播域,而macvlan则共享同一个广播域。

    macvlan会根据收到包的目的MAC地址判断这个包需要交给哪个虚拟网卡,然后再由虚拟网卡交予上层协议栈进行处理,具体的原理图可以参考图1所示。

    图1 macvlan工作原理图

                                                                                   


    二、四种工作模式

    根据macvlan子接口之间的通信模式,macvlan共有四种网络模式:bridge模式、vepa模式、private模式和passthru模式,默认是使用vepa模式,但是常用的是bridge模式。

    1、bridge模式

    bridge模式只是针对同属于一块宿主物理网卡的macvlan网卡以及宿主网卡之间的通信行为的,与外部通信无关。所谓的bridge指的是在这些网卡之间,数据流可以实现直接转发,不需要外部的协助,这有点像在Linux内建了一个bridge,但比bridge要好的一点是每块网卡的MAC地址都是已知的,不需要重新学习。

    图2 bridge模式(子接口可直接互通)

                                                                           

    2、vepa模式

    vepa模式下,子接口间不能直接通信,必须要通过与物理网卡相连的外部交换机(物理或虚拟的都可以,需支持802.1Qbg/VPEA功能,直白点就是数据包从接口收到上之后还能传回去)的协助,经由外部交换机转发,再绕回来。

    图3 vepa模式(子接口无法直接互通,需借助外界力量)

     

    3、private模式

    private模式的隔离性比vepa模式更强。在private模式下,即使是macvlan eth1和macvlan eth2同时配在在eth0上,eth0连接了外部交换机S,S支持“发夹弯”转发模式,macvlan eth1的广播/多播流量也无法到达macvlan eth2,反之亦然。也就是说,private模式下,子接口间是无法通信的。

    图4 private模式(子接口无法互通)

     

    4、passthrough模式

    passthrough模式只允许单个子接口连接主接口,且主接口必须设置成混杂模式,一般用于子接口桥接和创建vlan子接口的场景。

    图5 passthrough模式(一主接口仅虚拟出一子接口)

    三、macvlan收发包报文流程

    对于macvlan的收发包流程,这里不再一一介绍,具体的流程可参考图6所示,建议能够结合内核代码,加深macvlan收发包流程的理解。

    图6 macvlan收发包处理流程

    四、示例

    单独使用macvlan技术是毫无意义的,一般都是结合VM或容器来构建网络。下面我们就简单使用namespace来看看怎么使用macvlan的。以接口eth0为例创建两个macvlan子接口(使用bridge模式),配置IP并将其挂到两个namespace中,测试两macvlan子接口是否能通,具体的实验拓展图请参考图7所示。

     

    图7 实验拓展图

     

    1、创建2 macvlan子接口

    [root@node]# ip link add link eth0 dev macvlaneth00 type macvlan mode bridge[root@node]# ip link add link eth0 dev macvlaneth01 type macvlan mode bridge

    2、创建2 net namespace,并把2 macvlan子接口分别挂到2 namespace中

    [root@node]# ip netns add ns2[root@node]# ip netns add ns3[root@node]# ip link set macvlaneth00 netns ns2[root@node]# ip link set macvlaneth01 netns ns3
    

    3、配置macvlan子接口IP(需与eth0同网段),并启动

    [root@node]# ip netns exec ns2 ip a a 200.10.10.112/24 dev macvlaneth00[root@node]# ip netns exec ns3 ip a a 200.10.10.116/24 dev macvlaneth01[root@node]# ip netns exec ns2 ip l s macvlaneth00 up[root@node]# ip netns exec ns3 ip l s macvlaneth01 up

    4、验证2 macvlan子接口之间是否能通(从实验结果看,bridge模式下,2子接口是可以直接互通的)​​​​​​​

    [root@node]# ip netns exec ns3 ping 200.10.10.112PING200.10.10.112 (200.10.10.112) 56(84) bytes of data.64bytes from 200.10.10.112: icmp_seq=1 ttl=64 time=0.097 ms64bytes from 200.10.10.112: icmp_seq=2 ttl=64 time=0.065 ms64bytes from 200.10.10.112: icmp_seq=3 ttl=64 time=0.073 ms^C
    ---200.10.10.112 ping statistics ---3packets transmitted, 3 received, 0% packet loss, time 1999msrttmin/avg/max/mdev = 0.065/0.078/0.097/0.015 ms
    [root@node]# ip netns exec ns2 ping 200.10.10.116PING200.10.10.116 (200.10.10.116) 56(84) bytes of data.64bytes from 200.10.10.116: icmp_seq=1 ttl=64 time=0.056 ms64bytes from 200.10.10.116: icmp_seq=2 ttl=64 time=0.075 ms64bytes from 200.10.10.116: icmp_seq=3 ttl=64 time=0.077 ms64bytes from 200.10.10.116: icmp_seq=4 ttl=64 time=0.056 ms^C
    ---200.10.10.116 ping statistics ---4packets transmitted, 4 received, 0% packet loss, time 2999msrttmin/avg/max/mdev = 0.056/0.066/0.077/0.010 ms

    ​​​​​​​

    我的公众号「码农之屋」(id: Spider1818) ,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。

    展开全文
  • 本文首发于我的公众号码农之屋(id:Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。 导读:云化场景到处都是虚拟机和容器,它们...
  • 虚拟网络技术:ipvlan

    千次阅读 2019-09-07 13:28:52
    本文首发于我的公众号码农之屋(id:Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。 导读:ipvlan是linux kernel比较新颖的特性...
  • 本文首发于我的公众号码农之屋(id:Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。 导读:云化场景到处都是虚拟机和容器,它们...
  • 网络虚拟技术

    2011-12-01 23:47:04
    网络虚拟技术,交换机,网络虚拟技术,交换机
  • 网络虚拟化互通技术

    2021-01-19 19:38:14
    工业界和学术界提出了许多新的网络虚拟技术来满足云计算环境对网络服务的需求。网络虚拟技术的多样化使得云环境面临多种网络虚拟技术共存的状况。然而,网络虚拟技术间的差异会导致网络资源被分割成相互间不...
  • 网络虚拟技术在云计算数据中心的应用 云计算带来的超大规模数据中心建设,对数据中心网络提出了新的需求,网络虚拟技术是解决这些新需求的有效手段本文通过系统论述数据中心网络虚拟技术中涉及的控制平面虚拟化...
  • H3C IRF虚拟网络技术架构
  • 网络虚拟技术

    2018-04-21 10:36:00
    网络虚拟技术
  • 空间信息网络资源虚拟技术
  • 云计算中心网络虚拟技术.pdf
  • 虚拟网络感知技术

    千次阅读 2014-01-27 14:27:39
     VN-Tag的核心思想就是在现有的以太网数据桢的VLAN标识前面(或者源/目的MAC后面)增加一个专用标记字段VN-Tag,这个VN-Tag主要是dvif_id和svif_id一对地址,分别对应于源和目的虚拟机的虚拟网络接口VIF,
  • 了解虚拟技术基础、服务器虚拟化、存储虚拟化和网络虚拟技术
  • 浅谈网络虚拟技术

    2020-11-24 11:30:25
    数通网络虚拟化主要体现为对物理网络资源的抽象、切割和组合,最基本的网络虚拟化方式包括资源切割、资源聚合以及虚拟连接等3类。 1、资源切割 物理设备、链路或端口可以被划分为多个逻辑单位,通过对逻辑单位内资源...
  • 虚拟技术网络大会

    2017-11-14 13:41:00
    这是一份给所有“2009中国虚拟技术网络大会”参与者的谢意。 首先要感谢51CTO的忠实用户们,半年来你们对“2009中国虚拟技术网络大会”活动的关注和积极参与,帮助51CTO收集了数千例反馈,从而得出了这些能够...
  • 网络虚拟技术大观

    2018-04-23 23:52:00
    网络虚拟化(Network Virtualization)就是搭建一个与物理网络拓扑结构不同的虚拟网络。例如公司在世界各地有多个办事处,但希望公司的内部网络是一个整体,就需要网络虚拟化技术。&#13; 从 NAT 说起&#13...
  • Linux网络虚拟技术详解 【Linux虚拟化简介】 虚拟化是当今计算机及网络领域热门的技术方向之一,在某种程度上它为用户屏蔽了计算机底层异构系统的复杂性,带给用户操作及管理计算机系统上的极大方便性并降低了...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,466
精华内容 5,386
关键字:

虚拟网络技术