Index  •   DF Generator  •   MQ Generator  •    

It is currently Thu Nov 23, 2017 14:02 pm
LOG IN TO SEE THE REST OF THE FORUMS






Post new topic Reply to topic  [ 2 posts ] 
 Blocking Proxies, VPNs, and IP Addresses through PHP 
Author Message
 Post subject: Blocking Proxies, VPNs, and IP Addresses through PHP
PostPosted: Mon Sep 11, 2017 10:48 am 
User avatar

Joined: Thu Aug 25, 2016 11:02 am
Posts: 15
Reply with quote
Preface : It's recommended that you block addresses through Nginx or Apache settings before relying on PHP to handle this for you.
The PHP method is slower and less efficient than blocking these addresses through Nginx or Apache.

If you absolutely must rely on PHP (webhost restraints perhaps) then I suppose I can show you the method of blocking these types of connections from your websites.

Proxies : When it comes to blocking proxies, you'll most likely block all but Elite Proxies since all other proxy types will denote their proxy status to the server.

This means that the method of blocking elite proxies is different to the method of blocking the other proxy types out there. So let's get started by finding out where the proxy denotes its proxy status using PHP:

Code:

$headers 
= [
    'USERAGENT_VIA',
    'VIA',
    'HTTP_PROXY_CONNECTION',
    'HTTP_XPROXY_CONNECTION'
];

foreach(
$headers as $head) {
    filter_has_var(INPUT_SERVER, $head) ? die('No proxies allowed!') : '';
}
 


Let's say someone connects to the server using an anonymous proxy, they'll see "No proxies allowed!" instead of seeing the contents of the site.

Cloudflare : Cloudflare's reverse proxy can wind up causing a false positive with the proxy blocker method implemented in this tutorial. The way to solve this is to install mod_cloudflare by either asking your webhost to do it for you (since you're paying for the service) or by manually connecting to the webserver through SSH (use PuTTy if you don't have any other SSH client on hand) and then installing mod_cloudflare yourself with help of a quick Google search.

VPNs : Blocking VPNs through PHP is far more involved than blocking VPNs through Nginx or Apache. You have to convert IPv4 and IPv6 subnets into their respective address range and check the incoming IP address against all of those addresses in the subnet.

So we must start by introducing ASNs which is an Autonomous System Number that ISPs and VPNs must purchase which comes with a package of subnets (ranges of IP addresses) that they can issue out to their customers via their DHCP servers (the servers that are responsible for issuing you your IP address from the ISP).

The purpose of an ASN is so that two or more ISPs won't be issuing out the same IP address to 1 or more users. These ASNs are not private and so we can search for them and return a list of subnets that we can add to our blocklists: https://www.enjen.net/asn-blocklist/

Code:

function safe_base_dir
() {
    return strstr(filter_input(INPUT_SERVER, 'DOCUMENT_ROOT'), '/') ? filter_input(INPUT_SERVER, 'DOCUMENT_ROOT') : filter_input(INPUT_SERVER, 'DOCUMENT_ROOT') . '/'; // Return the base directory of the server.
}

function check_ipv4($ip, $cidr) {
    list($subnet, $bits) = explode('/', $cidr); // Splitting the CIDR notation subnet into its respective parts.
    
    $info 
= [
        'ip'        => ip2long($ip),       // Converting the IP address into a long integer.
        'subnet' => ip2long($subnet) // Converting the subnet value into a long integer.
    ];

    $mask = -<< (32 - $bits); // Using a bitwise operator to return the total number of IPs in the subnet.
    $info['subnet'] &= $mask;

    $info['ip'] & $mask === $info['subnet'] ? die('VPN Detected') : ''; // Kill the connection if a VPN is detected.
}

function check_ipv6($ip, $cidr) {
    list($subnet, $bits) = explode('/', $cidr);
    $char = (128 - $bits) / 4;

    $hex_subnet = substr(bin2hex(inet_pton($subnet)), 0, 0 - $char);
    $hex_ipaddr = substr(bin2hex(inet_pton($ip)), 0, 0 - $char);

    $hex_ipaddr === $hex_subnet ? die('VPN Detected') : '';
}

$ip = filter_input(INPUT_SERVER, 'REMOTE_ADDR'); // Gather the IP address of connected user.
$iptype = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? 'IPV4' : 'IPV6'; // Determine if IP is IPv4 or IPv6.

$asnsource = glob(safe_base_dir() . 'asn/*.asn'); // List all .asn files in the asn folder.

foreach($asnsource as $asnfile) {
    $asnlist = file($asnfile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); // Load the contents of the file into an array.
    
    foreach
($asnlist as $asnaddr) {
        $subtype = filter_var(explode('/', $asnaddr)[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? 'IPV4' : 'IPV6'; // Determine if the subnet address is an IPv4 or IPv6 subnet address.
        $vtotal = $iptype == 'IPV4' && $subtype == 'IPV4' ? check_ipv4($ip, $asnaddr) : check_ipv6($ip, $asnaddr); // Check the IP address against the subnet address.
    }
}
 


You may recognize this code from my ProxGFY plugin that I wrote for MyBB 1.8; and you'd be correct. This is the method that I'm most familiar with when it comes to blocking VPNs using PHP.

What makes this method slow is that the script has to check every single incoming IP address against a large list of subnet addresses in the ASN. So you could be running thousands of checks per IP depending on the number of ASNs you're blocking and the number of concurrent connections. This could overwhelm the server so it's always advised to block VPNs through Nginx or Apache and the ASN search site I linked includes a feature to generate blocklists for both Nginx and Apache. Please make use of that instead of doing it through PHP if you can.

IP Addresses : This method is a bit easier and is the only method I know of blocking elite proxies from accessing your site.

Code:
// Create an array of IP addresses you wish to block (IPv4 and IPv6 works just fine here).
$blacklist = [
    '127.0.0.1',
    '::1'
];

$ip = filter_input(INPUT_SERVER, 'REMOTE_ADDR'); // Grab the IP address.

in_array($ip, $blacklist) ? die('Your IP has been banned.') : ''; // Kill the connection if the IP is found in the blacklist.


It is faster to use Nginx or Apache IP blocking if you have a massive number of blacklisted IP addresses. Again the real lesson here is to rely on your Nginx or Apache server to block VPNs and IP addresses instead of using PHP.

Conclusion : When blocking non-elite proxies; you can definitely use PHP to do this and you'll be perfectly fine as long as you're not running behind a Cloudflare reverse proxy (install mod_cloudflare if you are in order to fix this).

When blocking VPNs and IP addresses, you are much better off using Nginx or Apache blocklists to accomplish this. Nginx requires you to add these IPs and VPNs to the configuration file and you can use .htaccess files to block IPs and VPNs if you're running with Apache.


Offline
 Profile  
 
 Post subject: Re: Blocking Proxies, VPNs, and IP Addresses through PHP
PostPosted: Thu Oct 12, 2017 7:33 am 
Site Admin

Joined: Fri Feb 27, 2015 18:30 pm
Posts: 761
Reply with quote
Nice share dude!


Offline
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 




 Who is online 

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for: