Iptables 将端口 80 转发到远程 squid

Iptables 将端口 80 转发到远程 squid

我有服务器 A,其 IP 为 192.0.2.2,它没有连接到互联网,因此它必须将所有互联网 http 流量传递到服务器 B 上的 squid 代理,其 IP 为 192.0.2.3,监听端口 8080。

我使用了以下规则来建立与 squid 代理的连接,但是当我启动 wget 时却收到 400 错误请求错误:

iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination IP:8080

wget:

wget external.example.net/v4/Picture/pic1.jpg
--2015-09-05 18:42:01--  http://external.example.net/v4/Picture/pic1.jpg
Resolving external.example.net... 60.192.194.32, 61.54.192.95, 77.36.14.19, ...
Connecting to external.example.net|60.192.194.32|:80... connected.
HTTP request sent, awaiting response... 400 Bad Request
2015-09-05 18:42:01 ERROR 400: Bad Request.

当我检查 squid 日志时,我发现 URL 中缺少域名。

1 192.0.2.2 NONE/400 1186 GET /v4/Picture/pic1.jpg - NONE/- -

如果我使用 bash http_proxy 代替 iptables 规则,我可以成功下载图像,并且 squid 会记录完整的 url

export http_proxy=http://192.0.2.3:8080
wget external.example.net/v4/Picture/pic1.jpg

wget:

2015-09-05 18:55:48--  http://external.example.net/v4/Picture/pic1.jpg
Connecting to 192.0.2.3:8080... connected.
Proxy request sent, awaiting response... 200 OK
Length: 83760 (82K) [image/jpeg]
Saving to: `pic1.jpg'

鱿鱼日志

 7 1.2.3.4 TCP_HIT/200 84455 GET http://external.example.net/v4/Picture/pic1.jpg - NONE/- image/jpeg

为什么我的第一个请求不起作用?

答案1

这与代理的工作方式不完全一致。

当您通过 HTTP 代理发送请求时,它看起来像这样,其中 proxy.example.net 是代理,而 target.example.net 是您要获取的站点:

GET http://target.example.net/path/to/resource HTTP/1.1
Host: proxy.example.net

这是为了说明目的,因为您会注意到用于向代理发出 HTTP 请求的 URL 是这样的:

http://proxy.example.net/http://target.example.net/path/to/resource

当您使用 DNAT 简单地重定向流量时,wget 将解析 target.example.net 并将 URI 的路径部分作为请求正文而不是要代理的 URL 发送,因此它只发送以下内容:

GET /path/to/resource HTTP/1.1
Host: target.example.net

squid 服务器对此感到困惑,因为它不是 target.example.net,也没有在 /path/to/resource 提供文档。

如果将 squid 配置为透明代理,您实际上可以使用以下指令来执行此操作(对于 2.6 版之前的 squid):

httpd_accel_host virtual
httpd_accel_port 8080
httpd_accel_with_proxy on
httpd_accel_uses_host_header on

最后一个,httpd_accel_uses_host_header on告诉 squid 使用Host:我上面示例中的标头(需要 HTTP 1.1)来确定从哪里获取资源,而不是使用我上面提到的显式代理请求。请参阅http://squidconfiguration.com/config-manual-2-4/httpd-accelerator-options/httpd_accel_uses_host_header/

对于较新版本的 squid(3.1 及更高版本),请使用以下 listen 指令:

http_port 8080 intercept

看这里:http://www.squid-cache.org/Doc/config/http_port/

对于一些老版本的squid来说,是“透明”而不是“拦截”。

squid wiki 上有一个很好的教程:http://wiki.squid-cache.org/ConfigExamples/Intercept/LinuxRedirect

相关内容