使用cdn后的问题——访客ip&ipv6

2247天前 · 分享 · 吐槽 · 1123次阅读

使用CF的CDN后,发现ip地址清一色的美国,后来才想起来访客ip这回事。
实际上服务器会得到访客的真实ip,只不过typecho获取ip的方法会默认先得到cdn的ip。

按网络的方法:

https://kotori.love/archives/typecho-plugin-access.html

在typecho的config.inc.php中配置define('__TYPECHO_IP_SOURCE__', 'HTTP_CF_CONNECTING_IP');

完全OK...

如果是其他cdn,可以在主页根目录下新建info.php
内容是<?php phpinfo(); ?>

然后访问你的网址/info.php

就能看到详细信息,在PHP Variables这个部分有访问的记录

我用的是CF,有$_SERVER['HTTP_CF_CONNECTING_IP']这样的字段,同时$_SERVER['HTTP_X_FORWARDED_FOR']这个字段也是真实ip,那么就可以按前面说的那样在config.inc.php添加配置,优先通过这个地方获取ip,那么就可以正常显示访客ip了。

不过数据库中Access插件的ip对于ipv6全部为0。
看了下源代码,作者使用的是ip2long和long2ip来处理ip,这对于ipv6没法正确处理。
在Access_Core.php中可以看到如下代码:

public function long2ip($long) {
    if ($long < 0 || $long > 4294967295) return false;
    $ip = "";
    for ($i=3;$i>=0;$i--) {
        $ip .= (int)($long / pow(256,$i));
        $long -= (int)($long / pow(256,$i))*pow(256,$i);
        if ($i>0) $ip .= ".";
    }
    return $ip;
}

long传入是ip转换后的十进制数,ipv6转换后大于4294967295,然后一系列的值就置0了。

根据官方文档,对于ipv6有人给出ip2bin和bin2ip的函数,如下:

function ip2bin($ip) 
{ 
    if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) 
        return base_convert(ip2long($ip),10,2); 
    if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) 
        return false; 
    if(($ip_n = inet_pton($ip)) === false) return false; 
    $bits = 15; // 16 x 8 bit = 128bit (ipv6) 
    while ($bits >= 0) 
    { 
        $bin = sprintf("%08b",(ord($ip_n[$bits]))); 
        $ipbin = $bin.$ipbin; 
        $bits--; 
    } 
    return $ipbin; 
} 

function bin2ip($bin) 
{ 
   if(strlen($bin) <= 32) // 32bits (ipv4) 
       return long2ip(base_convert($bin,2,10)); 
   if(strlen($bin) != 128) 
       return false; 
   $pad = 128 - strlen($bin); 
   for ($i = 1; $i <= $pad; $i++) 
   { 
       $bin = "0".$bin; 
   } 
   $bits = 0; 
   while ($bits <= 7) 
   { 
       $bin_part = substr($bin,($bits*16),16); 
       $ipv6 .= dechex(bindec($bin_part)).":"; 
       $bits++; 
   } 
   return inet_ntop(inet_pton(substr($ipv6,0,-1))); 
}

动手尝试更改了源代码,但是有些小问题,本身不懂php也不敢多折腾,暂时先不改...
tip:数据库ip的类型也需要更改。
在github的issue里面有ipv6显示正常的图,不过那里的ip的类型是varchar,目前的新版本又是int(32)。

相关链接:

https://kotori.love/archives/typecho-plugin-access.html?c
http://blog.lanyus.com/archives/323.html
https://github.com/kokororin/typecho-plugin-Access
http://php.net/manual/zh/function.ip2long.php

👍 0

none

还没有修改过

评论

贴吧 狗头 原神 小黄脸
收起

贴吧

狗头

原神

小黄脸

目录

avatar

未末

迷失

126

文章数

275

评论数

7

分类