diff options
author | Saurabh Mohan <saurabh.mohan@vyatta.com> | 2013-01-22 12:28:06 -0800 |
---|---|---|
committer | Saurabh Mohan <saurabh.mohan@vyatta.com> | 2013-01-22 12:28:06 -0800 |
commit | f0e5bb5e5341fd5128069639433960c39a9489cf (patch) | |
tree | b57cbdbd13368dceecd17eb3a62731abaac100b6 | |
parent | 0ec0f14dc864045fa1cc6ec317e3e8b62585072a (diff) | |
download | vyatta-op-vpn-f0e5bb5e5341fd5128069639433960c39a9489cf.tar.gz vyatta-op-vpn-f0e5bb5e5341fd5128069639433960c39a9489cf.zip |
Dmvpn merge with mirantis jan22-2013
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | lib/vpnprof/OPMode.pm | 823 | ||||
-rw-r--r-- | scripts/vyatta-op-vpnprof.pl | 59 | ||||
-rw-r--r-- | templates/show/vpn/ipsec/sa/node.def | 1 | ||||
-rw-r--r-- | templates/show/vpn/ipsec/sa/profile/node.def | 1 | ||||
-rw-r--r-- | templates/show/vpn/ipsec/sa/profile/node.tag/node.def | 3 | ||||
-rw-r--r-- | templates/show/vpn/ipsec/sa/profile/node.tag/tunnel/node.def | 1 | ||||
-rw-r--r-- | templates/show/vpn/ipsec/sa/profile/node.tag/tunnel/node.tag/node.def | 3 |
8 files changed, 894 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index ae1325d..02d96a4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,13 +2,16 @@ opdir = $(datadir)/vyatta-op/templates bin_sudo_usersdir = $(bindir)/sudo-users share_perl5dir = $(datarootdir)/perl5/Vyatta/VPN +share_perl5_vpnprofdir = $(datarootdir)/perl5/Vyatta/vpnprof share_perl5_DATA = lib/OPMode.pm +share_perl5_vpnprof_DATA = lib/vpnprof/OPMode.pm bin_sudo_users_SCRIPTS = scripts/gen_local_rsa_key.pl bin_sudo_users_SCRIPTS += scripts/vyatta-show-vpn.pl bin_sudo_users_SCRIPTS += scripts/vyatta-vpn-op.pl bin_sudo_users_SCRIPTS += scripts/vyatta-op-vpn.pl +bin_sudo_users_SCRIPTS += scripts/vyatta-op-vpnprof.pl bin_sudo_users_SCRIPTS += scripts/vyatta-show-ipsec-status.pl cpiop = find . ! -regex '\(.*~\|.*\.bak\|.*\.swp\|.*\#.*\#\)' -print0 | \ diff --git a/lib/vpnprof/OPMode.pm b/lib/vpnprof/OPMode.pm new file mode 100644 index 0000000..00c1ffd --- /dev/null +++ b/lib/vpnprof/OPMode.pm @@ -0,0 +1,823 @@ +#!/usr/bin/perl +# +# Module Vyatta::vpnprof::OpMode.pm +# + +package Vyatta::vpnprof::OPMode; + +use lib "/opt/vyatta/share/perl5/"; +use Vyatta::VPN::Util; +use Vyatta::Config; +use strict; + +sub conv_id { + my $peer = pop(@_); + if ( $peer =~ /\d+\.\d+\.\d+\.\d+/ ){ + $peer = $peer; + } elsif ($peer =~ /\d+\:\d+\:\d+\:\d+\:\d+\:\d+\:\d+\:\d+/){ + $peer = $peer; + } elsif ($peer =~ /\%any/){ + $peer = "any"; + } else { + $peer = "\@$peer"; + } + return $peer; +} + +sub conv_dh_group { + my $dhgrp = pop(@_); + my $dh_group = ''; + if ($dhgrp eq "MODP_768"){ + $dh_group = 1; + } elsif ($dhgrp eq "MODP_1024"){ + $dh_group = 2; + } elsif ($dhgrp eq "MODP_1536"){ + $dh_group = 5; + } elsif ($dhgrp eq "MODP_2048"){ + $dh_group = 7; + } elsif ($dhgrp eq "<N/A>"){ + $dh_group = "n/a"; + } else { + $dh_group = $dhgrp; + } + return $dh_group; +} + +sub conv_hash { + my $hash = pop(@_); + if ($hash =~ /.*_(.*)/){ + $hash = lc($1); + } + return $hash; +} + +sub conv_enc { + my $enc = pop(@_); + if ($enc =~ /(.*?)_.*?_(.*)/){ + $enc = lc($1).$2; + $enc =~ s/^ //g; + } elsif ($enc =~ /3DES/) { + $enc = "3des"; + } + return $enc; +} + +sub conv_natt { + my $natt = pop(@_); + if ($natt == 0){ + $natt = "no"; + } else { + $natt = "yes"; + } + return $natt; +} + +sub conv_id_rev +{ + my $peerid = pop(@_); + if ($peerid =~ /@(.*)/){ + $peerid = $1; + } + return $peerid; +} +sub conv_bytes { + my $bytes = pop(@_); + my $suffix = ''; + $bytes =~ s/\s+$//; + if ($bytes > 1024 && $bytes < 1048576){ + $bytes = $bytes/1024; + $suffix = "K"; + } elsif ($bytes >= 1048576 && $bytes < 1073741824){ + $bytes = $bytes/1048576; + $suffix = "M"; + } elsif ($bytes >= 1073741824){ + $bytes = $bytes/1073741824; + $suffix = "G"; + } + $bytes = sprintf("%.1f",$bytes); + $bytes = "$bytes$suffix"; +} +sub conv_ip{ + my $peerip = pop(@_); + if ($peerip =~ /\@.*/){ + $peerip = "0.0.0.0"; + } elsif ($peerip =~ /\%any/){ + $peerip = "0.0.0.0"; + } + return $peerip; +} +sub nat_detect { + (my $lip, my $rip) = @_; + my @values; + if ($lip =~ /(\d+\.\d+\.\d+\.\d+):(\d+)/){ + push (@values, $1); + push (@values, 1); + push (@values, $2); + } else { + push (@values, $lip); + push (@values, 0); + push (@values, 'n/a'); + } + if ($rip =~ /(\d+\.\d+\.\d+\.\d+):(\d+)/){ + push (@values, $1); + push (@values, $2); + } else { + push (@values, $rip); + push (@values, 'n/a'); + } + return @values; +} + +sub get_tunnel_info { + my $cmd = "sudo ipsec statusall"; + open(my $IPSECSTATUS, ,'-|', $cmd); + my @ipsecstatus = []; + while(<$IPSECSTATUS>){ + push (@ipsecstatus, $_); + } + process_tunnels(\@ipsecstatus); +} + +sub get_tunnel_info_profile { + my $profile = pop(@_); + my @tunnels = split(' ', `cli-shell-api listActiveNodes vpn ipsec profile $profile bind tunnel`); + + my $static_conn_str = "vpnprof-tunnel-\\("; + my $first_tun = 1; + for my $tun (@tunnels) { + if ($first_tun) { + } else { + $static_conn_str .= "\\|"; + } + $static_conn_str .= substr $tun, 1, -1; + $first_tun = 0; + } + $static_conn_str .= "\\)"; + + my $dyn_conn_str = "\\("; + my $first_addr = 1; + for my $tun (@tunnels) { + my @addresses = split(' ', `cli-shell-api returnActiveValues interfaces tunnel $tun address`); + for my $addr (@addresses) { + if ($first_addr) { + } else { + $dyn_conn_str .= "\\|"; + } + $dyn_conn_str .= substr $addr, 1, -4; + $first_addr = 0; + } + } + + $dyn_conn_str .= "\\)-to-"; + + my $search_str = "\\($static_conn_str\\)\\|\\($dyn_conn_str\\)"; + my $cmd = "sudo ipsec statusall | grep \"$search_str\""; + open(my $IPSECSTATUS, ,'-|', $cmd); + my @ipsecstatus = []; + while(<$IPSECSTATUS>){ + push (@ipsecstatus, $_); + } + process_tunnels(\@ipsecstatus); +} + +sub process_tunnels{ + my @ipsecstatus = @{pop(@_)}; + my %tunnel_hash = (); + foreach my $line (@ipsecstatus) { + if (($line =~ /\"(vpnprof-tunnel-.*?)\"/) || ($line =~ /\"(.*-to-.*)\"/)) { + my $connectid = $1; + if (($line =~ /\"(vpnprof-tunnel-.*?)\"(\[\d*\])/)){ + $connectid .= $2; + } + my $tunid = ""; + if (($connectid =~ /vpnprof-tunnel-(.*)/)) { + $tunid = $1; + } else { + # this is for whack connection, we are to find tunid for it. + $line =~ /\"(.*)-to-(.*)\"/; + my $lip = $1; + + my @tunnels = split(' ', `cli-shell-api listActiveNodes interfaces tunnel`); + for my $tun (@tunnels) { + my @addresses = split(' ', `cli-shell-api returnActiveValues interfaces tunnel $tun address`); + for my $addr (@addresses) { + my $tst = index $addr, $lip; + if ($tst > -1) { + $tunid = substr $tun, 1, -1; + } + } + } + } + if (not exists $tunnel_hash{$connectid}){ + $tunnel_hash{$connectid} = { + _peerid => undef, + _tunnelnum => $tunid, + _lip => 'n/a', + _rip => 'n/a', + _lid => 'n/a', + _rid => 'n/a', + _lsnet => 'n/a', + _rsnet => 'n/a', + _lproto => 'all', + _rproto => 'all', + _lport => 'all', + _rport => 'all', + _lca => undef, + _rca => undef, + _newestspi => 'n/a', + _newestike => 'n/a', + _encryption => 'n/a', + _hash => 'n/a', + _inspi => 'n/a', + _outspi => 'n/a', + _pfsgrp => 'n/a', + _ikeencrypt => 'n/a', + _ikehash => 'n/a', + _natt => 'n/a', + _natsrc => 'n/a', + _natdst => 'n/a', + _ikestate => "down", + _dhgrp => 'n/a', + _state => "down", + _inbytes => 'n/a', + _outbytes => 'n/a', + _ikelife => 'n/a', + _ikeexpire => 'n/a', + _lifetime => 'n/a', + _expire => 'n/a' }; + } + $line =~ s/---.*\.\.\./.../g; # remove the next hop router for local-ip 0.0.0.0 case + if ($line =~ /IKE.proposal:(.*?)\/(.*?)\/(.*)/){ + $tunnel_hash{$connectid}->{_ikeencrypt} = $1; + $tunnel_hash{$connectid}->{_ikehash} = $2; + $tunnel_hash{$connectid}->{_dhgrp} = $3; + } + # both subnets + elsif ($line =~ /: (.*?)===(.*?)\[(.*?)\]\.\.\.(.*?)\[(.*?)\]===(.*?);/){ + my $lsnet = $1; + my $lip = $2; + my $lid = $3; + my $rip = $4; + my $rid = $5; + my $rsnet = $6; + ($lip, my $natt, my $natsrc, $rip, my $natdst) = nat_detect($lip, $rip); + $tunnel_hash{$connectid}->{_lid} = conv_id($lid); + $tunnel_hash{$connectid}->{_lip} = $lip; + $tunnel_hash{$connectid}->{_lsnet} = $lsnet; + $tunnel_hash{$connectid}->{_rid} = conv_id($rid); + $tunnel_hash{$connectid}->{_rip} = $rip; + $tunnel_hash{$connectid}->{_rsnet} = $rsnet; + $tunnel_hash{$connectid}->{_natt} = $natt; + $tunnel_hash{$connectid}->{_natsrc} = $natsrc; + $tunnel_hash{$connectid}->{_natdst} = $natdst; + } + #left subnet + elsif ($line =~ /: (.*?)\[(.*?)\]\.\.\.(.*?)\[(.*?)\];/){ + my $lip = $1; + my $lid = $2; + my $rip = $3; + my $rid = $4; + my $lsnet; + if ($lip =~ /(.*?)===(.*)/){ + $lsnet = $1; + $lip = $2; + } + ($lip, my $natt, my $natsrc, $rip, my $natdst) = nat_detect($lip, $rip); + $tunnel_hash{$connectid}->{_lid} = conv_id($lid); + $tunnel_hash{$connectid}->{_lip} = $lip; + $tunnel_hash{$connectid}->{_rid} = conv_id($rid); + $tunnel_hash{$connectid}->{_rip} = $rip; + $tunnel_hash{$connectid}->{_natt} = $natt; + $tunnel_hash{$connectid}->{_natsrc} = $natsrc; + $tunnel_hash{$connectid}->{_natdst} = $natdst; + $tunnel_hash{$connectid}->{_lsnet} = $lsnet if (defined($lsnet)); + } + #left subnet with protocols + elsif ($line =~ /: (.*?)\[(.*?)\]:(\d+)\/(\d+)\.\.\.(.*?)\[(.*?)\]:(\d+)\/(\d+);/){ + my $lip = $1; + my $lsnet; + my $lid = $2; + my $lproto = conv_protocol($3); + my $lport = $4; + my $rip = $5; + my $rid = $6; + my $rproto = conv_protocol($7); + my $rport = $8; + if ($lip =~ /(.*?)===(.*)/){ + $lsnet = $1; + $lip = $2; + } + ($lip, my $natt, my $natsrc, $rip, my $natdst) = nat_detect($lip, $rip); + $tunnel_hash{$connectid}->{_lid} = conv_id($lid); + $tunnel_hash{$connectid}->{_lip} = $lip; + $tunnel_hash{$connectid}->{_lsnet} = $lsnet if (defined($lsnet)); + $tunnel_hash{$connectid}->{_rid} = conv_id($rid); + $tunnel_hash{$connectid}->{_rip} = $rip; + $tunnel_hash{$connectid}->{_natt} = $natt; + $tunnel_hash{$connectid}->{_natsrc} = $natsrc; + $tunnel_hash{$connectid}->{_natdst} = $natdst; + $tunnel_hash{$connectid}->{_lproto} = "$lproto"; + $tunnel_hash{$connectid}->{_rproto} = "$rproto"; + $tunnel_hash{$connectid}->{_lport} = "$lport"; + $tunnel_hash{$connectid}->{_rport} = "$rport"; + } + # both proto/port and subnets + elsif ($line =~ /: (.*)===(.*?)\[(.*?)\]:(\d+)\/(\d+)\.\.\.(.*?)\[(.*?)\]:(\d+)\/(\d+)===(.*?);/){ + my $lsnet = $1; + my $lip = $2; + my $lid = $3; + my $lproto = conv_protocol($4); + my $lport = $5; + my $rip = $6; + my $rid = $7; + my $rproto = conv_protocol($8); + my $rport = $9; + my $rsnet = $10; + my $lprotoport; + my $rprotoport; + $lprotoport = $lproto if ($lport == 0); + $lprotoport = "$lproto/$lport" if ($lport != 0); + $rprotoport = $rproto if ($rport == 0); + $rprotoport = "$rproto/$rport" if ($rport != 0); + ($lip, my $natt, my $natsrc, $rip, my $natdst) = nat_detect($lip, $rip); + $tunnel_hash{$connectid}->{_lid} = conv_id($lid); + $tunnel_hash{$connectid}->{_lip} = $lip; + $tunnel_hash{$connectid}->{_lsnet} = $lsnet; + $tunnel_hash{$connectid}->{_rid} = conv_id($rid); + $tunnel_hash{$connectid}->{_rip} = $rip; + $tunnel_hash{$connectid}->{_rsnet} = $rsnet; + $tunnel_hash{$connectid}->{_lproto} = "$lproto"; + $tunnel_hash{$connectid}->{_rproto} = "$rproto"; + $tunnel_hash{$connectid}->{_lport} = "$lport"; + $tunnel_hash{$connectid}->{_rport} = "$rport"; + $tunnel_hash{$connectid}->{_natt} = $natt; + $tunnel_hash{$connectid}->{_natsrc} = $natsrc; + $tunnel_hash{$connectid}->{_natdst} = $natdst; + } + # right proto/port only with subnet + elsif ($line =~ /: (.*)===(.*?)\[(.*?)\]\.\.\.(.*?)\[(.*?)\]:(\d+)\/(\d+)===(.*?);/){ + my $lsnet = $1; + my $lip = $2; + my $lid = $3; + my $rip = $4; + my $rid = $5; + my $rproto = conv_protocol($6); + my $rport = $7; + my $rsnet = $8; + my $lprotoport; + my $rprotoport; + $rprotoport = $rproto if ($rport == 0); + $rprotoport = "$rproto/$rport" if ($rport != 0); + ($lip, my $natt, my $natsrc, $rip, my $natdst) = nat_detect($lip, $rip); + $tunnel_hash{$connectid}->{_lid} = conv_id($lid); + $tunnel_hash{$connectid}->{_lip} = $lip; + $tunnel_hash{$connectid}->{_lsnet} = $lsnet; + $tunnel_hash{$connectid}->{_rid} = conv_id($rid); + $tunnel_hash{$connectid}->{_rip} = $rip; + $tunnel_hash{$connectid}->{_rsnet} = $rsnet; + $tunnel_hash{$connectid}->{_rproto} = "$rproto"; + $tunnel_hash{$connectid}->{_rport} = "$rport"; + $tunnel_hash{$connectid}->{_natt} = $natt; + $tunnel_hash{$connectid}->{_natsrc} = $natsrc; + $tunnel_hash{$connectid}->{_natdst} = $natdst; + } + # left proto/port only with subnet + elsif ($line =~ /: (.*)===(.*?)\[(.*?)\]:(\d+)\/(\d+)\.\.\.(.*?)\[(.*?)\]===(.*?);/){ + my $lsnet = $1; + my $lip = $2; + my $lid = $3; + my $lproto = conv_protocol($4); + my $lport = $5; + my $rip = $6; + my $rid = $7; + my $rsnet = $8; + my $lprotoport; + my $rprotoport; + $lprotoport = $lproto if ($lport == 0); + $lprotoport = "$lproto/$lport" if ($lport != 0); + ($lip, my $natt, my $natsrc, $rip, my $natdst) = nat_detect($lip, $rip); + $tunnel_hash{$connectid}->{_lid} = conv_id($lid); + $tunnel_hash{$connectid}->{_lip} = $lip; + $tunnel_hash{$connectid}->{_lsnet} = $lsnet; + $tunnel_hash{$connectid}->{_rid} = conv_id($rid); + $tunnel_hash{$connectid}->{_rip} = $rip; + $tunnel_hash{$connectid}->{_rsnet} = $rsnet; + $tunnel_hash{$connectid}->{_lproto} = "$lproto"; + $tunnel_hash{$connectid}->{_lport} = "$lport"; + $tunnel_hash{$connectid}->{_natt} = $natt; + $tunnel_hash{$connectid}->{_natsrc} = $natsrc; + $tunnel_hash{$connectid}->{_natdst} = $natdst; + } + elsif ($line =~ /ESP.proposal:(.*?)\/(.*?)\/(.*)/){ + $tunnel_hash{$connectid}->{_encryption} = $1; + $tunnel_hash{$connectid}->{_hash} = $2; + $tunnel_hash{$connectid}->{_pfsgrp} = $3; + } + elsif ($line =~ /STATE_MAIN_I1/){ + $tunnel_hash{$connectid}->{_ikestate} = "init"; + } + elsif ($line =~ /newest ISAKMP SA: (.*); newest IPsec SA: (.*);/){ + if ($tunnel_hash{$connectid}->{_newestike} ne 'n/a'){ + if ($tunnel_hash{$connectid}->{_newestike} lt $1){ + $tunnel_hash{$connectid}->{_newestike} = $1; + } + } else { + $tunnel_hash{$connectid}->{_newestike} = $1; + } + if ($tunnel_hash{$connectid}->{_newestspi} ne 'n/a'){ + if ($tunnel_hash{$connectid}->{newestspi} lt $2){ + $tunnel_hash{$connectid}->{_newestspi} = $2; + } + } else { + $tunnel_hash{$connectid}->{_newestspi} = $2; + } + } + elsif ($line =~ /ike_life: (.*?)s; ipsec_life: (.*?)s;/){ + $tunnel_hash{$connectid}->{_ikelife} = $1; + $tunnel_hash{$connectid}->{_lifetime} = $2; + } + elsif ($line=~ /CAs: (.*?)\.\.\.(.*)/){ + $tunnel_hash{$connectid}->{_lca} = $1; + $tunnel_hash{$connectid}->{_rca} = $2; + } + my $ike = $tunnel_hash{$connectid}->{_newestike}; + if ($ike ne 'n/a'){ + if ($line =~ /$ike:.*ISAKMP.SA.established.*EVENT_SA_REPLACE.in.(.*?)s;/) + { + $tunnel_hash{$connectid}->{_ikeexpire} = $1; + my $atime = $tunnel_hash{$connectid}->{_ikelife} - + $tunnel_hash{$connectid}->{_ikeexpire}; + if ($atime >= 0){ + $tunnel_hash{$connectid}->{_ikestate} = "up"; + } + } + if ($line =~ /$ike:.*ISAKMP.SA.established.*EVENT_SA_EXPIRE.in.(.*?)s;/) + { + $tunnel_hash{$connectid}->{_ikeexpire} = $1; + my $atime = $tunnel_hash{$connectid}->{_ikelife} - + $tunnel_hash{$connectid}->{_ikeexpire}; + if ($atime >= 0){ + $tunnel_hash{$connectid}->{_ikestate} = "up"; + } + } + } + my $spi = $tunnel_hash{$connectid}->{_newestspi}; + if ($spi ne 'n/a'){ + if ($line =~ /$spi:.*esp.(.*)\@.*\((.*)bytes.*esp.(.*)\@.*/){ + $tunnel_hash{$connectid}->{_outspi} = $1; + $tunnel_hash{$connectid}->{_outbytes} = $2; + $tunnel_hash{$connectid}->{_inspi} = $3; + } + if ($line =~ /$spi:.*esp.(.*)\@.*esp.(.*)\@.*\((.*)bytes/){ + $tunnel_hash{$connectid}->{_outspi} = $1; + $tunnel_hash{$connectid}->{_inspi} = $2; + $tunnel_hash{$connectid}->{_inbytes} = $3; + } + if ($line =~ /$spi:.*esp.(.*)\@.*\((.*)bytes.*esp.(.*)\@.*\((.*)bytes/) + { + $tunnel_hash{$connectid}->{_outspi} = $1; + $tunnel_hash{$connectid}->{_outbytes} = $2; + $tunnel_hash{$connectid}->{_inspi} = $3; + $tunnel_hash{$connectid}->{_inbytes} = $4; + } + if ($line =~ /$spi:.*?EVENT_SA_REPLACE.*? in (.*?)s;/){ + $tunnel_hash{$connectid}->{_expire} = $1; + my $atime = $tunnel_hash{$connectid}->{_lifetime} - + $tunnel_hash{$connectid}->{_expire}; + if ($atime >= 0){ + $tunnel_hash{$connectid}->{_state} = "up"; + } + } + if ($line =~ /$spi:.*?EVENT_SA_EXPIRE in (.*?)s;/){ + $tunnel_hash{$connectid}->{_expire} = $1; + my $atime = $tunnel_hash{$connectid}->{_lifetime} - + $tunnel_hash{$connectid}->{_expire}; + if ($atime >= 0){ + $tunnel_hash{$connectid}->{_state} = "up"; + } + } + } + } + } + return %tunnel_hash; +} + +sub get_conns +{ + my $cmd = "sudo cat /etc/dmvpn.conf"; + open(my $IPSECCONF, '-|', $cmd); + my @ipsecconf = []; + while(<$IPSECCONF>){ + push (@ipsecconf, $_); + } + my %th = (); + for my $line (@ipsecconf){ + next if ($line =~/^\#/); + if ($line =~ /vpnprof-tunnel-(.*)/){ + my $tun = $1; + if (not exists $th{$tun}){ + $th{$tun} = { _conns => [$tun], + _tunid => $tun + }; + } else { + push (@{$th{$tun}->{_conns}}, $tun); + } + } + } + return %th; +} + +sub get_profiles_for_cli +{ + my @profiles = split(' ', `cli-shell-api listActiveNodes vpn ipsec profile`); + for my $prof (@profiles) { + print substr $prof, 1, -1; + print "\n"; + } +} + +sub get_conn_for_cli +{ + my $profileid = pop(@_); + my %th = get_conns(); + for my $tun ( keys %th ) { + for my $conn ( @{$th{$tun}->{_conns}} ){ + print "$conn\n"; + } + } +} + +sub profileSort { + #TODO: It's not used now. Should implement smth meaningfull or delete this sub + sort { + $a->[0] <=> $b->[0]; + } @_; +} + +sub tunSort { + #TODO: not used now. Early it was sorting tun ids as numbers, but now we have 'tunX' as tunid. + sort { + $a->[0] <=> $b->[0]; + } @_; +} + +sub show_ipsec_sa +{ + my %tunnel_hash = get_tunnel_info(); + display_ipsec_sa_brief(\%tunnel_hash); +} +sub show_ipsec_sa_detail +{ + my %tunnel_hash = get_tunnel_info(); + display_ipsec_sa_detail(\%tunnel_hash); +} + +sub show_ipsec_sa_profile +{ + my $profile = pop(@_); + my %tunnel_hash = get_tunnel_info_profile($profile); + display_ipsec_sa_brief(\%tunnel_hash); +} + +sub show_ipsec_sa_stats_profile +{ + my $profile = pop(@_); + my %tunnel_hash = get_tunnel_info_profile($profile); + display_ipsec_sa_stats(\%tunnel_hash); +} + +sub show_ipsec_sa_stats_conn +{ + my %tmphash = (); + (my $profileid, my $tun) = @_; + my %th = get_tunnel_info_profile($profileid); + for my $profile ( keys %th ) { + if ($th{$profile}->{_tunnelnum} eq $tun){ + $tmphash{$profile} = \%{$th{$profile}}; + } + } + display_ipsec_sa_stats(\%tmphash); +} + +sub show_ipsec_sa_profile_detail +{ + my $profileid = pop(@_); + my %tunnel_hash = get_tunnel_info_profile($profileid); + display_ipsec_sa_detail(\%tunnel_hash); +} + +sub show_ipsec_sa_conn_detail +{ + my %tmphash = (); + (my $profileid, my $tun) = @_; + my %th = get_tunnel_info_profile($profileid); + for my $profile ( keys %th ) { + if ($th{$profile}->{_tunnelnum} eq $tun){ + $tmphash{$profile} = \%{$th{$profile}}; + } + } + display_ipsec_sa_detail(\%tmphash); +} + +sub show_ipsec_sa_conn +{ + my %tmphash = (); + (my $profileid, my $tun) = @_; + my %th = get_tunnel_info_profile($profileid); + for my $profile ( keys %th ) { + if ($th{$profile}->{_tunnelnum} eq $tun){ + $tmphash{$profile} = \%{$th{$profile}}; + } + } + display_ipsec_sa_brief(\%tmphash); +} + +sub display_ipsec_sa_brief +{ + my %th = %{pop(@_)}; + my $listref = []; + my %tunhash = (); + my $myid = undef; + my $peerid = undef; + for my $connectid (keys %th){ + $peerid = conv_ip($th{$connectid}->{_rip}); + my $lip = conv_ip($th{$connectid}->{_lip}); + my $tunnel = "$peerid-$lip"; + my $peer_configured = conv_id_rev($th{$connectid}->{_peerid}); + if (not exists $tunhash{$tunnel}) { + $tunhash{$tunnel} = { + _outspi => $th{$connectid}->{_outspi}, + _natt => $th{$connectid}->{_natt}, + _lip => $lip, + _peerid => $peer_configured, + _tunnels => [] + }; + } + my @tmp = ( $th{$connectid}->{_tunnelnum}, + $th{$connectid}->{_state}, + $th{$connectid}->{_inbytes}, + $th{$connectid}->{_outbytes}, + $th{$connectid}->{_encryption}, + $th{$connectid}->{_hash}, + $th{$connectid}->{_lifetime}, + $th{$connectid}->{_lproto}, + $th{$connectid}->{_expire}); + push (@{$tunhash{"$tunnel"}->{_tunnels}}, [ @tmp ]); + + } + for my $connid (keys %tunhash){ + print <<EOH; +Peer ID / IP Local ID / IP +------------ ------------- +EOH + (my $peerid, my $myid) = $connid =~ /(.*?)-(.*)/; + printf "%-39s %-39s\n", $peerid, $myid; + print <<EOH; + + Tunnel State Bytes Out/In Encrypt Hash NAT-T A-Time L-Time Proto + ------ ----- ------------- ------- ---- ----- ------ ------ ----- +EOH + for my $tunnel (@{$tunhash{$connid}->{_tunnels}}){ + (my $tunnum, my $state, my $inbytes, my $outbytes, + my $enc, my $hash, my $life, my $proto, my $expire) = @{$tunnel}; + my $lip = $tunhash{$connid}->{_lip}; + my $peerip = conv_ip($peerid); + my $natt = $tunhash{$connid}->{_natt}; + my $bytesp = 'n/a'; + $enc = conv_enc($enc); + $hash = conv_hash($hash); + $natt = conv_natt($natt); + if (!($inbytes eq 'n/a' && $outbytes eq 'n/a')){ + $outbytes = conv_bytes($outbytes); + $inbytes = conv_bytes($inbytes); + $bytesp = "$outbytes/$inbytes"; + } + my $atime = $life - $expire; + $atime = 0 if ($atime == $life); + printf " %-7s %-6s %-14s %-8s %-5s %-6s %-7s %-7s %-2s\n", + $tunnum, $state, $bytesp, $enc, $hash, $natt, + $atime, $life, $proto; + } + print "\n \n"; + } +} + +sub display_ipsec_sa_detail +{ + my %th = %{pop(@_)}; + my $listref = []; + my %tunhash = (); + my $myid = undef; + my $peerid = undef; + for my $connectid (keys %th){ + my $lip = conv_ip($th{$connectid}->{_lip}); + $peerid = conv_ip($th{$connectid}->{_rip}); + my $tunnel = "$peerid-$lip"; + + if (not exists $tunhash{$tunnel}) { + $tunhash{$tunnel} = { + _peerip => $th{$connectid}->{_rip}, + _peerid => $th{$connectid}->{_rid}, + _configpeer => conv_id_rev($th{$connectid}->{_peerid}), + _localip => $th{$connectid}->{_lip}, + _localid => $th{$connectid}->{_lid}, + _dhgrp => $th{$connectid}->{_dhgrp}, + _natt => $th{$connectid}->{_natt}, + _natsrc => $th{$connectid}->{_natsrc}, + _natdst => $th{$connectid}->{_natdst}, + _tunnels => [] + }; + } + my @tmp = ( $th{$connectid}->{_tunnelnum}, + $th{$connectid}->{_state}, + $th{$connectid}->{_inspi}, + $th{$connectid}->{_outspi}, + $th{$connectid}->{_encryption}, + $th{$connectid}->{_hash}, + $th{$connectid}->{_pfsgrp}, + $th{$connectid}->{_lsnet}, + $th{$connectid}->{_rsnet}, + $th{$connectid}->{_inbytes}, + $th{$connectid}->{_outbytes}, + $th{$connectid}->{_lifetime}, + $th{$connectid}->{_expire}, + $th{$connectid}->{_lca}, + $th{$connectid}->{_rca}, + $th{$connectid}->{_lproto}, + $th{$connectid}->{_rproto}, + $th{$connectid}->{_lport}, + $th{$connectid}->{_rport} ); + push (@{$tunhash{$tunnel}->{_tunnels}}, [ @tmp ]); + } + for my $connid (keys %tunhash){ + my $natt = conv_natt($tunhash{$connid}->{_natt}); + my $peerip = conv_ip($tunhash{$connid}->{_peerip}); + my $localid = $tunhash{$connid}->{_localid}; + if ($localid =~ /CN=(.*?),/){ + $localid = $1; + } + my $peerid = $tunhash{$connid}->{_peerid}; + if ($peerid =~ /CN=(.*?),/){ + $peerid = $1; + } + print "------------------------------------------------------------------\n"; + print "Peer IP:\t\t$peerip\n"; + print "Peer ID:\t\t$peerid\n"; + print "Local IP:\t\t$tunhash{$connid}->{_localip}\n"; + print "Local ID:\t\t$localid\n"; + print "NAT Traversal:\t\t$natt\n"; + print "NAT Source Port:\t$tunhash{$connid}->{_natsrc}\n"; + print "NAT Dest Port:\t\t$tunhash{$connid}->{_natdst}\n"; + print "\n"; + for my $tunnel (tunSort(@{$tunhash{$connid}->{_tunnels}})){ + (my $tunnum, my $state, my $inspi, my $outspi, my $enc, + my $hash, my $pfsgrp, my $srcnet, my $dstnet, + my $inbytes, my $outbytes, my $life, my $expire, my $lca, + my $rca, my $lproto, my $rproto, my $lport, my $rport) = @{$tunnel}; + $enc = conv_enc($enc); + $hash = conv_hash($hash); + $lport = 'all' if ($lport eq '0'); + $rport = 'all' if ($rport eq '0'); + $pfsgrp = conv_dh_group($pfsgrp); + + my $atime = $life - $expire; + $atime = 0 if ($atime == $life); + $inbytes = conv_bytes($inbytes); + $outbytes = conv_bytes($outbytes); + + print " Tunnel $tunnum:\n"; + print " State:\t\t\t$state\n"; + print " Inbound SPI:\t\t$inspi\n"; + print " Outbound SPI:\t\t$outspi\n"; + print " Encryption:\t\t$enc\n"; + print " Hash:\t\t\t$hash\n"; + print " PFS Group:\t\t$pfsgrp\n"; + if (defined $lca){ + print " \n"; + print " CA:\n"; + foreach my $field (split(', ', $lca)){ + $field=~s/\"//g; + print " $field\n"; + } + } + #print " Local CA:\t\t$lca\n" if defined($lca); + #print " Right CA:\t\t$rca\n" if defined($rca); + print " \n"; + print " Local Net:\t\t$srcnet\n"; + print " Local Protocol:\t\t$lproto\n"; + print " Local Port: \t\t$lport\n"; + print " \n"; + print " Remote Net:\t\t$dstnet\n"; + print " Remote Protocol:\t$rproto\n"; + print " Remote Port: \t\t$rport\n"; + print " \n"; + print " Inbound Bytes:\t\t$inbytes\n"; + print " Outbound Bytes:\t\t$outbytes\n"; + print " Active Time (s):\t$atime\n"; + print " Lifetime (s):\t\t$life\n"; + print " \n"; + } + print "\n"; + } +} +1; diff --git a/scripts/vyatta-op-vpnprof.pl b/scripts/vyatta-op-vpnprof.pl new file mode 100644 index 0000000..2f173fb --- /dev/null +++ b/scripts/vyatta-op-vpnprof.pl @@ -0,0 +1,59 @@ +#!/usr/bin/perl +# +# Module: vyatta-op-vpnprof.pl +# +use Getopt::Long; +use Data::Dumper; +use lib "/opt/vyatta/share/perl5/"; +use Vyatta::vpnprof::OPMode; + +use strict; + +my ($get_profiles_for_cli, $get_conn_for_cli, $show_ipsec_sa, $show_ipsec_sa_detail, + $show_ipsec_sa_profile, $show_ipsec_sa_profile_detail, + $show_ipsec_sa_stats, $show_ipsec_sa_stats_profile); +my @show_ipsec_sa_stats_conn; +my @show_ipsec_sa_conn_detail; +my @show_ipsec_sa_conn; + +GetOptions("show-ipsec-sa!" => \$show_ipsec_sa, + "show-ipsec-sa-detail!" => \$show_ipsec_sa_detail, + "get-profiles-for-cli!" => \$get_profiles_for_cli, + "get-conn-for-cli=s" => \$get_conn_for_cli, + "show-ipsec-sa-profile=s" => \$show_ipsec_sa_profile, + "show-ipsec-sa-profile-detail=s" => \$show_ipsec_sa_profile_detail, + "show-ipsec-sa-stats!" => \$show_ipsec_sa_stats, + "show-ipsec-sa-stats-profile=s" => \$show_ipsec_sa_stats_profile, + "show-ipsec-sa-conn-detail=s{2}" => \@show_ipsec_sa_conn_detail, + "show-ipsec-sa-conn=s{2}" => \@show_ipsec_sa_conn); + +if (defined $get_profiles_for_cli) { + Vyatta::vpnprof::OPMode::get_profiles_for_cli(); +} +if (defined $get_conn_for_cli) { + Vyatta::vpnprof::OPMode::get_conn_for_cli($get_conn_for_cli); +} +if (defined $show_ipsec_sa) { + Vyatta::vpnprof::OPMode::show_ipsec_sa(); +} +if (defined $show_ipsec_sa_detail) { + Vyatta::vpnprof::OPMode::show_ipsec_sa_detail(); +} +if (defined $show_ipsec_sa_profile) { + Vyatta::vpnprof::OPMode::show_ipsec_sa_profile($show_ipsec_sa_profile); +} +if (defined $show_ipsec_sa_profile_detail) { + Vyatta::vpnprof::OPMode::show_ipsec_sa_profile_detail($show_ipsec_sa_profile_detail); +} +if (defined @show_ipsec_sa_conn_detail) { + Vyatta::vpnprof::OPMode::show_ipsec_sa_conn_detail(@show_ipsec_sa_conn_detail); +} +if (defined @show_ipsec_sa_conn) { + Vyatta::vpnprof::OPMode::show_ipsec_sa_conn(@show_ipsec_sa_conn); +} +if (defined $show_ipsec_sa_stats) { + Vyatta::vpnprof::OPMode::show_ipsec_sa_stats(); +} +if (defined $show_ipsec_sa_stats_profile) { + Vyatta::vpnprof::OPMode::show_ipsec_sa_stats_profile($show_ipsec_sa_stats_profile); +} diff --git a/templates/show/vpn/ipsec/sa/node.def b/templates/show/vpn/ipsec/sa/node.def index a3f0f6b..287d489 100644 --- a/templates/show/vpn/ipsec/sa/node.def +++ b/templates/show/vpn/ipsec/sa/node.def @@ -1,2 +1,3 @@ help: Show all active IPsec Security Associations (SA) run: sudo /opt/vyatta/bin/sudo-users/vyatta-op-vpn.pl --show-ipsec-sa + sudo /opt/vyatta/bin/sudo-users/vyatta-op-vpnprof.pl --show-ipsec-sa diff --git a/templates/show/vpn/ipsec/sa/profile/node.def b/templates/show/vpn/ipsec/sa/profile/node.def new file mode 100644 index 0000000..a0d7b44 --- /dev/null +++ b/templates/show/vpn/ipsec/sa/profile/node.def @@ -0,0 +1 @@ +help: Show all active IPsec Security Associations (SA) for a profile diff --git a/templates/show/vpn/ipsec/sa/profile/node.tag/node.def b/templates/show/vpn/ipsec/sa/profile/node.tag/node.def new file mode 100644 index 0000000..76e66a5 --- /dev/null +++ b/templates/show/vpn/ipsec/sa/profile/node.tag/node.def @@ -0,0 +1,3 @@ +help: Show all active IPsec Security Associations (SA) for a profile +allowed: /opt/vyatta/bin/sudo-users/vyatta-op-vpnprof.pl --get-profiles-for-cli +run: sudo /opt/vyatta/bin/sudo-users/vyatta-op-vpnprof.pl --show-ipsec-sa-profile="$6" diff --git a/templates/show/vpn/ipsec/sa/profile/node.tag/tunnel/node.def b/templates/show/vpn/ipsec/sa/profile/node.tag/tunnel/node.def new file mode 100644 index 0000000..ca0ec72 --- /dev/null +++ b/templates/show/vpn/ipsec/sa/profile/node.tag/tunnel/node.def @@ -0,0 +1 @@ +help: Show the active IPsec Security Association (SA) for a profiles's tunnel diff --git a/templates/show/vpn/ipsec/sa/profile/node.tag/tunnel/node.tag/node.def b/templates/show/vpn/ipsec/sa/profile/node.tag/tunnel/node.tag/node.def new file mode 100644 index 0000000..3f0af98 --- /dev/null +++ b/templates/show/vpn/ipsec/sa/profile/node.tag/tunnel/node.tag/node.def @@ -0,0 +1,3 @@ +help: Show the active IPsec Security Association (SA) for a profile's tunnel +allowed: /opt/vyatta/bin/sudo-users/vyatta-op-vpnprof.pl --get-conn-for-cli=${COMP_WORDS[5]} +run: sudo /opt/vyatta/bin/sudo-users/vyatta-op-vpnprof.pl --show-ipsec-sa-conn $6 $8 |