/
log-openvpn-users.pl
136 lines (128 loc) · 3.92 KB
/
log-openvpn-users.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/perl -w
#
# log-openvpn-users.pl v1
# Logs OpenVPN users and activity
# Reads the openvpn-status.log and reports changes to to a log
# openvpn-status.log is normally updated every minut andhence you should have a cron job to execute the script every minute too
#
# Cron job:
# * * * * * /usr/bin/perl /script/location/log-openvpn-users.pl
#
# Changes:
# v1: First version
# v2: Error handling improvements
use strict;
use warnings;
my $input_file = '/etc/openvpn/openvpn-status.log';
my $output_file = '/var/log/openvpn/openvpn-clients.log';
my $temp_file = '/etc/openvpn/openvpn-tmp.log';
my $sep = ",";
my $clientlist = 0;
my $routingtable = 0;
my @tokens = "";
my %arraytemp = ();
my %arraybuff = ();
my $debug = 0;
if(open TEMP, , "<", $temp_file)
{ # Read temp file
my $dummy = <TEMP>; #Skip header in file
my @linestemp = <TEMP>;
close TEMP;
foreach my $line (@linestemp) {
chop($line);
@tokens = split(/,/, $line);
#ID,IP,CN,BS,BR,CS,LR
$arraytemp{$tokens[0]}{'IP'}=$tokens[1];
$arraytemp{$tokens[0]}{'CN'}=$tokens[2];
$arraytemp{$tokens[0]}{'BS'}=$tokens[3];
$arraytemp{$tokens[0]}{'BR'}=$tokens[4];
$arraytemp{$tokens[0]}{'CS'}=$tokens[5];
$arraytemp{$tokens[0]}{'LR'}=$tokens[6];
}
}
open( INPUTF, "<", $input_file ) || die "Can't open $input_file: $!";
my @lines = <INPUTF>;
close INPUTF;
foreach my $line (@lines)
{
chop($line);
if($line =~ m/^GLOBAL STATS/)
{
last;
}
if($clientlist eq 1)
{
if($line =~ m/^ROUTING TABLE/)
{
next;
}
if($line =~ m/^Virtual Address,Common Name,Real Address,Last Ref/)
{
$clientlist = 0;
$routingtable = 1;
next;
}
@tokens = split(/,/, $line);
$arraybuff{$tokens[1]}{'CN'}=$tokens[0];
$arraybuff{$tokens[1]}{'BR'}=$tokens[2];
$arraybuff{$tokens[1]}{'BS'}=$tokens[3];
$arraybuff{$tokens[1]}{'CS'}=$tokens[4];
}
if($line =~ m/^Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since/)
{
$clientlist = 1;
next;
}
if($routingtable eq 1)
{
@tokens = split(/,/, $line);
$arraybuff{$tokens[2]}{'IP'}=$tokens[0];
$arraybuff{$tokens[2]}{'LR'}=$tokens[3];
}
}
open( TEMP, ">", $temp_file ) || die "Can't open $temp_file: $!";
print TEMP 'ID'.$sep.'IP'.$sep.'CN'.$sep.'BS'.$sep.'BR'.$sep.'CS'.$sep.'LR'."\n";
foreach my $id ( keys %arraybuff)
{
if($debug eq 1)
{
if((!defined($arraybuff{$id}{'IP'}))||(!defined($arraybuff{$id}{'CN'}))||(!defined($arraybuff{$id}{'BS'}))||(!defined($arraybuff{$id}{'BR'}))||(!defined($arraybuff{$id}{'CS'}))||(!defined($arraybuff{$id}{'LR'})))
{
print "== VAR: ===============================\n";
print "id is [$id]\n";
print "IP is [$arraybuff{$id}{'IP'}]\n";
print "CN is [$arraybuff{$id}{'CN'}]\n";
print "BS is [$arraybuff{$id}{'BS'}]\n";
print "BR is [$arraybuff{$id}{'BR'}]\n";
print "CS is [$arraybuff{$id}{'CS'}]\n";
print "LR is [$arraybuff{$id}{'LR'}]\n";
print "== FILE: ===============================\n";
foreach my $line (@lines)
{
print $line."\n";
}
print "== ARRAY: ===============================\n";
use Data::Dumper;
print Dumper(\%arraybuff);
}
}
if(defined($arraybuff{$id}{'IP'}))
{
print TEMP $id.$sep.$arraybuff{$id}{'IP'}.$sep.$arraybuff{$id}{'CN'}.$sep.$arraybuff{$id}{'BS'}.$sep.$arraybuff{$id}{'BR'}.$sep.$arraybuff{$id}{'CS'}.$sep.$arraybuff{$id}{'LR'}."\n";
}
}
close TEMP;
(my $sec,my $min,my $hour,my $mday,my $mon,my $year,my $wday,my $yday,my $isdst) = localtime();
$year += 1900;
$mon++;
my $now_string = sprintf ("%02d-%02d-%04d %02d:%02d:%02d", $mday, $mon, $year, $hour, $min, $sec);
open( OUTPUT, ">>", $output_file ) || die "Can't open $output_file: $!";
foreach my $id ( keys %arraytemp)
{
if (!defined($arraybuff{$id}{'IP'}))
{
# Connection not longer anymore, report it
print OUTPUT $now_string.$sep.$id.$sep.$arraytemp{$id}{'IP'}.$sep.$arraytemp{$id}{'CN'}.$sep.$arraytemp{$id}{'BS'}.$sep.$arraytemp{$id}{'BR'}.$sep.$arraytemp{$id}{'CS'}.$sep.$arraytemp{$id}{'LR'}."\n";
}
}
close OUTPUT;