Micro-howto : how to get rid of IP addresses in Apache's logs

Apache, amongst other server pieces of software, logs IP addresses by default, into its access.log and error.log. We don't want this to happen.

access.log

This one can easily be customized so that no IP is logged :

LogFormat "0.0.0.0 - - %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %T %V" noip
CustomLog /var/log/apache/what_you_want.log noip

error.log

This other one can be neither turned off nor customized. You can only choose its LogLevel, and thus reduce its verbosity like this :

LogLevel emerg

References :

But it will still potentially log IP addresses ; so a missing image embedded in a page... 404... IP address logged. Several workarounds are available, still. Let's see what they are.

Redirect to /dev/null

Just put the following line into your Apache configuration file, and you'll never hear of error.log again.

ErrorLog /dev/null

The problem is : we sometimes need these logs for sysadmin reasons, indeed.

Regularly remove the IP addresses contained in ErrorLog

A cron job can run, on a regular basis, a script whose only purpose is to remove the IP addresses contained in ErrorLog.

This code sample is supposed to work, not tested it though :

sed s/'\['client.*'\]'/'\['noip'\]'/ $1 > $2

The problem is : if the aliens are quick enough, they can seize your server after the problematic material is posted but before your script is executed. And the "bad" IP is in, and he/she goes to jail. This is probably almost impossible because of administrative slowness, but who knows...

Have Apache store its ErrorLog in RAM

The Linux kernel allows us to create temporary file-systems stored in RAM ; these file-systems won't survive a power off.

Try it like this :
mount -t tmpfs \
      -o auto,size=50M,nr_inodes=20k,mode=700,uid=www-data,gid=root \
      tmpfs /ram
after you've mkdir'ed /ram of course.

Then redirect Apache error.log to this ramdisk :

ErrorLog /ram/error.log

And you're done. Don't forget to write the appropriate line to /etc/fstab, uh.

