【学习VPN之路】Linux虚拟网络

294 阅读21分钟

1. 前言

  • 在共有云快速发展的时代,厂商为了快速部署,发明了容器技术(Docker/K8s),并跟随云快速跌打发展。容器技术的其中一个核心目标是:在物理网络基础上,构建多个独立的 “虚拟网络”,彼此隔离且可灵活配置。
    • 比如在一台物理机器上部署多个Docker容器,每个Docker容器具备独立的IP,并且链接到自己专属的网络中,这个网络中有部署了数据库服务、文件服务、web服务的Docker,这些Docker可能在一台物理机器上,也可能不在一台物理机器上,但Docker的使用者不关心这些Docker容器物理上是否在一台机器&物理上是否在一个局域网中,而是关心在Docker内部是否可以像在一个网络中一样可以访问上面的服务。
    • 再比如在家里突然要访问公司内网里的一台web服务器提供的网页,怎么办?需要通过VPN+虚拟网络技术为你的家里的电脑虚拟化一个公司内网的环境,家里电脑有了这个环境就可以像在公司内网一样方案web服务器。这里要用到TUN虚拟网卡、网络转发技术、NET技术、加密技术等。

2. 什么是虚拟网络

Linux 网络虚拟化的核心是隔离抽象

  • 隔离:不同虚拟网络中的设备 / 流量互不干扰(如容器 A 和容器 B 的网络完全独立)。
  • 抽象:通过虚拟设备(如虚拟网卡、虚拟交换机)屏蔽物理网络细节,简化配置。

2.1.1. 二、常用技术及示例

下面从基础到复杂,介绍核心技术及实操示例:

2.1.1.1. 1. Network Namespace:网络栈隔离的基础

作用:为进程提供独立的网络栈(包括独立的网卡、路由表、ARP 表、iptables 规则等),是容器 / 虚拟机网络隔离的底层依赖。
类比:每个 namespace 相当于一个 “独立的网络环境”,进程在其中看到的网络资源与其他 namespace 完全隔离。

示例:创建两个隔离的 Network Namespace 并通信

# 1. 创建两个namespace:ns1和ns2
ip netns add ns1
ip netns add ns2

# 2. 创建一对VETH虚拟网卡(veth0和veth1,类似“虚拟网线”,两端需分别放入不同namespace)
ip link add veth0 type veth peer name veth1

# 3. 将veth1放入ns1,veth0放入ns2
ip link set veth1 netns ns1
ip link set veth0 netns ns2

# 4. 为两个namespace中的VETH网卡配置IP并启动
ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth1  # ns1的veth1配置IP
ip netns exec ns1 ip link set veth1 up              # 启动veth1
ip netns exec ns1 ip link set lo up                 # 启动回环接口(否则ping可能失败)

ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth0  # ns2的veth0配置IP
ip netns exec ns2 ip link set veth0 up
ip netns exec ns2 ip link set lo up

# 5. 测试隔离性:在ns1中ping ns2的IP(能通,因为VETH连接)
ip netns exec ns1 ping 10.0.0.2  # 成功:PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.042 ms

# 6. 验证隔离:ns1中看不到ns2的其他网络资源(如ns2的lo接口)
ip netns exec ns1 ip link show  # 只能看到veth1和lo,看不到ns2的veth0
2.1.1.2. 2. VETH 对:跨 Namespace 通信的 “虚拟网线”

作用:VETH(Virtual Ethernet)是一对 “peer 接口”,数据从一端进入后会直接从另一端流出,用于连接两个网络命名空间(或连接 namespace 与物理网络)。
类比:像一根网线,一端插在 “房间 A(ns1)”,另一端插在 “房间 B(ns2)”,让两个隔离环境能通信。

2.1.1.3. 3. Linux Bridge:虚拟交换机

作用:Bridge(网桥)是二层虚拟交换机,可连接多个虚拟接口(如 VETH、虚拟机网卡),实现它们之间的二层通信(类似物理交换机)。
场景:当需要多个 namespace / 容器 / 虚拟机在二层互通时,用 Bridge 连接它们。

示例:用 Bridge 连接 3 个 namespace

bash

# 1. 创建Bridge(虚拟交换机)
ip link add br0 type bridge
ip link set br0 up  # 启动网桥

