initial commit of file from CVS for smeserver-webfilter on Sat Sep 7 16:44:31 AEST 2024

This commit is contained in:
Trevor Batley
2024-09-07 16:44:31 +10:00
parent d8b207fd9e
commit 4e92e4ef80
87 changed files with 9052 additions and 2 deletions

223
root/usr/bin/squid-db-logd Normal file
View File

@@ -0,0 +1,223 @@
#!/usr/bin/perl -w
use File::Tail;
use DBI;
use URI;
use Getopt::Long;
use threads;
use threads::shared;
use strict;
our %opts = ();
# Set default options
$opts{squidlog} = '/var/log/squid/access.log';
$opts{squidguardlog} = '/var/log/squidGuard/deny.log';
$opts{squid} = 1;
$opts{squidguard} = 0;
$opts{debug} = 0;
$opts{dbhost} = 'localhost';
$opts{dbname} = 'squid_log';
$opts{dbuser} = 'squid';
$opts{dbpass} = 'squid';
# get command line arguments
GetOptions(
"debug=i" => \$opts{debug},
"squidlog=s" => \$opts{squidlog},
"squidguardlog=s" => \$opts{squidguardlog},
"squid!" => \$opts{squid},
"squidguard!" => \$opts{squidguard},
"dbhost=s" => \$opts{dbhost},
"dbname=s" => \$opts{dbname},
"dbuser=s" => \$opts{dbuser},
"dbpass=s" => \$opts{dbpass}
);
# Disable output buffering
select(STDOUT);
$| = 1;
select(STDERR);
$| = 1;
open STDERR, '>&STDOUT';
# Set process name
$0 = 'squid-db-logd';
# Get hostname
our $host = `hostname`;
chomp($host);
### Subroutines
# Print messages on stderr
# for debuging purpose
sub printlog {
my $msg = shift;
print "$msg\n";
return;
}
# Connect to the database
sub db_connect {
my $dbh = DBI->connect("DBI:mysql:database=$opts{dbname};host=$opts{dbhost}",
$opts{dbuser}, $opts{dbpass}, {RaiseError => 1});
die "Couldn't connect to database\n" unless ($dbh);
return $dbh;
}
# escape chars for MySQL queries
sub mysql_escape {
my $string = shift;
$string =~ s|'|\\'|g;
return $string;
}
# log squid access
# prepare squid insert query
sub squid_prepare {
my $dbh = shift;
my $q = "INSERT INTO access_log (proxy_host, timestamp, response_time, ".
"client_ip, squid_status, http_status, reply_size, request_method, ".
"url, domain, username, squid_connect, server_ip, mime_type) ".
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
my $qh = $dbh->prepare($q);
return $qh;
}
# prepare squidGuard insert query
sub squidguard_prepare {
my $dbh = shift;
my $q = "INSERT INTO deny_log (proxy_host, date_day, date_time, ".
"category, client_ip, url, domain, username) ".
"VALUES(?,?,?,?,?,?,?,?)";
my $qh = $dbh->prepare($q);
return $qh;
}
sub squid_log {
my $logfile = shift;
printlog("squid_log thread connecting to database") if ($opts{debug} ge 1);
my $dbh = db_connect;
my $qh = squid_prepare($dbh);
# Open log file
printlog("opening squid log file") if ($opts{debug} ge 1);
my $tail = File::Tail->new(name=>$logfile, maxinterval=>15);
while (defined(my $line=$tail->read)){
my ($timestamp, $response_time, $client_ip, $status, $reply_size,
$request_method, $url, $username, $server, $mime_type) = split /\s+/, $line;
my ($squid_status, $http_status) = split /\//, $status;
my ($squid_connect, $server_ip) = split /\//, $server;
# Skip stats requested by squidclient
next if ($url =~ m/^cache_object:/);
my $domain;
if ($request_method eq 'CONNECT'){
($domain,undef) = split /:/, $url;
}
elsif ($url =~ m/^error:/){
(undef,$domain) = split /:/, $url;
}
else{
my $uri = URI->new($url);
$domain = $uri->host;
}
# MySQL escape
# Shouldn't be needed, but just in case logs contains junk
$timestamp = mysql_escape($timestamp);
$response_time = mysql_escape($response_time);
$client_ip = mysql_escape($client_ip);
$squid_status = mysql_escape($squid_status);
$http_status = mysql_escape($http_status);
$reply_size = mysql_escape($reply_size);
$request_method = mysql_escape($request_method);
$url = mysql_escape($url);
$domain = mysql_escape($domain);
$username = mysql_escape($username);
$squid_connect = mysql_escape($squid_connect);
$server_ip = mysql_escape($server_ip);
$mime_type = mysql_escape($mime_type);
printlog("New access_log entry:\ntimestamp: $timestamp\nresponse_time: $response_time\n".
"client_ip: $client_ip\nsquid_status: $squid_status\nhttp_status: $http_status\n".
"reply_size: $reply_size\nrequest_method: $request_method\nurl: $url\n".
"username: $username\nsquid_connect: $squid_connect\n".
"server_ip: $server_ip\nmime_type: $mime_type\n\n") if ($opts{debug} ge 2);
$qh->execute($host, $timestamp,$response_time,$client_ip,$squid_status,
$http_status,$reply_size,$request_method,$url,$domain,
$username,$squid_connect,$server_ip,$mime_type) || die "Database error: ".$qh->errstr;
}
}
# log squid access
sub squidguard_log {
my $logfile = shift;
printlog("squidguard_log thread connecting to database") if ($opts{debug} ge 1);
my $dbh = db_connect;
my $qh = squidguard_prepare($dbh);
# Open log file
printlog("opening squidGuard log file") if ($opts{debug} ge 1);
my $tail = File::Tail->new(name=>$logfile, maxinterval=>15);
while (defined(my $line=$tail->read)){
my ($date_day, $date_time, undef, $category, $url, $client_ip, $username) = split /\s+/, $line;
# Clean some values
$category =~ m/default\/(\w+)/;
$category = $1;
$client_ip =~ s/\/\-$//;
my $domain;
# Use the URI parser if possible
if ($url =~ m/^https?:\/\//){
my $uri = URI->new($url);
$domain = $uri->host;
}
# Else, it's a CONNECT method like www.domain.tld:443
else {
($domain,undef) = split /:/, $url;
}
$domain = mysql_escape($domain);
# MySQL escape
$date_day = mysql_escape($date_day);
$date_time = mysql_escape($date_time);
$category = mysql_escape($category);
$url = mysql_escape($url);
$client_ip = mysql_escape($client_ip);
$username = mysql_escape($username);
printlog("New deny_log entry:\ndate: $date_day\ntime: $date_time\ncategory: $category\n".
"client_ip: $client_ip\nurl: $url\nusername: $username\n\n") if ($opts{debug} ge 2);
$qh->execute($host,$date_day,$date_time,$category,$client_ip,$url,$domain,$username) ||
die "Database error: ".$qh->errstr;
}
}
printlog("Starting log monitoring threads") if ($opts{debug} ge 1);
my $thr1 = threads->create('squid_log', $opts{squidlog}) if ($opts{squid});
my $thr = 1;
if ($opts{squidguard}){
my $thr2 = threads->create('squidguard_log', $opts{squidguardlog}) if ($opts{squidguard});
$thr++;
}
while (scalar(threads->list(threads::running)) ge $thr){
sleep(5);
}
die "At least one thread died\n";