Linux 中的虚拟网络接口 (2)

首先通过编译运行上述 c 程序,程序会阻塞住,等待数据到达:

# 编译,请忽略部分 warning > gcc mytun.c -o mytun # 创建并监听 tun 设备需要 root 权限 > sudo mytun Open tun/tap device: tun0 for reading...

现在使用 iproute2 查看下链路层设备:

# 能发现最后面有列出名为 tun0 的接口,但是状态为 down ❯ ip addr ls ...... 3: wlp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether c0:3c:59:36:a4:16 brd ff:ff:ff:ff:ff:ff inet 192.168.31.228/24 brd 192.168.31.255 scope global dynamic noprefixroute wlp4s0 valid_lft 41010sec preferred_lft 41010sec inet6 fe80::4ab0:130f:423b:5d37/64 scope link noprefixroute valid_lft forever preferred_lft forever 7: tun0: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 500 link/none # 为 tun0 设置 ip 地址,注意不要和其他接口在同一网段,会导致路由冲突 > sudo ip addr add 172.21.22.23/24 dev tun0 # 启动 tun0 这个接口,这一步会自动向路由表中添加将 172.21.22.23/24 路由到 tun0 的策略 > sudo ip link set tun0 up #确认上一步添加的路由策略是否存在 ❯ ip route ls default via 192.168.31.1 dev wlp4s0 proto dhcp metric 600 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 172.21.22.0/24 dev tun0 proto kernel scope link src 172.21.22.23 192.168.31.0/24 dev wlp4s0 proto kernel scope link src 192.168.31.228 metric 600 # 此时再查看接口,发现 tun0 状态为 unknown > ip addr ls ...... 8: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500 link/none inet 172.21.22.23/24 scope global tun0 valid_lft forever preferred_lft forever inet6 fe80::3d52:49b5:1cf3:38fd/64 scope link stable-privacy valid_lft forever preferred_lft forever # 使用 tcpdump 尝试抓下 tun0 的数据,会阻塞在这里,等待数据到达 > tcpdump -i tun0

现在再启动第三个窗口发点数据给 tun0,持续观察前面 tcpdump 和 mytun 的日志:

# 直接 ping tun0 的地址,貌似有问题,数据没进 mytun 程序,而且还有响应 ❯ ping -c 4 172.21.22.23 PING 172.21.22.23 (172.21.22.23) 56(84) bytes of data. 64 bytes from 172.21.22.23: icmp_seq=1 ttl=64 time=0.167 ms 64 bytes from 172.21.22.23: icmp_seq=2 ttl=64 time=0.180 ms 64 bytes from 172.21.22.23: icmp_seq=3 ttl=64 time=0.126 ms 64 bytes from 172.21.22.23: icmp_seq=4 ttl=64 time=0.141 ms --- 172.21.22.23 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3060ms rtt min/avg/max/mdev = 0.126/0.153/0.180/0.021 ms # 但是 ping 该网段下的其他地址,流量就会被转发给 mytun 程序,因为 mytun 啥数据也没回,自然丢包率 100% # tcpdump 和 mytun 都会打印出相关日志 ❯ ping -c 4 172.21.22.26 PING 172.21.22.26 (172.21.22.26) 56(84) bytes of data. --- 172.21.22.26 ping statistics --- 4 packets transmitted, 0 received, 100% packet loss, time 3055ms

下面给出 mytun 的输出:

Read 84 bytes from tun/tap device Read 84 bytes from tun/tap device Read 84 bytes from tun/tap device Read 84 bytes from tun/tap device

以及 tcpdump 的输出:

00:22:03.622684 IP (tos 0x0, ttl 64, id 37341, offset 0, flags [DF], proto ICMP (1), length 84) 172.21.22.23 > 172.21.22.26: ICMP echo request, id 11, seq 1, length 64 00:22:04.633394 IP (tos 0x0, ttl 64, id 37522, offset 0, flags [DF], proto ICMP (1), length 84) 172.21.22.23 > 172.21.22.26: ICMP echo request, id 11, seq 2, length 64 00:22:05.653356 IP (tos 0x0, ttl 64, id 37637, offset 0, flags [DF], proto ICMP (1), length 84) 172.21.22.23 > 172.21.22.26: ICMP echo request, id 11, seq 3, length 64 00:22:06.677341 IP (tos 0x0, ttl 64, id 37667, offset 0, flags [DF], proto ICMP (1), length 84) 172.21.22.23 > 172.21.22.26: ICMP echo request, id 11, seq 4, length 64

更复杂的 tun 程序,可以参考

simpletun

marywangran/simpletun

tun go 语言版

TUN 与 TAP 的区别

TUN 和 TAP 的区别在于工作的网络层次不同,用户程序通过 TUN 设备只能读写网络层的 IP 数据包,而 TAP 设备则支持读写链路层的数据包(通常是以太网数据包,带有 Ethernet headers)。

TUN 与 TAP 的关系,就类似于 socket 和 raw socket.

TUN/TAP 应用最多的场景是 VPN 代理,比如:

clash: 一个支持各种规则的隧道,也支持 TUN 模式

tun2socks: 一个全局透明代理,和 VPN 的工作模式一样,它通过创建虚拟网卡+修改路由表,在第三层网络层代理系统流量。

二、veth

veth 接口总是成对出现,一对 veth 接口就类似一根网线,从一端进来的数据会从另一端出去。

同时 veth 又是一个虚拟网络接口,因此它和 TUN/TAP 或者其他物理网络接口一样,也都能配置 mac/ip 地址(但是并不是一定得配 mac/ip 地址)。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxzxy.html