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