我的 Ubuntu 20.04 虚拟机上有一个 NAT 类型的虚拟网卡,它通过主机将其连接到互联网。对于某些处理,我需要通过我编写的程序路由所有传入和传出的数据包。例如,假设我必须丢弃一些数据包并且不让它们离开虚拟机。
为此,我创建了一个虚拟接口,内容如下:
modprobe dummy
ip link add tun0 type dummy
ifconfig tun0 up
为了使所有流量不直接通过 NIC,我添加了:
ip route add default dev tun0
现在一切都好了。例如当我
ping 4.2.2.4
,我发现当我的程序没有运行时,ping 没有得到响应,而运行时,ping 得到了正确的响应。目前,该程序就像 enp0s3 和 tun0 之间的桥梁。整个流量都通过我的程序进行路由。只是存在一个问题,即名称解析。那时我
ping google.com
,无法解析该名称。现在的路由表如下:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 tun0
0.0.0.0 10.0.2.2 0.0.0.0 UG 20100 0 0 enp0s3
10.0.2.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s3
169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 enp0s3
当然,如果我
sudo route del default
,名称解析通过主机的 NAT 适配器正确进行。请告诉我在这种情况下名称解析出了什么问题。
更新
看看这些图片:
在这里我看到 ping 没有响应。源 IP 和目标 IP 正确。请集中精力查看 DNS 数据包。这是我更改默认路由表以从 tun0 路由所有流量时的情况。
在这里我看到 ping 有响应。DNS 数据包使用相同的源 IP 和目标 IP。
在前一种情况下,我在数据包中发现的唯一提示是源 MAC 地址和目标 MAC 地址相同!我们只需要找出为什么 ping 会生成这样的 DNS 数据包?!虚拟机的系统配置似乎出了问题。
有什么想法吗?
答案1
为了使名称解析正常工作,您需要始终允许 TCP 和 UDP 端口 53。
使用您的方法,不可能在协议级别进行过滤。
您应该使用 IPTablesNFQUEUE
功能来实现您的程序,该功能允许您将数据包发送到用户空间进行评估,然后用户空间程序可以为该数据包做出裁决(ACCEPT
,REPEAT
和DROP
)。