~vcs-imports/ipfire/ipfire-2.x

« back to all changes in this revision

Viewing changes to src/squid-accounting/acct.pl

  • Committer: Dirk Wagner
  • Date: 2014-08-11 19:05:14 UTC
  • mfrom: (4405.1.185)
  • Revision ID: git-v1:f5480b13dd11f35cb6792c9f3cc867a1c0cff158
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into asterisk-update

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl
 
2
###############################################################################
 
3
#                                                                             #
 
4
# IPFire.org - A linux based firewall                                         #
 
5
# Copyright (C) 2014  IPFire Team  <alexander.marx@ipfire.org>                #
 
6
#                                                                             #
 
7
# This program is free software: you can redistribute it and/or modify        #
 
8
# it under the terms of the GNU General Public License as published by        #
 
9
# the Free Software Foundation, either version 3 of the License, or           #
 
10
# (at your option) any later version.                                         #
 
11
#                                                                             #
 
12
# This program is distributed in the hope that it will be useful,             #
 
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
 
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
 
15
# GNU General Public License for more details.                                #
 
16
#                                                                             #
 
17
# You should have received a copy of the GNU General Public License           #
 
18
# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
 
19
#                                                                             #
 
20
###############################################################################
 
21
 
 
22
 
 
23
###########
 
24
# Modules #
 
25
###########
 
26
 
 
27
use Time::Local;
 
28
use File::ReadBackwards;
 
29
use strict;
 
30
#use warnings;
 
31
 
 
32
require '/var/ipfire/general-functions.pl';
 
33
require "${General::swroot}/accounting/acct-lib.pl";
 
34
require "${General::swroot}/lang.pl";
 
35
 
 
36
#############
 
37
# Variables #
 
38
#############
 
39
 
 
40
my $count = 0;
 
41
my $dbh;
 
42
my $logfile = "/var/log/squid/access.log";
 
43
my $line = '';
 
44
my $checktime = 3600;  #1 hour = 3600 sec
 
45
my $starttime = time;
 
46
my ($time,$elapsed,$ip,$state,$bytes,$method,$url,$user,$peerstate,$type); #split logfileline into variables
 
47
my $name;
 
48
my $name1;
 
49
my $settingsfile = "${General::swroot}/accounting/settings.conf";
 
50
my $proxyenabled = "${General::swroot}/proxy/enable";
 
51
my %counter = ();
 
52
my %counterip = ();
 
53
my %settings = ();
 
54
my %toplist = ();
 
55
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$ydat,$isdst)=localtime();
 
56
my $skipurlcount=0;
 
57
my $skipurlsum=0;
 
58
&General::readhash("$settingsfile", \%settings);
 
59
my $skipurl=$settings{'SKIPURLS'};
 
60
$skipurl="'".$skipurl."'";
 
61
my ($mini,$max)=&ACCT::getminmax;
 
62
my $now = localtime;
 
63
my $proxylog;
 
64
my $proxysrv;
 
65
 
 
66
########
 
67
# Main #
 
68
########
 
69
 
 
70
&checkproxy;
 
71
 
 
72
#If we have a disabled file and the proxy is off, we don't need to check anything, exit!
 
73
if((! -f $proxyenabled || $proxylog eq $Lang::tr{'stopped'}) && -f "${General::swroot}/accounting/disabled"){
 
74
        &ACCT::logger($settings{'LOG'}," Proxy or proxylogging disabled - exiting with no data collection\n");
 
75
        exit 0;
 
76
}
 
77
#If proxy was turned off within last hour, we need to check missing minutes and write a disabled file
 
78
if ((! -f $proxyenabled || $proxylog eq $Lang::tr{'stopped'}) && ! -f "${General::swroot}/accounting/disabled"){
 
79
        $checktime = (time-$max);
 
80
        open (FH,">${General::swroot}/accounting/disabled");
 
81
        close (FH);
 
82
        &ACCT::logger($settings{'LOG'}," Proxy or proxylogging was disabled during last hour - just checking meantime and disabling data collection\n");
 
83
}
 
84
 
 
85
#If proxy is on, we are doing a normal run. maybe we had a disabled file, so delete it here
 
