Simple Login-Wall iRule - Redirect unauthenticated users back to login page

Contributed by: David Holmes

Description

Defend against pernicious layer-7 DDoS attacks with this iRule. Clever hackers using tools such as Dirt Jumper can request your web objects and queries over and over again. Supposed you have a 5Mb PDF on your site and the attack requests it 100 times a second. That kind of load can quickly fill up a small pipe or crash a server.
When under attack, use this iRule to put up a “Login-Wall” to refuse any web request by an unauthenticated user.
The rule works by setting a cookie in the user’s browser when they successfully pass the login page and then checking for that cookie on every request. If there is no cookie, or it doesn’t match their IP address, they are sent back to the login page.
Some modifications are required to make this work for your application.
1. This iRule uses high speed logging - modify the HSL::open command to include your syslog pool.
2. The iRule must be able to detect when a successful authentication has happened. In my example application, a successful login will result in the user getting sent to a special page ($loggedinpage) where a special variable ($successheader) will be set. Your application may be easier. Maybe you already set a cookie in your application and you can simplifiy this irule even more.
Note: The new Dirt Jumper may be watching for cookies like these - if you run into that situation, this iRule can be modified to use JavaScript redirects instead.

iRule Source

    # ---
    # This simple rule implements a quick "login-wall" in front of an
    # application. If the user logs in successfully they can go about
    # their business - otherwise they cannot access any other page except
    # the login page.
    #
    # This particular iRule relies on the application to have a specific
    # page that indicates a successful login. The cookie that is provided
    # to the user is just their encrypted IP address.
    #
    # While relatively short and somewhat crude, this iRule may help you
    # repel a "recursive GET" attack until you can deploy a better defense
    # such as as BIG-IP ASM.
    # ---

    when CLIENT_ACCEPTED {
    set authstate 0
    set forceauth 1
    set ckname "DwhCkie"
    set ckpass "Khalisi"
    set c_ip [IP::client_addr]

    # Map this to your syslog pool
    set hsl [HSL::open -proto UDP -pool hsl_pool]

    # Modify these per your application
    set loginpage "/user_login.php"
    set loggedinpage "/logged_in.php"
    set successheader "X-DMX-Auth"
}

when HTTP_REQUEST {
    # ---
    # Did they get forwarded to the "now logged in page"?
    # If so, examine response in HTTP_RESPONSE
    # ---
    if { [HTTP::path] eq $loggedinpage } {
        # HSL::send $hsl "looking at loggedinpage"
        set authstate 1
    }
    elseif { not ([HTTP::uri] contains $loginpage) } { # check their cookie
        # ---
        # If they aren't at the login page, they must have the cookie
        # or they are going back to the login page.
        # ---
        set authstate 0
        if { [HTTP::cookie exists $ckname] } {
            HTTP::cookie decrypt $ckname $ckpass 128
            if { [HTTP::cookie value $ckname] eq $c_ip } {
                # Cookie looks good everything's okay
                                # HSL::send $hsl "Client $c_ip Cookie Looks Good [HTTP::cookie $ckname]"
            }
            else {
                # Cookie is wrong
                HSL::send $hsl "client $c_ip Invalid Cookie [HTTP::cookie value $ckname]"
                drop
            }
        }
        else {
            # HSL::send $hsl "Client $c_ip no cookie, redirecting to login page [HTTP::cookie $ckname]"
            HTTP::redirect $loginpage
        }
    }
}

when HTTP_RESPONSE {
    # ---
    # My application sends user to this "you're logged in!" page on
    # successful authentication. It also sets a special header that
    # we can look for:
    #    X-DMX-Auth: Success
    # If we find this, then assume they logged in okay and give the
    # user their auth-cookie.
    # ---
    if { $authstate eq 1 } {
        if { [HTTP::header $successheader] == "Success" } {
            HTTP::cookie insert name $ckname value $c_ip
            HTTP::cookie encrypt $ckname $ckpass 128
            # HSL::send $hsl "Client $c_ip - inserted encrypted cookie"
        }
        else {
            HTTP::cookie remove $ckname
            # HSL::send $hsl "Client $c_ip - bad login, deleting cookie"
        }
        set authstate 0
    }
}

The BIG-IP API Reference documentation contains community-contributed content. F5 does not monitor or control community code contributions. We make no guarantees or warranties regarding the available code, and it may contain errors, defects, bugs, inaccuracies, or security vulnerabilities. Your access to and use of any code available in the BIG-IP API reference guides is solely at your own risk.