# 2. 创建3个namespace:ns1、ns2、ns3
ip netns add ns1
ip netns add ns2
ip netns add ns3

# 3. 为每个namespace创建VETH对,一端连Bridge,另一端连namespace
# 连接ns1和br0
ip link add veth1 type veth peer name veth1-br
ip link set veth1 netns ns1
ip link set veth1-br master br0  # 将veth1-br挂到br0上
ip link set veth1-br up
ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth1
ip netns exec ns1 ip link set veth1 up
ip netns exec ns1 ip link set lo up

# 连接ns2和br0(步骤同上)
ip link add veth2 type veth peer name veth2-br
ip link set veth2 netns ns2
ip link set veth2-br master br0
ip link set veth2-br up
ip netns exec ns2 ip addr add 192.168.1.2/24 dev veth2
ip netns exec ns2 ip link set veth2 up
ip netns exec ns2 ip link set lo up

# 连接ns3和br0(步骤同上)
ip link add veth3 type veth peer name veth3-br
ip link set veth3 netns ns3
ip link set veth3-br master br0
ip link set veth3-br up
ip netns exec ns3 ip addr add 192.168.1.3/24 dev veth3
ip netns exec ns3 ip link set veth3 up
ip netns exec ns3 ip link set lo up

# 4. 测试通信:ns1 ping ns2/ns3(通过br0转发,二层互通)
ip netns exec ns1 ping 192.168.1.2  # 成功
ip netns exec ns1 ping 192.168.1.3  # 成功
2.1.1.4. 4. VLAN:二层隔离技术

作用:VLAN(Virtual LAN)通过在以太网帧中添加 VLAN 标签(Tag),将同一物理网络划分为多个逻辑子网(VLAN),实现二层隔离(不同 VLAN 的设备默认不能直接通信)。
类比:同一栋楼(物理网络)被分成多个独立的房间(VLAN),房间内可通信,跨房间需通过路由器。

示例:用 VLAN 隔离 Bridge 上的设备

bash

# 1. 创建带VLAN支持的Bridge
ip link add br0 type bridge
ip link set br0 up

# 2. 创建两个VETH对,分别加入VLAN 10和VLAN 20
# VLAN 10的设备:ns1的veth1-br加入br0的vlan 10
ip link add veth1 type veth peer name veth1-br
ip link set veth1 netns ns1
ip link set veth1-br master br0
ip link set veth1-br up
ip link set veth1-br type bridge_slave vlan_tci 0x100  # 打上VLAN 10标签(0x100表示vlan 10)
ip netns exec ns1 ip addr add 10.0.10.1/24 dev veth1
ip netns exec ns1 ip link set veth1 up

# VLAN 20的设备:ns2的veth2-br加入br0的vlan 20
ip link add veth2 type veth peer name veth2-br
ip link set veth2 netns ns2
ip link set veth2-br master br0
ip link set veth2-br up
ip link set veth2-br type bridge_slave vlan_tci 0x200  # 打上VLAN 20标签
ip netns exec ns2 ip addr add 10.0.20.1/24 dev veth2
ip netns exec ns2 ip link set veth2 up

# 3. 测试隔离:ns1 ping ns2失败(VLAN不同)
ip netns exec ns1 ping 10.0.20.1  # 失败(无响应)

# 4. 同一VLAN内通信:再创建ns3加入VLAN 10,与ns1通信
ip netns add ns3
ip link add veth3 type veth peer name veth3-br
ip link set veth3 netns ns3
ip link set veth3-br master br0
ip link set veth3-br up
ip link set veth3-br type bridge_slave vlan_tci 0x100  # VLAN 10
ip netns exec ns3 ip addr add 10.0.10.2/24 dev veth3
ip netns exec ns3 ip link set veth3 up
ip netns exec ns1 ping 10.0.10.2  # 成功(同VLAN)
2.1.1.5. 5. VXLAN:跨主机的虚拟网络(Overlay 网络)

作用:VXLAN(Virtual Extensible LAN)是三层 Overlay 技术,通过将二层帧封装在 UDP 报文中(外层是物理网络 IP),实现跨物理主机的虚拟网络(让不同物理机上的虚拟设备感觉在同一二层网络)。
场景:云平台中,跨主机的容器 / 虚拟机通信(如 K8s 的 Flannel 网络插件默认用 VXLAN)。

