summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Harpin <development@landsofshadow.co.uk>2014-10-05 15:24:57 +0100
committerAlex Harpin <development@landsofshadow.co.uk>2014-10-05 17:08:48 +0100
commit1d2040456666b91963dbe5fd704e2f496c76974f (patch)
treebe0478c631b05de5f043c2b362c0af6f775bbbbd
parenta45c529838e42e5584b9cb991c893d1675054b35 (diff)
downloadvyatta-cfg-vpn-1d2040456666b91963dbe5fd704e2f496c76974f.tar.gz
vyatta-cfg-vpn-1d2040456666b91963dbe5fd704e2f496c76974f.zip
vyatta-cfg-vpn: formatting changes for style consistency
Update scripts/vpn-config.pl to have consistent identation levels and style throughout.
-rwxr-xr-xscripts/vpn-config.pl2765
1 files changed, 1308 insertions, 1457 deletions
diff --git a/scripts/vpn-config.pl b/scripts/vpn-config.pl
index 82b80eb..bda9920 100755
--- a/scripts/vpn-config.pl
+++ b/scripts/vpn-config.pl
@@ -44,9 +44,9 @@ my $config_file;
my $secrets_file;
my $init_script;
GetOptions(
- "config_file=s" => \$config_file,
- "secrets_file=s" => \$secrets_file,
- "init_script=s" => \$init_script
+ "config_file=s" => \$config_file,
+ "secrets_file=s" => \$secrets_file,
+ "init_script=s" => \$init_script
);
my $CA_CERT_PATH = '/etc/ipsec.d/cacerts';
my $CRL_PATH = '/etc/ipsec.d/crls';
@@ -80,1597 +80,1448 @@ $vcVPN->setLevel('vpn');
my $ipsecstatus = $vcVPN->isChanged('ipsec');
my $rsastatus = $vcVPN->isChanged('rsa-keys');
if (!$ipsecstatus && !$rsastatus) {
- exit 0;
+ exit 0;
}
-if ( $vcVPN->exists('ipsec') ) {
-
- #
- # Check that ESP groups have been specified
- #
- my @esp_groups = $vcVPN->listNodes('ipsec esp-group');
- if ( @esp_groups == 0 ) {
-
- #print STDERR "$vpn_cfg_err No ESP groups configured." .
- # " At least one ESP group required.\n";
- # XXX for now this will be checked below for site-to-site peer
-
- } else {
- foreach my $esp_group (@esp_groups) {
- my @esp_group_proposals =
- $vcVPN->listNodes("ipsec esp-group $esp_group proposal");
- if ( @esp_group_proposals == 0 ) {
- vpn_die(["vpn","ipsec","esp-group",$esp_group,"proposal"],
- "$vpn_cfg_err No proposals configured for ESP group \"$esp_group\""
- . ". At least one proposal required.\n");
- } elsif ( @esp_group_proposals > VPN_MAX_PROPOSALS ) {
- vpn_die(["vpn","ipsec","esp-group",$esp_group],
- "$vpn_cfg_err A total of "
- . @esp_group_proposals
- . " proposals have been configured for ESP group \"$esp_group\"."
- . " The maximum proposals allowed for an ESP group is "
- . VPN_MAX_PROPOSALS . "\n");
- } else {
- foreach my $esp_group_proposal (@esp_group_proposals) {
- my $esp_group_proposal_encryption = $vcVPN->returnValue(
- "ipsec esp-group $esp_group proposal $esp_group_proposal encryption"
- );
- if ( !defined($esp_group_proposal_encryption)
- || $esp_group_proposal_encryption eq "" )
- {
- vpn_die(["vpn","ipsec","esp-group",$esp_group,"proposal",$esp_group_proposal,"encryption"],
- "$vpn_cfg_err No encryption specified for ESP group "
- . "\"$esp_group\" proposal $esp_group_proposal.\n");
-
- }
- my $esp_group_proposal_hash = $vcVPN->returnValue(
- "ipsec esp-group $esp_group proposal $esp_group_proposal hash");
- if ( !defined($esp_group_proposal_hash)
- || $esp_group_proposal_hash eq "" )
- {
- vpn_die(["vpn","ipsec","esp-group",$esp_group,"proposal",$esp_group_proposal,"hash"],
- "$vpn_cfg_err No hash specified for ESP group \"$esp_group\""
- . " proposal $esp_group_proposal.\n");
- }
+if ($vcVPN->exists('ipsec')) {
+
+ #
+ # Check that ESP groups have been specified
+ #
+ my @esp_groups = $vcVPN->listNodes('ipsec esp-group');
+ if (@esp_groups == 0) {
+
+ #print STDERR "$vpn_cfg_err No ESP groups configured." .
+ # " At least one ESP group required.\n";
+ # XXX for now this will be checked below for site-to-site peer
+
+ } else {
+ foreach my $esp_group (@esp_groups) {
+ my @esp_group_proposals =$vcVPN->listNodes("ipsec esp-group $esp_group proposal");
+ if (@esp_group_proposals == 0) {
+ vpn_die(["vpn","ipsec","esp-group",$esp_group,"proposal"],"$vpn_cfg_err No proposals configured for ESP group \"$esp_group\"".
+ ". At least one proposal required.\n");
+ } elsif (@esp_group_proposals > VPN_MAX_PROPOSALS) {
+ vpn_die(["vpn","ipsec","esp-group",$esp_group],"$vpn_cfg_err A total of ". @esp_group_proposals.
+ " proposals have been configured for ESP group \"$esp_group\".". " The maximum proposals allowed for an ESP group is ". VPN_MAX_PROPOSALS . "\n");
+ } else {
+ foreach my $esp_group_proposal (@esp_group_proposals) {
+ my $esp_group_proposal_encryption = $vcVPN->returnValue("ipsec esp-group $esp_group proposal $esp_group_proposal encryption");
+ if (!defined($esp_group_proposal_encryption)
+ || $esp_group_proposal_encryption eq "")
+ {
+ vpn_die(["vpn","ipsec","esp-group",$esp_group,"proposal",$esp_group_proposal,"encryption"],"$vpn_cfg_err No encryption specified for ESP group ".
+ "\"$esp_group\" proposal $esp_group_proposal.\n");
+
+ }
+ my $esp_group_proposal_hash = $vcVPN->returnValue("ipsec esp-group $esp_group proposal $esp_group_proposal hash");
+ if (!defined($esp_group_proposal_hash)
+ || $esp_group_proposal_hash eq "") {
+ vpn_die(["vpn","ipsec","esp-group",$esp_group,"proposal",$esp_group_proposal,"hash"],"$vpn_cfg_err No hash specified for ESP group \"$esp_group\"".
+ " proposal $esp_group_proposal.\n");
+ }
+ }
+ }
}
- }
}
- }
-
- #
- # Check that IKE groups have been specified
- #
- my @ike_groups = $vcVPN->listNodes('ipsec ike-group');
- if ( @ike_groups == 0 ) {
-
- #print STDERR "$vpn_cfg_err No IKE groups configured." .
- # " At least one IKE group required.\n";
- # XXX for now this will be checked below for site-to-site peer
-
- } else {
- foreach my $ike_group (@ike_groups) {
- my @ike_group_proposals =
- $vcVPN->listNodes("ipsec ike-group $ike_group proposal");
- if ( @ike_group_proposals == 0 ) {
- vpn_die(["vpn","ipsec","ike-group",$ike_group, "proposal"],
- "$vpn_cfg_err No proposals configured for IKE group \"$ike_group\""
- . ". At least one proposal required.\n");
- } elsif ( @ike_group_proposals > VPN_MAX_PROPOSALS ) {
- vpn_die(["vpn","ipsec","ike-group",$ike_group],
- "$vpn_cfg_err A total of "
- . @ike_group_proposals
- . " proposals have been configured for IKE group \"$ike_group\"."
- . " The maximum proposals allowed for an IKE group is "
- . VPN_MAX_PROPOSALS . "\n");
- } else {
- foreach my $ike_group_proposal (@ike_group_proposals) {
- my $ike_group_proposal_encryption = $vcVPN->returnValue(
- "ipsec ike-group $ike_group proposal $ike_group_proposal encryption"
- );
- if ( !defined($ike_group_proposal_encryption)
- || $ike_group_proposal_encryption eq "" )
- {
- vpn_die(["vpn","ike-group",$ike_group,"proposal",$ike_group_proposal,"encryption"],
- "$vpn_cfg_err No encryption specified for IKE group "
- . "\"$ike_group\" proposal $ike_group_proposal.\n");
- }
- my $ike_group_proposal_hash = $vcVPN->returnValue(
- "ipsec ike-group $ike_group proposal $ike_group_proposal hash");
- if ( !defined($ike_group_proposal_hash)
- || $ike_group_proposal_hash eq "" )
- {
- vpn_die(["vpn","ike-group",$ike_group,"proposal",$ike_group_proposal,"hash"],
- "$vpn_cfg_err No hash specified for IKE group \"$ike_group\""
- . " proposal $ike_group_proposal.\n");
- }
+
+ #
+ # Check that IKE groups have been specified
+ #
+ my @ike_groups = $vcVPN->listNodes('ipsec ike-group');
+ if (@ike_groups == 0) {
+ #print STDERR "$vpn_cfg_err No IKE groups configured." .
+ # " At least one IKE group required.\n";
+ # XXX for now this will be checked below for site-to-site peer
+ } else {
+ foreach my $ike_group (@ike_groups) {
+ my @ike_group_proposals =$vcVPN->listNodes("ipsec ike-group $ike_group proposal");
+ if (@ike_group_proposals == 0) {
+ vpn_die(["vpn","ipsec","ike-group",$ike_group, "proposal"],"$vpn_cfg_err No proposals configured for IKE group \"$ike_group\"".
+ ". At least one proposal required.\n");
+ } elsif (@ike_group_proposals > VPN_MAX_PROPOSALS) {
+ vpn_die(["vpn","ipsec","ike-group",$ike_group],"$vpn_cfg_err A total of ". @ike_group_proposals.
+ " proposals have been configured for IKE group \"$ike_group\".". " The maximum proposals allowed for an IKE group is ". VPN_MAX_PROPOSALS . "\n");
+ } else {
+ foreach my $ike_group_proposal (@ike_group_proposals) {
+ my $ike_group_proposal_encryption = $vcVPN->returnValue("ipsec ike-group $ike_group proposal $ike_group_proposal encryption");
+ if (!defined($ike_group_proposal_encryption)
+ || $ike_group_proposal_encryption eq "")
+ {
+ vpn_die(["vpn","ike-group",$ike_group,"proposal",$ike_group_proposal,"encryption"],"$vpn_cfg_err No encryption specified for IKE group ".
+ "\"$ike_group\" proposal $ike_group_proposal.\n");
+ }
+ my $ike_group_proposal_hash = $vcVPN->returnValue("ipsec ike-group $ike_group proposal $ike_group_proposal hash");
+ if (!defined($ike_group_proposal_hash)
+ || $ike_group_proposal_hash eq "") {
+ vpn_die(["vpn","ike-group",$ike_group,"proposal",$ike_group_proposal,"hash"],"$vpn_cfg_err No hash specified for IKE group \"$ike_group\"".
+ " proposal $ike_group_proposal.\n");
+ }
+ }
+ }
}
- }
}
- }
-
- #
- # Check the local key file
- # Note: $local_key_file will be used later when reading the keys
- #
- my $running_local_key_file = rsa_get_local_key_file();
- my $local_key_file = $vcVPN->returnValue('rsa-keys local-key file');
- if ( !defined($local_key_file) ) {
- $local_key_file = LOCAL_KEY_FILE_DEFAULT;
- }
- if ( $local_key_file ne $running_local_key_file ) {
-
- # Sanity check the usr specified local_key_file
+
#
- # 1). Must start with "/"
- # 2). Only allow alpha-numeric, ".", "-", "_", or "/".
- # 3). Don't allow "//"
- # 4). Verify that it's not a directory
+ # Check the local key file
+ # Note: $local_key_file will be used later when reading the keys
#
- if ( $local_key_file !~ /^\// ) {
- vpn_die(["vpn", "rsa-keys", "local-key", "file"],
- "$vpn_cfg_err Invalid local RSA key file path \"$local_key_file\"."
- . " Does not start with a '/'.\n");
- }
- if ( $local_key_file =~ /[^a-zA-Z0-9\.\-\_\/]/g ) {
- vpn_die(["vpn", "rsa-keys", "local-key", "file"],
- "$vpn_cfg_err Invalid local RSA key file path \"$local_key_file\"."
- . " Contains a character that is not alpha-numeric and not '.', '-', '_', '/'.\n");
- }
- if ( $local_key_file =~ /\/\//g ) {
- vpn_die(["vpn", "rsa-keys", "local-key", "file"],
- "$vpn_cfg_err Invalid local RSA key file path \"$local_key_file\"."
- . " Contains string \"//\".\n");
- }
- if ( -d $local_key_file ) {
- vpn_die(["vpn", "rsa-keys", "local-key", "file"],
- "$vpn_cfg_err Invalid local RSA key file path \"$local_key_file\"."
- . " Path is a directory rather than a file.\n");
+ my $running_local_key_file = rsa_get_local_key_file();
+ my $local_key_file = $vcVPN->returnValue('rsa-keys local-key file');
+ if (!defined($local_key_file)) {
+ $local_key_file = LOCAL_KEY_FILE_DEFAULT;
}
+ if ($local_key_file ne $running_local_key_file) {
- if ( -r $running_local_key_file && !( -e $local_key_file ) ) {
- vpn_debug "cp $running_local_key_file $local_key_file";
- my ($dirpath) = ( $local_key_file =~ m#^(.*/)?.*#s );
- my $rc = system("mkdir -p $dirpath");
- if ( $rc != 0 ) {
- vpn_die(["vpn", "rsa-keys", "local-key", "file"],
- "$vpn_cfg_err Could not copy previous local RSA key file "
- . "\"$running_local_key_file\" to new local RSA key file "
- . "\"$local_key_file\". Could not mkdir [$dirpath] $!\n");
- } else {
- $rc = system("cp $running_local_key_file $local_key_file");
- if ( $rc != 0 ) {
- vpn_die(["vpn", "rsa-keys", "local-key", "file"],
- "$vpn_cfg_err Could not copy previous local RSA key file "
- . "\"$running_local_key_file\" to new local RSA key file "
- . "\"$local_key_file\". $!\n");
+ # Sanity check the usr specified local_key_file
+ #
+ # 1). Must start with "/"
+ # 2). Only allow alpha-numeric, ".", "-", "_", or "/".
+ # 3). Don't allow "//"
+ # 4). Verify that it's not a directory
+ #
+ if ($local_key_file !~ /^\//) {
+ vpn_die(["vpn", "rsa-keys", "local-key", "file"],"$vpn_cfg_err Invalid local RSA key file path \"$local_key_file\".". " Does not start with a '/'.\n");
}
- }
- }
- }
-
- #
- # Version 2
- #
- $genout .= "version 2.0\n";
- $genout .= "\n";
- $genout .= "config setup\n";
- $genout .= "\tcharonstart=yes\n";
-
- #
- # Interfaces
- #
- my @interfaces = $vcVPN->returnValues('ipsec ipsec-interfaces interface');
- if ( @interfaces == 0 ) {
- #*THIS CHECK'S ALSO USED BY OP-MODE CMNDS TO CHECK IF IPSEC IS CONFIGURED*#
- vpn_die(["vpn", "ipsec","ipsec-interfaces"],
- "$vpn_cfg_err No IPSEC interfaces specified.\n");
- } else {
-
- # We need to generate an "interfaces=..." entry in the setup section
- # only if the underlying IPsec kernel code we are using is KLIPS.
- # If we are using NETKEY, the "interfaces=..." entry is essentially
- # not used, though we do need to include the line and the keyword
- # "%none" to keep the IPsec setup code from defaulting the entry.
- if ($using_klips) {
- $genout .= "\tinterfaces=\"";
- my $counter = 0;
- foreach my $interface (@interfaces) {
- if ( !( -d "/sys/class/net/$interface" ) ) {
- next;
+ if ($local_key_file =~ /[^a-zA-Z0-9\.\-\_\/]/g) {
+ vpn_die(["vpn", "rsa-keys", "local-key", "file"],"$vpn_cfg_err Invalid local RSA key file path \"$local_key_file\".".
+ " Contains a character that is not alpha-numeric and not '.', '-', '_', '/'.\n");
}
- if ( $counter > 0 ) {
- $genout .= ' ';
+ if ($local_key_file =~ /\/\//g) {
+ vpn_die(["vpn", "rsa-keys", "local-key", "file"],"$vpn_cfg_err Invalid local RSA key file path \"$local_key_file\".". " Contains string \"//\".\n");
}
- $genout .= "ipsec$counter=$interface";
- ++$counter;
- }
- if ( hasLocalWildcard( $vcVPN, 0 ) ) {
- if ( $counter > 0 ) {
- $genout .= ' ';
+ if (-d $local_key_file) {
+ vpn_die(["vpn", "rsa-keys", "local-key", "file"],"$vpn_cfg_err Invalid local RSA key file path \"$local_key_file\".". " Path is a directory rather than a file.\n");
}
- $genout .= '%defaultroute';
- }
- $genout .= "\"\n";
- } else {
- my $counter = 0;
- $genout .= "\t";
- if ( hasLocalWildcard( $vcVPN, 0 ) ) {
- $genout .= 'interfaces="';
- foreach my $interface (@interfaces) {
- next if !-d "/sys/class/net/$interface";
- next if scalar( getIP($interface) ) < 1;
- $genout .= "ipsec$counter=$interface ";
- ++$counter;
+
+ if (-r $running_local_key_file && !(-e $local_key_file)) {
+ vpn_debug "cp $running_local_key_file $local_key_file";
+ my ($dirpath) = ($local_key_file =~ m#^(.*/)?.*#s);
+ my $rc = system("mkdir -p $dirpath");
+ if ($rc != 0) {
+ vpn_die(["vpn", "rsa-keys", "local-key", "file"],"$vpn_cfg_err Could not copy previous local RSA key file ".
+ "\"$running_local_key_file\" to new local RSA key file ". "\"$local_key_file\". Could not mkdir [$dirpath] $!\n");
+ } else {
+ $rc = system("cp $running_local_key_file $local_key_file");
+ if ($rc != 0) {
+ vpn_die(["vpn", "rsa-keys", "local-key", "file"],"$vpn_cfg_err Could not copy previous local RSA key file ".
+ "\"$running_local_key_file\" to new local RSA key file ". "\"$local_key_file\". $!\n");
+ }
+ }
}
- $genout .= '%defaultroute"';
- } else {
- $genout .= 'interfaces="%none"';
- }
- $genout .= "\n";
- }
- }
-
- #
- # NAT traversal
- #
- my $nat_traversal = $vcVPN->returnValue('ipsec nat-traversal');
- if ( defined($nat_traversal) ) {
- if ( $nat_traversal eq 'enable' ) {
- $genout .= "\tnat_traversal=yes\n";
- } elsif ( $nat_traversal eq 'disable' ) {
- $genout .= "\tnat_traversal=no\n";
- } elsif ( $nat_traversal ne '' ) {
- vpn_die(["vpn", "ipsec", "nat-traversal"],
- "$vpn_cfg_err Invalid value \"$nat_traversal\" specified for "
- . "'nat-traversal'. Only \"enable\" or \"disable\" accepted.\n");
- }
- }
-
- #
- # NAT networks
- #
- my @nat_networks = $vcVPN->listNodes('ipsec nat-networks allowed-network');
- if ( @nat_networks > 0 ) {
- my $first_nat_net = 1;
- foreach my $nat_network (@nat_networks) {
- if ($first_nat_net) {
- $genout .= "\tvirtual_private=\"\%v4:$nat_network";
- $first_nat_net = 0;
- } else {
- $genout .= ",\%v4:$nat_network";
- }
-
- my @nat_network_excludes = $vcVPN->returnValues(
- "ipsec nat-networks allowed-network $nat_network exclude");
- foreach my $nat_network_exclude (@nat_network_excludes) {
- $genout .= ",\%v4:\!$nat_network_exclude";
- }
- }
- $genout .= "\"\n";
- }
-
- #
- # log-mode
- #
- my @logmodes = $vcVPN->returnValues('ipsec logging log-modes');
- if ( @logmodes > 0 ) {
- my $debugmode = '';
- foreach my $mode (@logmodes) {
- if ( $mode eq "all" ) {
- $debugmode = "all";
- last;
- }
- if ( $debugmode eq '' ) {
- $debugmode = "$mode";
- } else {
- $debugmode .= " $mode";
- }
}
- $genout .= "\tplutodebug=\"$debugmode\"\n";
- }
-
- # Set plutoopts:
- # Disable uniqreqids?
- #
- if ( $vcVPN->exists('ipsec disable-uniqreqids') ) {
- $genout .= "\tdisableuniqreqids=yes\n";
- }
-
- #
- # Disable implicit connections
- #
- foreach my $conn (
- qw/clear clear-or-private private-or-clear private block packetdefault/)
- {
+
+ #
+ # Version 2
+ #
+ $genout .= "version 2.0\n";
$genout .= "\n";
- $genout .= "conn $conn\n";
- $genout .= "\tauto=ignore\n";
- }
-
- #
- # Default keyengine is ikev1
- #
- $genout .= "\n";
- $genout .= "conn %default\n";
- $genout .= "\tkeyexchange=ikev1\n\n";
-
- #
- # Connection configurations
- #
- my @peers = $vcVPN->listNodes('ipsec site-to-site peer');
- if ( @peers == 0 && !( $vcVPN->exists('l2tp') ) && !( $vcVPN->exists('ipsec profile') ) ) {
- print "VPN Warning: IPSec configured but no site-to-site peers or l2tp"
- . " remote-users configured\n";
- }
- my $prev_peer = "";
- vtiIntf::discoverVtiIntfs();
- foreach my $peer (@peers) {
- my $peer_ike_group =
- $vcVPN->returnValue("ipsec site-to-site peer $peer ike-group");
- if ( !defined($peer_ike_group) || $peer_ike_group eq '' ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"ike-group"],
- "$vpn_cfg_err No IKE group specified for peer \"$peer\".\n");
- } elsif ( !$vcVPN->exists("ipsec ike-group $peer_ike_group") ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"ike-group"],
- "$vpn_cfg_err The IKE group \"$peer_ike_group\" specified for peer "
- . "\"$peer\" has not been configured.\n");
- }
+ $genout .= "config setup\n";
+ $genout .= "\tcharonstart=yes\n";
- my $lip = $vcVPN->returnValue("ipsec site-to-site peer $peer local-address");
-
- my $peer_proto = ((is_ip_v4_or_v6($peer) && (is_ip_v4_or_v6($peer) == 6))) ? 6 : 4;
- my $conn_proto = 4;
-
- # Check peer and local-address consistency
- if ($peer_proto == 6) {
- if (defined($lip)) {
- if (is_ip_v4_or_v6($lip) && (is_ip_v4_or_v6($lip) == 6)) {
- $conn_proto = 6;
- } else {
- # Protocols don't match
- if (isIpAddress($lip)) {
- vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "local-address"],
- "$vpn_cfg_err The 'local-address' and peer protocols do not match");
- # %defaultroute for IPv6 IKEv1 is not supported by StrongS/WAN
- } elsif($lip eq 'any') {
- vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "local-address"],
- "$vpn_cfg_err 'any' local address is not supported for IPv6 peers");
- }
- }
- } else {
- vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer],
- "$vpn_cfg_err 'local-address' is required for IPv6 peers");
- }
+ #
+ # Interfaces
+ #
+ my @interfaces = $vcVPN->returnValues('ipsec ipsec-interfaces interface');
+ if (@interfaces == 0) {
+ #*THIS CHECK'S ALSO USED BY OP-MODE CMNDS TO CHECK IF IPSEC IS CONFIGURED*#
+ vpn_die(["vpn", "ipsec","ipsec-interfaces"],"$vpn_cfg_err No IPSEC interfaces specified.\n");
+ } else {
+ # We need to generate an "interfaces=..." entry in the setup section
+ # only if the underlying IPsec kernel code we are using is KLIPS.
+ # If we are using NETKEY, the "interfaces=..." entry is essentially
+ # not used, though we do need to include the line and the keyword
+ # "%none" to keep the IPsec setup code from defaulting the entry.
+ if ($using_klips) {
+ $genout .= "\tinterfaces=\"";
+ my $counter = 0;
+ foreach my $interface (@interfaces) {
+ if (!(-d "/sys/class/net/$interface")) {
+ next;
+ }
+ if ($counter > 0) {
+ $genout .= ' ';
+ }
+ $genout .= "ipsec$counter=$interface";
+ ++$counter;
+ }
+ if (hasLocalWildcard($vcVPN, 0)) {
+ if ($counter > 0) {
+ $genout .= ' ';
+ }
+ $genout .= '%defaultroute';
+ }
+ $genout .= "\"\n";
+ } else {
+ my $counter = 0;
+ $genout .= "\t";
+ if (hasLocalWildcard($vcVPN, 0)) {
+ $genout .= 'interfaces="';
+ foreach my $interface (@interfaces) {
+ next if !-d "/sys/class/net/$interface";
+ next if scalar(getIP($interface)) < 1;
+ $genout .= "ipsec$counter=$interface ";
+ ++$counter;
+ }
+ $genout .= '%defaultroute"';
+ } else {
+ $genout .= 'interfaces="%none"';
+ }
+ $genout .= "\n";
+ }
}
- my $dhcp_iface = $vcVPN->returnValue("ipsec site-to-site peer $peer dhcp-interface");
- if (defined($lip) && defined($dhcp_iface)){
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer],
- "$vpn_cfg_err Only one of local-address or dhcp-interface may be defined");
- }
- if (defined($dhcp_iface)){
- $dhcp_if = $dhcp_if + 1;
- $lip = get_dhcp_addr($dhcp_iface, $peer);
+ #
+ # NAT traversal
+ #
+ my $nat_traversal = $vcVPN->returnValue('ipsec nat-traversal');
+ if (defined($nat_traversal)) {
+ if ($nat_traversal eq 'enable') {
+ $genout .= "\tnat_traversal=yes\n";
+ } elsif ($nat_traversal eq 'disable') {
+ $genout .= "\tnat_traversal=no\n";
+ } elsif ($nat_traversal ne '') {
+ vpn_die(["vpn", "ipsec", "nat-traversal"],"$vpn_cfg_err Invalid value \"$nat_traversal\" specified for ".
+ "'nat-traversal'. Only \"enable\" or \"disable\" accepted.\n");
+ }
}
- my $authid =
- $vcVPN->returnValue("ipsec site-to-site peer $peer authentication id");
- my $authremoteid = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer authentication remote-id");
- if ( (!defined($lip) || $lip eq "") && (!defined($dhcp_iface) || $dhcp_iface eq "") ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"local-address"],
- "$vpn_cfg_err No local-address specified for peer \"$peer\"\n");
- } elsif ( $lip ne 'any' ) {
-
- # not 'any' special case.
- # check interface addresses.
- if ( !Vyatta::Misc::isIPinInterfaces( $vc, $lip, @interfaces ) ) {
- vpn_log(
-"The local-address $lip of peer \"$peer\" has not been configured in any of the ipsec-interfaces.\n"
- );
- if ( Vyatta::Misc::isClusterIP( $vc, $lip ) ) {
-
- # Verified that dealing with a cluster IP.
- $clustering_ip = 1;
- } elsif (!defined($dhcp_iface)) {
- print
- "Warning: Local address $lip specified for peer \"$peer\"\n";
- print
- "is not configured on any of the ipsec-interfaces and is not the\n";
- print "clustering address. IPsec must be re-started after address\n";
- print "has been configured.\n";
- print "\n";
+
+ #
+ # NAT networks
+ #
+ my @nat_networks = $vcVPN->listNodes('ipsec nat-networks allowed-network');
+ if (@nat_networks > 0) {
+ my $first_nat_net = 1;
+ foreach my $nat_network (@nat_networks) {
+ if ($first_nat_net) {
+ $genout .= "\tvirtual_private=\"\%v4:$nat_network";
+ $first_nat_net = 0;
+ } else {
+ $genout .= ",\%v4:$nat_network";
+ }
+
+ my @nat_network_excludes = $vcVPN->returnValues("ipsec nat-networks allowed-network $nat_network exclude");
+ foreach my $nat_network_exclude (@nat_network_excludes) {
+ $genout .= ",\%v4:\!$nat_network_exclude";
+ }
}
- }
+ $genout .= "\"\n";
}
-
+
#
- # Default ESP group
+ # log-mode
#
- my $def_esp_group = $vcVPN->returnValue("ipsec site-to-site peer $peer default-esp-group");
- $def_esp_group = '' if !defined($def_esp_group);
- if ( !$vcVPN->exists("ipsec esp-group $def_esp_group") ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"default-esp-group"],
- "$vpn_cfg_err The ESP group \"$def_esp_group\" specified "
- . "for peer \"$peer\" has not been configured.\n");
+ my @logmodes = $vcVPN->returnValues('ipsec logging log-modes');
+ if (@logmodes > 0) {
+ my $debugmode = '';
+ foreach my $mode (@logmodes) {
+ if ($mode eq "all") {
+ $debugmode = "all";
+ last;
+ }
+ if ($debugmode eq '') {
+ $debugmode = "$mode";
+ } else {
+ $debugmode .= " $mode";
+ }
+ }
+ $genout .= "\tplutodebug=\"$debugmode\"\n";
}
+ # Set plutoopts:
+ # Disable uniqreqids?
#
- # Name connection by peer and tunnel
+ if ($vcVPN->exists('ipsec disable-uniqreqids')) {
+ $genout .= "\tdisableuniqreqids=yes\n";
+ }
+
#
- my $isVti = 0;
- my @tunnels = $vcVPN->listNodes("ipsec site-to-site peer $peer tunnel");
- if ( @tunnels == 0 ) {
- #
- # Check if this is VTI
- #
- if ($vcVPN->exists("ipsec site-to-site peer $peer vti") ) {
- $isVti = 1;
- @tunnels = (@tunnels, "vti");
- }
- if (@tunnels == 0) {
- vpn_die(["vpn", "ipsec", "site-to-site","peer",$peer,"tunnel"],
- "$vpn_cfg_err No tunnels configured for peer \"$peer\". At least"
- . " one tunnel required per peer.\n");
- }
- } else {
- #
- # Check if this is VTI
- #
- if ($vcVPN->exists("ipsec site-to-site peer $peer vti") ) {
- vpn_die(["vpn", "ipsec", "site-to-site","peer",$peer,"vti"],
- "$vpn_cfg_err Both Vti and tunnel(s) configured for peer \"$peer\n");
- }
+ # Disable implicit connections
+ #
+ foreach my $conn (qw/clear clear-or-private private-or-clear private block packetdefault/){
+ $genout .= "\n";
+ $genout .= "conn $conn\n";
+ $genout .= "\tauto=ignore\n";
}
- foreach my $tunnel (@tunnels) {
-
- my $needs_passthrough = 'false';
- my $tunKeyword;
- if ($isVti == 1) {
- $tunKeyword = 'vti';
- } else {
- $tunKeyword = 'tunnel '."$tunnel";
- }
-
- #
- # Add support for tunnel disable.
- #
- if (
- $vcVPN->exists("ipsec site-to-site peer $peer $tunKeyword disable") )
- {
- next;
- }
-
- my $peer_tunnel_esp_group = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer $tunKeyword esp-group");
- $peer_tunnel_esp_group = '' if (!defined($peer_tunnel_esp_group));
- if ( (!defined($peer_tunnel_esp_group) || $peer_tunnel_esp_group eq '') &&
- (!defined($def_esp_group) || $def_esp_group eq '')) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,$tunKeyword,"esp-group"],
- "$vpn_cfg_err No ESP group specified for peer \"$peer\" "
- . "$tunKeyword.\n");
- } elsif ( !$vcVPN->exists("ipsec esp-group $peer_tunnel_esp_group") ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,$tunKeyword,"esp-group"],
- "$vpn_cfg_err The ESP group \"$peer_tunnel_esp_group\" specified "
- . "for peer \"$peer\" $tunKeyword has not been configured.\n");
- }
-
- my $conn_head = "\nconn peer-$peer-tunnel-$tunnel\n";
- $conn_head =~ s/ peer-@/ peer-/;
- $genout .= $conn_head;
-
- # Support for dhcp-interfaces
- # The comment dhcp-interface will be used by the dhclient hook to do connection updates.
- if (defined($dhcp_iface)){
- $genout .= "\t\#dhcp-interface=$dhcp_iface\n";
- $lip = get_dhcp_addr($dhcp_iface);
- }
-
- # -> leftsourceip is the internal source IP to use in a tunnel
- # -> we use leftsourceip to add a route to the rightsubnet
- # only when rightsubnet is defined and is not 0.0.0.0/0. we do not
- # want to add a vpn route for everything i.e. rightsubnet = 0.0.0.0/0
- # -> if leftsubnet is defined and is not 0.0.0.0/0; we try and find
- # an interface on the system that has an IP address lying within
- # the leftsubnet and use that as leftsourceip. if leftsubnet is not
- # defined or is 0.0.0.0/0 then we use local-address as leftsourceip.
- my $leftsourceip = undef;
-
- #
- # Assign left and right to local and remote interfaces
- #
- if ( defined($lip) ) {
- if ( $lip eq 'any' ) {
- if ($isVti) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,$tunKeyword,"local-address"],
- "$vpn_cfg_err The local interface must be specified "
- . "for peer \"$peer\" $tunKeyword.\n");
- }
- $genout .= "\tleft=%defaultroute\n";
- # no need for leftsourceip as a defaultroute is must for this to work
- } else {
- $genout .= "\tleft=$lip\n";
- $leftsourceip = "\tleftsourceip=$lip\n";
- }
- $genout .= "\tleftid=$authid\n" if defined $authid;
- }
-
- # @SM Todo: must have explicit settings for VTI.
- my $any_peer = 0;
- my $right;
- my $rightid = undef;
- if ( $peer =~ /^\@/ ) {
-
- # peer is an "ID"
- $rightid = $peer;
- $any_peer = 1;
- } elsif ($authremoteid) {
- $rightid = $authremoteid;
- }
- if ( ( $peer eq 'any' )
- or ( $peer eq '0.0.0.0' )
- or $any_peer == 1 )
- {
- if ($isVti) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer],
- "$vpn_cfg_err The \"$peer\" is invalid "
- . "ip address must be specified for $tunKeyword.\n");
- }
- $right = '%any';
- $any_peer = 1;
- } else {
- $right = $peer;
- }
- $genout .= "\tright=$right\n";
- $genout .= "\trightid=\"$rightid\"\n" if ( defined($rightid) );
- if ($any_peer) {
- $genout .= "\trekey=no\n";
- }
-
- #
- # Write tunnel configuration
- #
- my $leftsubnet = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer $tunKeyword local prefix");
- if ( (defined($leftsubnet) && $leftsubnet eq 'any') || $isVti == 1 ) {
- $leftsubnet = '0.0.0.0/0';
- }
-
- if ( defined($leftsubnet) ) {
- $genout .= "\tleftsubnet=$leftsubnet\n";
- if ( !( $leftsubnet eq '0.0.0.0/0' ) ) {
- my $localsubnet_object = new NetAddr::IP($leftsubnet);
-
- # leftsourceip should now be an IP on system lying within the leftsubnet
- my @system_ips = Vyatta::Misc::getIP( undef, '4' );
- foreach my $system_ip (@system_ips) {
- my $systemip_object = new NetAddr::IP($system_ip);
- if (
- CheckIfAddressInsideNetwork(
- $systemip_object, $localsubnet_object
- )
- )
- {
- my $sourceip = $systemip_object->addr();
- $leftsourceip = "\tleftsourceip=$sourceip\n";
- }
- }
- }
- }
-
- my $remotesubnet = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer $tunKeyword remote prefix");
- if ($isVti) {
- $remotesubnet = 'any';
- }
-
- # Check local and remote prefix protocol consistency
- my $leftsubnet_proto = is_ip_v4_or_v6($leftsubnet);
- my $remotesubnet_proto = is_ip_v4_or_v6($remotesubnet);
- if ( !$isVti && ($leftsubnet_proto != $remotesubnet_proto) ) {
- vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "tunnel", $tunnel],
- "$vpn_cfg_err The 'remote prefix' and 'local prefix' protocols ".
- "do not match");
- }
- # Check remote/local and peer protocol consistency
- # IPv6 over IPv6 scenario is actually supported by StrongS/WAN,
- # we do not allow it in this version because of design and QA issues.
- if (($conn_proto != 6) && ($leftsubnet_proto == 6)) {
- vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "tunnel", $tunnel],
- "$vpn_cfg_err IPv6 over IPv4 IPsec is not supported");
- } elsif (($conn_proto == 6) && ($leftsubnet_proto != 6)) {
- vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "tunnel", $tunnel],
- "$vpn_cfg_err IPv4 over IPv6 IPsec is not supported");
- }
-
- my $rightsubnet;
- my $allow_nat_networks = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer $tunKeyword allow-nat-networks");
- my $allow_public_networks = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer $tunKeyword allow-public-networks");
-
- if ( defined($allow_nat_networks) && $allow_nat_networks eq 'enable' ) {
- if ( defined($remotesubnet) && $remotesubnet ne "" ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],
- "$vpn_cfg_err The 'remote-subnet' has been specified while "
- . "'allow-nat-networks' has been enabled for peer \"$peer\" tunnel "
- . "$tunnel. Both not allowed at once.\n");
- }
+ #
+ # Default keyengine is ikev1
+ #
+ $genout .= "\n";
+ $genout .= "conn %default\n";
+ $genout .= "\tkeyexchange=ikev1\n\n";
- my @allowed_network =
- $vcVPN->listNodes('ipsec nat-networks allowed-network');
- if ( @allowed_network == 0 ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],
- "$vpn_cfg_err While 'allow-nat-networks' has been enabled for peer"
- . " \"$peer\" $tunKeyword, no global allowed NAT networks have"
- . " been configured.\n");
+ #
+ # Connection configurations
+ #
+ my @peers = $vcVPN->listNodes('ipsec site-to-site peer');
+ if (@peers == 0 && !($vcVPN->exists('l2tp')) && !($vcVPN->exists('ipsec profile'))) {
+ print "VPN Warning: IPSec configured but no site-to-site peers or l2tp". " remote-users configured\n";
+ }
+ my $prev_peer = "";
+ vtiIntf::discoverVtiIntfs();
+ foreach my $peer (@peers) {
+ my $peer_ike_group =$vcVPN->returnValue("ipsec site-to-site peer $peer ike-group");
+ if (!defined($peer_ike_group) || $peer_ike_group eq '') {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"ike-group"],"$vpn_cfg_err No IKE group specified for peer \"$peer\".\n");
+ } elsif (!$vcVPN->exists("ipsec ike-group $peer_ike_group")) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"ike-group"],"$vpn_cfg_err The IKE group \"$peer_ike_group\" specified for peer ".
+ "\"$peer\" has not been configured.\n");
}
- $rightsubnet = "vhost:%priv";
- if ( defined($allow_public_networks)
- && $allow_public_networks eq "enable" )
- {
- if ( defined($remotesubnet) && $remotesubnet ne "" ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],
- "$vpn_cfg_err The 'remote-subnet' has been specified while "
- . "'allow-public-networks' has been enabled for peer \"$peer\" "
- . "$tunKeyword. Both not allowed at once.\n");
- }
- $rightsubnet .= ",%no";
- }
- } else {
- $rightsubnet = $remotesubnet;
- if ( defined($rightsubnet) && $rightsubnet eq 'any' ) {
- $rightsubnet = '0.0.0.0/0';
+ my $lip = $vcVPN->returnValue("ipsec site-to-site peer $peer local-address");
+
+ my $peer_proto = ((is_ip_v4_or_v6($peer) && (is_ip_v4_or_v6($peer) == 6))) ? 6 : 4;
+ my $conn_proto = 4;
+
+ # Check peer and local-address consistency
+ if ($peer_proto == 6) {
+ if (defined($lip)) {
+ if (is_ip_v4_or_v6($lip) && (is_ip_v4_or_v6($lip) == 6)) {
+ $conn_proto = 6;
+ } else {
+
+ # Protocols don't match
+ if (isIpAddress($lip)) {
+ vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "local-address"],"$vpn_cfg_err The 'local-address' and peer protocols do not match");
+
+ # %defaultroute for IPv6 IKEv1 is not supported by StrongS/WAN
+ } elsif($lip eq 'any') {
+ vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "local-address"],"$vpn_cfg_err 'any' local address is not supported for IPv6 peers");
+ }
+ }
+ } else {
+ vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer],"$vpn_cfg_err 'local-address' is required for IPv6 peers");
+ }
}
- }
- if ( defined($rightsubnet) ) {
- $genout .= "\trightsubnet=$rightsubnet\n";
-
- # not adding vpn route if remote prefix is 0.0.0.0/0
- # user should add a route [default/static] manually
- $leftsourceip = undef if $rightsubnet eq '0.0.0.0/0';
- if ($rightsubnet =~ /vhost:%priv/) {
- # can't add route when rightsubnet is not specific
- $leftsourceip = undef;
+
+ my $dhcp_iface = $vcVPN->returnValue("ipsec site-to-site peer $peer dhcp-interface");
+ if (defined($lip) && defined($dhcp_iface)){
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer],"$vpn_cfg_err Only one of local-address or dhcp-interface may be defined");
}
- } else {
- $leftsourceip =
- undef; # no need for vpn route if rightsubnet not defined
- }
-
- $genout .= $leftsourceip if defined $leftsourceip;
-
- #
- # Protocol/port
- #
- my $protocol = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer $tunKeyword protocol");
- my $lprotoport = '';
- if (defined($protocol)){
- $lprotoport .= $protocol;
- }
- my $lport = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer $tunKeyword local port");
- if (defined($lport)){
- if (!defined($protocol)){
- $lprotoport .= "0/$lport";
- } elsif (is_tcp_udp($protocol)){
- $lprotoport .= "/$lport";
- } else {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer, "tunnel", $tunnel, "local", "port"],
- "$vpn_cfg_err local port can only be defined when protocol is tcp, udp, or undefined.\n");
- }
- }
- if (not ($lprotoport eq '')){
- $genout .= "\tleftprotoport=$lprotoport\n";
- }
-
- my $rprotoport = '';
- if (defined($protocol)){
- $rprotoport .= $protocol;
- }
- my $rport = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer $tunKeyword remote port");
- if (defined($rport)){
- if (!defined($protocol)){
- $rprotoport .= "0/$rport";
- } elsif (is_tcp_udp($protocol)){
- $rprotoport .= "/$rport";
- } else {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer, "tunnel", $tunnel, "remote", "port"],
- "$vpn_cfg_err remote port can only be defined when protocol is tcp, udp, or undefined.\n");
- }
- }
- if (not ($rprotoport eq '')){
- $genout .= "\trightprotoport=$rprotoport\n";
- }
-
-
- #
- # check if passthrough connection is needed
- # needed when remote-subnet encompasses local-subnet
- #
- if (!$isVti && defined $leftsubnet && defined $rightsubnet) {
- # validate that these values are ipv4net
- my $valid_leftsubnet = 'false';
- my $valid_rightsubnet = 'false';
-
- $valid_leftsubnet = 'true' if validateType( 'ipv4net', $leftsubnet, 'quiet' );
- $valid_rightsubnet = 'true' if validateType( 'ipv4net', $rightsubnet, 'quiet' );
-
- if ($valid_leftsubnet eq 'true' && $valid_rightsubnet eq 'true') {
-
- my $localsubnet_object = new NetAddr::IP($leftsubnet);
- my $remotesubnet_object = new NetAddr::IP($rightsubnet);
- if ($remotesubnet_object == $localsubnet_object) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer],
- "$vpn_cfg_err local prefix and remote prefix cannot be the same.\n");
- }
- if ($remotesubnet_object->contains($localsubnet_object)) {
- $needs_passthrough = 'true';
- }
+ if (defined($dhcp_iface)){
+ $dhcp_if = $dhcp_if + 1;
+ $lip = get_dhcp_addr($dhcp_iface, $peer);
}
- }
-
- #
- # Write IKE configuration from group
- #
- my $ikelifetime = IKELIFETIME_DEFAULT;
- $genout .= "\tike=";
- my $ike_group =
- $vcVPN->returnValue("ipsec site-to-site peer $peer ike-group");
- if ( defined($ike_group) && $ike_group ne '' ) {
- my @ike_proposals =
- $vcVPN->listNodes("ipsec ike-group $ike_group proposal");
-
- my $first_ike_proposal = 1;
- foreach my $ike_proposal (@ike_proposals) {
-
- #
- # Get encryption, hash & Diffie-Hellman key size
- #
- my $encryption = $vcVPN->returnValue(
- "ipsec ike-group $ike_group proposal $ike_proposal encryption");
- my $hash = $vcVPN->returnValue(
- "ipsec ike-group $ike_group proposal $ike_proposal hash");
- my $dh_group = $vcVPN->returnValue(
- "ipsec ike-group $ike_group proposal $ike_proposal dh-group");
-
- #
- # Write separator if not first proposal
- #
- if ($first_ike_proposal) {
- $first_ike_proposal = 0;
- } else {
- $genout .= ",";
- }
-
- #
- # Write values
- #
- if ( defined($encryption) && defined($hash) ) {
- $genout .= "$encryption-$hash";
- if ( defined($dh_group) ) {
- if ( $dh_group eq '2' ) {
- $genout .= '-modp1024';
- } elsif ( $dh_group eq '5' ) {
- $genout .= '-modp1536';
- } elsif ( $dh_group eq '14' ) {
- $genout .= '-modp2048';
- } elsif ( $dh_group eq '15' ) {
- $genout .= '-modp3072';
- } elsif ( $dh_group eq '16' ) {
- $genout .= '-modp4096';
- } elsif ( $dh_group eq '17' ) {
- $genout .= '-modp6144';
- } elsif ( $dh_group eq '18' ) {
- $genout .= '-modp8192';
- } elsif ( $dh_group eq '19' ) {
- $genout .= '-ecp256';
- } elsif ( $dh_group eq '20' ) {
- $genout .= '-ecp384';
- } elsif ( $dh_group eq '21' ) {
- $genout .= '-ecp521';
- } elsif ( $dh_group eq '22' ) {
- $genout .= '-modp1024s160';
- } elsif ( $dh_group eq '23' ) {
- $genout .= '-modp2048s224';
- } elsif ( $dh_group eq '24' ) {
- $genout .= '-modp2048s256';
- } elsif ( $dh_group eq '25' ) {
- $genout .= '-ecp192';
- } elsif ( $dh_group eq '26' ) {
- $genout .= '-ecp224';
- } elsif ( $dh_group ne '' ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],
- "$vpn_cfg_err Invalid 'dh-group' $dh_group specified for "
- . "peer \"$peer\" $tunKeyword. Only 2, 5, or 14 through 26 accepted.\n");
- }
+ my $authid =$vcVPN->returnValue("ipsec site-to-site peer $peer authentication id");
+ my $authremoteid = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication remote-id");
+ if ((!defined($lip) || $lip eq "") && (!defined($dhcp_iface) || $dhcp_iface eq "")) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"local-address"],"$vpn_cfg_err No local-address specified for peer \"$peer\"\n");
+ } elsif ($lip ne 'any') {
+
+ # not 'any' special case.
+ # check interface addresses.
+ if (!Vyatta::Misc::isIPinInterfaces($vc, $lip, @interfaces)) {
+ vpn_log("The local-address $lip of peer \"$peer\" has not been configured in any of the ipsec-interfaces.\n");
+ if (Vyatta::Misc::isClusterIP($vc, $lip)) {
+
+ # Verified that dealing with a cluster IP.
+ $clustering_ip = 1;
+ } elsif (!defined($dhcp_iface)) {
+ print"Warning: Local address $lip specified for peer \"$peer\"\n";
+ print"is not configured on any of the ipsec-interfaces and is not the\n";
+ print "clustering address. IPsec must be re-started after address\n";
+ print "has been configured.\n";
+ print "\n";
+ }
}
- }
}
- $genout .= "!\n";
#
- # Get IKE version setting
+ # Default ESP group
#
- my $key_exchange = $vcVPN->returnValue(
- "ipsec ike-group $ike_group key-exchange");
- if ( defined($key_exchange) ) {
- if ($key_exchange eq 'ikev1') {
- $genout .= "\tkeyexchange=ikev1\n";
- }
- if ($key_exchange eq 'ikev2') {
- $genout .= "\tkeyexchange=ikev2\n";
- }
- }
- else {
- $genout .= "\tkeyexchange=ikev1\n";
+ my $def_esp_group = $vcVPN->returnValue("ipsec site-to-site peer $peer default-esp-group");
+ $def_esp_group = '' if !defined($def_esp_group);
+ if (!$vcVPN->exists("ipsec esp-group $def_esp_group")) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"default-esp-group"],"$vpn_cfg_err The ESP group \"$def_esp_group\" specified ".
+ "for peer \"$peer\" has not been configured.\n");
}
-
+
#
- # Allow the user to disable MOBIKE for IKEv2 connections
+ # Name connection by peer and tunnel
#
- my $mob_ike = $vcVPN->returnValue(
- "ipsec ike-group $ike_group mobike");
-
- if ( defined($mob_ike) ) {
- if ( defined($key_exchange) && $key_exchange eq 'ikev2' ) {
- if ($mob_ike eq 'enable') {
- $genout .= "\tmobike=yes\n";
+ my $isVti = 0;
+ my @tunnels = $vcVPN->listNodes("ipsec site-to-site peer $peer tunnel");
+ if (@tunnels == 0) {
+ #
+ # Check if this is VTI
+ #
+ if ($vcVPN->exists("ipsec site-to-site peer $peer vti")) {
+ $isVti = 1;
+ @tunnels = (@tunnels, "vti");
}
- if ($mob_ike eq 'disable') {
- $genout .= "\tmobike=no\n";
+ if (@tunnels == 0) {
+ vpn_die(["vpn", "ipsec", "site-to-site","peer",$peer,"tunnel"],"$vpn_cfg_err No tunnels configured for peer \"$peer\". At least".
+ " one tunnel required per peer.\n");
+ }
+ } else {
+ #
+ # Check if this is VTI
+ #
+ if ($vcVPN->exists("ipsec site-to-site peer $peer vti")) {
+ vpn_die(["vpn", "ipsec", "site-to-site","peer",$peer,"vti"],"$vpn_cfg_err Both Vti and tunnel(s) configured for peer \"$peer\n");
}
- }
- else {
- vpn_die(["vpn","ipsec","ike-group", $ike_group, "mobike"],
- "$vpn_cfg_err MOBIKE is only valid for IKEv2 configurations.\n");
- }
- }
-
- my $t_ikelifetime =
- $vcVPN->returnValue("ipsec ike-group $ike_group lifetime");
- if ( defined($t_ikelifetime) && $t_ikelifetime ne '' ) {
- $ikelifetime = $t_ikelifetime;
}
- $genout .= "\tikelifetime=$ikelifetime" . "s\n";
- #
- # Check for Dead Peer Detection DPD
- #
- my $dpd_interval = $vcVPN->returnValue(
- "ipsec ike-group $ike_group dead-peer-detection interval");
- my $dpd_timeout = $vcVPN->returnValue(
- "ipsec ike-group $ike_group dead-peer-detection timeout");
- my $dpd_action = $vcVPN->returnValue(
- "ipsec ike-group $ike_group dead-peer-detection action");
- if ( defined($dpd_interval)
- && defined($dpd_timeout)
- && defined($dpd_action) )
- {
- $genout .= "\tdpddelay=$dpd_interval" . "s\n";
- $genout .= "\tdpdtimeout=$dpd_timeout" . "s\n";
- $genout .= "\tdpdaction=$dpd_action\n";
- }
- }
-
- #
- # Write ESP configuration from group
- #
- my $esplifetime = ESPLIFETIME_DEFAULT;
- $genout .= "\tesp=";
- my $esp_group = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer $tunKeyword esp-group");
- if (!defined($esp_group) || $esp_group eq ''){
- $esp_group = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer default-esp-group");
- }
- if ( defined($esp_group) && $esp_group ne '' ) {
- my @esp_proposals =
- $vcVPN->listNodes("ipsec esp-group $esp_group proposal");
- my $first_esp_proposal = 1;
- foreach my $esp_proposal (@esp_proposals) {
-
- #
- # Get encryption, hash
- #
- my $encryption = $vcVPN->returnValue(
- "ipsec esp-group $esp_group proposal $esp_proposal encryption");
- my $hash = $vcVPN->returnValue(
- "ipsec esp-group $esp_group proposal $esp_proposal hash");
-
- #
- # Write separator if not first proposal
- #
- if ($first_esp_proposal) {
- $first_esp_proposal = 0;
- } else {
- $genout .= ",";
- }
-
- #
- # Write values
- #
- if ( defined($encryption) && defined($hash) ) {
- $genout .= "$encryption-$hash";
- }
- }
- $genout .= "!\n";
+ foreach my $tunnel (@tunnels) {
- my $t_esplifetime =
- $vcVPN->returnValue("ipsec esp-group $esp_group lifetime");
- if ( defined($t_esplifetime) && $t_esplifetime ne '' ) {
- $esplifetime = $t_esplifetime;
- }
- $genout .= "\tkeylife=$esplifetime" . "s\n";
+ my $needs_passthrough = 'false';
+ my $tunKeyword;
+ if ($isVti == 1) {
+ $tunKeyword = 'vti';
+ } else {
+ $tunKeyword = 'tunnel '."$tunnel";
+ }
- my $lower_lifetime = $ikelifetime;
- if ( $esplifetime < $ikelifetime ) {
- $lower_lifetime = $esplifetime;
- }
+ #
+ # Add support for tunnel disable.
+ #
+ if ($vcVPN->exists("ipsec site-to-site peer $peer $tunKeyword disable")){
+ next;
+ }
- #
- # The lifetime values need to be greater than:
- # rekeymargin*(100+rekeyfuzz)/100
- #
- my $rekeymargin = REKEYMARGIN_DEFAULT;
- if ( $lower_lifetime <= ( 2 * $rekeymargin ) ) {
- $rekeymargin = int( $lower_lifetime / 2 ) - 1;
- }
- $genout .= "\trekeymargin=$rekeymargin" . "s\n";
+ my $peer_tunnel_esp_group = $vcVPN->returnValue("ipsec site-to-site peer $peer $tunKeyword esp-group");
+ $peer_tunnel_esp_group = '' if (!defined($peer_tunnel_esp_group));
+ if ( (!defined($peer_tunnel_esp_group) || $peer_tunnel_esp_group eq '')
+ &&(!defined($def_esp_group) || $def_esp_group eq ''))
+ {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,$tunKeyword,"esp-group"],"$vpn_cfg_err No ESP group specified for peer \"$peer\" ". "$tunKeyword.\n");
+ } elsif (!$vcVPN->exists("ipsec esp-group $peer_tunnel_esp_group")) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,$tunKeyword,"esp-group"],"$vpn_cfg_err The ESP group \"$peer_tunnel_esp_group\" specified ".
+ "for peer \"$peer\" $tunKeyword has not been configured.\n");
+ }
- #
- # Mode (tunnel or transport)
- #
- my $espmode = $vcVPN->returnValue("ipsec esp-group $esp_group mode");
- if ( !defined($espmode) || $espmode eq '' ) {
- $espmode = "tunnel";
- }
- if ( $espmode eq "transport" ) {
- if ( defined $leftsubnet or defined $rightsubnet ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"$tunKeyword"],
- "$vpn_cfg_err Can not use local-subnet or remote-subnet when "
- . "using transport mode\n");
- }
- if ( $isVti == 1) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"$tunKeyword"],
- "$vpn_cfg_err Can not use transport mode for \"$peer\" with vti\n");
- }
- }
- $genout .= "\ttype=$espmode\n";
+ my $conn_head = "\nconn peer-$peer-tunnel-$tunnel\n";
+ $conn_head =~ s/ peer-@/ peer-/;
+ $genout .= $conn_head;
- #
- # Perfect Forward Secrecy
- #
- my $pfs = $vcVPN->returnValue("ipsec esp-group $esp_group pfs");
- if ( defined($pfs) ) {
- if ( $pfs eq 'enable' ) {
- $genout .= "\tpfs=yes\n";
- } elsif ( $pfs eq 'dh-group2' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=modp1024\n";
- } elsif ( $pfs eq 'dh-group5' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=modp1536\n";
- } elsif ( $pfs eq 'dh-group14' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=modp2048\n";
- } elsif ( $pfs eq 'dh-group15' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=modp3072\n";
- } elsif ( $pfs eq 'dh-group16' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=modp4096\n";
- } elsif ( $pfs eq 'dh-group17' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=modp6144\n";
- } elsif ( $pfs eq 'dh-group18' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=modp8192\n";
- } elsif ( $pfs eq 'dh-group19' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=ecp256\n";
- } elsif ( $pfs eq 'dh-group20' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=ecp384\n";
- } elsif ( $pfs eq 'dh-group21' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=ecp521\n";
- } elsif ( $pfs eq 'dh-group22' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=modp1024s160\n";
- } elsif ( $pfs eq 'dh-group23' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=modp2048s224\n";
- } elsif ( $pfs eq 'dh-group24' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=modp2048s256\n";
- } elsif ( $pfs eq 'dh-group25' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=ecp192\n";
- } elsif ( $pfs eq 'dh-group26' ) {
- $genout .= "\tpfs=yes\n";
- $genout .= "\tpfsgroup=ecp224\n";
- } else {
- $genout .= "\tpfs=no\n";
- }
- }
+ # Support for dhcp-interfaces
+ # The comment dhcp-interface will be used by the dhclient hook to do connection updates.
+ if (defined($dhcp_iface)){
+ $genout .= "\t\#dhcp-interface=$dhcp_iface\n";
+ $lip = get_dhcp_addr($dhcp_iface);
+ }
- #
- # Compression
- #
- my $compression =
- $vcVPN->returnValue("ipsec esp-group $esp_group compression");
- if ( defined($compression) ) {
- if ( $compression eq 'enable' ) {
- $genout .= "\tcompress=yes\n";
- } else {
- $genout .= "\tcompress=no\n";
- }
- }
- }
-
- #
- # Authentication mode
- #
- #
- # Write shared secrets to ipsec.secrets
- #
- my $auth_mode = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer authentication mode");
- if ( !defined($auth_mode) || $auth_mode eq '' ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],
- "$vpn_cfg_err No authentication mode for peer \"$peer\" specified.\n");
- } elsif ( defined($auth_mode) && ( $auth_mode eq 'pre-shared-secret' ) ) {
- my $psk = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer authentication pre-shared-secret");
- my $orig_psk = $vcVPN->returnOrigValue(
- "ipsec site-to-site peer $peer authentication pre-shared-secret");
- $orig_psk = "" if (!defined($orig_psk));
- if ($psk ne $orig_psk && $orig_psk ne ""){
- print "WARNING: The pre-shared-secret will not be updated until the next re-keying interval\n";
- print "To force the key change use: 'reset vpn ipsec-peer'\n";
- }
- if ( !defined($psk) || $psk eq '' ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],
- "$vpn_cfg_err No 'pre-shared-secret' specified for peer \"$peer\""
- . " while 'pre-shared-secret' authentication mode is specified.\n");
- }
+ # -> leftsourceip is the internal source IP to use in a tunnel
+ # -> we use leftsourceip to add a route to the rightsubnet
+ # only when rightsubnet is defined and is not 0.0.0.0/0. we do not
+ # want to add a vpn route for everything i.e. rightsubnet = 0.0.0.0/0
+ # -> if leftsubnet is defined and is not 0.0.0.0/0; we try and find
+ # an interface on the system that has an IP address lying within
+ # the leftsubnet and use that as leftsourceip. if leftsubnet is not
+ # defined or is 0.0.0.0/0 then we use local-address as leftsourceip.
+ my $leftsourceip = undef;
+
+ #
+ # Assign left and right to local and remote interfaces
+ #
+ if (defined($lip)) {
+ if ($lip eq 'any') {
+ if ($isVti) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,$tunKeyword,"local-address"],"$vpn_cfg_err The local interface must be specified ".
+ "for peer \"$peer\" $tunKeyword.\n");
+ }
+ $genout .= "\tleft=%defaultroute\n";
+
+ # no need for leftsourceip as a defaultroute is must for this to work
+ } else {
+ $genout .= "\tleft=$lip\n";
+ $leftsourceip = "\tleftsourceip=$lip\n";
+ }
+ $genout .= "\tleftid=$authid\n" if defined $authid;
+ }
- my $right;
- if ( ( $peer eq 'any' )
- or ( $peer eq '0.0.0.0' )
- or ( $peer =~ /^\@/ ) )
- {
- $right = '%any';
- } else {
- $right = $peer;
- }
- my $index1 = ( defined($authid) ) ? "$authid" : $lip;
- my $index2 = ( defined($authremoteid) ) ? "$authremoteid" : $right;
- if ($lip eq '0.0.0.0'&&!defined($dhcp_iface)) {
- if ($index1 =~ m/^@/) {
- # In main mode PSK, the responder needs to look up the secret
- # before the Peer's ID payload has been decoded, so the ID used
- # will be the IP address. Note that this'll work with aggressive
- # mode PSK but starting VC6, we use strongswan which doesn't
- # support aggressive mode. More info on reported bug :
- # http://bugzilla.vyatta.com/show_bug.cgi?id=5500
- vpn_die(["vpn","ipsec","site-to-site","peer","0.0.0.0","authentication"],
- "$vpn_cfg_err cannot use authentication id with pre-shared-secret"
- . " when local-address is 0.0.0.0\n");
- }
- # when local-address is dynamic then only the following generic form works
- $genout_secrets .= ": PSK \"$psk\"\n";
- } else {
- if (not ($prev_peer eq $peer)){
- if (defined($dhcp_iface) && $lip eq ''){
- $genout_secrets .= "# $right ";
+ # @SM Todo: must have explicit settings for VTI.
+ my $any_peer = 0;
+ my $right;
+ my $rightid = undef;
+ if ($peer =~ /^\@/) {
+
+ # peer is an "ID"
+ $rightid = $peer;
+ $any_peer = 1;
+ } elsif ($authremoteid) {
+ $rightid = $authremoteid;
+ }
+ if ( ($peer eq 'any')
+ or ($peer eq '0.0.0.0')
+ or $any_peer == 1)
+ {
+ if ($isVti) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer],"$vpn_cfg_err The \"$peer\" is invalid ". "ip address must be specified for $tunKeyword.\n");
+ }
+ $right = '%any';
+ $any_peer = 1;
} else {
- $genout_secrets .= "$lip $right ";
+ $right = $peer;
+ }
+ $genout .= "\tright=$right\n";
+ $genout .= "\trightid=\"$rightid\"\n" if (defined($rightid));
+ if ($any_peer) {
+ $genout .= "\trekey=no\n";
+ }
+
+ #
+ # Write tunnel configuration
+ #
+ my $leftsubnet = $vcVPN->returnValue("ipsec site-to-site peer $peer $tunKeyword local prefix");
+ if ((defined($leftsubnet) && $leftsubnet eq 'any') || $isVti == 1) {
+ $leftsubnet = '0.0.0.0/0';
+ }
+
+ if (defined($leftsubnet)) {
+ $genout .= "\tleftsubnet=$leftsubnet\n";
+ if (!($leftsubnet eq '0.0.0.0/0')) {
+ my $localsubnet_object = new NetAddr::IP($leftsubnet);
+
+ # leftsourceip should now be an IP on system lying within the leftsubnet
+ my @system_ips = Vyatta::Misc::getIP(undef, '4');
+ foreach my $system_ip (@system_ips) {
+ my $systemip_object = new NetAddr::IP($system_ip);
+ if (CheckIfAddressInsideNetwork($systemip_object, $localsubnet_object)){
+ my $sourceip = $systemip_object->addr();
+ $leftsourceip = "\tleftsourceip=$sourceip\n";
+ }
+ }
+ }
}
- if ( defined ($authid) ){
- $genout_secrets .= "$authid ";
+
+ my $remotesubnet = $vcVPN->returnValue("ipsec site-to-site peer $peer $tunKeyword remote prefix");
+ if ($isVti) {
+ $remotesubnet = 'any';
}
- if ( defined ($authremoteid) ) {
- $genout_secrets .= "$authremoteid ";
+
+ # Check local and remote prefix protocol consistency
+ my $leftsubnet_proto = is_ip_v4_or_v6($leftsubnet);
+ my $remotesubnet_proto = is_ip_v4_or_v6($remotesubnet);
+ if (!$isVti && ($leftsubnet_proto != $remotesubnet_proto)) {
+ vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "tunnel", $tunnel],"$vpn_cfg_err The 'remote prefix' and 'local prefix' protocols "."do not match");
}
- # tag the secrets lines with 3 entries so the op mode command can
- # deal with them properly. (LEFT means localid, RIGHT means remoteid)
- if ((!defined($authid)) && (defined($authremoteid))) {
- $genout_secrets .= ": PSK \"$psk\" #RIGHT# ";
- } elsif ((defined($authid)) && (!defined($authremoteid))) {
- $genout_secrets .= ": PSK \"$psk\" #LEFT# ";
+
+ # Check remote/local and peer protocol consistency
+ # IPv6 over IPv6 scenario is actually supported by StrongS/WAN,
+ # we do not allow it in this version because of design and QA issues.
+ if (($conn_proto != 6) && ($leftsubnet_proto == 6)) {
+ vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "tunnel", $tunnel],"$vpn_cfg_err IPv6 over IPv4 IPsec is not supported");
+ } elsif (($conn_proto == 6) && ($leftsubnet_proto != 6)) {
+ vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "tunnel", $tunnel],"$vpn_cfg_err IPv4 over IPv6 IPsec is not supported");
+ }
+
+ my $rightsubnet;
+ my $allow_nat_networks = $vcVPN->returnValue("ipsec site-to-site peer $peer $tunKeyword allow-nat-networks");
+ my $allow_public_networks = $vcVPN->returnValue("ipsec site-to-site peer $peer $tunKeyword allow-public-networks");
+
+ if (defined($allow_nat_networks) && $allow_nat_networks eq 'enable') {
+ if (defined($remotesubnet) && $remotesubnet ne "") {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],"$vpn_cfg_err The 'remote-subnet' has been specified while ".
+ "'allow-nat-networks' has been enabled for peer \"$peer\" tunnel ". "$tunnel. Both not allowed at once.\n");
+ }
+
+ my @allowed_network =$vcVPN->listNodes('ipsec nat-networks allowed-network');
+ if (@allowed_network == 0) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],"$vpn_cfg_err While 'allow-nat-networks' has been enabled for peer".
+ " \"$peer\" $tunKeyword, no global allowed NAT networks have". " been configured.\n");
+ }
+
+ $rightsubnet = "vhost:%priv";
+ if (defined($allow_public_networks)
+ && $allow_public_networks eq "enable")
+ {
+ if (defined($remotesubnet) && $remotesubnet ne "") {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],"$vpn_cfg_err The 'remote-subnet' has been specified while ".
+ "'allow-public-networks' has been enabled for peer \"$peer\" ". "$tunKeyword. Both not allowed at once.\n");
+ }
+ $rightsubnet .= ",%no";
+ }
} else {
- $genout_secrets .= ": PSK \"$psk\" ";
+ $rightsubnet = $remotesubnet;
+ if (defined($rightsubnet) && $rightsubnet eq 'any') {
+ $rightsubnet = '0.0.0.0/0';
+ }
}
- if (defined($dhcp_iface)){
- $genout_secrets .= "#dhcp-interface=$dhcp_iface#\n";
+ if (defined($rightsubnet)) {
+ $genout .= "\trightsubnet=$rightsubnet\n";
+
+ # not adding vpn route if remote prefix is 0.0.0.0/0
+ # user should add a route [default/static] manually
+ $leftsourceip = undef if $rightsubnet eq '0.0.0.0/0';
+ if ($rightsubnet =~ /vhost:%priv/) {
+
+ # can't add route when rightsubnet is not specific
+ $leftsourceip = undef;
+ }
} else {
- $genout_secrets .= "\n";
+ $leftsourceip =undef; # no need for vpn route if rightsubnet not defined
}
- }
- $prev_peer = $peer;
- }
- $genout .= "\tauthby=secret\n";
- } elsif ( defined($auth_mode) && $auth_mode eq 'x509') {
- $genout .= get_x509($peer);
- $genout_secrets .= get_x509_secret($peer);
- } elsif ( defined($auth_mode) && $auth_mode eq 'rsa' ) {
-
- unless ( -r $local_key_file ) {
- if ( -e $local_key_file ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],
- "$vpn_cfg_err Invalid local RSA key file path "
- . "\"$local_key_file\". Filesystem read permission absent.\n");
- } else {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],
- "$vpn_cfg_err Invalid local RSA key file path \"$local_key_file\"."
- . " File absent. Use the 'vpn rsa-key generate' command to create.\n");
- }
- }
- $genout .= "\tauthby=rsasig\n";
- my $local_key = rsa_get_local_pubkey($local_key_file);
- if ( !defined($local_key) || $local_key eq "" ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],
- "$vpn_cfg_err Unable to determine local public key from local key"
- . " file \"$local_key_file\" for peer \"$peer\".\n");
- } else {
- $genout .= "\tleftrsasigkey=\"$local_key\"\n";
- }
+ $genout .= $leftsourceip if defined $leftsourceip;
- my $rsa_key_name = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer authentication rsa-key-name");
- if ( !defined($rsa_key_name) || $rsa_key_name eq "" ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication","rsa-key-name"],
- "$vpn_cfg_err No 'rsa-key-name' specified for peer \"$peer\""
- . " while 'rsa' authentication mode is specified.\n");
- } else {
- my $remote_key =
- $vcVPN->returnValue("rsa-keys rsa-key-name $rsa_key_name rsa-key");
- if ( !defined($remote_key) || $remote_key eq "" ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],
- "$vpn_cfg_err No remote key configured for rsa key name "
- . "\"$rsa_key_name\" that is specified for peer \"$peer\".\n");
- } else {
- $genout .= "\trightrsasigkey=\"$remote_key\"\n";
- }
- }
- $genout_secrets .= "include $local_key_file\n";
- } else {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],
- "$vpn_cfg_err Unknown authentication mode \"$auth_mode\" for peer "
- . "\"$peer\" specified.\n");
- }
-
- #
- # Mark setting for vti.
- # and up/down script hook.
- #
- if ($isVti) {
- my $mark = vtiIntf::isVtimarkpresent($peer, $lip);
- if (!defined($mark) || $mark eq '') {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"vti"],
- "$vpn_cfg_err No mark specified for peer \"$peer\" vti\n");
- } else {
- $genout .= "\tmark=$mark\n";
- }
- # up/down script hook.
- my $tunName = $vcVPN->returnValue("ipsec site-to-site peer $peer vti bind");
- if (!defined($tunName)) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"vti","bind"],
- "$vpn_cfg_err No interface bind specified for peer \"$peer\" vti\n");
- }
- $genout .= "\tleftupdown=\"/usr/lib/ipsec/vti-up-down $tunName\"\n";
- }
-
- #
- # Start automatically
- #
- if ($any_peer) {
- $genout .= "\tauto=add\n";
- $genout .= "\tkeyingtries=%forever\n";
- } else {
- my $conntype = $vcVPN->returnValue("ipsec site-to-site peer $peer connection-type");
- if (defined ($conntype)){
- if ($conntype eq "initiate"){
- $genout .= "\tauto=start\n";
- $genout .= "\tkeyingtries=%forever\n";
- } elsif ($conntype eq "respond"){
- $genout .= "\tauto=route\n";
- ## We want to act as a responder. Ideally we do not want to ever
- ## be a initiator, but we can't avoid it if SPD entries are installed
- ## to protect selected traffic from going out unencrypted. The best we
- ## can do is to not try to attempt keying forever.
- $genout .= "\tkeyingtries=1\n";
- }
- }
- else{
- $genout .= "\tauto=start\n";
+ #
+ # Protocol/port
+ #
+ my $protocol = $vcVPN->returnValue("ipsec site-to-site peer $peer $tunKeyword protocol");
+ my $lprotoport = '';
+ if (defined($protocol)){
+ $lprotoport .= $protocol;
+ }
+ my $lport = $vcVPN->returnValue("ipsec site-to-site peer $peer $tunKeyword local port");
+ if (defined($lport)){
+ if (!defined($protocol)){
+ $lprotoport .= "0/$lport";
+ } elsif (is_tcp_udp($protocol)){
+ $lprotoport .= "/$lport";
+ } else {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer, "tunnel", $tunnel, "local", "port"],
+ "$vpn_cfg_err local port can only be defined when protocol is tcp, udp, or undefined.\n");
+ }
+ }
+ if (not($lprotoport eq '')){
+ $genout .= "\tleftprotoport=$lprotoport\n";
+ }
+
+ my $rprotoport = '';
+ if (defined($protocol)){
+ $rprotoport .= $protocol;
+ }
+ my $rport = $vcVPN->returnValue("ipsec site-to-site peer $peer $tunKeyword remote port");
+ if (defined($rport)){
+ if (!defined($protocol)){
+ $rprotoport .= "0/$rport";
+ } elsif (is_tcp_udp($protocol)){
+ $rprotoport .= "/$rport";
+ } else {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer, "tunnel", $tunnel, "remote", "port"],
+ "$vpn_cfg_err remote port can only be defined when protocol is tcp, udp, or undefined.\n");
+ }
+ }
+ if (not($rprotoport eq '')){
+ $genout .= "\trightprotoport=$rprotoport\n";
+ }
+
+ #
+ # check if passthrough connection is needed
+ # needed when remote-subnet encompasses local-subnet
+ #
+ if (!$isVti && defined $leftsubnet && defined $rightsubnet) {
+
+ # validate that these values are ipv4net
+ my $valid_leftsubnet = 'false';
+ my $valid_rightsubnet = 'false';
+
+ $valid_leftsubnet = 'true' if validateType('ipv4net', $leftsubnet, 'quiet');
+ $valid_rightsubnet = 'true' if validateType('ipv4net', $rightsubnet, 'quiet');
+
+ if ($valid_leftsubnet eq 'true' && $valid_rightsubnet eq 'true') {
+
+ my $localsubnet_object = new NetAddr::IP($leftsubnet);
+ my $remotesubnet_object = new NetAddr::IP($rightsubnet);
+ if ($remotesubnet_object == $localsubnet_object) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer],"$vpn_cfg_err local prefix and remote prefix cannot be the same.\n");
+ }
+ if ($remotesubnet_object->contains($localsubnet_object)) {
+ $needs_passthrough = 'true';
+ }
+ }
+ }
+
+ #
+ # Write IKE configuration from group
+ #
+ my $ikelifetime = IKELIFETIME_DEFAULT;
+ $genout .= "\tike=";
+ my $ike_group =$vcVPN->returnValue("ipsec site-to-site peer $peer ike-group");
+ if (defined($ike_group) && $ike_group ne '') {
+ my @ike_proposals =$vcVPN->listNodes("ipsec ike-group $ike_group proposal");
+
+ my $first_ike_proposal = 1;
+ foreach my $ike_proposal (@ike_proposals) {
+
+ #
+ # Get encryption, hash & Diffie-Hellman key size
+ #
+ my $encryption = $vcVPN->returnValue("ipsec ike-group $ike_group proposal $ike_proposal encryption");
+ my $hash = $vcVPN->returnValue("ipsec ike-group $ike_group proposal $ike_proposal hash");
+ my $dh_group = $vcVPN->returnValue("ipsec ike-group $ike_group proposal $ike_proposal dh-group");
+
+ #
+ # Write separator if not first proposal
+ #
+ if ($first_ike_proposal) {
+ $first_ike_proposal = 0;
+ } else {
+ $genout .= ",";
+ }
+
+ #
+ # Write values
+ #
+ if (defined($encryption) && defined($hash)) {
+ $genout .= "$encryption-$hash";
+ if (defined($dh_group)) {
+ if ($dh_group eq '2') {
+ $genout .= '-modp1024';
+ } elsif ($dh_group eq '5') {
+ $genout .= '-modp1536';
+ } elsif ($dh_group eq '14') {
+ $genout .= '-modp2048';
+ } elsif ($dh_group eq '15') {
+ $genout .= '-modp3072';
+ } elsif ($dh_group eq '16') {
+ $genout .= '-modp4096';
+ } elsif ($dh_group eq '17') {
+ $genout .= '-modp6144';
+ } elsif ($dh_group eq '18') {
+ $genout .= '-modp8192';
+ } elsif ($dh_group eq '19') {
+ $genout .= '-ecp256';
+ } elsif ($dh_group eq '20') {
+ $genout .= '-ecp384';
+ } elsif ($dh_group eq '21') {
+ $genout .= '-ecp521';
+ } elsif ($dh_group eq '22') {
+ $genout .= '-modp1024s160';
+ } elsif ($dh_group eq '23') {
+ $genout .= '-modp2048s224';
+ } elsif ($dh_group eq '24') {
+ $genout .= '-modp2048s256';
+ } elsif ($dh_group eq '25') {
+ $genout .= '-ecp192';
+ } elsif ($dh_group eq '26') {
+ $genout .= '-ecp224';
+ } elsif ($dh_group ne '') {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],"$vpn_cfg_err Invalid 'dh-group' $dh_group specified for ".
+ "peer \"$peer\" $tunKeyword. Only 2, 5, or 14 through 26 accepted.\n");
+ }
+ }
+ }
+ }
+ $genout .= "!\n";
+
+ #
+ # Get IKE version setting
+ #
+ my $key_exchange = $vcVPN->returnValue("ipsec ike-group $ike_group key-exchange");
+ if (defined($key_exchange)) {
+ if ($key_exchange eq 'ikev1') {
+ $genout .= "\tkeyexchange=ikev1\n";
+ }
+ if ($key_exchange eq 'ikev2') {
+ $genout .= "\tkeyexchange=ikev2\n";
+ }
+ }else {
+ $genout .= "\tkeyexchange=ikev1\n";
+ }
+
+ #
+ # Allow the user to disable MOBIKE for IKEv2 connections
+ #
+ my $mob_ike = $vcVPN->returnValue("ipsec ike-group $ike_group mobike");
+
+ if (defined($mob_ike)) {
+ if (defined($key_exchange) && $key_exchange eq 'ikev2') {
+ if ($mob_ike eq 'enable') {
+ $genout .= "\tmobike=yes\n";
+ }
+ if ($mob_ike eq 'disable') {
+ $genout .= "\tmobike=no\n";
+ }
+ }else {
+ vpn_die(["vpn","ipsec","ike-group", $ike_group, "mobike"],"$vpn_cfg_err MOBIKE is only valid for IKEv2 configurations.\n");
+ }
+ }
+
+ my $t_ikelifetime =$vcVPN->returnValue("ipsec ike-group $ike_group lifetime");
+ if (defined($t_ikelifetime) && $t_ikelifetime ne '') {
+ $ikelifetime = $t_ikelifetime;
+ }
+ $genout .= "\tikelifetime=$ikelifetime" . "s\n";
+
+ #
+ # Check for Dead Peer Detection DPD
+ #
+ my $dpd_interval = $vcVPN->returnValue("ipsec ike-group $ike_group dead-peer-detection interval");
+ my $dpd_timeout = $vcVPN->returnValue("ipsec ike-group $ike_group dead-peer-detection timeout");
+ my $dpd_action = $vcVPN->returnValue("ipsec ike-group $ike_group dead-peer-detection action");
+ if ( defined($dpd_interval)
+ && defined($dpd_timeout)
+ && defined($dpd_action))
+ {
+ $genout .= "\tdpddelay=$dpd_interval" . "s\n";
+ $genout .= "\tdpdtimeout=$dpd_timeout" . "s\n";
+ $genout .= "\tdpdaction=$dpd_action\n";
+ }
+ }
+
+ #
+ # Write ESP configuration from group
+ #
+ my $esplifetime = ESPLIFETIME_DEFAULT;
+ $genout .= "\tesp=";
+ my $esp_group = $vcVPN->returnValue("ipsec site-to-site peer $peer $tunKeyword esp-group");
+ if (!defined($esp_group) || $esp_group eq ''){
+ $esp_group = $vcVPN->returnValue("ipsec site-to-site peer $peer default-esp-group");
+ }
+ if (defined($esp_group) && $esp_group ne '') {
+ my @esp_proposals =$vcVPN->listNodes("ipsec esp-group $esp_group proposal");
+ my $first_esp_proposal = 1;
+ foreach my $esp_proposal (@esp_proposals) {
+
+ #
+ # Get encryption, hash
+ #
+ my $encryption = $vcVPN->returnValue("ipsec esp-group $esp_group proposal $esp_proposal encryption");
+ my $hash = $vcVPN->returnValue("ipsec esp-group $esp_group proposal $esp_proposal hash");
+
+ #
+ # Write separator if not first proposal
+ #
+ if ($first_esp_proposal) {
+ $first_esp_proposal = 0;
+ } else {
+ $genout .= ",";
+ }
+
+ #
+ # Write values
+ #
+ if (defined($encryption) && defined($hash)) {
+ $genout .= "$encryption-$hash";
+ }
+ }
+ $genout .= "!\n";
+
+ my $t_esplifetime =$vcVPN->returnValue("ipsec esp-group $esp_group lifetime");
+ if (defined($t_esplifetime) && $t_esplifetime ne '') {
+ $esplifetime = $t_esplifetime;
+ }
+ $genout .= "\tkeylife=$esplifetime" . "s\n";
+
+ my $lower_lifetime = $ikelifetime;
+ if ($esplifetime < $ikelifetime) {
+ $lower_lifetime = $esplifetime;
+ }
+
+ #
+ # The lifetime values need to be greater than:
+ # rekeymargin*(100+rekeyfuzz)/100
+ #
+ my $rekeymargin = REKEYMARGIN_DEFAULT;
+ if ($lower_lifetime <= (2 * $rekeymargin)) {
+ $rekeymargin = int($lower_lifetime / 2) - 1;
+ }
+ $genout .= "\trekeymargin=$rekeymargin" . "s\n";
+
+ #
+ # Mode (tunnel or transport)
+ #
+ my $espmode = $vcVPN->returnValue("ipsec esp-group $esp_group mode");
+ if (!defined($espmode) || $espmode eq '') {
+ $espmode = "tunnel";
+ }
+ if ($espmode eq "transport") {
+ if (defined $leftsubnet or defined $rightsubnet) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"$tunKeyword"],"$vpn_cfg_err Can not use local-subnet or remote-subnet when ".
+ "using transport mode\n");
+ }
+ if ($isVti == 1) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"$tunKeyword"],"$vpn_cfg_err Can not use transport mode for \"$peer\" with vti\n");
+ }
+ }
+ $genout .= "\ttype=$espmode\n";
+
+ #
+ # Perfect Forward Secrecy
+ #
+ my $pfs = $vcVPN->returnValue("ipsec esp-group $esp_group pfs");
+ if (defined($pfs)) {
+ if ($pfs eq 'enable') {
+ $genout .= "\tpfs=yes\n";
+ } elsif ($pfs eq 'dh-group2') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=modp1024\n";
+ } elsif ($pfs eq 'dh-group5') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=modp1536\n";
+ } elsif ($pfs eq 'dh-group14') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=modp2048\n";
+ } elsif ($pfs eq 'dh-group15') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=modp3072\n";
+ } elsif ($pfs eq 'dh-group16') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=modp4096\n";
+ } elsif ($pfs eq 'dh-group17') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=modp6144\n";
+ } elsif ($pfs eq 'dh-group18') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=modp8192\n";
+ } elsif ($pfs eq 'dh-group19') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=ecp256\n";
+ } elsif ($pfs eq 'dh-group20') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=ecp384\n";
+ } elsif ($pfs eq 'dh-group21') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=ecp521\n";
+ } elsif ($pfs eq 'dh-group22') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=modp1024s160\n";
+ } elsif ($pfs eq 'dh-group23') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=modp2048s224\n";
+ } elsif ($pfs eq 'dh-group24') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=modp2048s256\n";
+ } elsif ($pfs eq 'dh-group25') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=ecp192\n";
+ } elsif ($pfs eq 'dh-group26') {
+ $genout .= "\tpfs=yes\n";
+ $genout .= "\tpfsgroup=ecp224\n";
+ } else {
+ $genout .= "\tpfs=no\n";
+ }
+ }
+
+ #
+ # Compression
+ #
+ my $compression =$vcVPN->returnValue("ipsec esp-group $esp_group compression");
+ if (defined($compression)) {
+ if ($compression eq 'enable') {
+ $genout .= "\tcompress=yes\n";
+ } else {
+ $genout .= "\tcompress=no\n";
+ }
+ }
+ }
+
+ #
+ # Authentication mode
+ #
+ #
+ # Write shared secrets to ipsec.secrets
+ #
+ my $auth_mode = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication mode");
+ if (!defined($auth_mode) || $auth_mode eq '') {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],"$vpn_cfg_err No authentication mode for peer \"$peer\" specified.\n");
+ } elsif (defined($auth_mode) && ($auth_mode eq 'pre-shared-secret')) {
+ my $psk = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication pre-shared-secret");
+ my $orig_psk = $vcVPN->returnOrigValue("ipsec site-to-site peer $peer authentication pre-shared-secret");
+ $orig_psk = "" if (!defined($orig_psk));
+ if ($psk ne $orig_psk && $orig_psk ne ""){
+ print "WARNING: The pre-shared-secret will not be updated until the next re-keying interval\n";
+ print "To force the key change use: 'reset vpn ipsec-peer'\n";
+ }
+ if (!defined($psk) || $psk eq '') {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],"$vpn_cfg_err No 'pre-shared-secret' specified for peer \"$peer\"".
+ " while 'pre-shared-secret' authentication mode is specified.\n");
+ }
+
+ my $right;
+ if ( ($peer eq 'any')
+ or ($peer eq '0.0.0.0')
+ or ($peer =~ /^\@/))
+ {
+ $right = '%any';
+ } else {
+ $right = $peer;
+ }
+ my $index1 = (defined($authid)) ? "$authid" : $lip;
+ my $index2 = (defined($authremoteid)) ? "$authremoteid" : $right;
+ if ($lip eq '0.0.0.0'&&!defined($dhcp_iface)) {
+ if ($index1 =~ m/^@/) {
+ # In main mode PSK, the responder needs to look up the secret
+ # before the Peer's ID payload has been decoded, so the ID used
+ # will be the IP address. Note that this'll work with aggressive
+ # mode PSK but starting VC6, we use strongswan which doesn't
+ # support aggressive mode. More info on reported bug :
+ # http://bugzilla.vyatta.com/show_bug.cgi?id=5500
+ vpn_die(["vpn","ipsec","site-to-site","peer","0.0.0.0","authentication"],"$vpn_cfg_err cannot use authentication id with pre-shared-secret".
+ " when local-address is 0.0.0.0\n");
+ }
+ # when local-address is dynamic then only the following generic form works
+ $genout_secrets .= ": PSK \"$psk\"\n";
+ } else {
+ if (not($prev_peer eq $peer)){
+ if (defined($dhcp_iface) && $lip eq ''){
+ $genout_secrets .= "# $right ";
+ } else {
+ $genout_secrets .= "$lip $right ";
+ }
+ if (defined($authid)){
+ $genout_secrets .= "$authid ";
+ }
+ if (defined($authremoteid)) {
+ $genout_secrets .= "$authremoteid ";
+ }
+
+ # tag the secrets lines with 3 entries so the op mode command can
+ # deal with them properly. (LEFT means localid, RIGHT means remoteid)
+ if ((!defined($authid)) && (defined($authremoteid))) {
+ $genout_secrets .= ": PSK \"$psk\" #RIGHT# ";
+ } elsif ((defined($authid)) && (!defined($authremoteid))) {
+ $genout_secrets .= ": PSK \"$psk\" #LEFT# ";
+ } else {
+ $genout_secrets .= ": PSK \"$psk\" ";
+ }
+ if (defined($dhcp_iface)){
+ $genout_secrets .= "#dhcp-interface=$dhcp_iface#\n";
+ } else {
+ $genout_secrets .= "\n";
+ }
+ }
+ $prev_peer = $peer;
+ }
+ $genout .= "\tauthby=secret\n";
+ } elsif (defined($auth_mode) && $auth_mode eq 'x509') {
+ $genout .= get_x509($peer);
+ $genout_secrets .= get_x509_secret($peer);
+ } elsif (defined($auth_mode) && $auth_mode eq 'rsa') {
+
+ unless (-r $local_key_file) {
+ if (-e $local_key_file) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],"$vpn_cfg_err Invalid local RSA key file path ".
+ "\"$local_key_file\". Filesystem read permission absent.\n");
+ } else {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],"$vpn_cfg_err Invalid local RSA key file path \"$local_key_file\".".
+ " File absent. Use the 'vpn rsa-key generate' command to create.\n");
+ }
+ }
+
+ $genout .= "\tauthby=rsasig\n";
+ my $local_key = rsa_get_local_pubkey($local_key_file);
+ if (!defined($local_key) || $local_key eq "") {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],"$vpn_cfg_err Unable to determine local public key from local key".
+ " file \"$local_key_file\" for peer \"$peer\".\n");
+ } else {
+ $genout .= "\tleftrsasigkey=\"$local_key\"\n";
+ }
+
+ my $rsa_key_name = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication rsa-key-name");
+ if (!defined($rsa_key_name) || $rsa_key_name eq "") {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication","rsa-key-name"],"$vpn_cfg_err No 'rsa-key-name' specified for peer \"$peer\"".
+ " while 'rsa' authentication mode is specified.\n");
+ } else {
+ my $remote_key =$vcVPN->returnValue("rsa-keys rsa-key-name $rsa_key_name rsa-key");
+ if (!defined($remote_key) || $remote_key eq "") {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],"$vpn_cfg_err No remote key configured for rsa key name ".
+ "\"$rsa_key_name\" that is specified for peer \"$peer\".\n");
+ } else {
+ $genout .= "\trightrsasigkey=\"$remote_key\"\n";
+ }
+ }
+ $genout_secrets .= "include $local_key_file\n";
+ } else {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"authentication"],"$vpn_cfg_err Unknown authentication mode \"$auth_mode\" for peer ".
+ "\"$peer\" specified.\n");
+ }
+
+ #
+ # Mark setting for vti.
+ # and up/down script hook.
+ #
+ if ($isVti) {
+ my $mark = vtiIntf::isVtimarkpresent($peer, $lip);
+ if (!defined($mark) || $mark eq '') {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"vti"],"$vpn_cfg_err No mark specified for peer \"$peer\" vti\n");
+ } else {
+ $genout .= "\tmark=$mark\n";
+ }
+
+ # up/down script hook.
+ my $tunName = $vcVPN->returnValue("ipsec site-to-site peer $peer vti bind");
+ if (!defined($tunName)) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"vti","bind"],"$vpn_cfg_err No interface bind specified for peer \"$peer\" vti\n");
+ }
+ $genout .= "\tleftupdown=\"/usr/lib/ipsec/vti-up-down $tunName\"\n";
+ }
+
+ #
+ # Start automatically
+ #
+ if ($any_peer) {
+ $genout .= "\tauto=add\n";
+ $genout .= "\tkeyingtries=%forever\n";
+ } else {
+ my $conntype = $vcVPN->returnValue("ipsec site-to-site peer $peer connection-type");
+ if (defined($conntype)){
+ if ($conntype eq "initiate"){
+ $genout .= "\tauto=start\n";
+ $genout .= "\tkeyingtries=%forever\n";
+ } elsif ($conntype eq "respond"){
+ $genout .= "\tauto=route\n";
+ ## We want to act as a responder. Ideally we do not want to ever
+ ## be a initiator, but we can't avoid it if SPD entries are installed
+ ## to protect selected traffic from going out unencrypted. The best we
+ ## can do is to not try to attempt keying forever.
+ $genout .= "\tkeyingtries=1\n";
+ }
+ }else{
+ $genout .= "\tauto=start\n";
+ }
+ }
+ $conn_head =~ s/\n//;
+ $genout .= "#$conn_head"; # to identify end of connection definition
+ # used by clear vpn op-mode command
+
+ if ($needs_passthrough eq 'true') {
+
+ # CREATE A PASSTHROUGH CONNECTION
+ my $passthrough_conn_head = "\nconn passthrough-peer-$peer-tunnel-$tunnel\n";
+ $passthrough_conn_head =~ s/ peer-@/ peer-/;
+ $genout .= $passthrough_conn_head;
+ if ($lip eq '0.0.0.0') {
+ $genout .= "\tleft=%defaultroute\n";
+ } else {
+ $genout .= "\tleft=$lip\n";
+ }
+ $genout .= "\tright=$right\n";
+ $genout .= "\tleftsubnet=$leftsubnet\n";
+ $genout .= "\trightsubnet=$leftsubnet\n";
+ $genout .= "\ttype=passthrough\n";
+ $genout .= "\tauthby=never\n";
+ $genout .= "\tauto=route\n";
+ $passthrough_conn_head =~ s/\n//;
+ $genout .= "#$passthrough_conn_head";
+
+ }
}
- }
- $conn_head =~ s/\n//;
- $genout .= "#$conn_head"; # to identify end of connection definition
- # used by clear vpn op-mode command
-
- if ( $needs_passthrough eq 'true' ) {
-
- # CREATE A PASSTHROUGH CONNECTION
- my $passthrough_conn_head = "\nconn passthrough-peer-$peer-tunnel-$tunnel\n";
- $passthrough_conn_head =~ s/ peer-@/ peer-/;
- $genout .= $passthrough_conn_head;
- if ( $lip eq '0.0.0.0' ) {
- $genout .= "\tleft=%defaultroute\n";
- } else {
- $genout .= "\tleft=$lip\n";
- }
- $genout .= "\tright=$right\n";
- $genout .= "\tleftsubnet=$leftsubnet\n";
- $genout .= "\trightsubnet=$leftsubnet\n";
- $genout .= "\ttype=passthrough\n";
- $genout .= "\tauthby=never\n";
- $genout .= "\tauto=route\n";
- $passthrough_conn_head =~ s/\n//;
- $genout .= "#$passthrough_conn_head";
-
- }
}
- }
- if (-e '/etc/dmvpn.conf') {
- $genout .= "\ninclude /etc/dmvpn.conf\n";
- }
- if (-e '/etc/dmvpn.secrets') {
- $genout_secrets .= "\ninclude /etc/dmvpn.secrets\n";
- }
-
+ if (-e '/etc/dmvpn.conf') {
+ $genout .= "\ninclude /etc/dmvpn.conf\n";
+ }
+ if (-e '/etc/dmvpn.secrets') {
+ $genout_secrets .= "\ninclude /etc/dmvpn.secrets\n";
+ }
+
} else {
- #
- # remove any previous config lines, so that when "clear vpn ipsec-process"
- # is called it won't find the vyatta keyword and therefore will not try
- # to start the ipsec process.
- #
- $genout = '';
- $genout .= "# No VPN configuration exists.\n";
- $genout_secrets .= "# No VPN configuration exists.\n";
+ #
+ # remove any previous config lines, so that when "clear vpn ipsec-process"
+ # is called it won't find the vyatta keyword and therefore will not try
+ # to start the ipsec process.
+ #
+ $genout = '';
+ $genout .= "# No VPN configuration exists.\n";
+ $genout_secrets .= "# No VPN configuration exists.\n";
}
-if (
- !(
- defined($config_file)
- && ( $config_file ne '' )
- && defined($secrets_file)
- && ( $secrets_file ne '' )
- )
- )
-{
- print "Regular config file output would be:\n\n$genout\n\n";
- print "Secrets config file output would be:\n\n$genout_secrets\n\n";
- exit(0);
+if (!(defined($config_file)&& ($config_file ne '')&& defined($secrets_file)&& ($secrets_file ne ''))){
+ print "Regular config file output would be:\n\n$genout\n\n";
+ print "Secrets config file output would be:\n\n$genout_secrets\n\n";
+ exit(0);
}
-if ( $vcVPN->isDeleted('.')
+if ( $vcVPN->isDeleted('.')
|| !$vcVPN->exists('.')
|| $vcVPN->isDeleted('ipsec')
- || !$vcVPN->exists('ipsec') )
+ || !$vcVPN->exists('ipsec'))
{
- if ( Vyatta::Misc::isClusterIP( $vc, 'ipsec' ) ) {
- vpn_die(["vpn","ipsec"],
- "VPN commit error. Cluster service is referencing ipsec config.\n");
- }
- if ( is_vpn_running() ) {
- vpn_exec( 'ipsec stop >&/dev/null', 'stop ipsec' );
- }
- if ( !enableICMP('1') ) {
- vpn_die(["vpn","ipsec"],
- "VPN commit error. Unable to re-enable ICMP redirects.\n");
- }
- write_config( $genout, $config_file, $genout_secrets, $secrets_file, $dhcp_if);
+ if (Vyatta::Misc::isClusterIP($vc, 'ipsec')) {
+ vpn_die(["vpn","ipsec"],"VPN commit error. Cluster service is referencing ipsec config.\n");
+ }
+ if (is_vpn_running()) {
+ vpn_exec('ipsec stop >&/dev/null', 'stop ipsec');
+ }
+ if (!enableICMP('1')) {
+ vpn_die(["vpn","ipsec"],"VPN commit error. Unable to re-enable ICMP redirects.\n");
+ }
+ write_config($genout, $config_file, $genout_secrets, $secrets_file, $dhcp_if);
} else {
- if ( !enableICMP('0') ) {
- vpn_die(["vpn","ipsec"],
- "VPN commit error. Unable to disable ICMP redirects.\n");
- }
-
- write_config( $genout, $config_file, $genout_secrets, $secrets_file, $dhcp_if );
-
- # Assumming that if there was a local IP missmatch and clustering is enabled,
- # then the clustering scripts will take care of starting the VPN daemon.
- if ($clustering_ip) {
-
-# If the local-address is provided by clustering, then just write out the configuration,
-# but do not start the VPN daemon
-
- vpn_log(
-"Wrote out configuration to files '$config_file' and '$secrets_file'. VPN/ipsec daemons not started due to clustering.\n"
- );
- print "Clustering configured - not restarting ipsec\n";
- } else {
- my $update_interval = $vcVPN->returnValue("ipsec auto-update");
- my $update_interval_orig = $vcVPN->returnOrigValue("ipsec auto-update");
- $update_interval_orig = 0 if !defined($update_interval_orig);
- if ( is_vpn_running() ) {
- if (defined($update_interval) && ($update_interval != $update_interval_orig)){
- print "Re-starting IPsec daemon to activate new auto-update interval...\n";
- vpn_exec( 'ipsec restart --auto-update '.$update_interval.' >&/dev/null',
- 're-starting ipsec with updated auto-update interval $update_interval' );
- } elsif (!defined($update_interval) && ($update_interval_orig != 0)){
- print "Re-starting IPsec daemon to deactivate auto-update...\n";
- vpn_exec( 'ipsec restart >&/dev/null', 're-starting ipsec' );
- }
- else {
- vpn_exec( 'ipsec rereadall >&/dev/null', 're-read secrets and certs' );
- vpn_exec( 'ipsec update >&/dev/null', 'update changes to ipsec.conf' );
- }
+ if (!enableICMP('0')) {
+ vpn_die(["vpn","ipsec"],"VPN commit error. Unable to disable ICMP redirects.\n");
+ }
+
+ write_config($genout, $config_file, $genout_secrets, $secrets_file, $dhcp_if);
+
+ # Assumming that if there was a local IP missmatch and clustering is enabled,
+ # then the clustering scripts will take care of starting the VPN daemon.
+ if ($clustering_ip) {
+
+ # If the local-address is provided by clustering, then just write out the configuration,
+ # but do not start the VPN daemon
+
+ vpn_log("Wrote out configuration to files '$config_file' and '$secrets_file'. VPN/ipsec daemons not started due to clustering.\n");
+ print "Clustering configured - not restarting ipsec\n";
} else {
- if (! defined($update_interval) ) {
- vpn_exec( 'ipsec start >&/dev/null', 'start ipsec' );
- } else {
- vpn_exec( 'ipsec start --auto-update '.$update_interval.' >&/dev/null',
- 'start ipsec with auto-update $update_interval' );
- }
+ my $update_interval = $vcVPN->returnValue("ipsec auto-update");
+ my $update_interval_orig = $vcVPN->returnOrigValue("ipsec auto-update");
+ $update_interval_orig = 0 if !defined($update_interval_orig);
+ if (is_vpn_running()) {
+ if (defined($update_interval) && ($update_interval != $update_interval_orig)){
+ print "Re-starting IPsec daemon to activate new auto-update interval...\n";
+ vpn_exec('ipsec restart --auto-update '.$update_interval.' >&/dev/null','re-starting ipsec with updated auto-update interval $update_interval');
+ } elsif (!defined($update_interval) && ($update_interval_orig != 0)){
+ print "Re-starting IPsec daemon to deactivate auto-update...\n";
+ vpn_exec('ipsec restart >&/dev/null', 're-starting ipsec');
+ }else {
+ vpn_exec('ipsec rereadall >&/dev/null', 're-read secrets and certs');
+ vpn_exec('ipsec update >&/dev/null', 'update changes to ipsec.conf');
+ }
+ } else {
+ if (!defined($update_interval)) {
+ vpn_exec('ipsec start >&/dev/null', 'start ipsec');
+ } else {
+ vpn_exec('ipsec start --auto-update '.$update_interval.' >&/dev/null','start ipsec with auto-update $update_interval');
+ }
+ }
}
- }
}
-
#
# Return success
#
exit 0;
+
sub vpn_die {
- my (@path,$msg) = @_;
- Vyatta::Config::outputError(@path, $msg);
- exit 1;
+ my (@path,$msg) = @_;
+ Vyatta::Config::outputError(@path, $msg);
+ exit 1;
}
+
sub write_config {
- my ( $genout, $config_file, $genout_secrets, $secrets_file, $dhcp_if ) = @_;
-
- open my $output_config, '>', $config_file
- or die "Can't open $config_file: $!";
- print ${output_config} $genout;
- close $output_config;
-
- my @lines = split("\n", $genout_secrets);
- my @any = grep(/%any/, @lines);
- if (scalar(@any) > 0) {
- my @noany = grep(!/%any/, @lines);
- @lines = (@noany, @any);
- $genout_secrets = join("\n", @lines);
- $genout_secrets .= "\n";
- }
-
- open my $output_secrets, '>', $secrets_file
- or die "Can't open $secrets_file: $!";
- print ${output_secrets} $genout_secrets;
- close $output_secrets;
- dhcp_hook($dhcp_if);
+ my ($genout, $config_file, $genout_secrets, $secrets_file, $dhcp_if) = @_;
+
+ open my $output_config, '>', $config_file
+ or die "Can't open $config_file: $!";
+ print ${output_config} $genout;
+ close $output_config;
+
+ my @lines = split("\n", $genout_secrets);
+ my @any = grep(/%any/, @lines);
+ if (scalar(@any) > 0) {
+ my @noany = grep(!/%any/, @lines);
+ @lines = (@noany, @any);
+ $genout_secrets = join("\n", @lines);
+ $genout_secrets .= "\n";
+ }
+
+ open my $output_secrets, '>', $secrets_file
+ or die "Can't open $secrets_file: $!";
+ print ${output_secrets} $genout_secrets;
+ close $output_secrets;
+ dhcp_hook($dhcp_if);
}
sub vpn_exec {
- my ( $command, $desc ) = @_;
+ my ($command, $desc) = @_;
- open my $logf, '>>', $LOGFILE
- or die "Can't open $LOGFILE: $!";
+ open my $logf, '>>', $LOGFILE
+ or die "Can't open $LOGFILE: $!";
- use POSIX;
- my $timestamp = strftime( "%Y-%m-%d %H:%M.%S", localtime );
+ use POSIX;
+ my $timestamp = strftime("%Y-%m-%d %H:%M.%S", localtime);
- print ${logf} "$timestamp\nExecuting: $command\nDescription: $desc\n";
+ print ${logf} "$timestamp\nExecuting: $command\nDescription: $desc\n";
- my $cmd_out = qx($command);
- my $rval = ( $? >> 8 );
- print ${logf} "Output:\n$cmd_out\n---\n";
- print ${logf} "Return code: $rval\n";
- if ($rval) {
- if ( $command =~ /^ipsec.*--asynchronous$/
- && ( $rval == 104 || $rval == 29 ) )
- {
- print ${logf} "OK when bringing up VPN connection\n";
- } else {
-
- #
- # We use to consider the commit failed if we got a error
- # from the call to ipsec, but this causes the configuration
- # to not get included in the running config. Now that
- # we support dynamic interface/address (e.g. dhcp, pppoe)
- # we want a valid config to get committed even if the
- # interface doesn't exist yet. That way we can use
- # "clear vpn ipsec-process" to bring up the tunnel once
- # the interface is instantiated. For pppoe we will add
- # a script to /etc/ppp/ip-up.d to bring up the vpn
- # tunnel.
- #
- print ${logf}
- "VPN commit error. Unable to $desc, received error code $?\n";
- #
- # code 768 is for a syntax error in the secrets file
- # this happens when a dhcp interface is configured
- # but no address is assigned yet.
- # only the line that has the syntax error is not loaded
- # So we can safely ignore this error since our code generates
- # secrets file.
- #
- if ($? ne '768'){
- print "Warning: unable to [$desc], received error code $?\n";
- print "$cmd_out\n";
- }
+ my $cmd_out = qx($command);
+ my $rval = ($? >> 8);
+ print ${logf} "Output:\n$cmd_out\n---\n";
+ print ${logf} "Return code: $rval\n";
+ if ($rval) {
+ if ($command =~ /^ipsec.*--asynchronous$/
+ && ($rval == 104 || $rval == 29))
+ {
+ print ${logf} "OK when bringing up VPN connection\n";
+ } else {
+ #
+ # We use to consider the commit failed if we got a error
+ # from the call to ipsec, but this causes the configuration
+ # to not get included in the running config. Now that
+ # we support dynamic interface/address (e.g. dhcp, pppoe)
+ # we want a valid config to get committed even if the
+ # interface doesn't exist yet. That way we can use
+ # "clear vpn ipsec-process" to bring up the tunnel once
+ # the interface is instantiated. For pppoe we will add
+ # a script to /etc/ppp/ip-up.d to bring up the vpn
+ # tunnel.
+ #
+ print ${logf}"VPN commit error. Unable to $desc, received error code $?\n";
+ #
+ # code 768 is for a syntax error in the secrets file
+ # this happens when a dhcp interface is configured
+ # but no address is assigned yet.
+ # only the line that has the syntax error is not loaded
+ # So we can safely ignore this error since our code generates
+ # secrets file.
+ #
+ if ($? ne '768'){
+ print "Warning: unable to [$desc], received error code $?\n";
+ print "$cmd_out\n";
+ }
+ }
}
- }
- print ${logf} "---\n\n";
- close $logf;
+ print ${logf} "---\n\n";
+ close $logf;
}
sub vpn_log {
- my ($log) = @_;
+ my ($log) = @_;
- open my $logfile, '>>', $LOGFILE
- or die "Can't open $LOGFILE: $!";
+ open my $logfile, '>>', $LOGFILE
+ or die "Can't open $LOGFILE: $!";
- use POSIX;
- my $timestamp = strftime( "%Y-%m-%d %H:%M.%S", localtime );
+ use POSIX;
+ my $timestamp = strftime("%Y-%m-%d %H:%M.%S", localtime);
- print ${logfile} "$timestamp\n$log\n";
- print ${logfile} "---\n\n";
- close $logfile;
+ print ${logfile} "$timestamp\n$log\n";
+ print ${logfile} "---\n\n";
+ close $logfile;
}
sub printTree {
- my ( $vc, $path, $depth ) = @_;
-
- my @children = $vc->listNodes($path);
- foreach my $child (@children) {
- print ' ' x $depth;
- print $child . "\n";
- printTree( $vc, "$path $child", $depth + 1 );
- }
+ my ($vc, $path, $depth) = @_;
+
+ my @children = $vc->listNodes($path);
+ foreach my $child (@children) {
+ print ' ' x $depth;
+ print $child . "\n";
+ printTree($vc, "$path $child", $depth + 1);
+ }
}
sub printTreeOrig {
- my ( $vc, $path, $depth ) = @_;
-
- my @children = $vc->listOrigNodes($path);
- foreach my $child (@children) {
- print ' ' x $depth;
- print $child . "\n";
- printTreeOrig( $vc, "$path $child", $depth + 1 );
- }
+ my ($vc, $path, $depth) = @_;
+
+ my @children = $vc->listOrigNodes($path);
+ foreach my $child (@children) {
+ print ' ' x $depth;
+ print $child . "\n";
+ printTreeOrig($vc, "$path $child", $depth + 1);
+ }
}
sub hasLocalWildcard {
- my $vc = shift;
- my $orig = shift;
- my @peers = $vc->listNodes('ipsec site-to-site peer');
- if ($orig) {
- @peers = $vc->listOrigNodes('ipsec site-to-site peer');
- }
- return 0 if ( @peers == 0 );
- foreach my $peer (@peers) {
- my $lip = $vcVPN->returnValue("ipsec site-to-site peer $peer local-address");
+ my $vc = shift;
+ my $orig = shift;
+ my @peers = $vc->listNodes('ipsec site-to-site peer');
if ($orig) {
- $lip = $vcVPN->returnOrigValue("ipsec site-to-site peer $peer local-address");
+ @peers = $vc->listOrigNodes('ipsec site-to-site peer');
+ }
+ return 0 if (@peers == 0);
+ foreach my $peer (@peers) {
+ my $lip = $vcVPN->returnValue("ipsec site-to-site peer $peer local-address");
+ if ($orig) {
+ $lip = $vcVPN->returnOrigValue("ipsec site-to-site peer $peer local-address");
+ }
+ return 1 if ($lip && $lip eq '0.0.0.0');
}
- return 1 if ( $lip && $lip eq '0.0.0.0' );
- }
- return 0;
+ return 0;
}
sub CheckIfAddressInsideNetwork {
- my ( $address, $naipNetwork ) = @_;
+ my ($address, $naipNetwork) = @_;
- if ( !defined($address) || !defined($naipNetwork) ) {
- return 0;
- }
+ if (!defined($address) || !defined($naipNetwork)) {
+ return 0;
+ }
- my $naipSM = new NetAddr::IP($address);
- if ( defined($naipSM) ) {
- my $subnetIA = $naipSM->network()->addr();
- my $naipIA = new NetAddr::IP( $subnetIA, $naipSM->masklen() );
+ my $naipSM = new NetAddr::IP($address);
+ if (defined($naipSM)) {
+ my $subnetIA = $naipSM->network()->addr();
+ my $naipIA = new NetAddr::IP($subnetIA, $naipSM->masklen());
- if ( defined($naipIA) && $naipNetwork->within($naipIA) ) {
- return 1;
+ if (defined($naipIA) && $naipNetwork->within($naipIA)) {
+ return 1;
+ }
}
- }
- return 0;
+ return 0;
}
sub get_x509 {
- my $peer = pop(@_);
- # Setup x509, based on the L2TP x509 code
- #
- ## check that proper nodes are defined.
- my $path = "vpn ipsec site-to-site peer $peer authentication x509 ";
- my $cacrt = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 ca-cert-file");
- vpn_die([split(' ', ($path."ca-cert-file"))],
- "$vpn_cfg_err No CA certificate for peer \"$peer\" specified.\n") if !defined($cacrt);
- my $crl = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 crl-file");
- my $crt = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 cert-file");
- vpn_die([split(' ', ($path."cert-file"))],
- "$vpn_cfg_err No Certificate for peer \"$peer\" specified.\n") if !defined($crt);
- my $key = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 key file");
- vpn_die([split(' ', ($path."key-file"))],
- "$vpn_cfg_err No Key for peer \"$peer\" specified.\n") if !defined($key);
-
- # Verify the files exist
- vpn_die([split(' ', ($path."ca-cert-file"))] , "Invalid ca-cert-file \"$cacrt\"")
- if (! -f $cacrt);
- vpn_die([split(' ', ($path."cert-file"))] , "Invalid cert-file \"$crt\"")
- if (! -f $crt);
- vpn_die([split(' ', ($path."key-file"))] , "Invalid key-file \"$key\"" )
- if (! -f $key);
-
-
- # Copy files to the ipsec directory
- system("cp -f $cacrt $CA_CERT_PATH/");
- vpn_die([split(' ', ($path."ca-cert-file"))] , "Cannot copy ca-cert-file \"$cacrt\"")
- if ($? >> 8);
- system("cp -f $crt $SERVER_CERT_PATH/");
- vpn_die([split(' ', ($path."cert-file"))] , "Cannot copy cert-file \"$crt\"")
- if ($? >> 8);
- system("cp -f $key $SERVER_KEY_PATH/");
- vpn_die([split(' ', ($path."key-file"))] , "Cannot copy key-file \"$key\"" )
- if ($? >> 8);
-
- # Handle CRL file if it is defined
- if (defined($crl)) {
- vpn_die([split(' ', ($path."crl-file"))], "Invalid crl-file \"$crl\"")
- if (! -f $crl);
- system("cp -f $crl $CRL_PATH/");
- vpn_die([split(' ', ($path."crl-file"))], "Cannot copy crl-file \"$crl\"")
- if ($? >> 8);
- }
- $crt =~ s/^.*(\/[^\/]+)$/${SERVER_CERT_PATH}$1/;
- my $auth_str = "\tauthby=rsasig\n";
- $auth_str .= "\tleftrsasigkey=%cert\n";
- $auth_str .= "\trightrsasigkey=%cert\n";
- $auth_str .= "\trightca=%same\n";
- $auth_str .= "\tleftcert=$crt\n";
- return $auth_str;
+ my $peer = pop(@_);
+
+ # Setup x509, based on the L2TP x509 code
+ #
+ ## check that proper nodes are defined.
+ my $path = "vpn ipsec site-to-site peer $peer authentication x509 ";
+ my $cacrt = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 ca-cert-file");
+ vpn_die([split(' ', ($path."ca-cert-file"))],"$vpn_cfg_err No CA certificate for peer \"$peer\" specified.\n") if !defined($cacrt);
+ my $crl = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 crl-file");
+ my $crt = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 cert-file");
+ vpn_die([split(' ', ($path."cert-file"))],"$vpn_cfg_err No Certificate for peer \"$peer\" specified.\n") if !defined($crt);
+ my $key = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 key file");
+ vpn_die([split(' ', ($path."key-file"))],"$vpn_cfg_err No Key for peer \"$peer\" specified.\n") if !defined($key);
+
+ # Verify the files exist
+ vpn_die([split(' ', ($path."ca-cert-file"))], "Invalid ca-cert-file \"$cacrt\"")
+ if (!-f $cacrt);
+ vpn_die([split(' ', ($path."cert-file"))], "Invalid cert-file \"$crt\"")
+ if (!-f $crt);
+ vpn_die([split(' ', ($path."key-file"))], "Invalid key-file \"$key\"")
+ if (!-f $key);
+
+ # Copy files to the ipsec directory
+ system("cp -f $cacrt $CA_CERT_PATH/");
+ vpn_die([split(' ', ($path."ca-cert-file"))], "Cannot copy ca-cert-file \"$cacrt\"")
+ if ($? >> 8);
+ system("cp -f $crt $SERVER_CERT_PATH/");
+ vpn_die([split(' ', ($path."cert-file"))], "Cannot copy cert-file \"$crt\"")
+ if ($? >> 8);
+ system("cp -f $key $SERVER_KEY_PATH/");
+ vpn_die([split(' ', ($path."key-file"))], "Cannot copy key-file \"$key\"")
+ if ($? >> 8);
+
+ # Handle CRL file if it is defined
+ if (defined($crl)) {
+ vpn_die([split(' ', ($path."crl-file"))], "Invalid crl-file \"$crl\"")
+ if (!-f $crl);
+ system("cp -f $crl $CRL_PATH/");
+ vpn_die([split(' ', ($path."crl-file"))], "Cannot copy crl-file \"$crl\"")
+ if ($? >> 8);
+ }
+ $crt =~ s/^.*(\/[^\/]+)$/${SERVER_CERT_PATH}$1/;
+ my $auth_str = "\tauthby=rsasig\n";
+ $auth_str .= "\tleftrsasigkey=%cert\n";
+ $auth_str .= "\trightrsasigkey=%cert\n";
+ $auth_str .= "\trightca=%same\n";
+ $auth_str .= "\tleftcert=$crt\n";
+ return $auth_str;
}
sub get_x509_secret {
- my $peer = pop(@_);
- my $key_file = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 key file");
- my $key_pass = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 key password");
- my $pstr = (defined($key_pass) ? " \"$key_pass\"" : '');
- $key_file =~ s/^.*(\/[^\/]+)$/${SERVER_KEY_PATH}$1/;
- my $str = ": RSA ${key_file}$pstr \n";
- return $str;
+ my $peer = pop(@_);
+ my $key_file = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 key file");
+ my $key_pass = $vcVPN->returnValue("ipsec site-to-site peer $peer authentication x509 key password");
+ my $pstr = (defined($key_pass) ? " \"$key_pass\"" : '');
+ $key_file =~ s/^.*(\/[^\/]+)$/${SERVER_KEY_PATH}$1/;
+ my $str = ": RSA ${key_file}$pstr \n";
+ return $str;
}
sub get_dhcp_addr {
- my ($dhcp_iface, $peer) = @_;
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"dhcp-interface"],
- "$vpn_cfg_err The specified interface is not configured for dhcp.")
- if (!(Vyatta::Misc::is_dhcp_enabled($dhcp_iface,0)));
- my @dhcp_addr = Vyatta::Misc::getIP($dhcp_iface,4);
- my $addr = pop(@dhcp_addr);
- if (!defined($addr)){
- $addr = '';
+ my ($dhcp_iface, $peer) = @_;
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"dhcp-interface"],"$vpn_cfg_err The specified interface is not configured for dhcp.")
+ if (!(Vyatta::Misc::is_dhcp_enabled($dhcp_iface,0)));
+ my @dhcp_addr = Vyatta::Misc::getIP($dhcp_iface,4);
+ my $addr = pop(@dhcp_addr);
+ if (!defined($addr)){
+ $addr = '';
+ return $addr;
+ }
+ @dhcp_addr = split(/\//, $addr);
+ $addr = $dhcp_addr[0];
return $addr;
- }
- @dhcp_addr = split(/\//, $addr);
- $addr = $dhcp_addr[0];
- return $addr;
}
sub dhcp_hook {
- my $dhcp_iface = pop(@_);
- my $str = '';
- if ($dhcp_iface > 0){
- $str =<<EOS;
+ my $dhcp_iface = pop(@_);
+ my $str = '';
+ if ($dhcp_iface > 0){
+ $str =<<EOS;
#!/bin/sh
/opt/vyatta/bin/sudo-users/vyatta-ipsec-dhcp.pl --interface=\"\$interface\" --new_ip=\"\$new_ip_address\" --reason=\"\$reason\" --old_ip=\"\$old_ip_address\"
EOS
- }
- my $hook = "/etc/dhcp3/dhclient-exit-hooks.d/ipsecd";
- open my $dhcp_hook, '>', $hook
- or die "cannot open $hook";
- print ${dhcp_hook} $str;
- close $dhcp_hook;
+ }
+ my $hook = "/etc/dhcp3/dhclient-exit-hooks.d/ipsecd";
+ open my $dhcp_hook, '>', $hook
+ or die "cannot open $hook";
+ print ${dhcp_hook} $str;
+ close $dhcp_hook;
}
# end of file