我正在使用 Cloudflare 和 nginx geoip 指令:
geoip_country /usr/local/share/GeoIP/GeoIP.dat;
geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat;
他们选择 IP 正常(pipaddress
因为请求在标头中标记为已转发),但将国家/地区显示为 SG(cloudflare 代理位置)。
如果HTTP_X_FORWARDED_FOR
设置了标题,是否有最终用户的国家?
<?php
if (getenv(HTTP_X_FORWARDED_FOR))
{
$pipaddress = getenv(HTTP_X_FORWARDED_FOR);
$ipaddress = getenv(REMOTE_ADDR);
echo "Your IP address is : ".$pipaddress. " (via proxy $ipaddress) " ;
}
else
{
$ipaddress = getenv(REMOTE_ADDR);
echo "Your IP address is : $ipaddress";
}
$country = getenv(GEOIP_COUNTRY_NAME);
$country_code = getenv(GEOIP_COUNTRY_CODE);
echo "<br/>Your country : $country ( $country_code ) ";
?>
并且/etc/nginx/fastcgi_params
如下:
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# Set php-fpm geoip variables
fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code;
fastcgi_param GEOIP_COUNTRY_CODE3 $geoip_country_code3;
fastcgi_param GEOIP_COUNTRY_NAME $geoip_country_name;
fastcgi_param GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code;
fastcgi_param GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3;
fastcgi_param GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name;
fastcgi_param GEOIP_REGION $geoip_region;
fastcgi_param GEOIP_CITY $geoip_city;
fastcgi_param GEOIP_POSTAL_CODE $geoip_postal_code;
fastcgi_param GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code;
fastcgi_param GEOIP_LATITUDE $geoip_latitude;
fastcgi_param GEOIP_LONGITUDE $geoip_longitude;
您的 nginx 服务器无法确定传递给 PHP 的请求的真实 IP。解决方法是使用 Nginx 的 Real IP 模块。
看看这个https://support.cloudflare.com/hc/en-us/articles/200170706-How-do-I-restore-original-visitor-IP-with-Nginx-
只需将链接中的代码片段添加到您的配置文件并重新启动 nginx。
@the_nuts 的答案扩展。我拼凑了一个小脚本,它会
geoip_proxy
根据 cloudflare 页面上的列表自动生成指令列表:用法:启动此脚本一次,它将生成
/etc/nginx/geoip_cloudflare.conf
文件。然后将以下内容添加到您的http
块中:或者,将脚本添加到 cron 以定期更新 IP 列表。不知道他们多久改变一次。
注意:脚本不是很优化,在更新过程中配置/包含文件会在短时间内为空。如果 nginx 恰好在那个时间重新启动,那么 geoip_proxy 指令将不起作用。
正确的方法是使用geoip_proxy指令将 CloudFlare IP 范围设置为受信任的代理。不需要额外的模块。
到今天为止,结果如下:
您可以在此处找到 CloudFlare IP 的更新列表:https ://www.cloudflare.com/ips/