核心原理

  • 每个 VXLAN 网络有一个唯一的 VNI(VXLAN Network Identifier,类似 VLAN ID)。
  • 发送端将虚拟网络的二层帧封装成 UDP 包(外层 IP 是物理机 IP),通过物理网络发送。
  • 接收端解封装,得到原始二层帧,转发到目标虚拟设备。

3. 虚拟网络在解决什么问题

虚拟网络(Virtual Networking)是通过软件技术将物理网络资源抽象、模拟或重组为逻辑网络的技术,其核心目标是解决传统物理网络在灵活性、效率、隔离性等方面的局限。以下从具体问题场景出发,说明虚拟网络解决的核心问题:

3.1. 解决 “物理硬件依赖与资源浪费” 问题

传统物理网络高度依赖物理设备(交换机、路由器、防火墙等),存在两个核心痛点:

  • 硬件成本高:每增加一个子网或业务,可能需要采购新的物理交换机、配置专用布线,成本随规模线性增长;
  • 资源利用率低:物理设备的端口、带宽等资源往往无法充分利用(例如一台 48 口交换机可能仅用 10 个端口),闲置资源浪费严重。

虚拟网络通过软件定义网络(SDN)、虚拟交换机(如 Open vSwitch)等技术,将物理网络资源抽象为 “虚拟端口”“虚拟路由” 等逻辑资源,无需依赖特定物理设备即可构建网络。例如:
在 Linux 中,通过bridge-utils创建虚拟网桥(br0),将多个虚拟网卡(veth)或物理网卡(eth0)接入网桥,即可模拟一个交换机的功能,无需额外物理硬件,大幅降低成本并提高资源利用率。

3.2. 解决 “多场景网络隔离不足” 问题

在多租户(如云计算)、多业务(如企业内部办公网与业务网)场景中,传统网络的隔离手段存在局限:

  • VLAN 的局限性:传统通过 VLAN 隔离网络,但 VLAN 最多支持 4096 个(12 位标识),无法满足大规模场景(如公有云需要支持数万租户);
  • 隔离不彻底:VLAN 依赖物理交换机配置,不同 VLAN 的流量仍可能在同一物理链路传输,存在数据泄露风险;
  • 灵活度低:调整 VLAN 划分需重新配置物理设备,无法快速适配业务变化。

虚拟网络通过隧道技术(如 VxLAN、GRE)或网络命名空间(Network Namespace) 实现更彻底的隔离:

  • VxLAN:通过将二层帧封装在 UDP 报文中(外层 IP 为物理网络地址),用 24 位 VNI(虚拟网络标识)区分租户,支持 1600 万个虚拟网络,满足大规模隔离需求;
  • Network Namespace:在 Linux 中,每个 namespace 拥有独立的网络栈(网卡、路由表、iptables 规则),不同 namespace 的虚拟网卡(如veth对)通过虚拟网桥或隧道通信,实现 “逻辑上完全独立” 的网络环境(例如 Kubernetes 中每个 Pod 的网络隔离依赖 namespace)。

3.3. 解决 “网络扩展与弹性不足” 问题

