Macos 如何以编程方式从特定进程重新路由所有TCP/IP或HTTP连接

Macos 如何以编程方式从特定进程重新路由所有TCP/IP或HTTP连接,macos,routing,network-programming,tcp-ip,Macos,Routing,Network Programming,Tcp Ip,这是一个相当高级的问题,答案可能涉及到一些我并不反对的系统和套接字级别的编码,因为现在似乎没有现成的东西可以做到这一点。我对所有现成的解决方案都持开放态度,或者自己构建解决方案。请提供你最好的建议 我正在构建一个测试执行环境,它执行由第三方提交的测试二进制文件。测试二进制文件是根据一个善意的测试框架构建的,该框架连接到HTTP服务器,用于在浏览器和被测虚拟设备之间传递测试命令和测试结果。该框架使用户可以轻松地硬编码测试以连接到静态IP地址和端口号,但不提供外部覆盖机制。编写这些测试二进制文件的人

这是一个相当高级的问题,答案可能涉及到一些我并不反对的系统和套接字级别的编码,因为现在似乎没有现成的东西可以做到这一点。我对所有现成的解决方案都持开放态度,或者自己构建解决方案。请提供你最好的建议

我正在构建一个测试执行环境,它执行由第三方提交的测试二进制文件。测试二进制文件是根据一个善意的测试框架构建的,该框架连接到HTTP服务器,用于在浏览器和被测虚拟设备之间传递测试命令和测试结果。该框架使用户可以轻松地硬编码测试以连接到静态IP地址和端口号,但不提供外部覆盖机制。编写这些测试二进制文件的人并不总是最精明的工具,因此要求他们做一些基本的事情,比如获取动态IP地址和端口号是不可能的。这将为这项免费服务的进入增加太多障碍

一个测试二进制文件需要连接到系统上可用的一个浏览器/设备主机HTTP服务器上。系统上将有几十个可用的浏览器/设备主机HTTP服务器。一次只允许一个测试二进制文件连接到任何特定的浏览器/设备主机HTTP服务器。我从和二进制文件相关联的上下文中知道它们需要连接到哪个设备。他们将尝试通过连接到默认IP/端口来连接它,其中默认IP是localhost。在这一点上,我想要一个软件,它根据连接过程的PID将该端口上的连接路由到一个动态端口。这就是魔法,对吧?根据请求过程,实际将它们连接到不同的端口。这可以在用户模式下完成吗?今天有没有一些漂亮的实用服务器可以做到这一点


最好选择针对Mac OS X Lion的答案,但我很乐意尝试采用任何适用于其他操作系统的解决方案。

您是否尝试过charlesproxy Mac或Fiddler Windows


两者都允许重写http连接。我知道Fiddler是可以编写脚本的,我相信Charles也是,但我还没有在基于Linux的操作系统上尝试过,我建议使用包装器启动器设置应用程序所有数据包中的服务位类型。然后,您可以使用iptables规则将具有该ToS位的所有数据包放入一个链中,并在其中执行您需要的任何操作。它不需要编写任何软件

可以通过使用预加载策略来控制对系统调用(如套接字)的访问,并在套接字上设置选项。服务的类型只是一个套接字选项。有关该策略的示例,请参见。我想我以前用过用户空间包装器,但现在找不到了

不过,我认为可能存在一种更简单的方法,即使用iptables。所有者匹配目标可以基于许多参数(如uid、gid、pid、sid等)进行匹配。在SMP内核上,pid和sid匹配似乎不起作用,因此不存在。至少在我运行的Linux3.2内核上,它们并不存在。如果您以单独的用户身份运行测试二进制文件,这仍然是从测试程序捕获所有数据包并重新路由的有效方法。您可以在输出nat表中捕获它们,并使用DNAT目标将它们重定向到任何地方。这里有一条假设规则

iptables -t nat -I OUTPUT -m owner --uid-owner softwaretesting -j DNAT --to-destination 192.168.1.1
在这里,运行测试的用户名为softwaretesting,该用户启动的程序的所有IP流量都重定向到192.168.1.1。这可能会产生一些意想不到的后果,比如让ssh无法真正为该用户工作。既然您说过测试框架是HTTP,那么您可以通过查找端口80来匹配它的流量

iptables -t nat -I OUTPUT -p tcp --dport 80 -m owner --uid-owner softwaretesting -j DNAT --to-destination 192.168.1.1

显然,如果HTTP在非标准端口上运行,则必须将80调整为正在使用的任何端口。

这对于Charles proxy来说有点高级,它不提供任何类似于流量重新路由的功能。Fiddler似乎能够跟踪发起请求的过程,但似乎也不能提供重新路由连接的功能。谢谢,Eric!您愿意提供额外的指导吗?我现在正努力弄清楚如何在应用程序的所有数据包中设置TOS位。经过一个小时的谷歌搜索和stackoverflow搜索,我什么也没找到。我假设我会进行某种系统调用来在包装器中设置它,然后是fork/exec?提前谢谢。我更新了我的答案,加入了一个更好更详细的策略。