我正在尝试将我的 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