通过路由器重定向环回流量

meg*_*rtz 5 networking routing iptables

出于某些测试目的,我在一台机器上运行多个基于套接字的应用程序,并希望模拟它们之间的“真实”网络条件。我认为最简单的方法是通过我的计算机连接的路由器重定向应用程序之间的所有流量。直观地说,这应该或多或少地像连接到同一网络的多台计算机一样执行,并且网络本身应该受路由器(100Mbps)的能力而不是本地机器间套接字连接的限制。

我的机器(192.168.1.101)通过接口直接连接到路由器(192.168.1.2)em1。我试图通过添加一个 ip 路由来做到这一点。我的 ip route 命令的结果是:

default via 192.168.1.2 dev em1  proto static  metric 1024 
192.168.1.0/24 dev em1  proto kernel  scope link  src 192.168.1.101 
192.168.1.101 via 192.168.1.2 dev em1 
Run Code Online (Sandbox Code Playgroud)

然而,这似乎没有任何影响,因为 ping localhost 返回的结果与间接 ping 我的机器(192.168.1.101)大致相同,即大约 0.040 毫秒。同时,在我的网络中 ping 另一台机器会导致 ping 大约 0.3-0.5 毫秒。

我试过traceroute,这是我得到的:

$traceroute 192.168.1.200                    # my other computer
traceroute to 192.168.1.200 (192.168.1.200), 30 hops max, 60 byte packets
 1  192.168.1.200 (192.168.1.200)  1.005 ms  0.972 ms  0.954 ms

$traceroute 192.168.1.101
traceroute to 192.168.1.101 (192.168.1.101), 30 hops max, 60 byte packets
 1  localhost.localdomain (192.168.1.101)  0.051 ms  0.014 ms  0.013 ms

$traceroute 127.0.0.1
traceroute to 127.0.0.1 (127.0.0.1), 30 hops max, 60 byte packets
 1  localhost.localdomain (127.0.0.1)  0.053 ms  0.015 ms  0.013 ms
Run Code Online (Sandbox Code Playgroud)

我是否遗漏了什么,或者我以完全错误的方式做这件事?

Sté*_*las 3

问题是你的local表中有一条路线,上面写着:

$ ip route show table local
[...]
local 192.168.1.101 dev eth0 scope host
[...]
Run Code Online (Sandbox Code Playgroud)

当发送带有 [src=192.168.1.101 dst=192.168.1.101] 的数据包时,并期望路由器将该数据包发送回反射(有些人会拒绝这种事情),您希望传出数据包跳过该路由,但是不是返回的数据包。

为此,您可以更改ip rules

删除表的包罗万象的规则local

# ip rule del from all table local
Run Code Online (Sandbox Code Playgroud)

并将其替换为对 192.168.1.101->192.168.1.101 数据包不执行此操作的一个:

# ip rule add not from 192.168.1.101 to 192.168.1.101 table local pref 0
Run Code Online (Sandbox Code Playgroud)

然后用 netfilter 标记传入的数据包:

# iptables -t mangle -I PREROUTING -s 192.168.1.101 -d 192.168.1.101 -j MARK --set-mark 1
Run Code Online (Sandbox Code Playgroud)

local并告诉 ip 规则仅使用该表:

# ip rule add fwmark 1 table local pref 1
Run Code Online (Sandbox Code Playgroud)

(当然,你ip route add to 192.168.1.101 via 192.168.1.2 的桌子上也需要你的main