在使用和配置过程中,还是遇到了一些波折,这里分享、记录一下。
使用Apache内置的mod_proxy的Proxypass可以帮助我们实现基本的反向代理功能。但是,代理返回的结果页面包含的链接并不会被重写,所以如果被代理的Server返回的是绝对地址,用户则无法正确访问这些链接。例如:
我们有反向代理服务器http://myproxy.taobao.org/,而内网有需要代理的服务器http://internalserver.taobao.org/,通过基本的反向代理指令Proxypass:
ProxyPass ^/proxy_internal/(.*)$ http://internalserver.taobao.org/$1
可以完成基本的反向代理任务,但是如果internalserver.taobao.org返回的HTML代码中有如下链接,则客户端则无法正常链接到目标页面了:
<a href=”/test/index.html”>Sample Link</a>
因为,客户端点击该链接时会定向到http://myproxy.taobao.org/test/index.html,而资源实际是在http://internalserver.taobao.org/test/index.html上。
Apache自带的mod_proxy无法解决这个问题,开源的第三方模块mod_proxy_html为此而生。经过代理服务器的HTML可以通过该模块做一次替换,从而变成可以正常访问的URL(上例中会把/oninternal/index.html替换成/proxy_internal/test/index.html)。
我是在RHEL5.4上安装的,并不容易。理想的安装步骤(为了支持多字符集需要同时安装mod_xml2enc):
1. 检查是否安装了libxml2。
2. 下载mod_proxy_html源码:地址;下载mod_xml2enc的源码:地址mod_xml2enc
3. 编译mod_proxy_html和mod_xml2enc:
sudo /usr/sbin/apxs -c -I/usr/include/libxml2 -I. -I /usr/lib -i mod_proxy_html.c
sudo /usr/sbin/apxs -c -I/usr/include/libxml2 -I. -i mod_xml2enc.c
chmod 755 /usr/lib64/httpd/modules/mod_proxy_html.so
如果你这么顺利就编译好了模块,那你很幸运。
$ /usr/sbin/apxs -c -I/usr/include/libxml2 -I. -I /usr/lib -i mod_proxy_html.c
“my” variable $libdir masks earlier declaration in same scope at /usr/sbin/apxs line 36.
/apr-1/build/libtool –silent –mode=compile gcc -prefer-pic -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector –param=ssp-buffer-size=4 -m64 -mtune=generic -fno-strict-aliasing -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -pthread -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/apr-1 -I/usr/include/libxml2 -I. -I/usr/lib -c -o mod_proxy_html.lo mod_proxy_html.c && touch mod_proxy_html.slo
sh: /apr-1/build/libtool: No such file or directory
apxs:Error: Command failed with rc=8323072
仔细看是:/apr-1/build/libtool: No such file or directory。对libtool和apr-1不很熟悉,看出是因为没有正确找到libtool的路径导致的,所以修改了一下脚本apxs,强制指定libtool的位置,虽然这不是“优雅的”解决办法:
……
$vi /usr/sbin/apxs
…
my $libtool = `$apr_config –apr-libtool`;
chomp($libtool);
$libtool = “/usr/lib64/apr-1/build/libtool”;
…
It works! 如果有个有更好的办法,或者知道根本原因的,请告诉我,谢过先。
强烈建议参考mod_proxy_html源码中的proxy_html.conf,这是一个示例配置文件,非常有指导意义。我这里的配置如下:
1. 加载必要的模块:
LoadFile /usr/lib64/libxml2.so
LoadModule xml2enc_module modules/mod_xml2enc.so
LoadModule proxy_html_module modules/mod_proxy_html.so
2. 指定需要修改的链接标签:
SetOutputFilter proxy-html
ProxyHTMLExtended On
ProxyHTMLLinks a href
ProxyHTMLLinks area href
ProxyHTMLLinks link href
ProxyHTMLLinks img src longdesc usemap
ProxyHTMLLinks object classid codebase data usemap
ProxyHTMLLinks q cite
ProxyHTMLLinks blockquote cite
ProxyHTMLLinks ins cite
ProxyHTMLLinks del cite
ProxyHTMLLinks form action
ProxyHTMLLinks input src usemap
ProxyHTMLLinks head profile
ProxyHTMLLinks base href
ProxyHTMLLinks script src for
ProxyHTMLEvents onclick ondblclick onmousedown onmouseup \
onmouseover onmousemove onmouseout onkeypress \
onkeydown onkeyup onfocus onblur onload \
onunload onsubmit onreset onselect onchange
3. 指定的URL替换规则:
ProxyPassMatch ^/proxy_dir/(.*)$ http://yourdomain/$1 <LocationMatch "/proxy_dir/"> ProxyPassReverse / ProxyHTMLURLMap / /proxy_dir/ ProxyHTMLURLMap http://some_(reg_exp)_url_(is_supported)you_wanna_replace/ /proxy_dir/$1/$2/ R RequestHeader unset Accept-Encoding </LocationMatch>
OK,That’s all.
参考:
Leave a Reply