86
if (-f $proxyenabled && $proxylog eq $Lang::tr{'running'}){
 
87
        #check if we are running again after the was shutdown and reenabled
 
88
        if (-f "${General::swroot}/accounting/disabled"){
 
89
                unlink("${General::swroot}/accounting/disabled");
 
90
        }
 
91
        #Find out if the month changed
 
92
        $dbh=&ACCT::connectdb;
 
93
        my $m=sprintf("%d",(localtime((time-3600)))[4]+1);
 
94
        &ACCT::logger($settings{'LOG'},"month before one hour $m, now is ".($mon+1)."\n");
 
95
        if ($m < ($mon+1) || $m == '12' && ($mon+1) == '1'){
 
96
                #Logrotate
 
97
                my $year1=$year+1900;
 
98
                system ("tar", "cfz", "/var/log/accounting-$m-$year1.tar.gz", "/var/log/accounting.log");
 
99
                unlink ("/var/log/accounting.log");
 
100
                open (FH,">/var/log/accounting.log");
 
101
                close (FH);
 
102
                chmod 0755, "/var/log/accounting.log";
 
103
                #move all db entries older than 2 months to second table and cumulate them hourly
 
104
                &ACCT::movedbdata;
 
105
                &ACCT::logger($settings{'LOG'},"New Month. Old trafficvalues moved to ACCT_HIST Table\n");
 
106
                if ($settings{'USEMAIL'} eq 'on'){
 
107
                        &ACCT::logger($settings{'LOG'},"Mailserver is activated - Now sending bills via mail...\n");
 
108
                        my $res=&ACCT::getbillgroups;
 
109
                        foreach my $line (@$res){
 
110
                                my ($grp) = @$line;
 
111
                                &sendbill($grp,$settings{'MWST'},$settings{'CURRENCY'});
 
112
                        }
 
113
                }else{
 
114
                        &ACCT::logger($settings{'LOG'},"Mailserver is deactivated - We are NOT sending bills via mail...\n");
 
115
                }
 
116
        }
 
117
 
 
118
        &ACCT::logger($settings{'LOG'},"Start reading last hour of access.log\n");
 
119
        &readlog;
 
120
        &fill_db;
 
121
        &ACCT::closedb;
 
122
        $skipurlsum=sprintf("%.2f",$skipurlsum/(1024*1024));
 
123
        &ACCT::logger($settings{'LOG'},"skipped: $skipurlcount Adressen\n");
 
124
        &ACCT::logger($settings{'LOG'},"skipped: $skipurlsum MB\n") if ($skipurl);
 
125
}
 
126
#############
 
127
# functions #
 
128
#############
 
129
 
 
130
sub checkproxy{
 
131
        if(-f "${General::swroot}/proxy/enable"){
 
132
                $proxysrv=$Lang::tr{'running'};
 
133
        }else{
 
134
                $proxysrv=$Lang::tr{'stopped'};
 
135
        }
 
136
        my $srce = "${General::swroot}/proxy/squid.conf";
 
137
        my $string1 = 'access\.log';
 
138
        open(FH, $srce);
 
139
        while(my $line = <FH>) {
 
140
                if($line =~ m/$string1/) {
 
141
                        $proxylog=$Lang::tr{'running'};
 
142
                }
 
143
        }
 
144
        close FH;
 
145
        return;
 
146
}
 
147
 
 
148
sub readlog{
 
149
        my $url1;
 
150
        my $user1;
 
151
        $count = 0;
 
152
        my $urlcnt=0;
 
153
        &ACCT::logger($settings{'LOG'},"Start: $now. Reading data back till: ".localtime(($starttime-$checktime)).".\n");
 
154
        #Open Logfile and begin to read the file backwards
 
155
        my $bw = File::ReadBackwards->new( $logfile ) or die "can't read $logfile $!" ;
 
156
        while( defined( $line = $bw->readline ) ) {
 
157
                undef $url1;
 
158
                chomp $line;
 
159
                #Divide $line into single variables to get timestamp and check if we are within hte desired timerange
 
160
                ($time,$elapsed,$ip,$state,$bytes,$method,$url,$user,$peerstate,$type)=split(m/\s+/, $line);
 
161
                $count += $bytes;
 
162
                $time = substr($time, 0, -4);
 
163
                if (($time > ($starttime-$checktime))){
 
164
                        #Skip DENIED stated lines (can be reactivated later)
 
165
                        next if ($state =~ m/DENIED/);
 
166
 
 
167
                        #extract site name
 
168
                        if ($url =~ m/([a-z]+:\/\/)??([a-z0-9\-]+\.){1}(([a-z0-9\-]+\.){0,})([a-z0-9\-]+){1}(:[0-9]+)?\/(.*)/o) {
 
169
                           $url=$2.$3.$5;
 
170
                        } else {
 
171
                           my ($a,$b)=split(":",$url);
 
172
                           $url=$a;
 
173
                        }
 
174
 
 
175
                        #Skip special URLs like intranet and webservers from local network
 
176
                        if ($url =~ m/$skipurl/o) {
 
177
                          $skipurlcount++;
 
178
                          $skipurlsum+=$bytes;
 
179
                          next;
 
180
                        };
 
181
 
 
182
                        #Increase urlcounter
 
183
                        $urlcnt++;
 
184
 
 
185
                        #Get Data for accounting
 
186
                        $counter{$user}{'bytes'} += $bytes if ($user ne '-');
 
187
                        $counter{$ip}{'bytes'} += $bytes;
 
188
                }else{
 
189
                        #If we are out of timewindow, break
 
190
                        last;
 
191
                }
 
192
        }
 
193
        $count=sprintf("%.2f",$count/(1024*1024));
 
194
        &ACCT::logger($settings{'LOG'},"got $count MB from $urlcnt URLs this run.\n");
 
195
        $bw->close;
 
196
}
 