传统物理网络的扩展依赖人工配置,难以应对动态变化的业务需求:

  • 扩展慢:新增一个子网或路由规则,需要手动登录物理路由器 / 交换机配置(如router# ip route 192.168.2.0/24 10.0.0.1),耗时且易出错;
  • 弹性差:业务高峰时需要临时扩容带宽或增加节点,传统网络无法自动调整,可能导致服务中断。

虚拟网络通过软件自动化动态适配解决这一问题:

  • 自动化配置:通过 API(如 Open vSwitch 的ovs-vsctl、SDN 控制器的 REST API)可批量创建虚拟网络资源。例如,在云计算平台中,用户创建虚拟机时,系统自动调用 API 为其分配虚拟网卡、配置虚拟子网和路由,全程无需人工干预;
  • 弹性调整:当业务负载变化时,虚拟网络可动态调整带宽、路由路径。例如,Kubernetes 的 CNI 插件(如 Calico)可根据 Pod 的创建 / 销毁,自动更新虚拟路由表和 ACL 规则,确保网络随业务弹性伸缩。

3.4. 解决 “跨物理环境网络割裂” 问题

现代业务常分布在多物理环境(本地数据中心、公有云、边缘节点),传统网络因依赖物理位置,难以实现跨环境统一通信:

  • 物理位置限制:本地服务器与云服务器分属不同物理网络,需通过专线或公网通信,延迟高且成本高;
  • 管理复杂:跨环境网络的路由、防火墙规则需在多个物理设备上分别配置,一致性难以保证。

虚拟网络通过逻辑网络抽象打破物理位置限制:
例如,企业可通过 VxLAN 隧道将本地数据中心的服务器、AWS 云服务器、边缘节点的设备 “编织” 成一个逻辑上的虚拟网络(Overlay 网络)。这些设备的 IP 地址属于同一虚拟子网(如10.1.0.0/24),通信时通过隧道封装(外层 IP 为物理网络地址)跨物理环境传输,逻辑上如同在同一局域网内,且由统一的 SDN 控制器管理路由和安全策略,简化跨环境网络管理。

3.5. 解决 “开发测试环境搭建效率低” 问题

在网络协议开发、应用测试中,需要频繁构建特定网络场景(如复杂子网划分、异常路由拓扑),传统方式存在效率问题:

  • 搭建耗时:为测试 “跨 3 个子网的 ping 通信”,需准备多台物理机、交换机,手动配置 IP 和路由,可能耗时数小时;
  • 复用性差:测试完成后物理设备需重新配置才能用于其他场景,资源无法快速复用。

虚拟网络可快速构建 “一次性” 测试环境:
通过 Linux 的ip netns(网络命名空间)、veth(虚拟网卡对)、iptables(模拟防火墙)等工具,可在单台物理机上构建复杂虚拟网络。例如:

# 创建3个网络命名空间(模拟3台主机)
ip netns add ns1; ip netns add ns2; ip netns add ns3

# 创建虚拟网卡对,连接命名空间与虚拟网桥(模拟交换机)
ip link add veth1 type veth peer name br-veth1
ip link add veth2 type veth peer name br-veth2
ip link add veth3 type veth peer name br-veth3

# 将虚拟网卡接入命名空间和网桥
ip link set veth1 netns ns1
brctl addif br0 br-veth1 br-veth2 br-veth3

# 配置IP和路由(模拟跨子网通信)
ip netns exec ns1 ip addr add 192.168.1.10/24 dev veth1
ip netns exec ns2 ip addr add 192.168.2.10/24 dev veth2
ip route add 192.168.1.0/24 via 192.168.2.1  # 配置ns2到ns1的路由

通过上述命令,10 分钟内即可在单台物理机上构建包含 3 个节点、跨子网的虚拟网络,测试完成后可通过ip netns delete快速销毁,大幅提升开发测试效率。

4. 哪些应用使用了虚拟网络

4.1. WireGuard VPN

wg使用了tun虚拟网卡。wg客户端通过“tun+路由规则”拦截所有的发往外网IP包,并将这些IP包加密打包到UPD里,最后发送给wg服务端进行转发到的目标服务器。

这里wg通过tun技术组件了一个虚拟网络,虚拟网络的节点包括所有wg客户端和wg服务器。在虚拟网络里,每个节点都有自己的虚拟IP,wg服务端就像管理内网的主机一下管理wg客户端,其实它们在不同的网络,中间隔了公网。

4.2. Docker

  1. 核心组件
    • Network Namespace:每个容器有独立的 “网络小房间”,包含网卡、路由表。
    • veth Pair:虚拟网线,一端插容器,一端插宿主机网桥(类似交换机)。
    • docker0 网桥:宿主机上的虚拟交换机,连接所有容器的 veth。
  1. 容器间通信
    • 同一宿主机:容器 A→veth→docker0 网桥→veth→容器 B(二层直接互通)。
    • 跨宿主机:数据包通过 VXLAN 隧道封装,“假装” 在同一局域网。
  1. 访问外网
    • 容器数据包→docker0 网桥→宿主机网卡→NAT(容器 IP 换宿主机 IP)→公网。

类比:
Docker 像公寓楼,每个房间(容器)有独立网线(veth)插在总交换机(docker0),房间内设备(进程)互访通过交换机,出公寓楼(外网)时统一用公寓 IP(NAT)。

5. TUN 虚拟网卡:网络世界的「隐形管道工」

5.1. 本质:用户空间与内核的「桥梁」

TUN 是 Linux 内核提供的虚拟网络设备,工作在网络层(IP 层) ,允许用户空间程序直接发送和接收原始 IP 数据包。它通过字符设备/dev/net/tun与用户空间交互,就像一根「透明管道」——

  • 从内核到用户空间:当内核收到目的 IP 为 TUN 设备的数据包时,会将其写入/dev/net/tun,供用户程序读取;
  • 从用户空间到内核:用户程序写入/dev/net/tun的数据包会被内核视为从 TUN 设备接收,触发路由转发流程。

5.2. 解决的核心问题:突破内核「黑箱」

在 TUN 出现前,网络协议栈完全由内核控制,用户程序无法直接干预数据包处理。这导致两大痛点:

  1. 定制化网络功能受限
    例如,想实现 VPN 加密隧道时,需在内核中修改代码,这既复杂又危险。TUN 允许用户程序在用户空间封装 / 解封装 IP 包,无需修改内核。
  2. 流量控制不灵活
    传统方式难以实现细粒度的流量监控、负载均衡或自定义路由。TUN 让用户程序像「网络协议栈的外挂」,直接拦截和处理数据包。

5.3. 发明背景:2000 年代 VPN 的「突围战」

TUN 诞生于2000 年左右,最初由 Solaris 系统为实现隧道协议开发,后被移植到 Linux 内核(2.1 版引入,2.4 版默认集成)。其出现的直接动因是:

  • VPN 技术爆发期的需求
    2000 年代初,远程办公兴起,VPN 成为刚需。但当时主流的 IPsec 协议需在内核实现,部署复杂。TUN 的出现让开发者能在用户空间构建 VPN 隧道(如 OpenVPN),极大降低了技术门槛。
  • 网络虚拟化的萌芽
    云计算尚未普及,但虚拟化技术(如 QEMU-KVM)已开始探索。TUN 为虚拟机提供了灵活的网络接口,使其能通过用户空间程序与物理网络交互。

5.4. 经典应用场景:让数据「七十二变」

  1. VPN 加密隧道
    • 客户端程序通过 TUN 拦截所有进出的 IP 包,加密后封装到 UDP/IP 包中,通过公网传至服务器;服务器解封装后转发到内网。
    • WireGuard正是基于 TUN 实现,性能远超传统 VPN。
  1. 容器跨主机通信
    • 容器网络方案(如 Flannel)通过 TUN 设备构建 Overlay 网络,将跨主机流量封装成隧道包,实现容器间「逻辑同网段」。类似与wireguard组件虚拟网络,让家里的电脑可以访问公司内网。
  1. 流量监控与安全
    • 网络分析工具(如 Wireshark)可通过 TUN 捕获特定 IP 段的数据包,实现实时监控;
    • 入侵检测系统(IDS)可拦截可疑数据包并触发警报。

5.5. TUN 设备的特性:

  1. 虚拟化网络接口
    • TUN 设备是一个虚拟的网络接口,它模拟了一个真实的网络接口,允许用户空间的程序通过它发送和接收数据包。
    • TUN 设备通常与操作系统的网络栈进行交互,数据包通过 TUN 设备进入或离开系统。
  1. 基于 IP 层的数据处理
    • TUN 设备仅处理 IP 数据包(即,3 层数据包)。这意味着它不会关心帧的其他信息(如 MAC 地址)。它直接处理原始的网络协议栈数据。
    • 与 TUN 类似的 TAP 设备是基于数据链路层的,它处理 Ethernet 帧。TUN 只关心 IP 层的数据,因此它适用于 IP 隧道和 VPN。
  1. 用户空间接口
    • TUN 设备是由用户空间的程序来控制的,而不是内核直接管理。这使得它非常适合于用户自定义的网络应用,比如创建自定义 VPN 协议或其他网络隧道。
    • 用户空间的程序通过读取和写入 TUN 设备来与操作系统的内核进行通信。
  1. 支持路由和流量转发
    • TUN 设备允许设置路由规则,将通过它的数据包转发到其他网络接口或者隧道中。常见的应用场景是设置 VPN 服务,通过 TUN 设备将加密的 IP 数据包发送到远端服务器。
    • 它能与系统的网络栈进行交互,配合路由和 NAT 规则来处理数据包。
  1. 用于 VPN 隧道
    • TUN 设备常用于实现 IP 隧道。像 WireGuard、OpenVPN 等 VPN 协议都使用 TUN 设备来传输加密后的数据包。
    • 通过 TUN 设备,VPN 客户端或服务端可以创建一个私有网络通道,在这个通道中传输原始 IP 数据包,实现对跨网络的数据保护。
  1. 透明性
    • TUN 设备对操作系统和应用程序来说是透明的,它充当了网络栈的一部分。当数据包通过 TUN 设备时,它们看起来像是通过物理网络接口传输的一样,只是通过虚拟接口进行。
    • 用户空间应用程序通过读写设备文件来访问数据,而操作系统的内核负责将数据传递给相应的网络协议栈。
  1. 内存映射与异步操作
    • 数据从内核发送到用户空间,或者反向从用户空间发送到内核时,通常使用内存映射(mmap)技术,允许高效的数据传输。
    • 这种机制支持异步操作,允许应用程序在等待数据传输时不阻塞,从而提高性能,尤其是在处理大量数据时。
  1. 支持多个虚拟接口
    • 系统可以创建多个 TUN 设备,每个设备都可以用于不同的虚拟网络。比如,你可以在一个系统中同时运行多个 VPN 隧道,每个隧道通过独立的 TUN 设备进行管理。
    • 每个 TUN 设备都可以配置不同的 IP 地址和路由规则,以支持不同的网络配置。
  1. 没有数据链路层(L2)
    • 与 TAP 设备不同,TUN 设备不涉及以太网帧的传输,只处理 IP 数据包。因此,它不处理 Ethernet 框架的 MAC 地址,而是专注于 IP 地址的转发和处理。
  1. 操作系统兼容性
    • TUN 设备在许多主流操作系统中都有支持,包括 Linux、FreeBSD、macOS 等。
    • 在 Linux 中,TUN 设备通常由 TUN 驱动程序管理,而在其他系统中,TUN 设备的支持和配置可能略有不同,但基本概念是一致的。

5.5.1. TUN 设备的应用场景:

  1. VPN(虚拟专用网络)
    • TUN 设备通常用于创建 VPN 隧道,将用户的数据通过安全的加密隧道传输到远程服务器。WireGuard、OpenVPN 等 VPN 软件都使用 TUN 设备来实现数据隧道功能。
  1. 隧道协议的实现
    • 可以通过 TUN 设备实现自定义的隧道协议,例如将不同网络隔离或绕过 NAT 和防火墙。
  1. 流量过滤和转发
    • TUN 设备可用于网络流量的过滤和转发,支持自定义路由规则,以实现特定的流量控制或安全功能。
  1. 跨网络通信
    • 通过设置 TUN 设备,可以在不同的网络之间建立直接通信的隧道,常见的场景包括跨越公共网络(如互联网)进行企业间通信。

TUN 设备通过将虚拟网络接口与操作系统的网络栈连接起来,极大地简化了虚拟网络的构建和配置。如果你有具体的 TUN 使用问题或案例,欢迎继续询问。

5.6. 与其他虚拟设备的对比

技术工作层次核心功能典型场景
TUN三层(IP)直接处理 IP 包,支持用户空间自定义逻辑VPN 隧道、容器跨主机通信
Tap二层(MAC)处理以太网帧,类似虚拟交换机端口虚拟机桥接网络
Veth Pair二层(MAC)容器与宿主机间的双向管道Docker 容器互联

5.7. 总结:虚拟网络的「基石」

TUN 的价值在于将网络控制权下放给用户空间,让开发者能以更低成本实现复杂网络功能。从 VPN 到容器云,从加密通信到流量优化,TUN 始终是网络虚拟化的「隐形基石」。它的出现标志着网络技术从「内核垄断」走向「用户可编程」,为现代云计算和边缘计算奠定了基础。