Redirect based on php-set cookies

tqvn2004 nginx-forum at nginx.us
Wed Sep 22 00:05:22 MSD 2010


Thank to nginx, our server was able to mitigate the Slowloris DoS
attack, which killed Apache with partial or malformed HTTP headers. The
above mentioned secret_cookie module helped to filter out all other
valid botnet requests with this config:

[code]## If secret_cookie not set, redirect to verification page
if ($secret_cookie_not_set) {
   #store the old uri
   set $uri_old $uri$is_args$args;
   rewrite ^(.*)$ /verification/index.php;
}

## Verification page: a php code that check for user response (for
example recaptcha),
## and setting the secret_cookie if response is valid
location ~* /verification/.*\.php$ {
    # Do not allow direct access
    internal;
    # If IP in the white list,
    # return without the checking process
    if ($whitelist ~ ^bot) {
         rewrite ^ $uri_old last;
    }
    # Turn off the proxy's cache
    proxy_cache off;

    # Turn off access log, but turn on error log
    access_log off;
    error_log /usr/local/nginx-proxy3/logs/verification.log error;

    # Set the rate limite for verification page
    limit_req zone=vzone burst=15 nodelay;
    # Also set the connection limit for verification page
    limit_conn gulag 5;
    include /usr/local/nginx-proxy3/conf/fastcgi.conf;
    fastcgi_pass  127.0.0.1:9002;
    fastcgi_index index.php;
    fastcgi_param  SCRIPT_FILENAME 
/home/tqvn2004/public_html$fastcgi_script_name;
    fastcgi_param URI_OLD $uri_old;
}[/code]

And here is an example index.php code for user verification:

[code]<?php
$x = rand(1,15); 
$y = rand(1,15);

## Secret cookie setting, must match one define in nginx.conf
$secret_cookie_salt = "aDt%&sa";
$secret_cookie_valid_period = 86400;
$secret_cookie_name = "secret_cookie";
$errormsg = "";
$result_cookie_name = "verify_human";
$uri_cookie_name = "reference_uri";
$verification_uri = '/verification/index.php';
$test_uri = '/verification/';
$domain = ".example.org";
setcookie($result_cookie_name, 
          sha1($secret_cookie_salt . strval($x+$y) .
$secret_cookie_salt), 
          time() + 600, 
          '/verification', // Only available in 'verification' folder
          $domain, FALSE, TRUE);
if (isset($_SERVER['URI_OLD']) && (strpos($_SERVER['URI_OLD'],
$test_uri) !== 0)){
    setcookie($uri_cookie_name, 
              $_SERVER['URI_OLD'], 
              time() + 600, 
              '/verification',  // Only available in 'verification
folder
              $domain, FALSE, TRUE);
}

if (isset($_GET) && isset($_GET['result'])) {
    if  (isset($_COOKIE) && isset($_COOKIE[$result_cookie_name])){
        if (sha1($secret_cookie_salt . $_GET['result'] .
$secret_cookie_salt) 
                         == $_COOKIE[$result_cookie_name]){
            // Set the secret cookie and redirect
            setcookie($secret_cookie_name, 
                      sha1($secret_cookie_salt . 
                          
floor($_SERVER['REQUEST_TIME']/$secret_cookie_valid_period) . 
                           $_SERVER['REMOTE_ADDR'] .
                           $_SERVER['HTTP_USER_AGENT'] .
                           $secret_cookie_salt), 
                      time()+$secret_cookie_valid_period, 
                      '/', 
                      $domain, FALSE, TRUE);
            //$http = (isset($_SERVER['HTTPS']) ? 'https://' :
'http://');
            //$port = ($_SERVER['SERVER_PORT'] == 80 ? '' :
':'.$_SERVER['SERVER_PORT']);
            $http = ($_SERVER['SERVER_PORT'] == 443 ? 'https://' :
'http://');
            $uri  = (!isset($_COOKIE[$uri_cookie_name]) ? '/' :
$_COOKIE[$uri_cookie_name]);
            // Redirect to new location
            header("Location: " . $http . $_SERVER['HTTP_HOST'] .
$uri);
        } else {
            $errormsg = "The result is not correct, try again!!!";     

        }
   } else {
        $errormsg = "Cannot verify your result. Try again!! You should
also check if: (1) your browser does accept cookies, (2) your proxy, if
any, does accept cookies...";
   }
}

echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>




body {
    background-color: #999999;
    font-size:13px;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}
div#outer {
    width: 60%;
    background-color:#FFFFFF;
    margin-top: 50px;
    margin-bottom: 50px;
    margin-left: auto;
    margin-right: auto;
    padding: 0px;
    border: thin solid #000000;
}
div#header {
    padding: 15px;
    margin: 0px;
    text-align: center;
    color: #999999;
}
div#main {
    margin-top: 0px;
    margin-bottom: 20px;
    padding: 10px;
    text-align: center;
    font-size: 15px;
}
div#main_header {
    padding-bottom: 15px;
}
div#main_error {
    padding-top: 15px;
    color: red;
}
#formula{
    font-weight:bold;
    font-size: 20px;
}
div#footer {
    padding: 15px;
    margin: 0px;
    border-top: thin solid #000000;
    text-align: center;
}

Example.org



    
        Example.org
    
    
      Perform the math question:' .
      '
          '. $x .' + '. $y .' = 
      '.$errormsg.'
      ' .
    '
    
        Our server is under heavy DoS attack, this verification page
helps us identify you as human.
    


';
?>
[/code]

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,55378,132704#msg-132704




More information about the nginx mailing list