使用 iptables 将 LAN HTTP 流量重新路由到 node.js 代理

使用 iptables 将 LAN HTTP 流量重新路由到 node.js 代理

我正在尝试将我的 LAN 中生成的所有 http 流量重定向到特定机器上运行的 node.js 代理。

我在用着:iptables -t nat -A PREROUTING -s 192.168.1.3 -p tcp --dport 80 -j DNAT --to 192.168.1.2:8080

(目前正在测试一台源机器。代理位于 192.168.1.2:8080)。不幸的是,流量无法到达代理。我可以看到规则上的数据包计数器在增加,如果我向 LOG 添加另一条规则,我可以看到来自 192.168.1.3 机器的 http 流量的日志条目。

但是,代理无法获取流量。我已将其设置为记录请求连接,但我什么也没看到。如果我让浏览器使用 192.168.1.2:8080 作为代理,它就可以正常工作。

node.js 代理是一个简单的透明代理,可以随机重定向流量。

var httpProxy = require("http-proxy");
var http = require("http");
var url = require("url");
var net = require('net');

var redirect_host = url.parse(redirect_url).host;

var server = http.createServer(function (req, res) {
  var urlObj = url.parse(req.url);
  var target = urlObj.protocol + "//" + urlObj.host;

  if (Math.random() > redirect_chance || urlObj.host == redirect_host) {
      var proxy = httpProxy.createProxyServer({});
      proxy.on("error", function (err, req, res) {
        console.log("proxy error", err);
        res.end();
      });
      console.log("Not redirecting " + target);
      proxy.web(req, res, {target: target});
  }
  else {
    console.log("Redirecting " + target + " to", redirect_url);
    res.writeHead(302, {'Location': redirect_url});
    res.end();
  }

}).listen(8080);

知道我做错了什么吗?

尝试添加以下规则:iptables -t nat -A POSTROUTING -s 192.168.1.3 -d 192.168.1.2 -j SNAT --to 192.168.1.1,但不起作用。嗯,不完全是。当我从客户端发出 http 请求时,我看到添加了此规则的以下数据包:

(网关:192.168.1.1,代理服务器:192.168.1.2,客户端:192.168.1.3)

SYN from Gateway to Proxy Server
SYN+ACK from Proxy Server to Gateway
ACK from Gateway to Proxy Server
HTTP Request from Client to Proxy Server

我不确定为什么 HTTP 请求没有被 SNAT...或者这是否重要(我猜不重要)。

接下来,我看到 HTTP 请求从客户端不断重新传输到代理服务器。据我所知,这是因为代理服务器从不发送 ACK。当我在浏览器中取消请求时,客户端会重新传输,但这次使用的是 ACK+FIN,这导致代理服务器 ACK 并发送响应(两者都发送到网关,而不是客户端)。这可能是代理服务器的问题,但可能是因为它从意外来源获取了 http 请求?

iptables:http://pastebin.com/FvNq1Dyf

tcpdump:http://pastebin.com/zMBj10Qj

答案1

您确实只设置了一半规则来确保数据包正确流动。您的规则的作用是,在数据包进入 iptables 网关时更改目标地址。

接下来,此数据包被转发到您的代理,但其源 IP 保持不变。因此,您的代理认为它从客户端计算机接收到了 TCP SYN 请求,并直接响应它,但由于客户端没有打开此连接,因此 SYN+ACK 被丢弃。您可以使用 Wireshark 和 tcpdump 来验证这一点。

为了缓解这种情况,您应该添加一条规则,POSTROUTING该规则还会将SNAT客户端的源 IP 更改为 iptables 网关的 IP。类似以下代码(我假设您的 iptables 网关 IP 为 192.168.1.1):

iptables -t nat -A POSTROUTING -s 192.168.1.3 -d 192.168.1.2 -j SNAT --to 192.168.1.1

相关内容