197
sub fill_db{
 
198
        my $tim=time();
 
199
        #Fill ACCT table with accounting information
 
200
        foreach my $name (sort keys %counter){
 
201
                foreach my $bytes (keys %{ $counter{$name} }) {
 
202
                        $dbh->do("insert into ACCT (TIME_RUN,NAME,BYTES) values ('$tim','$name','$counter{$name}{$bytes}');");
 
203
                }
 
204
        }
 
205
}
 
206
sub sendbill {
 
207
        my $rggrp=$_[0];
 
208
        my $mwst=$_[1];
 
209
        my $cur = $_[2];
 
210
        my @now = localtime(time);
 
211
        $now[5] = $now[5] + 1900;
 
212
        my $actmonth = $now[4];
 
213
        my $month                       = '0'.$actmonth if $actmonth < 10;
 
214
        my $actyear  = $now[5];
 
215
        my ($from,$till)=&ACCT::getmonth($actmonth,$actyear);                                   #FIXME month and year as variables!
 
216
        my @billar = &ACCT::GetTaValues($from,$till,$rggrp);
 
217
        my $address_cust = &ACCT::getTaAddress($rggrp,'CUST');
 
218
        my $address_host = &ACCT::getTaAddress($rggrp,'HOST');
 
219
        my $billpos             = &ACCT::getextrabillpos($rggrp);
 
220
        my $no                  = &ACCT::getBillNr;
 
221
        my $back = &ACCT::pdf2(\@billar,$actmonth,$actyear,$mwst,$address_cust,$address_host,$billpos,$rggrp,$cur);
 
222
        my ($company_cust,$type_cust,$name1_cust,$str_cust,$str_nr_cust,$plz_cust,$city_cust,$bank,$iban,$bic,$blz,$kto,$email,$internet,$hrb,$stnr,$tel_host,$fax_host,$ccmail,$billgrp,$text,$host,$cust,$cent);
 
223
 
 
224
        foreach my $addrline_cust (@$address_cust){
 
225
                ($company_cust,$type_cust,$name1_cust,$str_cust,$str_nr_cust,$plz_cust,$city_cust,$bank,$iban,$bic,$blz,$kto,$email,$internet,$hrb,$stnr,$tel_host,$fax_host,$ccmail,$billgrp,$text,$host,$cust,$cent)=@$addrline_cust;
 
226
        }
 
227
 
 
228
        if ($back eq '0'){
 
229
                &ACCT::logger($settings{'LOG'},"Bill for $company_cust successfully created.\n");
 
230
                my $file="'/var/ipfire/accounting/bill/$rggrp/$month-$actyear-$no.pdf'";
 
231
                $settings{'MAILTXT'} =~ tr/\|/\r\n/ ;
 
232
                my $cmd = "/usr/local/bin/sendEmail ";
 
233
                $cmd .= " -f $settings{'MAILSENDER'}";                                                  #Sender
 
234
                $cmd .= " -t $email";                                                                                   #Recipient
 
235
                if ($ccmail){
 
236
                        $cmd .= " -cc $ccmail";
 
237
                }
 
238
                #Send Mail via TLS?
 
239
                if ($settings{'TLS'} eq 'on'){
 
240
                        $cmd .= " -o tls=yes";                                                                          #TLS
 
241
                }
 
242
                $cmd .= " -u '$settings{'MAILSUB'}'";                                                   #Subject
 
243
                $cmd .= " -m '$settings{'MAILTXT'}'";                                                   #Mailtext
 
244
                $cmd .= " -s $settings{'MAILSRV'}:$settings{'MAILPORT'}";               #Mailserver:port
 
245
                $cmd .= " -a $file";
 
246
                my $res=system ($cmd);
 
247
                if ($res == 0){
 
248
                        &ACCT::logger($settings{'LOG'},"Bill for $company_cust successfully sent.\n");
 
249
                }elsif ($res > 0){
 
250
                        &ACCT::logger($settings{'LOG'},"ERROR: Bill for $company_cust NOT sent.\n");
 
251
                }
 
252
                return 0;
 
253
                
 
254
        }else{
 
255
                &ACCT::logger($settings{'LOG'},"ERROR Bill for $company_cust could not be created.\n");
 
256
                my $cmd = "/usr/local/bin/sendEmail ";
 
257
                $cmd .= " -f $settings{'MAILSENDER'}";
 
258
                $cmd .= " -t $settings{'MAILSENDER'}";
 
259
                $cmd .= " -u Fehler Squid Accounting";
 
260
                $cmd .= " -m 'Die Rechnung konnte nicht erzeugt und per Mail versendet werden' $company_cust";
 
261
                $cmd .= " -s $settings{'MAILSRV'}:$settings{'MAILPORT'}";
 
262
                my $res=system ($cmd);
 
263
                return 0;
 
264
        }
 
265
}