1
|
<?php
|
2
|
/*
|
3
|
* vpn.inc
|
4
|
*
|
5
|
* part of pfSense (https://www.pfsense.org)
|
6
|
* Copyright (c) 2004-2018 Rubicon Communications, LLC (Netgate)
|
7
|
* Copyright (c) 2008 Shrew Soft Inc
|
8
|
* All rights reserved.
|
9
|
*
|
10
|
* originally part of m0n0wall (http://m0n0.ch/wall)
|
11
|
* Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
|
12
|
* All rights reserved.
|
13
|
*
|
14
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
15
|
* you may not use this file except in compliance with the License.
|
16
|
* You may obtain a copy of the License at
|
17
|
*
|
18
|
* http://www.apache.org/licenses/LICENSE-2.0
|
19
|
*
|
20
|
* Unless required by applicable law or agreed to in writing, software
|
21
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
22
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
23
|
* See the License for the specific language governing permissions and
|
24
|
* limitations under the License.
|
25
|
*/
|
26
|
|
27
|
require_once("ipsec.inc");
|
28
|
require_once("filter.inc");
|
29
|
require_once("auth.inc");
|
30
|
|
31
|
function vpn_update_daemon_loglevel($category, $level) {
|
32
|
global $ipsec_log_cats, $ipsec_log_sevs;
|
33
|
|
34
|
if (in_array($category, array_keys($ipsec_log_cats), true) && in_array(intval($level), array_keys($ipsec_log_sevs), true)) {
|
35
|
|
36
|
/* if you're setting to -1, need to add "--" to args */
|
37
|
$argterm = "";
|
38
|
if ($level == "-1") {
|
39
|
$argterm = "--";
|
40
|
}
|
41
|
|
42
|
mwexec("/usr/local/sbin/ipsec stroke loglevel {$category} {$argterm} {$level}");
|
43
|
}
|
44
|
}
|
45
|
|
46
|
function vpn_logging_cfgtxt() {
|
47
|
global $config, $ipsec_log_cats, $ipsec_log_sevs;
|
48
|
|
49
|
$cfgtext = array();
|
50
|
$log_levels = ipsec_get_loglevels();
|
51
|
foreach (array_keys($ipsec_log_cats) as $cat) {
|
52
|
if (is_numeric($log_levels[$cat]) &&
|
53
|
in_array(intval($log_levels[$cat]), array_keys($ipsec_log_sevs), true)) {
|
54
|
$cfgtext[] = "${cat} = {$log_levels[$cat]}";
|
55
|
}
|
56
|
}
|
57
|
|
58
|
return $cfgtext;
|
59
|
}
|
60
|
|
61
|
/* include all configuration functions */
|
62
|
function vpn_ipsec_convert_to_modp($index) {
|
63
|
|
64
|
$conversion = "";
|
65
|
switch ($index) {
|
66
|
case '1':
|
67
|
$conversion = "modp768";
|
68
|
break;
|
69
|
case '2':
|
70
|
$conversion = "modp1024";
|
71
|
break;
|
72
|
case '5':
|
73
|
$conversion = "modp1536";
|
74
|
break;
|
75
|
case '14':
|
76
|
$conversion = "modp2048";
|
77
|
break;
|
78
|
case '15':
|
79
|
$conversion = "modp3072";
|
80
|
break;
|
81
|
case '16':
|
82
|
$conversion = "modp4096";
|
83
|
break;
|
84
|
case '17':
|
85
|
$conversion = "modp6144";
|
86
|
break;
|
87
|
case '18':
|
88
|
$conversion = "modp8192";
|
89
|
break;
|
90
|
case '19':
|
91
|
$conversion = "ecp256";
|
92
|
break;
|
93
|
case '20':
|
94
|
$conversion = "ecp384";
|
95
|
break;
|
96
|
case '21':
|
97
|
$conversion = "ecp521";
|
98
|
break;
|
99
|
case '22':
|
100
|
$conversion = "modp1024s160";
|
101
|
break;
|
102
|
case '23':
|
103
|
$conversion = "modp2048s224";
|
104
|
break;
|
105
|
case '24':
|
106
|
$conversion = "modp2048s256";
|
107
|
break;
|
108
|
case '28':
|
109
|
$conversion = "ecp256bp";
|
110
|
break;
|
111
|
case '29':
|
112
|
$conversion = "ecp384bp";
|
113
|
break;
|
114
|
case '30':
|
115
|
$conversion = "ecp512bp";
|
116
|
break;
|
117
|
}
|
118
|
|
119
|
return $conversion;
|
120
|
}
|
121
|
|
122
|
function vpn_ipsec_configure($restart = false) {
|
123
|
global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
|
124
|
|
125
|
$ipsecstartlock = lock('ipsec', LOCK_EX);
|
126
|
|
127
|
/* get the automatic ping_hosts.sh ready */
|
128
|
unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
|
129
|
touch("{$g['vardb_path']}/ipsecpinghosts");
|
130
|
$ipsecpinghostsactive = false;
|
131
|
|
132
|
/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
|
133
|
filter_configure();
|
134
|
|
135
|
$syscfg = $config['system'];
|
136
|
$ipseccfg = $config['ipsec'];
|
137
|
if (!ipsec_enabled()) {
|
138
|
/* try to stop charon */
|
139
|
mwexec("/usr/local/sbin/ipsec stop");
|
140
|
/* Stop dynamic monitoring */
|
141
|
killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
|
142
|
|
143
|
/* wait for process to die */
|
144
|
sleep(2);
|
145
|
|
146
|
/* IPSEC is off, shutdown enc interface.*/
|
147
|
mwexec("/sbin/ifconfig enc0 down");
|
148
|
|
149
|
unlock($ipsecstartlock);
|
150
|
return 0;
|
151
|
}
|
152
|
|
153
|
$a_phase1 = $config['ipsec']['phase1'];
|
154
|
$a_phase2 = $config['ipsec']['phase2'];
|
155
|
$a_client = $config['ipsec']['client'];
|
156
|
|
157
|
$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
|
158
|
$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
|
159
|
$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
|
160
|
$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
|
161
|
|
162
|
mwexec("/sbin/ifconfig enc0 up");
|
163
|
|
164
|
/* needed for config files */
|
165
|
if (!is_dir("{$g['varetc_path']}/ipsec")) {
|
166
|
mkdir("{$g['varetc_path']}/ipsec");
|
167
|
}
|
168
|
if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
|
169
|
mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
|
170
|
}
|
171
|
// delete these paths first to ensure old CAs, certs and CRLs aren't left behind. redmine #5238
|
172
|
rmdir_recursive($capath);
|
173
|
rmdir_recursive($keypath);
|
174
|
rmdir_recursive($crlpath);
|
175
|
rmdir_recursive($certpath);
|
176
|
if (!is_dir($capath)) {
|
177
|
mkdir($capath);
|
178
|
}
|
179
|
if (!is_dir($keypath)) {
|
180
|
mkdir($keypath);
|
181
|
}
|
182
|
if (!is_dir($crlpath)) {
|
183
|
mkdir($crlpath);
|
184
|
}
|
185
|
if (!is_dir($certpath)) {
|
186
|
mkdir($certpath);
|
187
|
}
|
188
|
if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
|
189
|
mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
|
190
|
}
|
191
|
if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
|
192
|
mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
|
193
|
}
|
194
|
if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
|
195
|
mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
|
196
|
}
|
197
|
if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
|
198
|
mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
|
199
|
}
|
200
|
|
201
|
if (!file_exists("/usr/local/etc/ipsec.d") ||
|
202
|
!is_link("/usr/local/etc/ipsec.d")) {
|
203
|
if (file_exists("/usr/local/etc/ipsec.d")) {
|
204
|
rmdir_recursive("/usr/local/etc/ipsec.d");
|
205
|
}
|
206
|
@symlink("{$g['varetc_path']}/ipsec/ipsec.d",
|
207
|
"/usr/local/etc/ipsec.d");
|
208
|
}
|
209
|
if (!file_exists("{$g['varetc_path']}/etc/strongswan.d") ||
|
210
|
!is_link("{$g['varetc_path']}/etc/strongswan.d")) {
|
211
|
if (is_link("{$g['varetc_path']}/etc/strongswan.d")) {
|
212
|
@unlink("{$g['varetc_path']}/etc/strongswan.d");
|
213
|
} else {
|
214
|
rmdir_recursive("{$g['varetc_path']}/etc/strongswan.d");
|
215
|
}
|
216
|
@symlink("/usr/local/etc/strongswan.d",
|
217
|
"{$g['varetc_path']}/ipsec/strongswan.d");
|
218
|
}
|
219
|
if (!file_exists("/usr/local/etc/strongswan.conf") ||
|
220
|
!is_link("/usr/local/etc/strongswan.conf")) {
|
221
|
@unlink("/usr/local/etc/strongswan.conf");
|
222
|
@symlink("{$g['varetc_path']}/ipsec/strongswan.conf",
|
223
|
"/usr/local/etc/strongswan.conf");
|
224
|
}
|
225
|
if (!file_exists("/usr/local/etc/ipsec.conf") ||
|
226
|
!is_link("/usr/local/etc/ipsec.conf")) {
|
227
|
@unlink("/usr/local/etc/ipsec.conf");
|
228
|
@symlink("{$g['varetc_path']}/ipsec/ipsec.conf",
|
229
|
"/usr/local/etc/ipsec.conf");
|
230
|
}
|
231
|
|
232
|
if (platform_booting()) {
|
233
|
echo gettext("Configuring IPsec VPN... ");
|
234
|
}
|
235
|
|
236
|
/* resolve all local, peer addresses and setup pings */
|
237
|
$ipmap = array();
|
238
|
$rgmap = array();
|
239
|
$filterdns_list = array();
|
240
|
$aggressive_mode_psk = false;
|
241
|
unset($iflist);
|
242
|
$ifacesuse = array();
|
243
|
$mobile_ipsec_auth = "";
|
244
|
if (is_array($a_phase1) && count($a_phase1)) {
|
245
|
|
246
|
$ipsecpinghosts = "";
|
247
|
/* step through each phase1 entry */
|
248
|
foreach ($a_phase1 as $ph1ent) {
|
249
|
if (isset($ph1ent['disabled'])) {
|
250
|
continue;
|
251
|
}
|
252
|
|
253
|
if (substr($ph1ent['interface'], 0, 4) == "_vip") {
|
254
|
$vpninterface = get_configured_vip_interface($ph1ent['interface']);
|
255
|
$ifacesuse[] = get_real_interface($vpninterface);
|
256
|
} else {
|
257
|
$vpninterface = get_failover_interface($ph1ent['interface']);
|
258
|
if (substr($vpninterface, 0, 4) == "_vip") {
|
259
|
$vpninterface = get_configured_vip_interface($vpninterface);
|
260
|
$ifacesuse[] = get_real_interface($vpninterface);
|
261
|
} elseif (!empty($vpninterface)) {
|
262
|
$ifacesuse[] = $vpninterface;
|
263
|
}
|
264
|
}
|
265
|
|
266
|
if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
|
267
|
$aggressive_mode_psk = true;
|
268
|
}
|
269
|
|
270
|
$ikeid = $ph1ent['ikeid'];
|
271
|
|
272
|
$ep = ipsec_get_phase1_src($ph1ent);
|
273
|
/* When automatically guessing, use the first address. */
|
274
|
$ep = explode(',', $ep);
|
275
|
$ep = $ep[0];
|
276
|
if (!is_ipaddr($ep)) {
|
277
|
log_error(sprintf(gettext("IPsec ERROR: Could not find phase 1 source for connection %s. Omitting from configuration file."), $ph1ent['descr']));
|
278
|
continue;
|
279
|
}
|
280
|
|
281
|
if (!in_array($ep, $ipmap)) {
|
282
|
$ipmap[] = $ep;
|
283
|
}
|
284
|
|
285
|
/* see if this tunnel has a hostname for the remote-gateway. If so,
|
286
|
try to resolve it now and add it to the list for filterdns */
|
287
|
|
288
|
if (isset ($ph1ent['mobile'])) {
|
289
|
$mobile_ipsec_auth = $ph1ent['authentication_method'];
|
290
|
continue;
|
291
|
}
|
292
|
|
293
|
$rg = $ph1ent['remote-gateway'];
|
294
|
|
295
|
if (!is_ipaddr($rg)) {
|
296
|
$filterdns_list[] = "{$rg}";
|
297
|
add_hostname_to_watch($rg);
|
298
|
if (!platform_booting()) {
|
299
|
$rg = resolve_retry($rg);
|
300
|
}
|
301
|
if (!is_ipaddr($rg)) {
|
302
|
continue;
|
303
|
}
|
304
|
}
|
305
|
if (array_search($rg, $rgmap)) {
|
306
|
log_error(sprintf(gettext("The remote gateway %s already exists on another phase 1 entry"), $rg));
|
307
|
continue;
|
308
|
}
|
309
|
$rgmap[$ph1ent['remote-gateway']] = $rg;
|
310
|
|
311
|
if (is_array($a_phase2)) {
|
312
|
/* step through each phase2 entry */
|
313
|
foreach ($a_phase2 as $ph2ent) {
|
314
|
if (isset($ph2ent['disabled'])) {
|
315
|
continue;
|
316
|
}
|
317
|
|
318
|
if ($ikeid != $ph2ent['ikeid']) {
|
319
|
continue;
|
320
|
}
|
321
|
|
322
|
/* add an ipsec pinghosts entry */
|
323
|
if ($ph2ent['pinghost']) {
|
324
|
if (!is_array($iflist)) {
|
325
|
$iflist = get_configured_interface_list();
|
326
|
}
|
327
|
$srcip = null;
|
328
|
$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
|
329
|
if (is_ipaddrv6($ph2ent['pinghost'])) {
|
330
|
foreach ($iflist as $ifent => $ifname) {
|
331
|
$interface_ip = get_interface_ipv6($ifent);
|
332
|
if (!is_ipaddrv6($interface_ip)) {
|
333
|
continue;
|
334
|
}
|
335
|
if (ip_in_subnet($interface_ip, $local_subnet)) {
|
336
|
$srcip = $interface_ip;
|
337
|
break;
|
338
|
}
|
339
|
}
|
340
|
} else {
|
341
|
foreach ($iflist as $ifent => $ifname) {
|
342
|
$interface_ip = get_interface_ip($ifent);
|
343
|
if (!is_ipaddrv4($interface_ip)) {
|
344
|
continue;
|
345
|
}
|
346
|
if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
|
347
|
$srcip = $interface_ip;
|
348
|
break;
|
349
|
}
|
350
|
}
|
351
|
}
|
352
|
/* if no valid src IP was found in configured interfaces, try the vips */
|
353
|
if (is_null($srcip)) {
|
354
|
$viplist = get_configured_vip_list();
|
355
|
foreach ($viplist as $vip => $address) {
|
356
|
if (ip_in_subnet($address, $local_subnet)) {
|
357
|
$srcip = $address;
|
358
|
break;
|
359
|
}
|
360
|
}
|
361
|
}
|
362
|
$dstip = $ph2ent['pinghost'];
|
363
|
if (is_ipaddrv6($dstip)) {
|
364
|
$family = "inet6";
|
365
|
} else {
|
366
|
$family = "inet";
|
367
|
}
|
368
|
if (is_ipaddr($srcip)) {
|
369
|
$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
|
370
|
$ipsecpinghostsactive = true;
|
371
|
}
|
372
|
}
|
373
|
}
|
374
|
}
|
375
|
}
|
376
|
@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
|
377
|
unset($ipsecpinghosts);
|
378
|
}
|
379
|
unset($iflist);
|
380
|
|
381
|
$accept_unencrypted = "";
|
382
|
if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
|
383
|
$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
|
384
|
}
|
385
|
|
386
|
$stronconf = '';
|
387
|
if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
|
388
|
$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
|
389
|
}
|
390
|
|
391
|
$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
|
392
|
if ($aggressive_mode_psk) {
|
393
|
log_error("WARNING: Setting i_dont_care_about_security_and_use_aggressive_mode_psk option because a phase 1 is configured using aggressive mode with pre-shared keys. This is not a secure configuration.");
|
394
|
if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
|
395
|
$restart = true;
|
396
|
}
|
397
|
$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
|
398
|
}
|
399
|
|
400
|
$unity_enabled = isset($config['ipsec']['unityplugin']) ? 'yes' : 'no';
|
401
|
|
402
|
$makebeforebreak = '';
|
403
|
if (isset($config['ipsec']['makebeforebreak'])) {
|
404
|
$makebeforebreak = 'make_before_break = yes';
|
405
|
}
|
406
|
|
407
|
if (isset($config['ipsec']['enableinterfacesuse'])) {
|
408
|
if (!empty($ifacesuse)) {
|
409
|
$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
|
410
|
} else {
|
411
|
$ifacesuse = '';
|
412
|
}
|
413
|
} else {
|
414
|
$ifacesuse = '';
|
415
|
}
|
416
|
|
417
|
unset($stronconf);
|
418
|
|
419
|
$strongswanlog = "";
|
420
|
$ipsecloglevels = vpn_logging_cfgtxt();
|
421
|
if (is_array($ipsecloglevels)) {
|
422
|
foreach ($ipsecloglevels as $loglevel) {
|
423
|
$strongswanlog .= "\t\t\t" . $loglevel . "\n";
|
424
|
}
|
425
|
}
|
426
|
$strongswan = <<<EOD
|
427
|
|
428
|
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
|
429
|
starter {
|
430
|
load_warning = no
|
431
|
config_file = {$g['varetc_path']}/ipsec/ipsec.conf
|
432
|
}
|
433
|
|
434
|
charon {
|
435
|
# number of worker threads in charon
|
436
|
threads = 16
|
437
|
ikesa_table_size = 32
|
438
|
ikesa_table_segments = 4
|
439
|
init_limit_half_open = 1000
|
440
|
install_routes = no
|
441
|
load_modular = yes
|
442
|
ignore_acquire_ts = yes
|
443
|
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
|
444
|
{$accept_unencrypted}
|
445
|
cisco_unity = {$unity_enabled}
|
446
|
{$ifacesuse}
|
447
|
{$makebeforebreak}
|
448
|
|
449
|
syslog {
|
450
|
identifier = charon
|
451
|
# log everything under daemon since it ends up in the same place regardless with our syslog.conf
|
452
|
daemon {
|
453
|
ike_name = yes
|
454
|
{$strongswanlog}
|
455
|
}
|
456
|
# disable logging under auth so logs aren't duplicated
|
457
|
auth {
|
458
|
default = -1
|
459
|
}
|
460
|
}
|
461
|
|
462
|
plugins {
|
463
|
# Load defaults
|
464
|
include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
|
465
|
|
466
|
stroke {
|
467
|
secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
|
468
|
}
|
469
|
|
470
|
unity {
|
471
|
load = {$unity_enabled}
|
472
|
}
|
473
|
|
474
|
EOD;
|
475
|
|
476
|
/* Find RADIUS servers designated for Mobile IPsec user auth */
|
477
|
$radius_server_txt = "";
|
478
|
$user_sources = explode(',', $config['ipsec']['client']['user_source']);
|
479
|
foreach ($user_sources as $user_source) {
|
480
|
$auth_server = auth_get_authserver($user_source);
|
481
|
$nice_user_source = strtolower(preg_replace('/\s+/', '_', $user_source));
|
482
|
if ($auth_server && $auth_server['type'] === 'radius') {
|
483
|
$radius_server_txt .= <<<EOD
|
484
|
{$nice_user_source} {
|
485
|
address = {$auth_server['host']}
|
486
|
secret = "{$auth_server['radius_secret']}"
|
487
|
auth_port = {$auth_server['radius_auth_port']}
|
488
|
acct_port = {$auth_server['radius_acct_port']}
|
489
|
}
|
490
|
|
491
|
EOD;
|
492
|
}
|
493
|
}
|
494
|
|
495
|
/* Activate RADIUS accounting if it was selected on the auth server view */
|
496
|
$radius_accounting = "";
|
497
|
if($auth_server && isset($auth_server['radius_acct_port'])){
|
498
|
$radius_accounting = 'accounting = yes';
|
499
|
}
|
500
|
|
501
|
/* write an eap-radius config section if appropriate */
|
502
|
if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) {
|
503
|
$strongswan .= <<<EOD
|
504
|
eap-radius {
|
505
|
class_group = yes
|
506
|
eap_start = no
|
507
|
{$radius_accounting}
|
508
|
servers {
|
509
|
{$radius_server_txt}
|
510
|
}
|
511
|
}
|
512
|
|
513
|
EOD;
|
514
|
}
|
515
|
|
516
|
if (is_array($a_client) && isset($a_client['enable'])) {
|
517
|
$strongswan .= "\t\tattr {\n";
|
518
|
|
519
|
$cfgservers = array();
|
520
|
if (!empty($a_client['dns_server1'])) {
|
521
|
$cfgservers[] = $a_client['dns_server1'];
|
522
|
}
|
523
|
if (!empty($a_client['dns_server2'])) {
|
524
|
$cfgservers[] = $a_client['dns_server2'];
|
525
|
}
|
526
|
if (!empty($a_client['dns_server3'])) {
|
527
|
$cfgservers[] = $a_client['dns_server3'];
|
528
|
}
|
529
|
if (!empty($a_client['dns_server4'])) {
|
530
|
$cfgservers[] = $a_client['dns_server4'];
|
531
|
}
|
532
|
|
533
|
if (!empty($cfgservers)) {
|
534
|
$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
|
535
|
}
|
536
|
unset($cfgservers);
|
537
|
$cfgservers = array();
|
538
|
if (!empty($a_client['wins_server1'])) {
|
539
|
$cfgservers[] = $a_client['wins_server1'];
|
540
|
}
|
541
|
if (!empty($a_client['wins_server2'])) {
|
542
|
$cfgservers[] = $a_client['wins_server2'];
|
543
|
}
|
544
|
if (!empty($cfgservers)) {
|
545
|
$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
|
546
|
}
|
547
|
unset($cfgservers);
|
548
|
|
549
|
if (isset($a_client['net_list']) && is_array($a_phase2)) {
|
550
|
$net_list = '';
|
551
|
foreach ($a_phase2 as $ph2ent) {
|
552
|
if (isset($ph2ent['disabled'])) {
|
553
|
continue;
|
554
|
}
|
555
|
|
556
|
if (!isset($ph2ent['mobile'])) {
|
557
|
continue;
|
558
|
}
|
559
|
|
560
|
$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
|
561
|
|
562
|
if (!empty($net_list)) {
|
563
|
$net_list .= ",";
|
564
|
}
|
565
|
$net_list .= $localid;
|
566
|
}
|
567
|
|
568
|
if (!empty($net_list)) {
|
569
|
$strongswan .= "\t\t\tsubnet = {$net_list}\n";
|
570
|
$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
|
571
|
unset($net_list);
|
572
|
}
|
573
|
}
|
574
|
|
575
|
if (!empty($a_client['dns_domain'])) {
|
576
|
$strongswan .= "\t\t\t# Search domain and default domain\n";
|
577
|
$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
|
578
|
if (empty($a_client['dns_split'])) {
|
579
|
$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
|
580
|
}
|
581
|
$strongswan .= "\n";
|
582
|
}
|
583
|
|
584
|
if (!empty($a_client['dns_split'])) {
|
585
|
$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
|
586
|
}
|
587
|
|
588
|
if (!empty($a_client['login_banner'])) {
|
589
|
$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
|
590
|
}
|
591
|
|
592
|
if (isset($a_client['save_passwd'])) {
|
593
|
$strongswan .= "\t\t\t28673 = 1\n";
|
594
|
}
|
595
|
|
596
|
if ($a_client['pfs_group']) {
|
597
|
$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
|
598
|
}
|
599
|
$strongswan .= "\t\t}\n";
|
600
|
|
601
|
if ($a_client['user_source'] != "none") {
|
602
|
$strongswan .= "\t\txauth-generic {\n";
|
603
|
$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
|
604
|
$strongswan .= "\t\t\tauthcfg = ";
|
605
|
$firstsed = 0;
|
606
|
$authcfgs = explode(",", $a_client['user_source']);
|
607
|
foreach ($authcfgs as $authcfg) {
|
608
|
if ($firstsed > 0) {
|
609
|
$strongswan .= ",";
|
610
|
}
|
611
|
if ($authcfg == "system") {
|
612
|
$authcfg = "Local Database";
|
613
|
}
|
614
|
$strongswan .= $authcfg;
|
615
|
$firstsed = 1;
|
616
|
}
|
617
|
$strongswan .= "\n";
|
618
|
$strongswan .= "\t\t}\n";
|
619
|
}
|
620
|
}
|
621
|
|
622
|
$strongswan .= "\n\t}\n}\n";
|
623
|
@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
|
624
|
unset($strongswan);
|
625
|
|
626
|
/* write out CRL files */
|
627
|
if (is_array($config['crl']) && count($config['crl'])) {
|
628
|
foreach ($config['crl'] as $crl) {
|
629
|
if (!isset($crl['text'])) {
|
630
|
log_error(sprintf(gettext("Warning: Missing CRL data for %s"), $crl['descr']));
|
631
|
continue;
|
632
|
}
|
633
|
$fpath = "{$crlpath}/{$crl['refid']}.crl";
|
634
|
if (!@file_put_contents($fpath, base64_decode($crl['text']))) {
|
635
|
log_error(sprintf(gettext("Error: Cannot write IPsec CRL file for %s"), $crl['descr']));
|
636
|
continue;
|
637
|
}
|
638
|
}
|
639
|
}
|
640
|
|
641
|
$pskconf = "";
|
642
|
|
643
|
$vpncas = array();
|
644
|
if (is_array($a_phase1) && count($a_phase1)) {
|
645
|
foreach ($a_phase1 as $ph1ent) {
|
646
|
|
647
|
if (isset($ph1ent['disabled'])) {
|
648
|
continue;
|
649
|
}
|
650
|
|
651
|
if (strstr($ph1ent['authentication_method'], 'rsa') ||
|
652
|
in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
|
653
|
$certline = '';
|
654
|
|
655
|
$ikeid = $ph1ent['ikeid'];
|
656
|
$cert = lookup_cert($ph1ent['certref']);
|
657
|
|
658
|
if (!$cert) {
|
659
|
log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
|
660
|
continue;
|
661
|
}
|
662
|
|
663
|
/* add signing CA cert chain of server cert
|
664
|
* to the list of CAs to write
|
665
|
*/
|
666
|
$cachain = ca_chain_array($cert);
|
667
|
if ($cachain && is_array($cachain)) {
|
668
|
foreach ($cachain as $cacrt) {
|
669
|
$vpncas[$cacrt['refid']] = $cacrt;
|
670
|
}
|
671
|
}
|
672
|
|
673
|
@chmod($certpath, 0600);
|
674
|
|
675
|
$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
|
676
|
if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
|
677
|
log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
|
678
|
continue;
|
679
|
}
|
680
|
@chmod($ph1keyfile, 0600);
|
681
|
|
682
|
$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
|
683
|
if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
|
684
|
log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
|
685
|
@unlink($ph1keyfile);
|
686
|
continue;
|
687
|
}
|
688
|
@chmod($ph1certfile, 0600);
|
689
|
|
690
|
/* XXX" Traffic selectors? */
|
691
|
$pskconf .= " : RSA {$ph1keyfile}\n";
|
692
|
} else {
|
693
|
list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
|
694
|
list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
|
695
|
|
696
|
$myid = trim($myid_data);
|
697
|
|
698
|
if (empty($peerid_data)) {
|
699
|
continue;
|
700
|
}
|
701
|
|
702
|
if ($myid_type == 'fqdn' && !empty($myid)) {
|
703
|
$myid = "@{$myid}";
|
704
|
}
|
705
|
|
706
|
$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
|
707
|
|
708
|
$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
|
709
|
|
710
|
if ($peerid_type == 'fqdn' && !empty($peerid)) {
|
711
|
$peerid = "@{$peerid}";
|
712
|
}
|
713
|
|
714
|
if (!empty($ph1ent['pre-shared-key'])) {
|
715
|
$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
|
716
|
if (isset($ph1ent['mobile'])) {
|
717
|
$pskconf .= "{$myid} %any : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
|
718
|
$pskconf .= " : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
|
719
|
}
|
720
|
}
|
721
|
}
|
722
|
|
723
|
/* if the client authenticates with a cert add the
|
724
|
* client cert CA chain to the list of CAs to write
|
725
|
*/
|
726
|
if (in_array($ph1ent['authentication_method'],
|
727
|
array('rsasig', 'eap-tls', 'xauth_rsa_server'))) {
|
728
|
|
729
|
if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
|
730
|
$thisca = lookup_ca($ph1ent['caref']);
|
731
|
$vpncas[$ph1ent['caref']] = $thisca;
|
732
|
|
733
|
/* follow chain up to root */
|
734
|
$cachain = ca_chain_array($thisca);
|
735
|
if ($cachain and is_array($cachain)) {
|
736
|
foreach ($cachain as $cacrt) {
|
737
|
$vpncas[$cacrt['refid']] = $cacrt;
|
738
|
}
|
739
|
}
|
740
|
}
|
741
|
}
|
742
|
}
|
743
|
}
|
744
|
|
745
|
/* write the required CAs */
|
746
|
foreach ($vpncas as $carefid => $cadata) {
|
747
|
$cacrt = base64_decode($cadata['crt']);
|
748
|
$cacrtattrs = openssl_x509_parse($cacrt);
|
749
|
if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) {
|
750
|
log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr']));
|
751
|
continue;
|
752
|
}
|
753
|
$cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt";
|
754
|
if (!@file_put_contents($cafilename, $cacrt)) {
|
755
|
log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr']));
|
756
|
continue;
|
757
|
}
|
758
|
}
|
759
|
|
760
|
/* Add user PSKs */
|
761
|
if (is_array($config['system']) && is_array($config['system']['user'])) {
|
762
|
foreach ($config['system']['user'] as $user) {
|
763
|
if (!empty($user['ipsecpsk'])) {
|
764
|
$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
|
765
|
}
|
766
|
}
|
767
|
unset($user);
|
768
|
}
|
769
|
|
770
|
/* add PSKs for mobile clients */
|
771
|
if (is_array($ipseccfg['mobilekey'])) {
|
772
|
foreach ($ipseccfg['mobilekey'] as $key) {
|
773
|
if ($key['ident'] == "allusers") {
|
774
|
$key['ident'] = '%any';
|
775
|
}
|
776
|
if ($key['ident'] == "any") {
|
777
|
$key['ident'] = '%any';
|
778
|
}
|
779
|
if (empty($key['type'])) {
|
780
|
$key['type'] = 'PSK';
|
781
|
}
|
782
|
$pskconf .= " {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
|
783
|
}
|
784
|
unset($key);
|
785
|
}
|
786
|
|
787
|
@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
|
788
|
chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
|
789
|
unset($pskconf);
|
790
|
|
791
|
$uniqueids = 'yes';
|
792
|
if (!empty($config['ipsec']['uniqueids'])) {
|
793
|
if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
|
794
|
$uniqueids = $config['ipsec']['uniqueids'];
|
795
|
}
|
796
|
}
|
797
|
$natfilterrules = false;
|
798
|
/* begin ipsec.conf */
|
799
|
$ipsecconf = "";
|
800
|
$enablecompression = false;
|
801
|
if (is_array($a_phase1) && count($a_phase1)) {
|
802
|
|
803
|
$ipsecconf .= "# This file is automatically generated. Do not edit\n";
|
804
|
$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
|
805
|
|
806
|
if (isset($config['ipsec']['strictcrlpolicy'])) {
|
807
|
$ipsecconf .= "\tstrictcrlpolicy = yes \n";
|
808
|
}
|
809
|
|
810
|
if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
|
811
|
$bypassnets = array();
|
812
|
if ($config['interfaces']['lan']) {
|
813
|
$lanip = get_interface_ip("lan");
|
814
|
if (!empty($lanip) && is_ipaddrv4($lanip)) {
|
815
|
$lansn = get_interface_subnet("lan");
|
816
|
$lansa = gen_subnetv4($lanip, $lansn);
|
817
|
if (!empty($lansa) && !empty($lansn)) {
|
818
|
$bypassnets[] = "{$lansa}/{$lansn}";
|
819
|
}
|
820
|
}
|
821
|
$lanip6 = get_interface_ipv6("lan");
|
822
|
if (!empty($lanip6) && is_ipaddrv6($lanip6)) {
|
823
|
$lansn6 = get_interface_subnetv6("lan");
|
824
|
$lansa6 = gen_subnetv6($lanip6, $lansn6);
|
825
|
if (!empty($lansa6) && !empty($lansn6)) {
|
826
|
$bypassnets[] = "{$lansa6}/{$lansn6}";
|
827
|
}
|
828
|
}
|
829
|
}
|
830
|
if (!empty($bypassnets)) {
|
831
|
$bypass = implode(',', $bypassnets);
|
832
|
$ipsecconf .= <<<EOD
|
833
|
|
834
|
conn bypasslan
|
835
|
leftsubnet = {$bypass}
|
836
|
rightsubnet = {$bypass}
|
837
|
authby = never
|
838
|
type = passthrough
|
839
|
auto = route
|
840
|
|
841
|
EOD;
|
842
|
}
|
843
|
}
|
844
|
|
845
|
foreach ($a_phase1 as $ph1ent) {
|
846
|
if (isset($ph1ent['disabled'])) {
|
847
|
continue;
|
848
|
}
|
849
|
|
850
|
if ($ph1ent['mode'] == "aggressive") {
|
851
|
$aggressive = "yes";
|
852
|
} else {
|
853
|
$aggressive = "no";
|
854
|
}
|
855
|
|
856
|
$ep = ipsec_get_phase1_src($ph1ent);
|
857
|
if (!$ep) {
|
858
|
continue;
|
859
|
}
|
860
|
|
861
|
$ikeid = $ph1ent['ikeid'];
|
862
|
$keyexchange = "ikev1";
|
863
|
$passive = "route";
|
864
|
if (!empty($ph1ent['iketype'])) {
|
865
|
if ($ph1ent['iketype'] == "ikev2") {
|
866
|
$keyexchange = "ikev2";
|
867
|
} elseif ($ph1ent['iketype'] == "auto") {
|
868
|
$keyexchange = "ike";
|
869
|
}
|
870
|
}
|
871
|
|
872
|
if (isset($ph1ent['mobile'])) {
|
873
|
$right_spec = "%any";
|
874
|
$passive = 'add';
|
875
|
} else {
|
876
|
if (isset($ph1ent['responderonly'])) {
|
877
|
$passive = 'add';
|
878
|
}
|
879
|
|
880
|
$right_spec = $ph1ent['remote-gateway'];
|
881
|
if (is_ipaddr($right_spec)) {
|
882
|
$sourcehost = $right_spec;
|
883
|
} else {
|
884
|
$sourcehost = $rgmap[$right_spec];
|
885
|
}
|
886
|
|
887
|
if (substr($ph1ent['interface'], 0, 4) == "_vip") {
|
888
|
$vpninterface = get_configured_vip_interface($ph1ent['interface']);
|
889
|
if (substr($vpninterface, 0, 4) == "_vip") {
|
890
|
// vips are nested if its a ipalias with a carp parent
|
891
|
$vpninterface = get_configured_vip_interface($vpninterface);
|
892
|
}
|
893
|
$ifacesuse = get_real_interface($vpninterface);
|
894
|
} else {
|
895
|
$ifacesuse = get_failover_interface($ph1ent['interface']);
|
896
|
if (substr($ifacesuse, 0, 4) == "_vip") {
|
897
|
$vpninterface = get_configured_vip_interface($ifacesuse);
|
898
|
$ifacesuse = get_real_interface($vpninterface);
|
899
|
} else {
|
900
|
$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
|
901
|
}
|
902
|
}
|
903
|
if ($ph1ent['protocol'] == 'inet') {
|
904
|
if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
|
905
|
$gatewayip = get_interface_gateway($vpninterface);
|
906
|
$interfaceip = get_interface_ip($vpninterface);
|
907
|
$subnet_bits = get_interface_subnet($vpninterface);
|
908
|
$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
|
909
|
/* if the remote gateway is in the local subnet, then don't add a route */
|
910
|
if (is_ipaddrv4($sourcehost) &&
|
911
|
!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
|
912
|
if (is_ipaddrv4($gatewayip)) {
|
913
|
// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
|
914
|
route_add_or_change("-host {$sourcehost} {$gatewayip}");
|
915
|
}
|
916
|
}
|
917
|
}
|
918
|
} else if ($ph1ent['protocol'] == 'inet6') {
|
919
|
if (!empty($ifacesuse) && interface_has_gatewayv6($vpninterface)) {
|
920
|
$gatewayip = get_interface_gateway_v6($vpninterface);
|
921
|
$interfaceip = get_interface_ipv6($vpninterface);
|
922
|
$subnet_bits = get_interface_subnetv6($vpninterface);
|
923
|
$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
|
924
|
/* if the remote gateway is in the local subnet, then don't add a route */
|
925
|
if (is_ipaddrv6($sourcehost) &&
|
926
|
!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
|
927
|
if (is_ipaddrv6($gatewayip)) {
|
928
|
// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
|
929
|
route_add_or_change("-inet6 -host {$sourcehost} {$gatewayip}");
|
930
|
}
|
931
|
}
|
932
|
}
|
933
|
}
|
934
|
}
|
935
|
|
936
|
list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
|
937
|
if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
|
938
|
$myid_data = "{$myid_type}:{$myid_data}";
|
939
|
} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
|
940
|
if ($myid_data[0] == '#') {
|
941
|
/* asn1dn needs double quotes */
|
942
|
$myid_data = "\"{$myid_type}:{$myid_data}\"";
|
943
|
} else {
|
944
|
$myid_data = "\"{$myid_data}\"";
|
945
|
}
|
946
|
}
|
947
|
$leftid = '';
|
948
|
if (!empty($myid_data)) {
|
949
|
$leftid = "leftid = {$myid_data}";
|
950
|
}
|
951
|
|
952
|
$peerid_spec = '';
|
953
|
if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
|
954
|
// Only specify peer ID if we are not dealing with mobile PSK
|
955
|
} else {
|
956
|
list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
|
957
|
if ($peerid_type == 'any') {
|
958
|
$peerid_spec = '';
|
959
|
} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
|
960
|
$peerid_spec = "{$peerid_type}:{$peerid_data}";
|
961
|
} elseif ($peerid_type == "asn1dn") {
|
962
|
/* asn1dn needs double quotes */
|
963
|
if ($peerid_data[0] == '#') {
|
964
|
$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
|
965
|
} elseif (!empty($peerid_data)) {
|
966
|
$peerid_spec = "\"{$peerid_data}\"";
|
967
|
}
|
968
|
} else {
|
969
|
$peerid_spec = $peerid_data;
|
970
|
}
|
971
|
}
|
972
|
|
973
|
$ealgosp1 = '';
|
974
|
if (is_array($ph1ent['encryption']['item'])) {
|
975
|
$ciphers = "";
|
976
|
foreach($ph1ent['encryption']['item'] as $p1enc) {
|
977
|
if (!is_array($p1enc['encryption-algorithm']) ||
|
978
|
empty($p1enc['encryption-algorithm']['name']) ||
|
979
|
empty($p1enc['hash-algorithm'])) {
|
980
|
continue;
|
981
|
}
|
982
|
$ciphers .= ",";
|
983
|
$ciphers .= $p1enc['encryption-algorithm']['name'];
|
984
|
$ealg_kl = $p1enc['encryption-algorithm']['keylen'];
|
985
|
if ($ealg_kl) {
|
986
|
$ciphers .= "{$ealg_kl}";
|
987
|
}
|
988
|
$ciphers .= "-{$p1enc['hash-algorithm']}";
|
989
|
|
990
|
$modp = vpn_ipsec_convert_to_modp($p1enc['dhgroup']);
|
991
|
if (!empty($modp)) {
|
992
|
$ciphers .= "-{$modp}";
|
993
|
}
|
994
|
}
|
995
|
$ciphers = substr($ciphers, 1);
|
996
|
$ealgosp1 = "ike = {$ciphers}!";
|
997
|
}
|
998
|
|
999
|
if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
|
1000
|
if ($passive == "route") {
|
1001
|
$dpdline = "dpdaction = restart";
|
1002
|
} else {
|
1003
|
$dpdline = "dpdaction = clear";
|
1004
|
}
|
1005
|
$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
|
1006
|
$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
|
1007
|
$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
|
1008
|
} else {
|
1009
|
$dpdline = "dpdaction = none";
|
1010
|
}
|
1011
|
|
1012
|
$ikelifeline = '';
|
1013
|
if ($ph1ent['lifetime']) {
|
1014
|
$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
|
1015
|
}
|
1016
|
|
1017
|
$rightsourceip = NULL;
|
1018
|
if (isset($ph1ent['mobile'])) {
|
1019
|
$rightsourceips = array();
|
1020
|
if (!empty($a_client['pool_address'])) {
|
1021
|
$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
|
1022
|
}
|
1023
|
if (!empty($a_client['pool_address_v6'])) {
|
1024
|
$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
|
1025
|
}
|
1026
|
if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
|
1027
|
$rightsourceips[] = "%radius";
|
1028
|
}
|
1029
|
if (count($rightsourceips)) {
|
1030
|
$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
|
1031
|
}
|
1032
|
}
|
1033
|
|
1034
|
if (!empty($ph1ent['caref'])) {
|
1035
|
$ca = lookup_ca($ph1ent['caref']);
|
1036
|
if ($ca) {
|
1037
|
$casubarr = cert_get_subject_array($ca['crt']);
|
1038
|
$casub = "";
|
1039
|
foreach ($casubarr as $casubfield) {
|
1040
|
if (empty($casub)) {
|
1041
|
$casub = "/";
|
1042
|
}
|
1043
|
/* The subfield value could be an array. To avoid duplicating code,
|
1044
|
* always make it an array then iterate.
|
1045
|
* See https://redmine.pfsense.org/issues/7929
|
1046
|
*/
|
1047
|
if (!is_array($casubfield['v'])) {
|
1048
|
$casubfield['v'] = array($casubfield['v']);
|
1049
|
}
|
1050
|
foreach ($casubfield['v'] as $casubval) {
|
1051
|
$casub .= "{$casubfield['a']}={$casubval}/";
|
1052
|
}
|
1053
|
}
|
1054
|
|
1055
|
}
|
1056
|
}
|
1057
|
|
1058
|
$authentication = "";
|
1059
|
switch ($ph1ent['authentication_method']) {
|
1060
|
case 'eap-mschapv2':
|
1061
|
if (isset($ph1ent['mobile'])) {
|
1062
|
$authentication = "eap_identity=%any\n\t";
|
1063
|
$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
|
1064
|
if (!empty($ph1ent['certref'])) {
|
1065
|
$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
|
1066
|
$authentication .= "\n\tleftsendcert=always";
|
1067
|
}
|
1068
|
}
|
1069
|
break;
|
1070
|
case 'eap-tls':
|
1071
|
if (isset($ph1ent['mobile'])) {
|
1072
|
$authentication = "eap_identity=%identity\n\t";
|
1073
|
$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
|
1074
|
if (!empty($ph1ent['certref'])) {
|
1075
|
$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
|
1076
|
$authentication .= "\n\tleftsendcert=always";
|
1077
|
}
|
1078
|
} else {
|
1079
|
$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
|
1080
|
if (!empty($ph1ent['certref'])) {
|
1081
|
$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
|
1082
|
$authentication .= "\n\tleftsendcert=always";
|
1083
|
}
|
1084
|
}
|
1085
|
if (isset($casub)) {
|
1086
|
$authentication .= "\n\trightca=\"$casub\"";
|
1087
|
}
|
1088
|
break;
|
1089
|
case 'eap-radius':
|
1090
|
if (isset($ph1ent['mobile'])) {
|
1091
|
$authentication = "eap_identity=%identity\n\t";
|
1092
|
$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
|
1093
|
if (!empty($ph1ent['certref'])) {
|
1094
|
$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
|
1095
|
$authentication .= "\n\tleftsendcert=always";
|
1096
|
}
|
1097
|
} else {
|
1098
|
$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
|
1099
|
if (!empty($ph1ent['certref'])) {
|
1100
|
$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
|
1101
|
$authentication .= "\n\tleftsendcert=always";
|
1102
|
}
|
1103
|
}
|
1104
|
break;
|
1105
|
case 'xauth_rsa_server':
|
1106
|
$authentication = "leftauth = pubkey\n\trightauth = pubkey";
|
1107
|
$authentication .= "\n\trightauth2 = xauth-generic";
|
1108
|
if (!empty($ph1ent['certref'])) {
|
1109
|
$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
|
1110
|
$authentication .= "\n\tleftsendcert=always";
|
1111
|
}
|
1112
|
if (isset($casub)) {
|
1113
|
$authentication .= "\n\trightca=\"$casub\"";
|
1114
|
}
|
1115
|
break;
|
1116
|
case 'xauth_psk_server':
|
1117
|
$authentication = "leftauth = psk\n\trightauth = psk";
|
1118
|
$authentication .= "\n\trightauth2 = xauth-generic";
|
1119
|
break;
|
1120
|
case 'pre_shared_key':
|
1121
|
$authentication = "leftauth = psk\n\trightauth = psk";
|
1122
|
break;
|
1123
|
case 'rsasig':
|
1124
|
$authentication = "leftauth = pubkey\n\trightauth = pubkey";
|
1125
|
if (!empty($ph1ent['certref'])) {
|
1126
|
$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
|
1127
|
$authentication .= "\n\tleftsendcert=always";
|
1128
|
}
|
1129
|
if (isset($casub)) {
|
1130
|
$authentication .= "\n\trightca=\"$casub\"";
|
1131
|
}
|
1132
|
break;
|
1133
|
case 'hybrid_rsa_server':
|
1134
|
$authentication = "leftauth = pubkey\n\trightauth = xauth-generic";
|
1135
|
if (!empty($ph1ent['certref'])) {
|
1136
|
$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
|
1137
|
$authentication .= "\n\tleftsendcert=always";
|
1138
|
}
|
1139
|
break;
|
1140
|
}
|
1141
|
|
1142
|
$left_spec = $ep;
|
1143
|
|
1144
|
if (isset($ph1ent['reauth_enable'])) {
|
1145
|
$reauth = "reauth = no";
|
1146
|
} else {
|
1147
|
$reauth = "reauth = yes";
|
1148
|
}
|
1149
|
|
1150
|
if (isset($ph1ent['rekey_enable'])) {
|
1151
|
$rekeyline = "rekey = no";
|
1152
|
} else {
|
1153
|
$rekeyline = "rekey = yes";
|
1154
|
if(!empty($ph1ent['margintime'])){
|
1155
|
$rekeyline .= "\n\tmargintime = {$ph1ent['margintime']}s";
|
1156
|
}
|
1157
|
}
|
1158
|
|
1159
|
if ($ph1ent['nat_traversal'] == 'off') {
|
1160
|
$forceencaps = 'forceencaps = no';
|
1161
|
} else if ($ph1ent['nat_traversal'] == 'force') {
|
1162
|
$forceencaps = 'forceencaps = yes';
|
1163
|
} else {
|
1164
|
$forceencaps = 'forceencaps = no';
|
1165
|
}
|
1166
|
|
1167
|
if ($ph1ent['mobike'] == 'on') {
|
1168
|
$mobike = 'mobike = yes';
|
1169
|
} else {
|
1170
|
$mobike = 'mobike = no';
|
1171
|
}
|
1172
|
|
1173
|
if (isset($ph1ent['tfc_enable'])) {
|
1174
|
if (isset($ph1ent['tfc_bytes']) && is_numericint($ph1ent['tfc_bytes'])) {
|
1175
|
$tfc = "tfc = {$ph1ent['tfc_bytes']}";
|
1176
|
} else {
|
1177
|
$tfc = "tfc = %mtu";
|
1178
|
}
|
1179
|
}
|
1180
|
|
1181
|
$ipseclifetime = 0;
|
1182
|
$rightsubnet_spec = array();
|
1183
|
$leftsubnet_spec = array();
|
1184
|
$reqids = array();
|
1185
|
$vtireq = array();
|
1186
|
$ealgoAHsp2arr = array();
|
1187
|
$ealgoESPsp2arr = array();
|
1188
|
if (is_array($a_phase2) && count($a_phase2)) {
|
1189
|
foreach ($a_phase2 as $ph2ent) {
|
1190
|
if ($ikeid != $ph2ent['ikeid']) {
|
1191
|
continue;
|
1192
|
}
|
1193
|
|
1194
|
if (isset($ph2ent['disabled'])) {
|
1195
|
continue;
|
1196
|
}
|
1197
|
|
1198
|
if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
|
1199
|
continue;
|
1200
|
}
|
1201
|
|
1202
|
if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
|
1203
|
$tunneltype = "type = tunnel";
|
1204
|
$installpolicy = "installpolicy = yes";
|
1205
|
|
1206
|
$localid_type = $ph2ent['localid']['type'];
|
1207
|
$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
|
1208
|
|
1209
|
/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
|
1210
|
if (($localid_type == "none" || $localid_type == "mobile") &&
|
1211
|
isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid) == 1)) {
|
1212
|
$left_spec = '%any';
|
1213
|
} else {
|
1214
|
if ($localid_type != "address") {
|
1215
|
$localid_type = "subnet";
|
1216
|
}
|
1217
|
// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
|
1218
|
if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
|
1219
|
log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
|
1220
|
continue;
|
1221
|
}
|
1222
|
if (!empty($ph2ent['natlocalid'])) {
|
1223
|
$natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
|
1224
|
if ($ph2ent['natlocalid']['type'] != "address") {
|
1225
|
if (is_subnet($natleftsubnet_data)) {
|
1226
|
$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
|
1227
|
}
|
1228
|
} else {
|
1229
|
if (is_ipaddr($natleftsubnet_data)) {
|
1230
|
$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
|
1231
|
}
|
1232
|
}
|
1233
|
$natfilterrules = true;
|
1234
|
}
|
1235
|
}
|
1236
|
|
1237
|
$leftsubnet_spec[] = $leftsubnet_data;
|
1238
|
|
1239
|
if (!isset($ph2ent['mobile'])) {
|
1240
|
$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
|
1241
|
$rightsubnet_spec[] = $tmpsubnet;
|
1242
|
} else if (!empty($a_client['pool_address'])) {
|
1243
|
$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
|
1244
|
}
|
1245
|
} elseif ($ph2ent['mode'] == 'vti') {
|
1246
|
$tunneltype = "";
|
1247
|
$installpolicy = "installpolicy = no";
|
1248
|
$passive = 'start';
|
1249
|
|
1250
|
$localid_type = $ph2ent['localid']['type'];
|
1251
|
$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
|
1252
|
$leftsubnet_spec[] = $leftsubnet_data;
|
1253
|
|
1254
|
$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
|
1255
|
$rightsubnet_spec[] = $tmpsubnet;
|
1256
|
$vtireq[] = $ph2ent['reqid'];
|
1257
|
} else {
|
1258
|
$tunneltype = "type = transport";
|
1259
|
$installpolicy = "installpolicy = yes";
|
1260
|
|
1261
|
if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
|
1262
|
($ph1ent['authentication_method'] == "pre_shared_key")) &&
|
1263
|
isset($ph1ent['mobile'])) {
|
1264
|
$left_spec = "%any";
|
1265
|
} else {
|
1266
|
$tmpsubnet = ipsec_get_phase1_src($ph1ent);
|
1267
|
$leftsubnet_spec[] = $tmpsubnet;
|
1268
|
}
|
1269
|
|
1270
|
if (!isset($ph2ent['mobile'])) {
|
1271
|
$rightsubnet_spec[] = $right_spec;
|
1272
|
}
|
1273
|
}
|
1274
|
|
1275
|
if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
|
1276
|
$ph2ent['pfsgroup'] = $a_client['pfs_group'];
|
1277
|
}
|
1278
|
|
1279
|
if ($ph2ent['protocol'] == 'esp') {
|
1280
|
if (is_array($ph2ent['encryption-algorithm-option'])) {
|
1281
|
foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
|
1282
|
$ealg_id = $ealg['name'];
|
1283
|
$ealg_kl = $ealg['keylen'];
|
1284
|
|
1285
|
if (!empty($ealg_kl) && $ealg_kl == "auto") {
|
1286
|
if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
|
1287
|
require_once("ipsec.inc");
|
1288
|
}
|
1289
|
$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
|
1290
|
$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
|
1291
|
$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
|
1292
|
/* XXX: in some cases where include ordering is suspect these variables
|
1293
|
* are somehow 0 and we enter this loop forever and timeout after 900
|
1294
|
* seconds wrecking bootup */
|
1295
|
if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
|
1296
|
for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
|
1297
|
if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
|
1298
|
foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
|
1299
|
$halgo = str_replace('hmac_', '', $halgo);
|
1300
|
$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
|
1301
|
$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
|
1302
|
if (!empty($modp)) {
|
1303
|
$tmpealgo .= "-{$modp}";
|
1304
|
}
|
1305
|
$ealgoESPsp2arr[] = $tmpealgo;
|
1306
|
}
|
1307
|
} else {
|
1308
|
$tmpealgo = "{$ealg_id}{$keylen}";
|
1309
|
$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
|
1310
|
if (!empty($modp)) {
|
1311
|
$tmpealgo .= "-{$modp}";
|
1312
|
}
|
1313
|
$ealgoESPsp2arr[] = $tmpealgo;
|
1314
|
}
|
1315
|
}
|
1316
|
}
|
1317
|
} else {
|
1318
|
if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
|
1319
|
foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
|
1320
|
$halgo = str_replace('hmac_', '', $halgo);
|
1321
|
$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
|
1322
|
$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
|
1323
|
if (!empty($modp)) {
|
1324
|
$tmpealgo .= "-{$modp}";
|
1325
|
}
|
1326
|
$ealgoESPsp2arr[] = $tmpealgo;
|
1327
|
}
|
1328
|
} else {
|
1329
|
$tmpealgo = "{$ealg_id}{$ealg_kl}";
|
1330
|
$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
|
1331
|
if (!empty($modp)) {
|
1332
|
$tmpealgo .= "-{$modp}";
|
1333
|
}
|
1334
|
$ealgoESPsp2arr[] = $tmpealgo;
|
1335
|
}
|
1336
|
}
|
1337
|
}
|
1338
|
}
|
1339
|
} else if ($ph2ent['protocol'] == 'ah') {
|
1340
|
if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
|
1341
|
$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
|
1342
|
foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
|
1343
|
$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
|
1344
|
if (!empty($modp)) {
|
1345
|
$tmpAHalgo = "-{$modp}";
|
1346
|
}
|
1347
|
$ealgoAHsp2arr[] = $tmpAHalgo;
|
1348
|
}
|
1349
|
}
|
1350
|
}
|
1351
|
|
1352
|
$reqids[] = $ph2ent['reqid'];
|
1353
|
|
1354
|
if (!empty($ph2ent['lifetime'])) {
|
1355
|
if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
|
1356
|
$ipseclifetime = intval($ph2ent['lifetime']);
|
1357
|
}
|
1358
|
}
|
1359
|
|
1360
|
}
|
1361
|
}
|
1362
|
|
1363
|
$ipsecconnect =<<<EOD
|
1364
|
fragmentation = yes
|
1365
|
keyexchange = {$keyexchange}
|
1366
|
{$reauth}
|
1367
|
{$forceencaps}
|
1368
|
{$mobike}
|
1369
|
{$tfc}
|
1370
|
{$rekeyline}
|
1371
|
{$installpolicy}
|
1372
|
{$tunneltype}
|
1373
|
{$dpdline}
|
1374
|
auto = {$passive}
|
1375
|
left = {$left_spec}
|
1376
|
right = {$right_spec}
|
1377
|
{$leftid}
|
1378
|
|
1379
|
EOD;
|
1380
|
|
1381
|
/* Disable ipcomp for now. redmine #6167
|
1382
|
if (isset($config['ipsec']['compression'])) {
|
1383
|
$ipsecconnect .= "\tcompress = yes\n";
|
1384
|
$enablecompression = true;
|
1385
|
} */
|
1386
|
if (!empty($ikelifeline)) {
|
1387
|
$ipsecconnect .= "\t{$ikelifeline}\n";
|
1388
|
}
|
1389
|
if ($ipseclifetime > 0) {
|
1390
|
$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
|
1391
|
}
|
1392
|
if (!empty($rightsourceip)) {
|
1393
|
$ipsecconnect .= "{$rightsourceip}";
|
1394
|
}
|
1395
|
if (!empty($ealgosp1)) {
|
1396
|
$ipsecconnect .= "\t{$ealgosp1}\n";
|
1397
|
}
|
1398
|
if (!empty($ealgoAHsp2arr)) {
|
1399
|
$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
|
1400
|
}
|
1401
|
if (!empty($ealgoESPsp2arr)) {
|
1402
|
$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
|
1403
|
}
|
1404
|
if (!empty($authentication)) {
|
1405
|
$ipsecconnect .= "\t{$authentication}\n";
|
1406
|
}
|
1407
|
if (!empty($peerid_spec)) {
|
1408
|
$ipsecconnect .= "\trightid = {$peerid_spec}\n";
|
1409
|
}
|
1410
|
if ($keyexchange != 'ikev2') {
|
1411
|
$ipsecconnect .= "\taggressive = {$aggressive}\n";
|
1412
|
}
|
1413
|
|
1414
|
if (!isset($ph1ent['mobile']) && ($keyexchange == 'ikev1' || isset($ph1ent['splitconn']))) {
|
1415
|
if (!empty($rightsubnet_spec)) {
|
1416
|
$ipsecfin = '';
|
1417
|
foreach ($rightsubnet_spec as $idx => $rsubnet) {
|
1418
|
$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
|
1419
|
//if (!empty($reqids[$idx])) {
|
1420
|
// $ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
|
1421
|
//}
|
1422
|
if (!empty($vtireq[$idx])) {
|
1423
|
$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
|
1424
|
}
|
1425
|
$ipsecfin .= $ipsecconnect;
|
1426
|
$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
|
1427
|
$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
|
1428
|
}
|
1429
|
} else {
|
1430
|
log_error(sprintf(gettext("No phase2 specifications for tunnel with REQID = %s"), $ikeid));
|
1431
|
}
|
1432
|
} else {
|
1433
|
if (isset($ph1ent['mobile'])) {
|
1434
|
$ipsecfin = "\nconn con-mobile\n";
|
1435
|
}
|
1436
|
else {
|
1437
|
$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
|
1438
|
}
|
1439
|
//if (!empty($reqids[$idx])) {
|
1440
|
// $ipsecfin .= "\treqid = " . $reqids[0] . "\n";
|
1441
|
//}
|
1442
|
if (!empty($vtireq[$idx])) {
|
1443
|
$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
|
1444
|
}
|
1445
|
$ipsecfin .= $ipsecconnect;
|
1446
|
if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
|
1447
|
$tempsubnets = array();
|
1448
|
foreach ($rightsubnet_spec as $rightsubnet) {
|
1449
|
$tempsubnets[$rightsubnet] = $rightsubnet;
|
1450
|
}
|
1451
|
$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
|
1452
|
unset($tempsubnets, $rightsubnet);
|
1453
|
}
|
1454
|
if (!empty($leftsubnet_spec)) {
|
1455
|
$tempsubnets = array();
|
1456
|
foreach ($leftsubnet_spec as $leftsubnet) {
|
1457
|
$tempsubnets[$leftsubnet] = $leftsubnet;
|
1458
|
}
|
1459
|
$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
|
1460
|
unset($tempsubnets, $leftsubnet);
|
1461
|
}
|
1462
|
}
|
1463
|
$ipsecconf .= $ipsecfin;
|
1464
|
unset($ipsecfin);
|
1465
|
}
|
1466
|
}
|
1467
|
|
1468
|
$a_mobilekey = $config['ipsec']['mobilekey'];
|
1469
|
|
1470
|
if (is_array($a_phase1) && count($a_phase1)) {
|
1471
|
foreach ($a_phase1 as $ph1ent) {
|
1472
|
if (!isset($ph1ent['mobile'])) {
|
1473
|
continue;
|
1474
|
}
|
1475
|
if (isset($ph1ent['disabled'])) {
|
1476
|
continue;
|
1477
|
}
|
1478
|
|
1479
|
if (is_array($a_mobilekey) && count($a_mobilekey)) {
|
1480
|
$ipsecfin = '';
|
1481
|
$mobilekey_counter = 1;
|
1482
|
foreach ($a_mobilekey as $mkent) {
|
1483
|
if ($mkent['type'] != "EAP") {
|
1484
|
continue;
|
1485
|
}
|
1486
|
|
1487
|
if (!isset($mkent['ident_type']) || !isset($mkent['pool_address']) || !isset($mkent['pool_netbits'])) {
|
1488
|
continue;
|
1489
|
}
|
1490
|
|
1491
|
if (strlen($mkent['pool_address'] < 1) || !is_ipaddr($mkent['pool_address'])) {
|
1492
|
continue;
|
1493
|
}
|
1494
|
|
1495
|
$ipsecfin .= "\nconn mobile-{$mobilekey_counter}\n";
|
1496
|
$ipsecfin .= "\talso = con-mobile\n";
|
1497
|
$ipsecfin .= "\teap_identity = %identity\n";
|
1498
|
$ipsecfin .= "\trightsourceip = {$mkent['pool_address']}/{$mkent['pool_netbits']}\n";
|
1499
|
|
1500
|
if ($mkent['ident_type'] == "none") {
|
1501
|
$ipsecfin .= "\trightid = \"{$mkent['ident']}\"\n";
|
1502
|
}
|
1503
|
else {
|
1504
|
$ipsecfin .= "\trightid = {$mkent['ident_type']}:{$mkent['ident']}\n";
|
1505
|
}
|
1506
|
|
1507
|
// optional: define left|rightid more granular
|
1508
|
// supported: ipv4, ipv6, rfc822, email, userfqdn, fqdn, dns, asn1dn, asn1gn, keyid
|
1509
|
// example: $ipsecfin = "\trightid = email:your@email.address\n";
|
1510
|
|
1511
|
// note: comma seperated list for access restriction, regardless of firewall rules
|
1512
|
// example: $ipsecfin = "\tleftsubnet = 1.1.1.1/32,1.1.1.2/32,2.2.2.0/24\n";
|
1513
|
|
1514
|
$mobilekey_counter++;
|
1515
|
}
|
1516
|
$ipsecconf .= $ipsecfin;
|
1517
|
unset($ipsecfin);
|
1518
|
unset($mobilekey_counter);
|
1519
|
}
|
1520
|
}
|
1521
|
}
|
1522
|
|
1523
|
@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
|
1524
|
unset($ipsecconf);
|
1525
|
/* end ipsec.conf */
|
1526
|
|
1527
|
if ($enablecompression === true) {
|
1528
|
set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
|
1529
|
} else {
|
1530
|
set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
|
1531
|
}
|
1532
|
|
1533
|
/* manage process */
|
1534
|
if ($restart === true) {
|
1535
|
mwexec("/usr/local/sbin/ipsec restart", false);
|
1536
|
} else {
|
1537
|
if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
|
1538
|
/* Update configuration changes */
|
1539
|
/* Read secrets */
|
1540
|
mwexec("/usr/local/sbin/ipsec rereadall", false);
|
1541
|
mwexec("/usr/local/sbin/ipsec reload", false);
|
1542
|
} else {
|
1543
|
mwexec("/usr/local/sbin/ipsec start", false);
|
1544
|
}
|
1545
|
}
|
1546
|
|
1547
|
// run ping_hosts.sh once if it's enabled to avoid wait for minicron
|
1548
|
if ($ipsecpinghostsactive == true) {
|
1549
|
mwexec_bg("/usr/local/bin/ping_hosts.sh");
|
1550
|
}
|
1551
|
|
1552
|
if ($natfilterrules == true) {
|
1553
|
filter_configure();
|
1554
|
}
|
1555
|
/* start filterdns, if necessary */
|
1556
|
if (count($filterdns_list) > 0) {
|
1557
|
$interval = 60;
|
1558
|
if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
|
1559
|
$interval = $ipseccfg['dns-interval'];
|
1560
|
}
|
1561
|
|
1562
|
$hostnames = "";
|
1563
|
array_unique($filterdns_list);
|
1564
|
foreach ($filterdns_list as $hostname) {
|
1565
|
$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
|
1566
|
}
|
1567
|
file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
|
1568
|
unset($hostnames);
|
1569
|
|
1570
|
if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
|
1571
|
sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
|
1572
|
} else {
|
1573
|
mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
|
1574
|
}
|
1575
|
} else {
|
1576
|
killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
|
1577
|
@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
|
1578
|
}
|
1579
|
|
1580
|
if (platform_booting()) {
|
1581
|
echo "done\n";
|
1582
|
}
|
1583
|
|
1584
|
unlock($ipsecstartlock);
|
1585
|
return count($filterdns_list);
|
1586
|
}
|
1587
|
|
1588
|
/*
|
1589
|
* Forcefully restart IPsec
|
1590
|
* This is required for when dynamic interfaces reload
|
1591
|
* For all other occasions the normal vpn_ipsec_configure()
|
1592
|
* will gracefully reload the settings without restarting
|
1593
|
*/
|
1594
|
function vpn_ipsec_force_reload($interface = "") {
|
1595
|
global $g, $config;
|
1596
|
|
1597
|
if (!ipsec_enabled()) {
|
1598
|
return;
|
1599
|
}
|
1600
|
|
1601
|
$ipseccfg = $config['ipsec'];
|
1602
|
|
1603
|
if (!empty($interface) && is_array($ipseccfg['phase1'])) {
|
1604
|
$found = false;
|
1605
|
foreach ($ipseccfg['phase1'] as $ipsec) {
|
1606
|
if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
|
1607
|
$found = true;
|
1608
|
break;
|
1609
|
}
|
1610
|
}
|
1611
|
if (!$found) {
|
1612
|
log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
|
1613
|
return;
|
1614
|
}
|
1615
|
}
|
1616
|
|
1617
|
/* If we get this far then we need to take action. */
|
1618
|
log_error(gettext("Forcefully reloading IPsec"));
|
1619
|
vpn_ipsec_configure();
|
1620
|
}
|
1621
|
|
1622
|
/* master setup for vpn (mpd) */
|
1623
|
function vpn_setup() {
|
1624
|
/* start pppoe server */
|
1625
|
vpn_pppoes_configure();
|
1626
|
|
1627
|
/* setup l2tp */
|
1628
|
vpn_l2tp_configure();
|
1629
|
}
|
1630
|
|
1631
|
function vpn_netgraph_support() {
|
1632
|
$iflist = get_configured_interface_list();
|
1633
|
foreach ($iflist as $iface) {
|
1634
|
$realif = get_real_interface($iface);
|
1635
|
/* Get support for netgraph(4) from the nic */
|
1636
|
$ifinfo = pfSense_get_interface_addresses($realif);
|
1637
|
if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
|
1638
|
pfSense_ngctl_attach(".", $realif);
|
1639
|
}
|
1640
|
}
|
1641
|
}
|
1642
|
|
1643
|
function vpn_pppoes_configure() {
|
1644
|
global $config;
|
1645
|
|
1646
|
if (is_array($config['pppoes']['pppoe'])) {
|
1647
|
foreach ($config['pppoes']['pppoe'] as $pppoe) {
|
1648
|
vpn_pppoe_configure($pppoe);
|
1649
|
}
|
1650
|
}
|
1651
|
}
|
1652
|
|
1653
|
function vpn_pppoe_configure(&$pppoecfg) {
|
1654
|
global $config, $g;
|
1655
|
|
1656
|
$syscfg = $config['system'];
|
1657
|
|
1658
|
/* create directory if it does not exist */
|
1659
|
if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
|
1660
|
mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
|
1661
|
}
|
1662
|
|
1663
|
if (platform_booting()) {
|
1664
|
if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
|
1665
|
return 0;
|
1666
|
}
|
1667
|
|
1668
|
echo gettext("Configuring PPPoE Server service... ");
|
1669
|
} else {
|
1670
|
/* kill mpd */
|
1671
|
killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
|
1672
|
|
1673
|
/* wait for process to die */
|
1674
|
sleep(2);
|
1675
|
|
1676
|
}
|
1677
|
|
1678
|
switch ($pppoecfg['mode']) {
|
1679
|
|
1680
|
case 'server':
|
1681
|
|
1682
|
$pppoe_interface = get_real_interface($pppoecfg['interface']);
|
1683
|
|
1684
|
if ($pppoecfg['paporchap'] == "chap") {
|
1685
|
$paporchap = "set link enable chap";
|
1686
|
} else {
|
1687
|
$paporchap = "set link enable pap";
|
1688
|
}
|
1689
|
|
1690
|
/* write mpd.conf */
|
1691
|
$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
|
1692
|
if (!$fd) {
|
1693
|
printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
|
1694
|
return 1;
|
1695
|
}
|
1696
|
|
1697
|
$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 ";
|
1698
|
if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
|
1699
|
$issue_ip_type .= "0.0.0.0/0";
|
1700
|
} else {
|
1701
|
$issue_ip_type .= "ippool p0";
|
1702
|
}
|
1703
|
|
1704
|
$ippool_p0 = ip_after($pppoecfg['remoteip'], $pppoecfg['n_pppoe_units'] - 1);
|
1705
|
|
1706
|
if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
|
1707
|
$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
|
1708
|
} else {
|
1709
|
$pppoemaxlogins = 1;
|
1710
|
}
|
1711
|
|
1712
|
$ipcp_dns = '';
|
1713
|
if (!empty($pppoecfg['dns1'])) {
|
1714
|
$ipcp_dns = "set ipcp dns " . $pppoecfg['dns1'];
|
1715
|
if (!empty($pppoecfg['dns2'])) {
|
1716
|
$ipcp_dns .= " " . $pppoecfg['dns2'];
|
1717
|
}
|
1718
|
} elseif (isset($config['dnsmasq']['enable']) ||
|
1719
|
isset ($config['unbound']['enable'])) {
|
1720
|
$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
|
1721
|
if ($syscfg['dnsserver'][0]) {
|
1722
|
$ipcp_dns .= " " . $syscfg['dnsserver'][0];
|
1723
|
}
|
1724
|
} elseif (is_array($syscfg['dnsserver']) &&
|
1725
|
($syscfg['dnsserver'][0])) {
|
1726
|
$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
|
1727
|
}
|
1728
|
|
1729
|
$mpdconf = <<<EOD
|
1730
|
startup:
|
1731
|
|
1732
|
poes:
|
1733
|
set ippool add p0 {$pppoecfg['remoteip']} {$ippool_p0}
|
1734
|
|
1735
|
create bundle template poes_b
|
1736
|
set bundle enable compression
|
1737
|
|
1738
|
set ccp yes mppc
|
1739
|
set mppc yes e40
|
1740
|
set mppc yes e128
|
1741
|
set mppc yes stateless
|
1742
|
|
1743
|
set iface group pppoe
|
1744
|
set iface up-script /usr/local/sbin/vpn-linkup-poes
|
1745
|
set iface down-script /usr/local/sbin/vpn-linkdown-poes
|
1746
|
set iface idle 0
|
1747
|
set iface disable on-demand
|
1748
|
set iface disable proxy-arp
|
1749
|
set iface enable tcpmssfix
|
1750
|
set iface mtu 1500
|
1751
|
|
1752
|
set ipcp no vjcomp
|
1753
|
{$issue_ip_type}
|
1754
|
{$ipcp_dns}
|
1755
|
|
1756
|
create link template poes_l pppoe
|
1757
|
set link action bundle poes_b
|
1758
|
|
1759
|
set auth max-logins {$pppoemaxlogins}
|
1760
|
|
1761
|
set pppoe iface {$pppoe_interface}
|
1762
|
|
1763
|
set link no multilink
|
1764
|
set link no pap chap
|
1765
|
{$paporchap}
|
1766
|
set link keep-alive 60 180
|
1767
|
set link max-redial -1
|
1768
|
set link mru 1492
|
1769
|
set link latency 1
|
1770
|
set link enable incoming
|
1771
|
|
1772
|
EOD;
|
1773
|
|
1774
|
if (isset ($pppoecfg['radius']['server']['enable'])) {
|
1775
|
$radiusport = "";
|
1776
|
$radiusacctport = "";
|
1777
|
if (isset($pppoecfg['radius']['server']['port'])) {
|
1778
|
$radiusport = $pppoecfg['radius']['server']['port'];
|
1779
|
}
|
1780
|
if (isset($pppoecfg['radius']['server']['acctport'])) {
|
1781
|
$radiusacctport = $pppoecfg['radius']['server']['acctport'];
|
1782
|
}
|
1783
|
$mpdconf .=<<<EOD
|
1784
|
set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
|
1785
|
set radius retries 3
|
1786
|
set radius timeout 10
|
1787
|
set auth enable radius-auth
|
1788
|
|
1789
|
EOD;
|
1790
|
|
1791
|
if (isset ($pppoecfg['radius']['accounting'])) {
|
1792
|
$mpdconf .=<<<EOD
|
1793
|
set auth enable radius-acct
|
1794
|
|
1795
|
EOD;
|
1796
|
}
|
1797
|
if (!empty($pppoecfg['radius']['nasip'])) {
|
1798
|
$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
|
1799
|
}
|
1800
|
}
|
1801
|
|
1802
|
fwrite($fd, $mpdconf);
|
1803
|
fclose($fd);
|
1804
|
unset($mpdconf);
|
1805
|
|
1806
|
if ($pppoecfg['username']) {
|
1807
|
/* write mpd.secret */
|
1808
|
$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
|
1809
|
if (!$fd) {
|
1810
|
printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
|
1811
|
return 1;
|
1812
|
}
|
1813
|
|
1814
|
$mpdsecret = "\n\n";
|
1815
|
|
1816
|
if (!empty($pppoecfg['username'])) {
|
1817
|
$item = explode(" ", $pppoecfg['username']);
|
1818
|
foreach ($item as $userdata) {
|
1819
|
$data = explode(":", $userdata);
|
1820
|
$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
|
1821
|
}
|
1822
|
}
|
1823
|
|
1824
|
fwrite($fd, $mpdsecret);
|
1825
|
fclose($fd);
|
1826
|
unset($mpdsecret);
|
1827
|
chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
|
1828
|
}
|
1829
|
|
1830
|
/* Check if previous instance is still up */
|
1831
|
while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
|
1832
|
killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
|
1833
|
}
|
1834
|
|
1835
|
/* Get support for netgraph(4) from the nic */
|
1836
|
pfSense_ngctl_attach(".", $pppoe_interface);
|
1837
|
/* fire up mpd */
|
1838
|
mwexec("/usr/local/sbin/mpd5 -b -d {$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn -p {$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid -s poes poes");
|
1839
|
|
1840
|
break;
|
1841
|
}
|
1842
|
|
1843
|
if (platform_booting()) {
|
1844
|
echo gettext("done") . "\n";
|
1845
|
}
|
1846
|
|
1847
|
return 0;
|
1848
|
}
|
1849
|
|
1850
|
function vpn_l2tp_configure() {
|
1851
|
global $config, $g;
|
1852
|
|
1853
|
$syscfg = $config['system'];
|
1854
|
$l2tpcfg = $config['l2tp'];
|
1855
|
|
1856
|
/* create directory if it does not exist */
|
1857
|
if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
|
1858
|
mkdir("{$g['varetc_path']}/l2tp-vpn");
|
1859
|
}
|
1860
|
|
1861
|
if (platform_booting()) {
|
1862
|
if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
|
1863
|
return 0;
|
1864
|
}
|
1865
|
|
1866
|
echo gettext("Configuring l2tp VPN service... ");
|
1867
|
} else {
|
1868
|
/* kill mpd */
|
1869
|
killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
|
1870
|
|
1871
|
/* wait for process to die */
|
1872
|
sleep(8);
|
1873
|
|
1874
|
}
|
1875
|
|
1876
|
/* make sure l2tp-vpn directory exists */
|
1877
|
if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
|
1878
|
mkdir("{$g['varetc_path']}/l2tp-vpn");
|
1879
|
}
|
1880
|
|
1881
|
switch ($l2tpcfg['mode']) {
|
1882
|
|
1883
|
case 'server':
|
1884
|
$l2tp_listen="";
|
1885
|
$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
|
1886
|
if (is_ipaddrv4($ipaddr)) {
|
1887
|
$l2tp_listen="set l2tp self $ipaddr";
|
1888
|
}
|
1889
|
|
1890
|
switch ($l2tpcfg['paporchap']) {
|
1891
|
case 'chap':
|
1892
|
$paporchap = "set link enable chap";
|
1893
|
break;
|
1894
|
case 'chap-msv2':
|
1895
|
$paporchap = "set link enable chap-msv2";
|
1896
|
break;
|
1897
|
default:
|
1898
|
$paporchap = "set link enable pap";
|
1899
|
break;
|
1900
|
}
|
1901
|
|
1902
|
/* write mpd.conf */
|
1903
|
$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
|
1904
|
if (!$fd) {
|
1905
|
printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
|
1906
|
return 1;
|
1907
|
}
|
1908
|
|
1909
|
$ippool_p0 = ip_after($l2tpcfg['remoteip'], $l2tpcfg['n_l2tp_units'] - 1);
|
1910
|
|
1911
|
$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 ";
|
1912
|
if (isset($l2tpcfg['radius']['radiusissueips']) && isset($l2tpcfg['radius']['server']['enable'])) {
|
1913
|
$issue_ip_type .= "0.0.0.0/0";
|
1914
|
} else {
|
1915
|
$issue_ip_type .= "ippool p0";
|
1916
|
}
|
1917
|
|
1918
|
$ipcp_dns = '';
|
1919
|
if (is_ipaddr($l2tpcfg['dns1'])) {
|
1920
|
$ipcp_dns = "set ipcp dns " . $l2tpcfg['dns1'];
|
1921
|
if (is_ipaddr($l2tpcfg['dns2'])) {
|
1922
|
$ipcp_dns .= " " . $l2tpcfg['dns2'];
|
1923
|
}
|
1924
|
} elseif (isset ($config['dnsmasq']['enable']) ||
|
1925
|
isset ($config['unbound']['enable'])) {
|
1926
|
$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
|
1927
|
if ($syscfg['dnsserver'][0]) {
|
1928
|
$ipcp_dns .= " " . $syscfg['dnsserver'][0];
|
1929
|
}
|
1930
|
} elseif (is_array($syscfg['dnsserver']) &&
|
1931
|
($syscfg['dnsserver'][0])) {
|
1932
|
$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
|
1933
|
}
|
1934
|
|
1935
|
$mpdconf =<<<EOD
|
1936
|
|
1937
|
startup:
|
1938
|
|
1939
|
l2tps:
|
1940
|
set ippool add p0 {$l2tpcfg['remoteip']} {$ippool_p0}
|
1941
|
|
1942
|
create bundle template l2tp_b
|
1943
|
set bundle enable compression
|
1944
|
set bundle yes crypt-reqd
|
1945
|
|
1946
|
set ccp yes mppc
|
1947
|
|
1948
|
set iface name l2tp
|
1949
|
set iface group l2tp
|
1950
|
set iface up-script /usr/local/sbin/vpn-linkup-l2tp
|
1951
|
set iface down-script /usr/local/sbin/vpn-linkdown-l2tp
|
1952
|
set iface disable on-demand
|
1953
|
set iface enable proxy-arp
|
1954
|
|
1955
|
set ipcp yes vjcomp
|
1956
|
{$issue_ip_type}
|
1957
|
{$ipcp_dns}
|
1958
|
|
1959
|
create link template l2tp_l l2tp
|
1960
|
set link action bundle l2tp_b
|
1961
|
|
1962
|
set link yes acfcomp protocomp
|
1963
|
set link enable multilink
|
1964
|
set link no pap chap chap-msv2
|
1965
|
{$paporchap}
|
1966
|
{$l2tp_listen}
|
1967
|
set link keep-alive 10 180
|
1968
|
set link enable incoming
|
1969
|
|
1970
|
EOD;
|
1971
|
|
1972
|
|
1973
|
if (isset ($l2tpcfg['radius']['enable'])) {
|
1974
|
$mpdconf .=<<<EOD
|
1975
|
set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
|
1976
|
set radius retries 3
|
1977
|
set radius timeout 10
|
1978
|
set auth disable internal
|
1979
|
set auth enable radius-auth
|
1980
|
|
1981
|
EOD;
|
1982
|
|
1983
|
if (isset ($l2tpcfg['radius']['accounting'])) {
|
1984
|
$mpdconf .=<<<EOD
|
1985
|
set auth enable radius-acct
|
1986
|
|
1987
|
EOD;
|
1988
|
}
|
1989
|
}
|
1990
|
|
1991
|
fwrite($fd, $mpdconf);
|
1992
|
fclose($fd);
|
1993
|
unset($mpdconf);
|
1994
|
|
1995
|
/* write mpd.secret */
|
1996
|
$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
|
1997
|
if (!$fd) {
|
1998
|
printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
|
1999
|
return 1;
|
2000
|
}
|
2001
|
|
2002
|
$mpdsecret = "\n\n";
|
2003
|
|
2004
|
if (is_array($l2tpcfg['user'])) {
|
2005
|
foreach ($l2tpcfg['user'] as $user) {
|
2006
|
$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
|
2007
|
}
|
2008
|
}
|
2009
|
|
2010
|
fwrite($fd, $mpdsecret);
|
2011
|
fclose($fd);
|
2012
|
unset($mpdsecret);
|
2013
|
chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
|
2014
|
|
2015
|
vpn_netgraph_support();
|
2016
|
|
2017
|
/* fire up mpd */
|
2018
|
mwexec("/usr/local/sbin/mpd5 -b -d {$g['varetc_path']}/l2tp-vpn -p {$g['varrun_path']}/l2tp-vpn.pid -s l2tps l2tps");
|
2019
|
|
2020
|
break;
|
2021
|
|
2022
|
case 'redir':
|
2023
|
break;
|
2024
|
}
|
2025
|
|
2026
|
if (platform_booting()) {
|
2027
|
echo "done\n";
|
2028
|
}
|
2029
|
|
2030
|
return 0;
|
2031
|
}
|
2032
|
|
2033
|
?>
|