为phpwind做代理加速镜像

今天给风云墙做了一个教育网的代理服务器来给教育网的用户加速。本来以为是一个很简单的问题,结果却大费周折。

第一打算是用squid来做,结果却由于原来的80端口被占用,暂时找不到一个圆满的解决方案,只好放弃。

80端口已经被apache占用了,也就只好用mod_proxy来做了。
在apache中加上这么一个vhost,理论上应该是可以了,但是,里面的链接还是指向原来的http://bbs.clwind.net,并不像反向代理所期待的http://edu.clwind.net.

<VirtualHost *:80>
    ServerAdmin myhnet@gmail.com
    DocumentRoot /none
    ServerName  edu.clwind.net
    ProxyRequests Off
    ProxyPass  / http://bbs.clwind.net
    ProxyPassReverse / http://bbs.clwind.net
</VirtualHost>

开始一直以为是反向代理的问题(我对反向代理不太熟悉),查找了好久,也没发现问题所在(本来就不是他的问题,怎么可能发现得了)。最好做了一个最简单的网站来做源站,才发现原来是phpwind的head部分的问题。

在phpwind的header.html中,给页面加上了一个base标签

<base id="headbase" href="$db_bbsurl/" />

base标签的作用是给网页中的链接指定一个默认的URL前缀或者是指定一个target,比如:

<base target="_blank" />

而在phpwind中,$db_bbsurl这个变量是由PHP系统变量$_SERVER[HTTP_HOST]得来的。

但是这个变量在使用了反向代理之后,并不是我们访问的URL,这个时候介入了一个新的变量,只有在使用代理访问之后才会有的变量:$_SERVER[HTTP_X_FORWARDED_HOST]。这个变量才是我们访问的URL。

这样,为了反向代理能够正常使用,我们需要更改phpwind的代码。
打开global.php

解决base标签的问题
找到:

$R_url = $db_bbsurl = Char_cv("http://$_SERVER[HTTP_HOST]".substr($tmp,0,strrpos($tmp,'/')));

修改为:

if ($_SERVER[HTTP_X_FORWARDED_HOST]) {
        $R_url = $db_bbsurl = Char_cv("http://$_SERVER[HTTP_X_FORWARDED_HOST]".substr($tmp,0,strrpos($tmp,'/')));
} else {
        $R_url = $db_bbsurl = Char_cv("http://$_SERVER[HTTP_HOST]".substr($tmp,0,strrpos($tmp,'/')));
}

解决前台发帖的非法操作问题
同样在global.php中:
找到:

list($http_host) = explode(':',$_SERVER['HTTP_HOST']);

修改为:

if ($_SERVER[HTTP_X_FORWARDED_HOST]){
                        list($http_host) = explode(':',$_SERVER['HTTP_X_FORWARDED_HOST']);
                } else {
                        list($http_host) = explode(':',$_SERVER['HTTP_HOST']);
                }

解决多重代理IP unknow问题
还是global.php
找到:

$onlineip = $_SERVER['HTTP_X_FORWARDED_FOR'];

改为:

$ip_temp=explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']);
        $onlineip = $ip_temp[0];

这样子做有一个BUG:如果访问者用内网代理,得到的IP将会是内网IP。我正在想办法解决。

最后,要做的就是解决后台操作非法的问题。由于有我前面说的那个BUG,我不建议修改这个,可以说明的就是修改的方法跟前台类似。