How can I track IPs to block malicious users?

2019-04-10 19:11发布

问题:

Here is a few theories to get user's IP

Theory1: If you don't use a load balancer, use REMOTE_ADDR. If you use a load balancer, use whatever it uses. In 99% of cases that appears to be HTTP_X_FORWARDED_FOR. So:

function get_ip_address(){
    $id = '';
    if (isset($_SERVER['REMOTE_ADDR']))
        $ip = $_SERVER['REMOTE_ADDR']; 
    else if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; 
    else
        $ip = 'UNKNOWN';
    return $ip;
}

Theory2: There is some other HTTP header information (ie. $_SERVER['HTTP_...]) which might be containing the IP. So:

function get_ip_address(){
    foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
        if (array_key_exists($key, $_SERVER) === true){
            foreach (explode(',', $_SERVER[$key]) as $ip){
                $ip = trim($ip); // just to be safe
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
                    return $ip;
                }
            }
        }
    }
}

Theory3: Storing both one of $_SERVER['HTTP_...] and $_SERVER['REMOTE_ADDR']. So there is two variables:

function get_ip_address(){
    foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED') as $key){
        if (array_key_exists($key, $_SERVER) === true){
            foreach (explode(',', $_SERVER[$key]) as $ip2){
                $ip2 = trim($ip2); // just to be safe
                if (filter_var($ip2, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
                    $ip1 = $_SERVER['REMOTE_ADDR'];
                    return array($ip2, ip1);
                }
            }
        }
    }
}

Well honestly I'm confused a little bit. How many column (in the database) do I need to store the user's IP? I mean should I store both REMOTE_ADDR and a HTTP_...? Or just one of them?

Actually I have a query which inserts the user's IP per each page loading in the database. So that query will be executed every time before loading of the page. Surely an INSERT query (everytime for each request, and each user) has a cost. So I don't want it be useless. I mean I want to store a correct/real IP or at least I want to do the best work which is possible to detect the user's IP * .

* When an user uses a proxy like HSS then detecting him would be impossible. That's why I said "at least".

Ok well, which theory is the best?

回答1:

You need to decide when you're storing the IP whether you trust the remote address that's sending the X-FORWARDED-FOR address. If you do, then you store the forwarded address, otherwise you store the remote address. So it could be like this:

$load_balancer = '10.20.30.40';
$ip = $_SERVER['REMOTE_ADDR'];
if (isset($_SERVER['X_FORWARDED_FOR'] && $ip = $load_balancer) {
    $ip = $_SERVER['X_FORWARDED_FOR'];
}

Then log $ip in the database.

I don't see any point in storing the load balancer IP in the database as well. Performing the trust check when processing the database data would require you to have another table that says what the load balancer IP was during different time periods.



回答2:

I think there is already a very good answer for this question on stackoverflow so i wouldn't elaborate which value to chose. See https://stackoverflow.com/a/15699240/6543678

I would note two things about logging user ip address.

First of all you should use some nosql database for this task. You might configure it as log backend and simple call something like \Log::info("{$ip} login as {$email}", \Log::GROUP_IP) or something similar what will be easy to use and later search in db for you.

On the other hand logging ip doesn't help at all from my point of view. Implement good strategies to avoid robots (e.g. google captcha), ban account's of aggressive users. Real hackers know how to hide their ip's. It's easy to use good proxy, you can use hacked personal computers/servers, use tor or many other ways to hide your identity.

Just don't waste too much time on the logging ip's in case your real goal is to secure your site.