强制本地IP通信到外部接口


30

我有一台具有多个接口的机器,可以根据需要进行配置,例如:

  • eth1:192.168.1.1
  • eth2:192.168.2.2

我想通过另一个接口转发所有发送到这些本地地址之一的流量。例如,到192.168.1.1处的iperf,ftp,http服务器的所有请求不仅应在内部进行路由,还应通过eth2转发(外部网络将负责将数据包重新路由到eth1)。

我尝试并查看了几个命令,例如iptables,ip route等...,但是没有任何效果。

我可以得到的最接近的行为是:

ip route change to 192.168.1.1/24 dev eth2

它将在eth2上发送所有192.168.1.x,除了192.168.1.1仍在内部进行路由。可能然后我可以对eth1上定向到伪造的192.168.1.2的所有流量进行NAT转发,并在内部重新路由到192.168.1.1吗?我实际上在为iptables奋斗,但这对我来说太难了。

此设置的目的是在不使用两台PC的情况下进行接口驱动程序测试。

我正在使用Linux,但是如果您知道如何在Windows上使用它,那我就买!

编辑:

外部网络只是eth1和eth2之间的交叉电缆。假设我的机器上有一个http服务器。现在,我想从同一台计算机访问此服务器,但是我想强制TCP / IP通信通过此eth1 / eth2电缆。我应该如何为此配置接口?


您是说要通过接口1和2镜像所有流量,但仅从另一台路由器返回到接口2吗?那岂不是在网络上做一些很奇怪的事情吗?将镜像流量从接口2引导到另一个刚刚丢弃流量的系统,然后您可以对其进行监视,或者使用虚拟化软件捕获流量,会更好吗?也许我在描述中遗漏了一些东西。
巴特·西尔弗斯

听起来他想生成一个数据包,例如192.168.1.1,这是eth1的IP。但是,不是希望Linux堆栈完全在内部接收该数据包,他希望将数据包强制输出eth2(它将先从外部传递回eth1,然后再传递给Linux堆栈)。我不确定这是否可行;一旦网络层检测到地址是内部接口,就没有理由查看路由表了。其他人可能会更好。
PP。

Answers:


14

由于看不到响应数据包,因此我扩展了caladona的答案。对于此示例:

  1. 在我的本地PC我有网卡在不同的子网,192.168.1 / 24192.168.2 / 24
  2. 有一个外部路由器/ PC可以访问两个子网。
  3. 我想通过本地PC上的NIC发送双向流量。
  4. 该配置要求每个子网两个未使用的IP地址。

将本地PC iptable路由设置为SNAT,将DNAT传出流量设置为“伪” IP。

iptables -t nat -A POSTROUTING -d 192.168.1.100 -s 192.168.2.0/24 -j SNAT --to-source      192.168.2.100
iptables -t nat -A PREROUTING  -d 192.168.1.100 -i eth0           -j DNAT --to-destination 192.168.1.1
iptables -t nat -A POSTROUTING -d 192.168.2.100 -s 192.168.1.0/24 -j SNAT --to-source      192.168.1.100
iptables -t nat -A PREROUTING  -d 192.168.2.100 -i eth1           -j DNAT --to-destination 192.168.2.1

规则执行以下操作:

  1. 将传出数据包上的192.168.2.1源重写为192.168.2.100
  2. 将传入数据包上的192.168.1.100目标重写为192.168.1.1
  3. 将传出数据包上的192.168.1.1源重写为192.168.1.100
  4. 将传入数据包上的192.168.2.100目标重写为192.168.2.1

总而言之,本地系统现在可以与地址为192.168.1.100和192.168.2.100的“虚拟”计算机进行对话。

接下来,您必须强制本地PC使用外部路由器来获取假IP。为此,您可以通过路由器创建到IP的直接路由。您要确保将数据包强制到目标子网的对面。

ip route 192.168.1.100 via $ROUTER_2_SUBNET_IP 
ip route 192.168.2.100 via $ROUTER_1_SUBNET_IP

最后,要使所有这些工作正常进行,外部路由器需要知道如何访问本地PC上的伪造IP。您可以通过为系统打开代理ARP来进行精简。

echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/proxy_arp
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

通过此设置,您现在可以将伪造的IP视为本地PC上的真实系统。将数据发送到.1子网将迫使数据包离开.2接口。将数据发送到.2子网将迫使数据包离开.1接口。

ping 192.168.1.100
ping 192.168.2.100

更好的方式!请注意,我还需要一个ip_forward来使ARP起作用:echo 1> / proc / sys / net / ipv4 / ip_forward
calandoa 2010年

28

我在Linux上成功使用了以下命令,以“环回”模式在新的双端口10Gbps卡上测试了吞吐量,即一个端口直接插入另一个端口。这只是为了将数据包强制发送出去而已,这只是一点巫毒,但是如果您不这样做,Linux只会使通过内核的流量短路(因此,OP提出了问题)。在以上Casey的回答中,我不确定是否确实需要在上面安装外部路由器,但是下面的内容是完全独立的。这两个接口是eth2和eth3。

将IP提供给接口,并将它们放在单独的网络上:

ifconfig eth2 10.50.0.1/24
ifconfig eth3 10.50.1.1/24

接下来,我们将建立一个双重NAT方案:两个新的虚假网络用来访问另一个。在出局时,将NAT发送到您的假网络。在途中,固定目的地。反之亦然:

# nat source IP 10.50.0.1 -> 10.60.0.1 when going to 10.60.1.1
iptables -t nat -A POSTROUTING -s 10.50.0.1 -d 10.60.1.1 -j SNAT --to-source 10.60.0.1

# nat inbound 10.60.0.1 -> 10.50.0.1
iptables -t nat -A PREROUTING -d 10.60.0.1 -j DNAT --to-destination 10.50.0.1

# nat source IP 10.50.1.1 -> 10.60.1.1 when going to 10.60.0.1
iptables -t nat -A POSTROUTING -s 10.50.1.1 -d 10.60.0.1 -j SNAT --to-source 10.60.1.1

# nat inbound 10.60.1.1 -> 10.50.1.1
iptables -t nat -A PREROUTING -d 10.60.1.1 -j DNAT --to-destination 10.50.1.1

现在告诉系统如何进入每个假网络,并预先填充arp项(请务必替换您的MAC地址,不要使用我的):

ip route add 10.60.1.1 dev eth2
arp -i eth2 -s 10.60.1.1 00:1B:21:C1:F6:0F # eth3's mac address

ip route add 10.60.0.1 dev eth3 
arp -i eth3 -s 10.60.0.1 00:1B:21:C1:F6:0E # eth2's mac address

这足以使Linux愚弄到实际将数据包放到网络上的程度。例如:

ping 10.60.1.1

如果从eth2退出,则源IP 10.50.0.1会被NAT转换为10.60.0.1,而在进入eth3时,目标IP 10.60.1.1会被NAT转换为10.50.1.1。答复也经历了类似的旅程。

现在使用iperf来测试吞吐量。绑定到正确的IP,并确定您要联系的IP(另一端的假地址):

# server
./iperf -B 10.50.1.1 -s

# client: your destination is the other end's fake address
./iperf -B 10.50.0.1 -c 10.60.1.1 -t 60 -i 10

确保确实有流量通过网络:

tcpdump -nn -i eth2 -c 500

您也可以观看/ proc / interrupts,以确保完全使用该卡:

while true ; do egrep 'eth2|eth3' /proc/interrupts ; sleep 1 ; done

无论如何,我发现这篇文章正在搜索如何执行此操作,感谢常见问题解答人员,并希望这可以帮助其他人在以后找到这篇文章。


+1很棒的解决方案-甚至不需要激活ip转发!这正是我现在所需要的(通过环回进行10GB测试)。
尼尔斯2013年

16