The problem : the IPs are stored in RAM and never written to the hard disk (please don't speak about swap space, I'm sure it's already encrypted on your box), sure. But they are stored. Although we can consider that the aliens generally turn the power off when they seize a server, there are two cases in which this does matter :
  • If the aliens break into the box and get root, you lose.
  • If the aliens send you in jail and hit you until you reveal the root password, you lose.

Pipe the ErrorLog output

To a cleaner program

The Apache documentation says it's possible to pipe the ErrorLog output to a program that is supposed to handle the error log. One possible implementation is this perl code:

#!/usr/bin/perl -w                                                                 

use strict;

# check we're called with exactly one argument, our output file name               
if ( @ARGV != 1 ) {die "I need exactly one argument <output file>";}

my $in="/dev/stdin";  # we're a filter read from stdin                             
my $out=$ARGV[0];

open (IN,"< $in") or die "Failed to open $in for reading: $! \n";
open (OUT,">> $out") or die "Failed to open $out for writing: $! \n";

# turn on buffer autoflush so tail -f error.log works                              
# (rather than waiting till file handle is closed                                  
my $outf = select(OUT);
$|=1;
select($outf);


# Strip IP's and replace with 0.0.0.0                                              
while (<IN>) {
    s/\[client.*\]/\[client 0.0.0.0\]/;
    print OUT;
}
    close (OUT);

I have tested it with Apache/2.0.52 and Apache/1.3.33. It has been running well on a 1hit/sec site, though I expect it would scale well as there's no real heavy lifting involved.

The configuration line would be something like this :

ErrorLog "| /usr/local/bin/error-log-cleanah.pl /var/log/apache/error.log"

If you prefer, you can use a bash script like this one:

#!/bin/bash
#
# Strip IPs from Apache's error log.
#

# If there is only one parameter, then it is the name of the error log.
if [[ -z "$2" ]]; then
  staticlog=$1
else
# For compatibility with rotatelog, accept the next few parameters as
# rotatelog command options.
# See http://httpd.apache.org/docs/2.0/programs/rotatelogs.html for a
# verbose description of these parameters.
  rotatelog=$1
  logfile=$2

# If there are only three parameters, then the last one is the log file size.
  if [[ -z "$4" ]]; then
    filesize=$3
  else
#   If there are two more parameters, they are the rotation time and offset
#   from GMT.
    rotationtime=$3
    offset=$4
  fi
fi

# If the rotatelog parameter is NOT defined, then just output to a log file.
if [[ -z "$rotatelog" ]]; then
  while read VALUE; do
    echo "$VALUE" | /bin/sed -e "s|\[client [0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\] ||" >> $staticlog
  done

# If the offset parameter is NOT defined, then use rotatelogs with file size.
elif [[ -z "$offset" ]]; then
  while read VALUE; do
    echo "$VALUE" | /bin/sed -e "s|\[client [0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\] ||" | $rotatelog $logfile $filesize
  done

# Last case, use rotatelogs with rotation time and offset.
else
  while read VALUE; do
    echo "$VALUE" | /bin/sed -e "s|\[client [0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\] ||" | $rotatelog $logfile $rotationtime $offset
  done
fi

And put it in the ErrorLog directive in one of three ways:

ErrorLog "| /usr/local/bin/stripip /var/log/apache/error.log"
ErrorLog "| /usr/local/bin/stripip /usr/local/bin/rotatelogs /var/log/apache/errors.%EY.%b.%d.log 5M"
ErrorLog "| /usr/local/bin/stripip /usr/local/bin/rotatelogs /var/log/apache/errors.%EY.%b.%d.log 2419200 -6"

The advantage of this bash script is that it runs with no problems inside a vserver where you dont have a /dev/stdin to open. Additionally, this bash script provides compatibility with rotatelogs, an Apache utility to automatically rotate the log to a new file after a certain time or file size is reached.

To an anonymizing syslog daemon

As explained on http://deb.riseup.net/logging/apache/, it is possible to send the ErrorLog to logger, if you're using an anonymizing syslog daemon such as syslog-ng-anon.

ErrorLog syslog:local7

Note: In the long run this seems to be the most comfortable alternative of all. You can update your Apache with the regular tools of your OS w/o need of repatching on every security update (syslog-ng is not that critical if there is a security problem and afaik hasn't that much the last years). And it is way more flexible than patching apache since the ErrorLog directive may exist in a vhost.

Patch Apache

See http://dev.riseup.net/patches/apache/ to learn how.

Tell Apache to throw away the IP information

This can be done with an Apache module, so that apache throws away the REMOTE_HOST and REMOTE_ADDR right at the beginning of dealing with the request. AndrewMcNaughton has written such a module, and it appears to work, although it hasn't been thoroughly tested. You can get it from http://conway.cat.org.au/~andrew/mod_removeip-0.1.tar.gz. Note that this is either on or off for the whole apache server. You can't turn it on for just one virtual host, directory, or whatever.

don't even let apache talk to the remote IP, so it can't know where the users are

You can do this by having a proxy handle the incoming http requests, log nothing, and pass the requests on to apache to process. Eg you could use squid in it's http_accelerator mode. By default squid adds a headers to tell apache where the request came from, but you can override that with the directive 'forwarded_for off' in the squid.conf file.

 


<p 

  • IntRigeri - 09 Dec 2004 -- initial release
  • LeXi - 10 Dec 2004 -- better use 0.0.0.0 instead of noip because else it could break some logfile analyzers
  • JonBoston - 24 Feb 2005 -- Perl for error.log cleaning is my fault
  • IntRigeri - 18 Apr 2005 -- send to anonymizing syslog daemon
  • RupI - 20 Apr 2005 -- note added
  • SilvioRhatto - 24 Jun 2005 -- added a bash solution for error_log
  • AndrewMcNaughton - 04 Aug 2005 -- added an apache module solution and a squid proxy solution
  • DavidZwarg - 27 Jan 2006 -- added rotatelogs to bash solution, and ErrorLog entry examples.
Topic revision: r16 - 14 May 2008, DannyP
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback