Allow a range of IP addresses to bypass maintenance mode in Laravel

In Laravel, you can put the app in Maintenance Mode by running php artisan down in the console. However, this also locks you out of the app. An easy way to get around this is to do a simple check for an array of allowed IP addresses in app/start/global.php where the Maintenance Mode Handler function exists.

App::down(function()
{
    if ( ! in_array(Request::getClientIp(), ['10.0.2.2']))
    {
    	return Response::view('maintenance', [], 503);
    }
});

You can take this a step further if you need more advanced functionality to check for IP ranges, which is not feasible with the solution above.

Create a config file maintenance.php to add an array of allowed IP addresses. The array can included a single IP address or a range of IP addresses.

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Allowed IP Addresses
    |--------------------------------------------------------------------------
    | Include an array of IP addresses or ranges that are allowed access to the app when
    | it is in maintenance mode.
    |
    | Supported formats:
    | 10.1.1.1
    | 10.1.*.*
    | 10.1.1.1-10.1.2.255
    |
    */

    'allowed_ips' => [
        '10.0.2.2',
        '10.2.*.*',
        '10.0.2.3 - 10.0.2.45',
        '10.0.3.0-10.3.3.3'
    ],

];

Create a helper file helpers.php in the app folder and add the functions below.

<?php

if ( ! function_exists('is_admin_ip'))
{
    /**
     * Checks whether an IP address exists in a given array of IP addresses
     *
     * @return boolean
     */
    function is_admin_ip($ip)
    {
        $allowedIps = Config::get('maintenance.allowed_ips');

        foreach ($allowedIps as $allowedIp)
        {
            if (strpos($allowedIp, '*'))
            {
                $range = [
                    str_replace('*', '0', $allowedIp),
                    str_replace('*', '255', $allowedIp)
                ];

                if(ip_exists_in_range($range, $ip)) return true;
            }
            else if(strpos($allowedIp, '-'))
            {
                $range = explode('-', str_replace(' ', '', $allowedIp));

                if(ip_exists_in_range($range, $ip)) return true;
            }
            else
            {
                if (ip2long($allowedIp) === ip2long($ip)) return true;
            }
        }
        return false;
    }
}

if ( ! function_exists('ip_exists_in_range'))
{
    /**
     * Checks whether an IP address exists within a range of IP addresses
     *
     * @return boolean
     */
    function ip_exists_in_range(array $range, $ip)
    {
        if (ip2long($ip) >= ip2long($range[0]) && ip2long($ip) <= ip2long($range[1]))
        {
            return true;
        }
        return false;
    }
}

Add the helpers.php file to the bottom of your app/start/global.php file.

require app_path().'/helpers.php';

Then just update the Maintenance Mode Handler in app/start/global.php to use the helper function.

App::down(function()
{
    if ( ! is_admin_ip(Request::getClientIp()))
    {
    	return Response::view('maintenance', [], 503);
    }
});