和往常一样-我有点晚了-但如今,人们可以使用网络名称空间来隔离接口并防止任何本地转发(并摆弄iptables :))。

创建名称空间(全部使用所需的权限(例如,以root用户身份)完成):

ip netns add ns_server
ip netns add ns_client

请注意,现在必须在分配的名称空间的上下文中访问接口状态/配置-因此,如果您运行裸IP链接,则它们不会出现,因为它是在默认名称空间的上下文中运行的。可以使用以下命令在名称空间中运行命令

ip netns exec <namespace-name> <command>

作为前缀。

现在为接口分配名称空间,应用配置并设置接口:

ip link set eth1 netns ns_server
ip netns exec ns_server ip addr add dev eth1 192.168.1.1/24
ip netns exec ns_server ip link set dev eth1 up
ip link set eth2 netns ns_client
ip netns exec ns_client ip addr add dev eth2 192.168.1.2/24
ip netns exec ns_client ip link set dev eth2 up

现在,您可以在命名空间中执行应用程序-用于iperf服务器运行

ip netns exec ns_server iperf -s -B 192.168.1.1

和客户:

ip netns exec ns_client iperf -c 192.168.1.1 -B 192.168.1.2

现在,流量将通过物理接口发送,因为整个网络堆栈,接口,路由...被名称空间隔离,因此内核无法将流量中使用的地址与本地(可用)接口进行匹配。

如果您完成了实验,只需删除名称空间:

ip netns del <namespace-name>

接口将被重新分配给默认名称空间,并且在名称空间内完成的所有配置都将消失(例如,无需删除分配的IP地址)。


这比建议的双重防御法要简单得多,并且不需要网络上其他计算机的任何协调,也不需要任何物理拓扑。我唯一的要求是添加命令以添加路由。
哈克

2

好的,我终于成功设置了配置。

这个想法是使用另一个伪地址,强制将该伪地址路由到接口2,然后使用NAT / iptables将伪地址转换为具有真实地址2的地址。

我的设置实际上是由一个我可以在IF1(接口1)和IF2之间进行telnet的路由器组成的

在我的设置中,FAKE_ADDR和IF1_ADDR在同一子网中。

ifconfig $IF1 $IF1_ADDR netmask 255.255.255.0
ifconfig $IF2 $IF2_ADDR netmask 255.255.255.0

iptables -t nat -A PREROUTING -d $FAKE_ADDR -i $IF2 -j DNAT --to-destination $IF2_ADDR
iptables -t nat -A POSTROUTING -s $IF2_ADDR -d $IF1_ADDR/24 -j SNAT --to-source $FAKE_ADDR

route add $FAKE_ADDR gw $ROUTER_ADDR

并在路由器上:

route add $FAKE_ADDR gw $IF2_ADDR

如果我发送一些东西到FAKE_ADDR,pkt通过IF1转发到路由器,再转发到IF2,则FAKE_IP被IF2_ADDR代替。数据包由服务器处理,结果从IF2_ADDR发送回IF1_ADDR,并由FAKE_ADDR代替。

可能只用一根交叉电缆就可以使用更简单的配置,但是由于我没有尝试过,因此我希望给出自己的解决方案。


如果路由器正在向$ IF2_ADDR发送$ FAKE_ADDR,那么您的DNAT规则不是必须是“ -i $ IF2”而不是“ -i $ IF1”吗?
cmcginty 2010年

您说得对,凯西,改正完成了。
calandoa 2010年

1

ThomasTannhäuser在上面给出的答案是正确的!

我有一个类似的情况:一台带有两个enet接口的机器。我的计划是将一个接口用作服务器(接收方),将另一个接口用作客户端(发送方)。每个接口都将连接到路由器,iperf将驱动流量通过路由器,以测量吞吐量,PPS,延迟等。

不幸的是,iptables方法是非直觉的,充满了问题。几个令人沮丧的小时后,我放弃了这一进攻计划。受Thomas的启发,我在Linux IP命名空间上做了一些功课,并开始体会到此解决方案的简洁性。

