当前位置: 首页 > news >正文

[Linux] 网络中的 `tun` 模式

引言

在网络编程和虚拟化技术中,tun 模式是一个非常重要的概念。

它通常用于实现虚拟网络设备,广泛应用于 VPN、容器网络、虚拟化环境等场景。

VPN(虚拟专用网络)就像一条加密的“秘密通道”,让你在公共网络上安全地访问私有网络资源,就像在家里的局域网一样安全)

在这里插入图片描述

本文将详细介绍 tun 模式的工作原理、应用场景以及它与 tap 模式的区别。

什么是 tun 模式?

tun(全称 Network TUNnel)是 Linux 内核提供的一种虚拟网络设备,工作在网络层(IP 层)

它模拟了一个点对点的网络设备,可以用于传输 IP 数据包。与物理网卡不同,tun 设备并不直接处理链路层(如以太网帧),而是专注于 IP 数据包的传输

特性

  1. 工作在 IP 层tun 设备只处理 IP 数据包,不涉及 MAC 地址或以太网帧。
  2. 点对点通信tun 设备通常用于两个端点之间的通信,类似于 VPN 中的隧道
  3. 用户空间驱动tun 设备的数据包由用户空间的程序处理,而不是内核协议栈。

tun 模式的工作原理

tun 设备的核心功能是将内核生成的 IP 数据包传递给用户空间的程序,或者将用户空间的 IP 数据包注入内核协议栈。以下是其工作流程:

  1. 数据包从内核到用户空间

    • 当内核需要发送一个 IP 数据包时,如果目标地址指向 tun 设备,数据包会被传递到用户空间的程序。
    • 用户空间的程序可以对这些数据包进行加密、封装或其他处理。
  2. 数据包从用户空间到内核

    • 用户空间的程序可以将处理后的 IP 数据包写入 tun 设备。
    • 内核会将这些数据包视为从外部接收的 IP 数据包,并进行路由或转发

示例

以下是一个简单的 tun 设备创建和使用的代码片段(C 语言):

#include <fcntl.h>
#include <linux/if_tun.h>
#include <sys/ioctl.h>int tun_alloc(char *dev) {struct ifreq ifr;int fd, err;if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {perror("Opening /dev/net/tun");return fd;}memset(&ifr, 0, sizeof(ifr));ifr.ifr_flags = IFF_TUN | IFF_NO_PI;strncpy(ifr.ifr_name, dev, IFNAMSIZ);if ((err = ioctl(fd, TUNSETIFF, (void *)&ifr)) < 0) {close(fd);perror("ioctl(TUNSETIFF)");return err;}return fd;
}

code:https://github.com/lvy010/linux-core
在这里插入图片描述

代码实现了一个名为tun_alloc的函数,用于在Linux系统中创建和配置TUN虚拟网络设备。

TUN设备属于操作系统内核中的虚拟网络接口,常用于实现VPN、隧道协议或网络层数据包处理。

解析

头文件引入

  • <fcntl.h>:提供文件控制相关函数(如open)和标志(如O_RDWR)。
  • <linux/if_tun.h>:定义TUN/TAP设备的常量(如IFF_TUN)和结构体(如ifreq)。
  • <sys/ioctl.h>:声明ioctl系统调用,用于设备配置。

函数参数

  • char *dev:指定要创建的TUN设备名称(如"tun0"),若为空则由内核自动分配。

核心流程

  1. 打开设备文件

    fd = open("/dev/net/tun", O_RDWR);
    

    以读写模式打开Linux的TUN设备控制文件,失败时返回负值并打印错误。

  2. 初始化结构体

    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
    strncpy(ifr.ifr_name, dev, IFNAMSIZ);
    
    • ifreq结构体清零后设置标志位:
      • IFF_TUN:创建三层(IP层)设备(区别于二层的IFF_TAP)。
      • IFF_NO_PI:禁用数据包信息头(Packet Information)。
    • 将用户指定的设备名复制到结构体中(最多IFNAMSIZ字符)。
  3. 配置设备

    ioctl(fd, TUNSETIFF, &ifr);
    

    通过TUNSETIFF命令绑定设备:

    • dev名称已存在则关联现有设备。
    • 若名称为空或未使用则创建新设备,内核可能修改ifr.ifr_name为实际名称。
  4. 错误处理
    失败时关闭文件描述符并返回错误码,成功则返回可用于读写数据的文件描述符。

应用场景

  • 读取fd可获取其他主机发送到该TUN设备的IP数据包。
  • 写入fd可模拟从该TUN设备发出的IP数据包。
  • 结合routeiptables配置路由才能使设备正常工作

详见code: https://github.com/lvy010/linux-core/tree/main/tun_test

运行测试:

在这里插入图片描述

安全注意事项

  • 需要CAP_NET_ADMIN权限或root用户身份执行。
  • 设备名称长度不应超过IFNAMSIZ(通常为16字节),strncpy确保不会缓冲区溢出。

扩展说明

返回的文件描述符后续可通过read/writepoll/select进行数据操作,每个读操作返回一个完整的IP数据包(因设置了IFF_NO_PI,无额外头部信息)。

tun 模式的应用场景

1. VPN(虚拟专用网络)

VPN 是 tun 模式最典型的应用之一。例如,OpenVPN 默认使用 tun 模式来建立安全的点对点隧道。用户空间的 VPN 程序通过 tun 设备接收和发送加密的 IP 数据包。

2. 容器网络

在容器化技术(如 Docker、Kubernetes)中,tun 设备可以用于实现容器之间的网络隔离和通信。例如,Flannel 的 VXLAN 后端就使用了 tun 设备。

3. 网络测试和调试

tun 设备可以用于模拟网络环境,方便开发者测试网络协议或调试网络问题。

tuntap 的区别

特性tun 模式tap 模式
工作层次网络层(IP 数据包)链路层(以太网帧)
典型应用VPN、点对点隧道虚拟机网络、桥接网络
数据包类型IP 数据包以太网帧
用户空间处理 IP 数据包处理以太网帧

总结

tun 模式是网络编程中一个强大而灵活的工具,特别适合需要处理 IP 层数据的场景。通过用户空间的程序,开发者可以轻松实现加密、隧道、网络隔离等功能。理解 tun 模式的工作原理和应用场景,有助于更好地设计和优化网络架构。

http://www.lryc.cn/news/625611.html

相关文章:

  • 神经网络拆解:用Excel模拟手写数字识别
  • Chrome 插件开发实战技术文章大纲
  • 从密度到聚类:DBSCAN算法的第一性原理解析
  • 【数据可视化-93】使用 Pyecharts 绘制旭日图:步骤与数据组织形式
  • 从接口自动化测试框架设计到开发(三)主流程封装、返回数据写入excel
  • 传统艾灸VS七彩喜艾灸机器人:同样的艾香,多了4分“巧”
  • JetBrains系列产品-IDEA/PyCharm/GoLand自动生成方法返回值的快捷键,查看方法参数的快捷键。
  • 0819 使用IP多路复用实现TCP并发服务器
  • Java -- 用户线程和守护线程--线程同步机制
  • Java开发过程中实用的技术点(一)
  • LIA-X - 一张照片生成任意表情肖像动画视频 精准操控面部动作 支持50系显卡 一键整合包下载
  • 免费dll修复?缺少xxx.dll?【图文详解】Visual C++运行库安装?无法定位程序输入点于动态链接库?
  • VulKan笔记(九)-着色器
  • 机器学习--决策树2
  • 力扣57:插入区间
  • 决策树二-泰坦尼克号幸存者
  • 决策树(2)
  • FPGA入门-多路选择器
  • 决策树1.1
  • 机器学习(决策树2)
  • Leetcode 深度优先搜索 (7)
  • Python爬虫第二课:爬取HTML静态网页之《某某小说》 小说章节和内容完整版
  • 【LeetCode】3655. 区间乘法查询后的异或 II (差分/商分 + 根号算法)
  • Mybatis执行SQL流程(四)之MyBatis中JDK动态代理
  • 【HTML】3D动态凯旋门
  • Leetcode 343. 整数拆分 动态规划
  • C++入门自学Day14-- Stack和Queue的自实现(适配器)
  • 神经网络中的那些关键设计:从输入输出到参数更新
  • 面试题储备-MQ篇 3-说说你对Kafka的理解
  • 图论\dp 两题