summaryrefslogtreecommitdiffstats
path: root/etc/inc/vpn.inc
diff options
context:
space:
mode:
authorErmal <eri@pfsense.org>2014-08-07 18:51:39 +0000
committerErmal <eri@pfsense.org>2014-08-07 18:53:12 +0000
commit0b5fc1d1a6c515d91df5ec1d848b6bbc1a05186b (patch)
treec826bbf8e6afae9f2e6309e606cfc30f230e9dbc /etc/inc/vpn.inc
parentb31a2c765fcb1042e604cd52908898fa5c0d2321 (diff)
downloadpfsense-0b5fc1d1a6c515d91df5ec1d848b6bbc1a05186b.zip
pfsense-0b5fc1d1a6c515d91df5ec1d848b6bbc1a05186b.tar.gz
Change the logic of the vpn config generation to make connectivity more stable especially ipsec. Also for IKEv1 just generate the policies and only on traffic start them.
Diffstat (limited to 'etc/inc/vpn.inc')
-rw-r--r--etc/inc/vpn.inc327
1 files changed, 166 insertions, 161 deletions
diff --git a/etc/inc/vpn.inc b/etc/inc/vpn.inc
index 39e4333..2e2100b 100644
--- a/etc/inc/vpn.inc
+++ b/etc/inc/vpn.inc
@@ -269,6 +269,9 @@ charon {
# number of worker threads in charon
threads = 16
+ # NOTE: Allows to send multiple subnets for IKEv1
+ cisco_unity = yes
+
# XXX: There is not much choice here really users win their security!
i_dont_care_about_security_and_use_aggressive_mode_psk=yes
@@ -475,10 +478,13 @@ EOD;
}
/* Add user PSKs */
- foreach ($config['system']['user'] as $user) {
- if (!empty($user['ipsecpsk'])) {
- $pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n";
+ if (is_array($config['system']) && is_array($config['system']['user'])) {
+ foreach ($config['system']['user'] as $user) {
+ if (!empty($user['ipsecpsk'])) {
+ $pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n";
+ }
}
+ unset($user);
}
/* add PSKs for mobile clients */
@@ -488,6 +494,7 @@ EOD;
$key['ident'] = '';
$pskconf .= "{$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
}
+ unset($key);
}
@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
@@ -497,182 +504,175 @@ EOD;
$natfilterrules = false;
/* begin ipsec.conf */
$ipsecconf = "";
- if ((is_array($a_phase1) && count($a_phase1)) || (is_array($a_phase2) && count($a_phase2))) {
+ if (is_array($a_phase1) && count($a_phase1)) {
$ipsecconf .= "# This file is automatically generated. Do not edit\n";
- if (is_array($a_phase2) && count($a_phase2)) {
- $ipsecconf .= "config setup\n\tuniqueids = yes\n";
- $ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
+ $ipsecconf .= "config setup\n\tuniqueids = yes\n";
+ $ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
- foreach ($a_phase2 as $ph2ent) {
- $ikeid = $ph2ent['ikeid'];
+ foreach ($a_phase1 as $ph1ent) {
+ if (isset($ph1ent['disabled']))
+ continue;
- $ph1ent = false;
- if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
- continue;
+ if ($ph1ent['mode'] == "aggressive")
+ $aggressive = "yes";
+ else
+ $aggressive = "no";
- if (isset($ph1ent['disabled']))
- continue;
+ $ep = ipsec_get_phase1_src($ph1ent);
+ if (!$ep)
+ continue;
- if (isset($ph2ent['disabled']))
- continue;
+ $keyexchange = "ikev1";
+ if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1") {
+ $keyexchange = "ikev2";
+ $passive = "start";
+ } else
+ $passive = "route";
+
+ if (isset($ph1ent['mobile'])) {
+ $right_spec = "%any";
+ $passive = 'add';
+ } else
+ $right_spec = $ph1ent['remote-gateway'];
+
+ list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
+ list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
+
+ /* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
+ $peerid_spec = '';
+ if (!isset($ph1ent['mobile']))
+ $peerid_spec = $peerid_data;
+
+ if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
+ $ealgosp1 = '';
+ $ealg_id = $ph1ent['encryption-algorithm']['name'];
+ $ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
+ if ($ealg_kl)
+ $ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
+ else
+ $ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
- if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
- continue;
+ $modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
+ if (!empty($modp))
+ $ealgosp1 .= "-{$modp}";
- $ikeid = $ph1ent['ikeid'];
+ if ($keyexchange == "ikev1")
+ $ealgosp1 .= "!";
+ }
- if ($ph1ent['mode'] == "aggressive")
- $aggressive = "yes";
+ if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
+ if ($passive == "start")
+ $dpdline = "dpdaction = restart";
else
- $aggressive = "no";
+ $dpdline = "dpdaction = clear";
+ $dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
+ $dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
+ $dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
+ } else
+ $dpdline = "dpdaction = none";
+
+ $ikelifeline = '';
+ if ($ph1ent['lifetime'])
+ $ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
+
+ $authentication = "";
+ switch ($ph1ent['authentication_method']) {
+ case 'xauth_rsa_server':
+ $authentication = "leftauth = pubkey\n\trightauth = pubkey";
+ $authentication .= "\n\trightauth2 = xauth-generic";
+ break;
+ case 'xauth_psk_server':
+ $authentication = "leftauth = psk\n\trightauth = psk";
+ $authentication .= "\n\trightauth2 = xauth-generic";
+ break;
+ case 'pre_shared_key':
+ $authentication = "leftauth = psk\n\trightauth = psk";
+ break;
+ case 'rsasig':
+ $authentication = "leftauth = pubkey\n\trightauth = pubkey";
+ break;
+ case 'hybrid_rsa_server':
+ $authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
+ $authentication .= "\n\trightauth2 = xauth";
+ break;
+ }
- $ep = ipsec_get_phase1_src($ph1ent);
- if (!$ep)
- continue;
+ $left_spec = $ep;
- $passive = "start";
- if (isset($ph1ent['mobile'])) {
- $rgip = "%any";
- $passive = 'add';
- } else
- $rgip = $ph1ent['remote-gateway'];
-
- $keyexchange = "ikev1";
- if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1") {
- $keyexchange = "ikev2";
- $rekey = "rekey = yes";
- } else {
- $rekey = "rekey = yes";
- }
+ $ipseclifetime = 0;
+ $rightsubnet_spec = array();
+ $leftsubnet_spec = array();
+ $ealgoAHsp2arr = array();
+ $ealgoESPsp2arr = array();
+ if (is_array($a_phase2) && count($a_phase2)) {
+ foreach ($a_phase2 as $ph2ent) {
+ $ikeid = $ph2ent['ikeid'];
+ if ($ikeid != $ph1ent['ikeid'])
+ continue;
- list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
- list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
+ if (isset($ph2ent['disabled']))
+ continue;
- /* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
- $peerid_spec = '';
- if (!isset($ph1ent['mobile']))
- $peerid_spec = $peerid_data;
-
- if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
- $ealgosp1 = '';
- $ealg_id = $ph1ent['encryption-algorithm']['name'];
- $ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
- if ($ealg_kl)
- $ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
- else
- $ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
-
- $modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
- if (!empty($modp))
- $ealgosp1 .= "-{$modp}";
-
- if ($keyexchange == "ikev1")
- $ealgosp1 .= "!";
- }
+ if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
+ continue;
- if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
- if ($passive == "start")
- $dpdline = "dpdaction = restart";
- else
- $dpdline = "dpdaction = clear";
- $dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
- $dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
- $dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
- } else
- $dpdline = "dpdaction = none";
-
- if (!empty($ph1ent['authentication_method']) && (strpos($ph1ent['authentication_method'], "xauth") || strpos($ph1ent['authentication_method'], "hybrid")))
- $xauth = "xauth = server";
-
- $ikelifeline = '';
- if ($ph1ent['lifetime'])
- $ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
-
- $remoteid_spec = '';
if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
$tunneltype = "type = tunnel";
$localid_type = $ph2ent['localid']['type'];
- $localid_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
+ $leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
if (($localid_type == "none" || $localid_type == "mobile")
- && isset($ph1ent['mobile'])
- && (ipsec_get_number_of_phase2($ikeid)==1))
- $localid_spec = "%any";
- else {
+ && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
+ $left_spec = '%any';
+ } else {
if ($localid_type != "address") {
$localid_type = "subnet";
}
// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
- if (!is_ipaddr($localid_data) && !is_subnet($localid_data) && ($localid_data != "0.0.0.0/0")) {
+ if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
continue;
}
- $localid_spec = $ep;
if (!empty($ph2ent['natlocalid'])) {
- $natlocalid_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
+ $natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
if ($ph2ent['natlocalid']['type'] != "address") {
- if (is_subnet($natlocalid_data))
- $localid_data = "{$natlocalid_data}|{$localid_data}";
+ if (is_subnet($natleftsubnet_data))
+ $leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
} else {
- if (is_ipaddr($natlocalid_data))
- $localid_data = "{$natlocalid_data}|{$localid_data}";
+ if (is_ipaddr($natleftsubnet_data))
+ $leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
}
$natfilterrules = true;
}
}
+ $leftsubnet_spec[] = $leftsubnet_data;
+
if (!isset($ph2ent['mobile'])) {
- $remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
- $remoteid_spec = "\trightsubnet = {$remoteid_data}";
+ $rightsubnet_spec[] = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
} else if (!empty($a_client['pool_address']))
- $remoteid_spec = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}";
+ $rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
} else {
$tunneltype = "type = transport";
- $rgip = $ph1ent['remote-gateway'];
if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
- ($ph1ent['authentication_method'] == "pre_shared_key"))
- && isset($ph1ent['mobile']))
- $localid_spec = "%any";
- else {
- $localid_data = ipsec_get_phase1_src($ph1ent);
- $localid_spec = $ep;
- }
- if (!isset($ph2ent['mobile'])) {
- $remoteid_spec = "\trightsubnet = {$rgip}";
+ ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
+ $left_spec = "%any";
+ } else {
+ $leftsubnet_spec[] = ipsec_get_phase1_src($ph1ent);
}
- }
- $authentication = "";
- switch ($ph1ent['authentication_method']) {
- case 'xauth_rsa_server':
- $authentication = "leftauth = pubkey\n\trightauth = pubkey";
- $authentication .= "\n\trightauth2 = xauth-generic";
- break;
- case 'xauth_psk_server':
- $authentication = "leftauth = psk\n\trightauth = psk";
- $authentication .= "\n\trightauth2 = xauth-generic";
- break;
- case 'pre_shared_key':
- $authentication = "leftauth = psk\n\trightauth = psk";
- break;
- case 'rsasig':
- $authentication = "leftauth = pubkey\n\trightauth = pubkey";
- break;
- case 'hybrid_rsa_server':
- $authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
- $authentication .= "\n\trightauth2 = xauth";
- break;
+
+ if (!isset($ph2ent['mobile']))
+ $rightsubnet_spec[] = $right_spec;
}
if (isset($a_client['pfs_group']))
$ph2ent['pfsgroup'] = $a_client['pfs_group'];
- $ealgosp2 = '';
if ($ph2ent['protocol'] == 'esp') {
if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
- $ealgosp2arr = array();
foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
$ealg_id = $ealg['name'];
$ealg_kl = $ealg['keylen'];
@@ -694,7 +694,7 @@ EOD;
$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
if (!empty($modp))
$tmpealgo .= "-{$modp}";
- $ealgosp2arr[] = $tmpealgo;
+ $ealgoESPsp2arr[] = $tmpealgo;
}
}
}
@@ -705,64 +705,69 @@ EOD;
$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
if (!empty($modp))
$tmpealgo .= "-{$modp}";
- $ealgosp2arr[] = $tmpealgo;
+ $ealgoESPsp2arr[] = $tmpealgo;
}
}
}
- $ealgosp2 = "esp = " . join(",", $ealgosp2arr);
- unset($ealgosp2arr);
- $ealgosp2 .= "!";
}
} else if ($ph2ent['protocol'] == 'ah') {
if (is_array($ph2ent['hash-algorithm-option'])) {
- $ealgosp2 = "ah = " . join(",", $ph2ent['hash-algorithm-option']);
- $ealgosp2 = str_replace('hmac_', '', $ealgosp2);
$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
- if (!empty($modp))
- $ealgosp2 .= "-{$modp}";
- $ealgosp2 .= "!";
+ foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
+ $tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
+ if (!empty($modp))
+ $tmpAHalgo = "-{$modp}";
+ $ealgoAHsp2arr[] = $tmpAHalgo;
+ }
}
}
- $ipseclifetime = '';
- if ($ph2ent['lifetime'])
- $ipseclifeline = "lifetime = {$ph2ent['lifetime']}s";
+ if (!empty($ph2ent['lifetime'])) {
+ if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
+ $ipseclifetime = intval($ph2ent['lifetime']);
+ }
+ }
+ }
- $ipsecconf .=<<<EOD
+ $ipsecconf .=<<<EOD
-conn con{$ph1ent['ikeid']}-{$ph2ent['uniqid']}
+conn con{$ph1ent['ikeid']}
aggressive = {$aggressive}
fragmentation = yes
keyexchange = {$keyexchange}
keyingtries = %forever
reauth = yes
- {$rekey}
+ rekey = yes
reqid = {$ikeid}
installpolicy = yes
- {$ikelifeline}
- {$ipseclifeline}
{$tunneltype}
{$dpdline}
auto = {$passive}
- left = {$localid_spec}
- leftsubnet = {$localid_data}
- right = {$rgip}
+ left = {$left_spec}
+ right = {$right_spec}
leftid = {$myid_data}
EOD;
- if (!empty($remoteid_spec))
- $ipsecconf .= "{$remoteid_spec}\n";
- if (!empty($ealgosp1))
- $ipsecconf .= "\t{$ealgosp1}\n";
- if (!empty($ealgosp2))
- $ipsecconf .= "\t{$ealgosp2}\n";
- if (!empty($authentication))
- $ipsecconf .= "\t{$authentication}\n";
- if (!empty($peerid_spec))
- $ipsecconf .= "\trightid = {$peerid_spec}\n";
- }
+ if (!empty($ikelifeline))
+ $ipsecconf .= "\t{$ikelifeline}\n";
+ if ($ipseclifetime > 0)
+ $ipsecconf .= "\tlifetime = {$ipseclifetime}s\n";
+ if (!empty($rightsubnet_spec))
+ $ipsecconf .= "\trightsubnet = " . join(",", $rightsubnet_spec) . "\n";
+ if (!empty($leftsubnet_spec))
+ $ipsecconf .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
+ if (!empty($ealgosp1))
+ $ipsecconf .= "\t{$ealgosp1}\n";
+ if (!empty($ealgoAHsp2arr))
+ $ipsecconf .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
+ if (!empty($ealgoESPsp2arr))
+ $ipsecconf .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
+ if (!empty($authentication))
+ $ipsecconf .= "\t{$authentication}\n";
+ if (!empty($peerid_spec))
+ $ipsecconf .= "\trightid = {$peerid_spec}\n";
}
}
}
OpenPOWER on IntegriCloud