以下是我用来配置Fedora FC26以这种能力使用的确切命令的列表。这两个接口是enp1s0和enp3s0。路由器有两个地址分别为192.168.2.112和172.16.16.2的接口。每个FC26 ENET连接器直接电缆连接到相应的路由器接口。

# How to configure the IP Namespaces
ip netns add iperf-server
ip netns add iperf-client
ip link set enp1s0 netns iperf-server
ip link set enp3s0 netns iperf-client
ip netns exec iperf-server ip addr add dev enp1s0 192.168.2.139/20
ip netns exec iperf-client ip addr add dev enp3s0 172.16.16.2/24
ip netns exec iperf-client ip link set dev enp3s0 up
ip netns exec iperf-server ip link set dev enp1s0 up
ip netns exec iperf-server route add default gw 192.168.2.112
ip netns exec iperf-client route add default gw 172.16.16.1

# Test the interfaces and network using ping
ip netns exec iperf-client ping -c1 172.16.16.1
ip netns exec iperf-server ping -c1 192.168.2.112
ip netns exec iperf-server ping -c1 172.16.16.2
ip netns exec iperf-client ping -c1 192.168.2.139

# Start Iperf Server for UDP test
ip netns exec iperf-server iperf -u -s
# Run Client against Iperf server for UDP test
ip netns exec iperf-client iperf -u -c 192.168.2.139

0

听起来您想将linux盒变成路由器/网桥/网关/防火墙类型盒。您可能正在寻找以下资源:

Linux路由器项目

路由器或防火墙分发列表

Linux LiveCD路由器

Linux Journal-Linux路由器

根据更多信息进行更新:

我认为您将无法做自己想做的事。操作系统始终会查看其内部路由表,并在本地“查看”两个IP地址。然后,它将在OS内路由流量,并且永远不会将其放在网上。您将需要第二台计算机或两个虚拟机(签出Xen)。


0

很多事情要经过这里,所以我不能完全保证我的准确性,但是最初的问题似乎是在寻找所谓的“自我发送”技术。链接搜索显示了我认为是维护最好的内核补丁,它是顶部链接+讨论以及各种邮件列表(尤其是其他方法)上的补丁。LKML。

我认为还应该研究使用iproute2的“ ip netns”完成的网络名称空间。这还需要一些额外的接口和路由魔术,因此它的复杂性甚至可能不比其他答案中的大型iptables hoopla复杂。

如果有人发现与这些有关的有用信息,绝对欢迎您提出评论-实现的方式,方式和地点。



-1

这是我如何为IPV6工作

分配的静态IP

/sbin/ifconfig eth1 inet6 add 2001:db8::1/127 
/sbin/ifconfig eth3 inet6 add 2001:db8::2/127 

设置仅主机路由到“假”地址

ip -6 route add 2001:db8::2/128 dev eth1 metric 1
ip -6 route add 2001:db8::1/128 dev eth3 metric 1

像arp一样填充邻居表

ip -6 neighbor add 2001:db8::1 lladdr 90:e2:ba:0d:75:e8 dev eth3 # eth1's mac address
ip -6 neighbor add 2001:db8::2 lladdr 90:e2:ba:0d:75:e9 dev eth1 # eth3's mac address

添加了ip6tables条目

ip6tables -t nat -A POSTROUTING -s 2001:db8::1 -d 2013::2 -j SNAT --to-source 2001:db8::1
ip6tables -t nat -A PREROUTING -d 2001:db8::1 -j DNAT --to-destination 2001:db8::1
ip6tables -t nat -A POSTROUTING -s 2001:db8::2 -d 2013::1 -j SNAT --to-source 2001:db8::2
ip6tables -t nat -A PREROUTING -d 2001:db8::2 -j DNAT --to-destination 2001:db8::2

您正在使用什么发行版?上次检查时,内核没有用于IPv6的NAT表。
fukawi2 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.