#!/usr/bin/perl -w use strict; ######################################################################### # Script for monitoring IPSec VPN based on racoon IKE daemon # # Author: Pavel Mracek mrak(at)mrak(dot)cz # # Version: 0.1 # ######################################################################### # For easy identification of peers must be added before every # remote in racoon.conf description in the following format: # # #description my_remote_office1 # remote 85.207.181.237 { # #exchange_mode main,aggressive,base; # exchange_mode main; # ..... # # If it be possible to restart the demon nonprivileged user, # it is necessary to add the following into /etc/sudoers # # Cmnd_Alias VPNADMIN = /sbin/service, /sbin/ip, /sbin/setkey # vpnadmin ALL=(ALL) NOPASSWD: VPNADMIN # # And of course to define users in the group vpnadmin # groupadd vpnadmin # usermod -G user1,vpnadmin user1 # my $r_cfg='/etc/racoon/racoon.conf'; my $s_cfg='/etc/racoon/setkey.conf'; my $setkey='sudo /sbin/setkey'; my $ip='sudo /sbin/ip'; my $restart_cmd='sudo /sbin/service racoon restart'; # my $racoonctl='sudo /usr/sbin/racoonctl'; ######################################################################### # This file may be distributed under the terms of the GNU General # # Public License. # ######################################################################### my ($remotes,$idcur,$action); my ($loop)=1; $SIG{INT} = sub {$loop = 0; }; sub get_conf($$){ my ($r_cfg, $s_cfg)=@_; my ($desc)=0; my ($id)=1; my (%remotes); open(CFG,"$r_cfg") || die "ERR can't open: $r_cfg $!"; while(){ if(/^#description\s+([\w\d]+)/){ $desc=$1; } if(/^remote\s+(\d+\.\d+\.\d+\.\d+)/){ $remotes{$id}{'desc'}=$desc; $remotes{$id}{'ip'}=$1; $desc=0; $id++; } } close(CFG); return(\%remotes); } sub print_menu($){ my ($remotes)=@_; my ($l,$num); do{ foreach $l (sort keys %$remotes){ print "$l ) $remotes->{$l}{'desc'} \t\t$remotes->{$l}{'ip'}\n"; } print "R ) Restart racoon daemon\n"; print "Q ) Quit\n"; $num=; }while($num !~ /^([\d+|Q|q|r|R])/); return $1; } sub monitor_remote($){ my ($ip)=@_; my ($parse, $out_head, $out_cur, $out, $spi, $reqid, $req_result, $return); open(SA,"$setkey -D|") || die "ERR: can't execute $setkey -D $!\n"; $out=''; $out_cur=''; while(){ if(/^(\d+\.\d+\.\d+\.\d+)\s+(\d+\.\d+\.\d+\.\d+)\s+$/){ #print ("detekted: $1 a $2"); if($1 eq $ip){ $parse=1; $out.=$out_cur; $out_cur=''; $out_head="\n$1 --> $2"; }elsif($2 eq $ip){ $parse=1; $out.=$out_cur; $out_cur=''; $out_head="\n$2 <-- $1"; }else{ $out.=$out_cur; $out_cur=''; $parse=0; } } if($parse && /^\s*esp.+spi=(\d+).+reqid=(\d+)/){ $spi=$1; $reqid=$2; $req_result=resolve_req($2); $out_cur="$out_head \t $req_result\n$out_cur"; } if($parse && /(diff)(:.*)\(s\)/){$out_cur.=" spi: $spi\t\ttime $1 $2\n"; } if($parse && /(current)(:.*)\(bytes\)/){ $out_cur.=" reqid: $reqid\t\t$1 data $2\n"; } } close(SA); $out.=$out_cur; $out_cur=''; print "\n\n$out Press Ctrl+C for exit\n"; } sub resolve_req($){ my ($req)=@_; my ($out)=''; open(IP,"$ip xfrm policy|") || die "ERR: can't execute $ip xfrm policy $!\n"; while(){ if(/src\s+(\d+\.\d+\.\d+\.\d+\/\d+)\s+dst\s+(\d+\.\d+\.\d+\.\d+\/\d+)/){ $out="src $1 dst $2"; } if(/reqid (\d+) mode/ && $req eq $1){ last; } } close(IP); return $out; } ################# MAIN ################## $remotes = get_conf($r_cfg,$s_cfg); do{ $idcur = print_menu($remotes); if($idcur =~ /[rR]/){ print "Restartuji racoon ...\n"; system("$restart_cmd"); }elsif( exists($remotes->{$idcur}) ){ # print statistic while($loop){ monitor_remote($remotes->{$idcur}{'ip'}); sleep 2; } $loop=1; } }while($idcur !~ /[qQ]/);