使用OpenShift、BAE等云引擎,访客都不是直接访问网站,需要云引擎“中转”一次。因此会出现访客IP信息为云引擎内部IP的问题。同理,网站启用CDN,或者是访客使用代理访问,WordPress默认设置也不能取得真实IP。这个问题不是Bug,而是IP获取方式的选择不同。
IP问题
一般,有三种获取IP方式,简单定义:
- REMOTE_ADDR = 当前网站浏览者的IP;
- HTTP_VIA = 代理服务器的IP;
- HTTP_X_FORWARDED_FOR = 代理服务器隐藏的IP。
如果使用过Opera mini/欧朋/Opera Mobile的用户应该“深有体会”,IP查询可以查到外部IP和内部IP,分别对应“REMOTE_ADDR”和“HTTP_X_FORWARDED_FOR”。
WordPress默认使用“REMOTE_ADDR”获取IP信息
wp-includes/comment.php
* We use REMOTE_ADDR here directly. If you are behind a proxy, you should ensure
* that it is properly set, such as in wp-config.php, for your environment.
在Openshift和BAE的云环境下,访客不是直接访问网站,而是还需要通过云环境的中转导向,所以WordPress默认获取的IP信息就是云环境的“中转站”信息是127.0.0.1等127开头的保留IP。
因此,用“HTTP_X_FORWARDED_FOR”替换默认的“REMOTE_ADDR”即可解决问题。
真实IP
适用范围:
- 云引擎:OpenShift、BAE……;
- WordPress启用CDN访问(部分CDN服务商也提供专门的插件);
- 访客使用透明代理(匿名代理可以欺骗)。
解决方法
1.wp-config.php(Apache,不仅仅适用于评论。如果同时使用OpenShift等云引擎和CDN,使用第四种方法)
<?php……后任意位置加入:
if ( !empty( $_SERVER[‘HTTP_X_FORWARDED_FOR’] ) )
$_SERVER[‘REMOTE_ADDR’] = $_SERVER[‘HTTP_X_FORWARDED_FOR’];
2.comment.php(只针对评论IP)
修改1706行的
$commentdata[‘comment_author_IP’] = preg_replace( ‘/[^0-9a-fA-F:., ]/’, ”,$_SERVER[‘REMOTE_ADDR’] );
为:
$commentdata[‘comment_author_IP’] = preg_replace( ‘/[^0-9a-fA-F:., ]/’, ”,$_SERVER[‘HTTP_X_FORWARDED_FOR’] );
3.Functions.php
代码不贴了,懒得测试一堆代码,网络上到处都有,没有前面两个方法来的直观。
4.同时使用OpenShift云引擎和CDN
在同时使用OpenShift和CDN后,方法一的代码依然有效,但评论记录会显示两个IP,一个是真实IP,一个是CDN的IP。
代码修正如下:
wp-config.php
<?php……后加入:
if(isset($_SERVER[‘HTTP_X_FORWARDED_FOR’])) { $list = explode(‘,’,$_SERVER[‘HTTP_X_FORWARDED_FOR’]); $_SERVER[‘REMOTE_ADDR’] = $list[0]; }