IP白名单使用范围

时间:2019-08-04 08:06:28

标签: php mysql

我为服务的用户提供了一个选项,使其仅允许从可以添加的某些IP地址访问其帐户。支票的工作方式如下:

$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
    exit;
} 

$whitelist = array();
$sql = "SELECT IP_Address FROM IPWhitelist WHERE owner=$userid";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
    // output data of each row
    while($row = $result->fetch_assoc()) {
        $whitelist[] = $row["IP_Address"];
    }

    if (in_array($_SERVER['REMOTE_ADDR'], $whitelist)) {
        //Action for allowed IP Addresses
    } else {
        //Action for all other IP Addresses
        echo '<html>This account has enabled IP Whitelisting and has rejected your connection.<br /><br />If you believe this to be an error, please email hello@xxxxxx'; 
        echo "<br /><br />IP Address: ".$_SERVER['REMOTE_ADDR']."</html>";
        exit;
    }
} 
$conn->close();

上面的方法可以很好地检查特定的IP地址,但是如何允许用户指定IP范围呢?所以167.22。*

1 个答案:

答案 0 :(得分:0)

如果要使用CIDR notation,而不是使用通配符(例如167.22.*),则可以采用这样的方法-主要使用PHP而不是复杂的sql查询。以下内容不代表IPv6地址。

<?php

    function createIPRange( $cidr ){
        $a = explode( '/', $cidr );
        $x = 32 - $a[1];
        $c = pow( 2, $x );
        $s = ip2long( $a[0] );
        $e = $s + $c;
        $r = array_map( 'long2ip', range( $s, $e ) );
        /* remove last 2 entries from generated list */
        array_pop( $r );
        array_pop( $r );
        /* return ip addresses */
        return $r;
    }

    $cidr='167.22.0.0/16'; // 65,535 addresses
    $ip=$_SERVER['REMOTE_ADDR'];
    $email='hello@xxx.yyy';

    $whitelist=array();
    $ranges=array();




    $sql='select `ip_address` from `ipwhitelist` where `owner`=?';
    $stmt=$conn->prepare( $sql );
    $stmt->bind_param( 's', $userid );
    $stmt->execute();

    $res=$stmt->get_result();
    while( $rs=$res->fetch_object() ){
        if( strstr( $rs->ip_address, '/' ) )$ranges[]=$rs->ip_address;
        else $whitelist[]=$rs->ip_address;
    }

    /* create the ip addresses for each cidr range */
    foreach( $ranges as $cidr ){
        $whitelist[]=createIPRange( $cidr );
    }


    /* test to see if the ip is allowed */
    if( in_array( $ip, $whitelist ) ){
        /* OK */
        http_response_code( 200 );
    } else {

        /* Bogus */
        $message=sprintf('
            This account has enabled "IP Whitelisting" and has rejected your connection.
            <br /><br />
            If you believe this to be an error, please email %s
            <br /><br />
            IP Address: %s', 
            $email,
            $ip
        );


        printf('
        <html>
            <head>
                <title>Forbidden</title>
            </head>
            <body>
                %s
            </body>
        </html>', $message );


        http_response_code( 403 );
    }