I will now propose a hybrid solution, which unites the simplicity of SQL logging with the power of Perl and encryption. The idea is to write a custom logging program, as I mentioned in the previous section. However, rather than implementing a transport protocol from scratch, the logging program will use Perl’s powerful DBD/DBI libraries (Database Driver/Database Interface) in order to access any SQL server and store logging information on a SQL database in the network. I will also use one of Perl’s libraries to encrypt the logging information before sending it to the database server. In this case, symmetric encryption is acceptable, because I will have access to both the encryption and the decryption script (hence, the key won’t have to travel anywhere). I will use the following components to implement this solution:
You will first need to install MySQL on your system (you can actually follow these instructions with any other database server by marginally changing the Perl code). Then, you can create the database with a mysqladmin command: [root@merc root]# mysqladmin create apacheThis command creates a database called apache. You now need to create a table to store the logging information: [root@merc root]# mysql apache Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> CREATE TABLE access_log (-> sequence int(10) NOT NULL auto_increment, -> log_line blob, -> PRIMARY KEY (sequence) -> ) TYPE=MyISAM; Query OK, 0 rows affected (0.00 sec) mysql> As you can see, the table is extremely simple: it only contains sequence, a column with a sequence number (automatically generated by MySQL), and log_line, the column that will contain the actual log line. Your database server is now ready to go. I suggest you leave this MySQL session open so that you can see if information actually does get added to your table while testing the script. Note that you should set login and password in order to access your MySQL server. The Perl ComponentsYou now need to install all the Perl components that will be needed by the script in order to work. They are Crypt-CBC-2.08, Crypt-Blowfish-2.09, and DBD-mysql-2.9002. They can all be found on CPAN (http://www.cpan.org, Comprehensive Perl Archive Network: a site that contains every single third-party Perl module), and they can all be installed with the usual perl Makefile.PL. Here is the installation log for Crypt-CBC: [root@merc root]# tar xvzf Crypt-CBC-2.08.tar.gz The same installation instructions apply to Crypt-Blowfish and DBD-mysql-2.9002.
You now need to configure Apache so that it pipes the logging information to a program. Here is what your httpd.conf should look like: CustomLog "|/usr/local/bin/custom_logging_program" common This is what custom_logging_program should contain: #!/usr/bin/perl # Libraries... # # Variables... # Create the cipher object # Connect to the database # Each log line is fetched and stored into $_... # ...and stored onto the database $dbh->disconnect(); # Disconnect from the database exit(0); # End of the program The code is well commented. The program first creates a Crypt::CBC object using the Crypt::CBC->new() command (refer to Crypt::CBC’s official documentation for more cipher options, perldoc Crypt::CBC). The program reads its standard input (while(<STDIN>)), encrypts the log line ($str-$cipher->encrypt($));) and stores the encrypted information in the database ($dbh->do("INSERT INTO access_log VALUES (0,".$dbh->quote("$str").")");). In order to test it, you should do the following:
The information stored in the database is not readable, which means it cannot be modified in any meaningful way. To read your logs, you will need to decrypt them using the same algorithm. Here is the program that will fetch and decrypt the log entries: #!/usr/bin/perl # Libraries... # Variables... # Create the cipher object # Connect to the database # Prepare the SQL query # Main cycle to read the information exit(0); # End of the program This program is very similar to the previous one. The difference is that the information is fetched from the database (while (my $ref = $sth->fetchrow_hashref()) {), and that it is decrypted ($str= $cipher->decrypt($ref->{'log_line'});). Once your log information has been fetched by this script, you can feed it to “classic” web analyzing tools and store it in a secure location.
blog comments powered by Disqus |
|
|
|
|
|
|
|