iptables将所有源端口修改为1个单一源端口

如何将所有从各个源端口的应用程序传出的数据包路由到端口x,使它们看起来好像来自端口x。 可能吗 ?

我不太了解iptables,但是我尝试了这些规则,它们是不正确的语法:

iptables --table nat --append POSTROUTING --protocol TCP --source-port 1:65534 --jump REDIRECT --to-port 9999 # copy and paste exact rule but for UDP : iptables --table nat --append POSTROUTING --protocol UDP --source-port 1:65534 --jump REDIRECT --to-port 9999 

REDIRECT目标不是你想要的。 REDIRECT用于当你想拦截通常通过你的盒子路由的连接,而将其redirect到本地端口。 这在实现某种透明的代理解决scheme时经常使用。 在这个模型中,你将有一个监听目标端口的服务(在你的例子中是9999),这个端口将响应stream量。

SNAT (源NAT)和MASQUERADE目标接近你想要的东西,但是我不确定这些东西中的任何一个能用于本地生成的通信(也就是说,连接源于你正在执行的系统这个iptables规则)…

……正如凯尔在评论中指出的那样,即使你能够实施一个“成功的”解决scheme,如果你一次只运行一次以上的应用程序,你将会破坏一切。

如果您可以提供更多关于您正在尝试解决的问题的详细信息,我们可能会提出更好的解决scheme。

我不知道这是否可能。 我怀疑即使是不应该使用它,因为它本身打破了TCP / IP模型对应用层(IP + port = socket = 1应用程序守护进程)所做的假设。 同样的原因,你不能将端口从防火墙上的单个端口转发到多个主机上的多个端口(除非你负载均衡相同的应用程序,但你需要比NAT和iptables更复杂的东西完成这一点,我认为)。

应用程序通常绑定到给定的端口,这将阻止其他应用程序绑定到同一个端口的尝试。 这个绑定是操作系统的networking编码知道哪个应用程序获得数据包的方式。 这就是为什么你不能同时在端口80上运行Apache和lighttpd的原因。 想想这个包。 所有传输层必须使用的是IP地址,源和目的地的端口号(加上会话ID,但是如果会话已经build立,则它也是无用的)。 哪个守护进程得到它都绑定到一个端口?

如果您拥有像inetd或xinetd这样的超级服务器守护程序或像RPC和WMI这样的远程命令中继,那么您可以“伪造”这种types的东西,但是每个客户端应用程序都必须知道它需要在应用程序层指定目的地,请求必须是协议特定的。

根据你想要做什么,我会研究如何设置“源NAT”。 好的参考资料似乎在netfilter HOWTO 6.1节。 在这里,netfilter框架跟踪更改,并将正确的发送端口的响应重写或重新路由。

例:

 polaris:~# iptables -t nat -A POSTROUTING -d qew -p tcp --destination-port 1444 -j SNAT --to :2347 polaris:~# telnet qew 1444 Trying 10.23.1.9... Connected to qew. Escape character is '^]'. hello world 

另一方面:

 qew:~# nc -l -p 1444 hello world 

在另外一个shell中,显示从polaris到qew的数据包的源端口实际上已经改变了。

 qew:~# netstat -n |grep 1444 tcp 0 0 10.23.1.9:1444 10.23.1.10:2347 ESTABLISHED 

如果你不想连接神奇地保持活着,你也可以尝试直接修改数据包。 我找不到这样做的端口的目标,但有一个扩展,允许更改TTL字段,所以我可能只是没有仔细看。

最后的办法是使用QUEUE目标将数据包路由到用户地址,修改它们,更新所有校验和,然后将它们返回给内核。