1

I need to put an php script on my website to log all HTTP requests. The access.log doesn't have enough info for my proposes.

My idea was to use an .htaccess on /www/ with a rewrite rule to every request pass trough a php script that would save in one log. (something like a print_r($_GLOBALS))

Do any of you guys know the better way of doing this?

7
  • 1
    what exactly do you want to log? Commented Jun 12, 2014 at 3:00
  • The user agent, client ip, method, full requested uri, cookies, post and get parameters. I really need all this information for understanding what is happening with my server Commented Jun 12, 2014 at 3:08
  • Apache Module mod_dumpio can do this, the Apache custom log can can do most of it. Commented Jun 12, 2014 at 3:15
  • Dagon, the problem is that i dont want to edit any config of the server, I'm limited to htaccess and php files. Is there a way? Commented Jun 12, 2014 at 3:19
  • yes but it will be a thousand times less efficient than using the tools in the web-server Commented Jun 12, 2014 at 3:24

1 Answer 1

3

I know this is an old question. If you're on shared hosting, as you're suggesting, you may be limited to having to redirect all traffic through a script.

I had to do this once. For a WordPress site that was getting hacked, I needed to determine how it was being attacked. Like you said, I redirected all requests with an .htaccess file to a single PHP script that would render a simple "Site is under Maintenance" page, but that also would record that request – the post data, cookies, upload filenames – pretty much anything I wanted to observe.

Conveniently, though, the site was also under Cloudflare protection; thus by doing so, Cloudflare ended up seeing the 503 Unavailable on the maintenance page, and served cache instead, thus keeping the site up almost completely. Better, the maintenance page was still able to record requests.


My .htaccess file appeared something like the following:

RewriteEngine On
RewriteRule ^index-maintenance\.php$ - [L]
RewriteRule .* /index-maintenance.php [L]

Then, the index-maintenance.php file looked something like:

<?php
    $record = TRUE; // whether or not to record requests

    header('HTTP/1.1 503 Service Unavailable', TRUE, 503);
    header('Retry-After: 18000');

    if($record) {
        // Get remote IP
        // If the site uses cloudflare, the true remote IP is served
        // in the HTTP_CF_CONNECTING_IP server var:
        $ip = isset($_SERVER['HTTP_CF_CONNECTING_IP'])
            ? $_SERVER['HTTP_CF_CONNECTING_IP']
            : $_SERVER['REMOTE_ADDR'];

        ob_start();

        // Request date / IP / URL
        echo date('Y-m-d H:i:s: ')
            . 'Remote IP: ' . $ip
            . ' - ' . $_SERVER['REQUEST_METHOD']
            . ' ' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']
            . "\r\n";

        // User agent
        echo $_SERVER['HTTP_USER_AGENT'] . "\r\n";

        // If you needed all headers:
        # foreach(getallheaders() as $header => $value)
        #   echo "$header: $value\r\n";

        // If you wanted raw request data vs. parsed POST data:
        # $postdata = file_get_contents('php://input');
        # if(strlen($postdata)) echo $postdata."\r\n";

        // Post data / Cookies / Files
        if(count($_POST) || count($_COOKIE)) {
            ob_start();

            echo "POST\n";
            var_dump($_POST);

            echo "COOKIES\n";
            var_dump($_COOKIE);

            echo "FILES\n";
            var_dump($_FILES);

            $postdata = ob_get_clean();
            echo str_replace("\n","\r\n",$postdata);
        }
        echo "\r\n";

        // usage of random character string discourages guessing
        // the url if the directory is web-accessible; but, if at
        // all possible, make it inaccessible:
        file_put_contents('../requests_n5io09d21mkp.log',ob_get_clean(),FILE_APPEND);
    }

    // then, a simple maintenance page:
?>
<!DOCTYPE html>
<html>
    <head>
        <title>Site Under Maintenance</title>
    </head>
    <style type="text/css">
        body {
            margin: 0;
            width: 100vw;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .notice {
            color: #808080;
            font: bold 20px/1.6em sans-serif;
            text-align: center;
        }
    </style>
    <body>
        <p class="notice">
            We're sorry. The site is under maintenance.<br/>Please check back later.
        </p>
    </body>
</html>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.