我发现以下命令集可以在 Linux 上打开一个将数据转发到互联网的 tun 设备。但是,数据包不会转发回 tun 设备
ip tuntap add dev tun1 mode tun user `id -un`
ip link set dev tun1 up
ip addr add dev tun1 local 192.168.69.0 remote 192.168.69.1
iptables -t filter -I FORWARD -i tun1 -o eth0 -j ACCEPT
iptables -t filter -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
是什么ip addr add dev tun1 local 192.168.69.0 remote 192.168.69.1
意思?local
和是什么remote
? 可能遗漏了什么?
我的客户端发送了一个 SYN,服务器以 SYN+ACK 进行响应,但是这个 SYN+ACK 并没有被传回 tun 设备。
答案1
简单来说,你可以区分两种类型的链接(这是简化,但对于这个问题来说已经足够了):
- 对等链路,链路的每一侧都是一个对等点。每个对等点都知道链路后面只有一个其他对等点,其他所有人都被路由。示例是串行链路(通过 PSTN 调制解调器)
- 多接入链路,链路后面可能有多个对等点。有很多例子,如以太网、WiFi 和一些过时的
当您通过 以“地址和网络掩码”的(通常)形式配置接口地址时ip address add x.y.z.t/n dev eth
,您主要执行以下操作:
- 告诉内核它应该识别
x.y.z.t
一个它自己的地址,因此它将范围本地路由添加到local
路由表中 - 告诉内核像
x.y.z.00...0
÷这样的地址x.y.z.11...1
可以在链接后面直接访问,因此它通过这个接口将一个范围链接路由添加到main
路由表中(/n
实际上指定了该网络上所有主机有多少位地址是通用的) - 告诉内核 xyz11...1 是链接的“广播”地址,因此它会在表中添加一条广播路由
local
(除了“节点个人”地址之外,还会考虑发往该地址的数据包x.y.z.t
)
但是点对点链接背后没有“网络”,没有人可以广播,可能只有一个其他对等点。当您在表单中将地址添加到链接时ip address add local x.y.z.t remote b.c.d.e dev tun
,您基本上执行以下操作:
- 告诉内核它应该识别
x.y.z.t
一个它自己的地址,因此它将范围本地路由添加到local
路由表中 - 告诉内核该地址
b.c.d.e
可以通过该链接直接访问,因此它通过此接口将到该地址的路由添加到main
路由表中。
例如,该命令ip address add local 10.0.1.0 remote 10.0.1.1 dev tun0
仅创建以下路线:
local 10.0.1.0 dev tun0 proto kernel scope host src 10.0.1.0
(表中local
)10.0.1.1 dev tun0 proto kernel scope link src 10.0.1.0
(表中main
)
在两种情况下,请在发出“ip address add”命令之前和之后检查路由表。
注意到你可能将对等式配置添加到多访问接口,反之亦然;您甚至可以添加单个“/32”地址,然后手动添加“通过接口”的路由,这将完全像您在命令中设置有意义的网络掩码或远程地址一样工作。您甚至可以将几种类型的配置添加到单个接口,并且它们都可以同时工作!因此,不要太认真地对待所有这些参数,将它们视为配置地址时自动添加必要路由的方式。