PHP项目境外IP如何拦截禁止访问站点

wen PHP项目 23

本文目录导读:

PHP项目境外IP如何拦截禁止访问站点

  1. 使用IPIP.net或纯真IP数据库(推荐)
  2. 使用IP地理位置API(在线查询)
  3. Nginx反向代理拦截(性能最优)
  4. 混合方案(缓存+数据库)
  5. 使用CDN/WAF服务(推荐企业使用)
  6. 注意事项
  7. 完整示例(推荐方案)

针对PHP项目拦截境外IP访问,有以下几种常用方案,按推荐程度排序:

使用IPIP.net或纯真IP数据库(推荐)

方案A:IPIP.net免费版

<?php
// 下载IPIP.net的datx文件(免费版)
// https://www.ipip.net/product/client.html
require_once 'IP.class.php';
function isChinaIP($ip) {
    $ipdb = new IP('ipipfree.ipdb');
    $result = $ipdb->find($ip, 'CN');
    return $result[0] === '中国';
}
$userIP = $_SERVER['REMOTE_ADDR'];
if (!isChinaIP($userIP)) {
    header('HTTP/1.1 403 Forbidden');
    die('Access Denied');
}
?>

方案B:纯真IP数据库

<?php
// 使用纯真IP数据库(推荐QQWry.dat)
require_once 'ip_library.php';
function isChinaIP($ip) {
    $location = ip2location($ip);
    return strpos($location, '中国') !== false || 
           strpos($location, 'China') !== false;
}
?>

使用IP地理位置API(在线查询)

<?php
function isForeignIP($ip) {
    // 使用ip-api.com免费API
    $url = "http://ip-api.com/json/{$ip}";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    $response = curl_exec($ch);
    curl_close($ch);
    $data = json_decode($response, true);
    return $data['countryCode'] !== 'CN';
}
$userIP = $_SERVER['REMOTE_ADDR'];
if (isForeignIP($userIP)) {
    header('HTTP/1.1 403 Forbidden');
    exit('Access Denied');
}
?>

Nginx反向代理拦截(性能最优)

# 在nginx配置中
geo $country {
    default 1;
    include /etc/nginx/geo/china_ip.txt;  # 中国IP列表
}
server {
    location / {
        if ($country = 1) {
            return 403;
        }
        # 正常处理...
    }
}

混合方案(缓存+数据库)

<?php
class IPBlocker {
    private $cacheFile = '/tmp/ip_cache.json';
    private $cacheTime = 3600; // 1小时缓存
    public function checkIP($ip) {
        // 先检查缓存
        $cached = $this->getCache($ip);
        if ($cached !== null) {
            return $cached;
        }
        // 查询IP归属地
        $isChina = $this->isChinaIP($ip);
        // 写入缓存
        $this->setCache($ip, $isChina);
        return $isChina;
    }
    private function isChinaIP($ip) {
        // 使用IPIP.net或纯真数据库查询
        // ...
    }
}
?>

使用CDN/WAF服务(推荐企业使用)

  • Cloudflare:规则拦截非中国IP
  • 阿里云WAF:地域封禁
  • 腾讯云CDN:IP黑白名单

注意事项

  1. 性能考虑:避免每次请求都查询API,建议使用本地数据库+缓存
  2. 误伤问题:海外华人、VPN用户可能被误伤
  3. 动态IP:部分境外IP可能走境内代理
  4. IPv6:需要同时处理IPv6地址

完整示例(推荐方案)

<?php
// 使用composer安装 ipip/ipip-php
// composer require ipip/ipip-php
require 'vendor/autoload.php';
use ipip\db\City;
function blockForeignIP() {
    try {
        $ip = $_SERVER['REMOTE_ADDR'];
        $db = new City('/path/to/ipipfree.ipdb');
        $result = $db->find($ip, 'CN');
        // 如果返回的国家不是中国
        if ($result[0] !== '中国') {
            header('HTTP/1.1 403 Forbidden');
            echo json_encode([
                'code' => 403,
                'message' => 'Access Denied: Foreign IP'
            ]);
            exit;
        }
    } catch (Exception $e) {
        // 数据库加载失败时的处理
        error_log('IP Database error: ' . $e->getMessage());
    }
}
// 在项目入口处调用
blockForeignIP();
?>

最佳实践建议:使用IPIP.net离线数据库 + 本地缓存机制,既能保证性能又能确保准确性,对于高流量站点,建议在Nginx/CDN层做拦截。

抱歉,评论功能暂时关闭!