我正在尝试编写一个iptables
规则,该规则将所有传出的UDP数据包重定向到本地套接字,但我还需要目标信息。我从
sudo iptables -t nat -A sshuttle-12300 -j RETURN --dest 127.0.0.0/8 -p udp
sudo iptables -t nat -A sshuttle-12300 -j REDIRECT --dest 0.0.0.0/0 -p udp --to-ports 15000
很好,现在我可以通过端口15000上的一个套接字来获取所有传出的UDP数据包。
现在,我需要目标信息(目标主机和端口号),所以一个简单的UDP套接字是不够的;需要一个原始套接字,以便它得到完整的IP头。
然而,事实证明,接收到的数据包似乎是为localhost:15000
寻址的。这是有意义的,因为这是套接字所在的位置,但这不是我想要的;我需要在数据包被iptables
重定向之前的主机/端口。
google找到了this question,答案是两种方法:TPROXY
和SO_ORIGINAL_DST
,推荐前者,所以这就是我试图采用的方法。
为TPROXY
添加了iptables
规则:
sudo iptables -t mangle -A PREROUTING -j TPROXY --dest 0.0.0.0/0 -p udp --on-port 15000
从tproxy.txt读取,我们需要使用IP_TRANSPARENT
选项创建一个监听套接字(这是以根用户身份完成的):
from socket import *
s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)
# The IP_TRANSPARENT option isn't defined in the socket module.
# Took the value (19) from the patch in http://bugs.python.org/issue12809
s.setsockopt(SOL_IP, 19, 1)
s.bind(('0.0.0.0', 15000))
s.recv(4096) # Will hang until it receives a packet
好吧,现在让我们编写另一个脚本来生成一个测试包,看看是否发生了什么:
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.connect(('192.168.1.1', 9001))
s.send('hello')
但是在接收端什么也没有发生。recv
调用似乎挂起,没有接收到任何数据。
所以,总的问题是:
TPROXY
规则接收数据的代码中是否有错误?或者
编辑:我应该坚持要重定向(因此拦截)数据包,而不是在数据包经过时检查它们。
我觉得你的问题很有趣。
以下解决方案基于标记主机生成的UDP通信量并将其重新路由回本地主机应用程序。在应用程序中,应该使用UDP套接字来读取数据,即使数据不是为主机本身准备的(请参阅下面的说明)。
网络设置:
套接字设置:
你现在应该可以从插座上读了。 Tip form Etienne Perot:要接受所有UDP通信,请绑定到0.0.0.0。
我在这里发现非常有趣的是,本地生成的流量(而不是路由的流量)可以使用iptables和路由规则进行分类和重新路由。
希望这有帮助。
你能控制主人吗?如果是,您可以使用Open vSwitch来编写一个规则,该规则只覆盖所讨论的流,将所有IP信息保留到tap端口(然后将侦听器绑定到tap端口)。
(OVS可以做各种更复杂的事情,但这是一项相对简单的任务)
您可以使用tun/tap设备,只需从python中读取它,例如:
隧道.py
完整的示例可以找到here
并将数据包路由到接口“tun0”或打印的inetrface名称。
linux发行版不需要安装任何东西,但如果您在windows上,请使用this,对于mac os,请使用this
编辑1 来自here的注释:
要查找数据包头信息(如src、dst等),可以使用dpkt
相关问题 更多 >
编程相关推荐