我正在尝试编写一个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
。
谷歌搜索导致了这个问题,答案提出了两种方法:TPROXY
并且SO_ORIGINAL_DST
,推荐前者,所以这就是我试图采用的方法。
添加了以下iptables
规则TPROXY
:
sudo iptables -t mangle -A PREROUTING -j TPROXY --dest 0.0.0.0/0 -p udp --on-port 15000
从tproxy.txt读取,我们需要创建一个带有IP_TRANSPARENT
选项的监听套接字(这是作为 root 完成的):
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 数据包重定向到本地套接字以获取目标信息)?
编辑:我应该坚持我想重定向(因此拦截)数据包,而不仅仅是在它们通过时检查它们。