Commit fb5e7863 authored by Franco Fichtner's avatar Franco Fichtner

ipsec: allow tunnel isolation compatibility mode

At least FortiGate doesn't like meshing the phase 2 entries so
instead isolete each phase 2 entry in its own tunnel.  This is
supposedly IKEv1 trickery, but it works...

Also see: https://wiki.strongswan.org/projects/strongswan/wiki/FAQ#Multiple-subnets-per-SA
Also see: https://lists.strongswan.org/pipermail/users/2013-March/004478.html
parent e7140a58
...@@ -1115,7 +1115,6 @@ conn con<<connectionId>> ...@@ -1115,7 +1115,6 @@ conn con<<connectionId>>
installpolicy = yes installpolicy = yes
{$tunneltype} {$tunneltype}
{$dpdline} {$dpdline}
auto = {$conn_auto}
left = {$left_spec} left = {$left_spec}
right = {$right_spec} right = {$right_spec}
leftid = {$myid_data} leftid = {$myid_data}
...@@ -1157,42 +1156,69 @@ EOD; ...@@ -1157,42 +1156,69 @@ EOD;
if (!empty($ealgoAHsp2arr[$idx])) { if (!empty($ealgoAHsp2arr[$idx])) {
$tmpconf .= "\tah = " . join(',', $ealgoAHsp2arr[$idx]) . "!\n"; $tmpconf .= "\tah = " . join(',', $ealgoAHsp2arr[$idx]) . "!\n";
} }
$tmpconf .= "\tauto = {$conn_auto}";
$ipsecconf .= $tmpconf; $ipsecconf .= $tmpconf;
} }
} else { } else {
// mobile and ikev2 // mobile and ikev2
$tmpconf = str_replace('<<connectionId>>', "{$ph1ent['ikeid']}", $connEntry); if (isset($ph1ent['tunnel_isolation'])) {
if (!empty($rightsubnet_spec)) { $ipsecconf .= str_replace('<<connectionId>>', "{$ph1ent['ikeid']}-000", $connEntry);
$tmpconf .= "\trightsubnet = " . join(',', array_unique($rightsubnet_spec)) . "\n"; for ($idx = 0; $idx < count($leftsubnet_spec); ++$idx) {
} // requires leading empty line:
if (!empty($leftsubnet_spec)) { $tmpconf = array('');
$tmpconf .= "\tleftsubnet = " . join(',', array_unique($leftsubnet_spec)) . "\n"; // fix for strongSwan to pick up the correct connection
} // name from the first configured tunnel ($idx == 0):
// merge esp phase 2 arrays. $conn_suffix = $idx ? sprintf('-%03d', $idx) : '';
$esp_content = array(); $tmpconf[] = "conn con{$ph1ent['ikeid']}{$conn_suffix}";
foreach ($ealgoESPsp2arr as $ealgoESPsp2arr_details) { $tmpconf[] = "\trightsubnet = {$rightsubnet_spec[$idx]}";
foreach ($ealgoESPsp2arr_details as $esp_item) { $tmpconf[] = "\tleftsubnet = {$leftsubnet_spec[$idx]}";
if (!in_array($esp_item, $esp_content)) { if (!empty($ealgoESPsp2arr[$idx])) {
$esp_content[] = $esp_item; $tmpconf[] = "\tesp = " . join(',', $ealgoESPsp2arr[$idx]) . '!';
} }
if (!empty($ealgoAHsp2arr[$idx])) {
$tmpconf[] = "\tah = " . join(',', $ealgoAHsp2arr[$idx]) . '!';
}
$tmpconf[] = "\talso = con{$ph1ent['ikeid']}-000";
$tmpconf[] = "\tauto = {$conn_auto}";
// requires trailing empty line:
$tmpconf[] = '';
$ipsecconf .= join("\n", $tmpconf);
} }
} } else {
// merge ah phase 2 arrays. $tmpconf = str_replace('<<connectionId>>', "{$ph1ent['ikeid']}", $connEntry);
$ah_content = array(); if (!empty($rightsubnet_spec)) {
foreach ($ealgoAHsp2arr as $ealgoAHsp2arr_details) { $tmpconf .= "\trightsubnet = " . join(',', array_unique($rightsubnet_spec)) . "\n";
foreach ($ealgoAHsp2arr_details as $ah_item) { }
if (!in_array($ah_item, $ah_content)) { if (!empty($leftsubnet_spec)) {
$ah_content[] = $ah_item; $tmpconf .= "\tleftsubnet = " . join(',', array_unique($leftsubnet_spec)) . "\n";
}
// merge esp phase 2 arrays.
$esp_content = array();
foreach ($ealgoESPsp2arr as $ealgoESPsp2arr_details) {
foreach ($ealgoESPsp2arr_details as $esp_item) {
if (!in_array($esp_item, $esp_content)) {
$esp_content[] = $esp_item;
}
} }
} }
// merge ah phase 2 arrays.
$ah_content = array();
foreach ($ealgoAHsp2arr as $ealgoAHsp2arr_details) {
foreach ($ealgoAHsp2arr_details as $ah_item) {
if (!in_array($ah_item, $ah_content)) {
$ah_content[] = $ah_item;
}
}
}
if (!empty($esp_content)) {
$tmpconf .= "\tesp = " . join(',', $esp_content) . "!\n";
}
if (!empty($ah_content)) {
$tmpconf .= "\tah = " . join(',', $ah_content) . "!\n";
}
$tmpconf .= "\tauto = {$conn_auto}";
$ipsecconf .= $tmpconf;
} }
if (!empty($esp_content)) {
$tmpconf .= "\tesp = " . join(',', $esp_content) . "!\n";
}
if (!empty($ah_content)) {
$tmpconf .= "\tah = " . join(',', $ah_content) . "!\n";
}
$ipsecconf .= $tmpconf;
} }
} }
} }
......
...@@ -87,7 +87,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { ...@@ -87,7 +87,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$phase1_fields = "mode,protocol,myid_type,myid_data,peerid_type,peerid_data $phase1_fields = "mode,protocol,myid_type,myid_data,peerid_type,peerid_data
,encryption-algorithm,hash-algorithm,dhgroup,lifetime,authentication_method,descr,nat_traversal ,encryption-algorithm,hash-algorithm,dhgroup,lifetime,authentication_method,descr,nat_traversal
,interface,iketype,dpd_delay,dpd_maxfail,remote-gateway,pre-shared-key,certref ,interface,iketype,dpd_delay,dpd_maxfail,remote-gateway,pre-shared-key,certref
,caref,reauth_enable,rekey_enable, auto"; ,caref,reauth_enable,rekey_enable,auto,tunnel_isolation";
if (isset($p1index) && isset($config['ipsec']['phase1'][$p1index])) { if (isset($p1index) && isset($config['ipsec']['phase1'][$p1index])) {
// 1-on-1 copy // 1-on-1 copy
foreach (explode(",", $phase1_fields) as $fieldname) { foreach (explode(",", $phase1_fields) as $fieldname) {
...@@ -359,6 +359,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { ...@@ -359,6 +359,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$ph1ent['rekey_enable'] = true; $ph1ent['rekey_enable'] = true;
} }
if (isset($pconfig['tunnel_isolation'])) {
$ph1ent['tunnel_isolation'] = true;
}
if (isset($pconfig['dpd_enable'])) { if (isset($pconfig['dpd_enable'])) {
$ph1ent['dpd_delay'] = $pconfig['dpd_delay']; $ph1ent['dpd_delay'] = $pconfig['dpd_delay'];
$ph1ent['dpd_maxfail'] = $pconfig['dpd_maxfail']; $ph1ent['dpd_maxfail'] = $pconfig['dpd_maxfail'];
...@@ -920,6 +924,15 @@ endforeach; ?> ...@@ -920,6 +924,15 @@ endforeach; ?>
</div> </div>
</td> </td>
</tr> </tr>
<tr>
<td><a id="help_for_tunnel_isolation" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext('Tunnel Isolation') ?></td>
<td>
<input name="tunnel_isolation" type="checkbox" id="tunnel_isolation" value="yes" <?= !empty($pconfig['tunnel_isolation']) ? 'checked="checked"' : '' ?>/>
<div class="hidden" for="help_for_tunnel_isolation">
<?= gettext('This option will create a tunnel for each phase 2 entry for IKEv2 interoperability with e.g. FortiGate devices.') ?>
</div>
</td>
</tr>
<tr> <tr>
<td><a id="help_for_nat_traversal" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("NAT Traversal"); ?></td> <td><a id="help_for_nat_traversal" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("NAT Traversal"); ?></td>
<td> <td>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment