我可以强制 apache 的 mod_proxy 通过主机名而不是 IP 连接到远程服务器吗?

我可以强制 apache 的 mod_proxy 通过主机名而不是 IP 连接到远程服务器吗?

我正在将 Apache2 设置为远程站点的反向代理。假设远程站点是http://app.remotesite.com。这是我的虚拟主机配置的一个片段:

ProxyPass /pxy/ http://app.remotesite.com/

因此这应该接受如下请求http://app.mysite.com/pxy/search?q=abc,并将其传递为http://app.remotesite.com/search?q=abc

当我尝试这个时,我得到了一个“错误请求”。根据 /var/log/apache2/error.log 中的输出,它正确地执行了代理,但当它连接到远程站点时,它似乎使用其 IP 地址进行连接。如果我获取该 IP 地址(打印在 error.log 中)并使用它发出请求,例如http://[IPaddress]/search?q=abc,我得到了同样的“错误请求”错误。我的假设是远程站点依赖主机名来正确处理请求,但 mod_proxy 没有发送它。我知道 ProxyPreserveHost 设置,但这是为了在代理请求中保留原始主机名(在本例中为 app.mysite.com),这不是我想要的。

有人能建议我强制 mod_proxy 在请求中使用远程站点的主机名吗?或者,如果我的假设不合理,请指出可能还有哪些地方出了问题?

答案1

您的假设可能不正确。 mod_proxy使用您在代理 URL 中提供的主机名进行连接。

如果您http://app.remotesite.com/search?q=abc在命令行上使用发出请求curl,您会得到预期的响应吗?如果是这样,那么一个好的起点是查看 curl 生成的请求与mod_proxy发送的请求之间的差异。

要查看curl正在执行的操作,您可以使用以下--trace-ascii <file>选项,如下所示:

curl --trace-ascii trace.out http://app.remotesite.com/search?q=abc

这将产生trace.out如下输出:

== Info: About to connect() to google.com port 80 (#0)
== Info:   Trying 74.125.228.8... == Info: connected
== Info: Connected to google.com (74.125.228.8) port 80 (#0)
=> Send header, 165 bytes (0xa5)
0000: GET / HTTP/1.1
0010: User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7
0050:  NSS/3.13.1.0 zlib/1.2.3 libidn/1.18 libssh2/1.2.2
0084: Host: google.com
0096: Accept: */*
00a3: 

从 Apache 获取相同的信息有点棘手;我会使用tcpdump,这是一个数据包捕获工具。开始捕获数据包,如下所示:

tcpdump -w packets -s 1500 port 80 and host app.remotesite.com

当 tcpdump 运行时,从浏览器(或 curl 或其他)发出请求,使用 停止tcpdump^C然后像这样检查文件:

strings packets

这将给你类似这样的结果:

{GET / HTTP/1.1
User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.1.0 zlib/1.2.3 libidn/1.18 libssh2/1.2.2
Host: google.com
Accept: */*

这将显示所请求的 URL、Host:标头和其他有用信息。查看它的外观,如果您没有发现任何明显的问题,请返回此处。

相关内容