Project

General

Profile

Download (12.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * vpn.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2020 Rubicon Communications, LLC (Netgate)
9
 * Copyright (c) 2008 Shrew Soft Inc
10
 * All rights reserved.
11
 *
12
 * originally part of m0n0wall (http://m0n0.ch/wall)
13
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
 * All rights reserved.
15
 *
16
 * Licensed under the Apache License, Version 2.0 (the "License");
17
 * you may not use this file except in compliance with the License.
18
 * You may obtain a copy of the License at
19
 *
20
 * http://www.apache.org/licenses/LICENSE-2.0
21
 *
22
 * Unless required by applicable law or agreed to in writing, software
23
 * distributed under the License is distributed on an "AS IS" BASIS,
24
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25
 * See the License for the specific language governing permissions and
26
 * limitations under the License.
27
 */
28

    
29
require_once("ipsec.inc");
30
require_once("filter.inc");
31
require_once("auth.inc");
32
require_once("certs.inc");
33

    
34
/* master setup for vpn (mpd) */
35
function vpn_setup() {
36
	/* start pppoe server */
37
	vpn_pppoes_configure();
38

    
39
	/* setup l2tp */
40
	vpn_l2tp_configure();
41
}
42

    
43
function vpn_netgraph_support() {
44
	$iflist = get_configured_interface_list();
45
	foreach ($iflist as $iface) {
46
		$realif = get_real_interface($iface);
47
		/* Get support for netgraph(4) from the nic */
48
		$ifinfo = pfSense_get_interface_addresses($realif);
49
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
50
			pfSense_ngctl_attach(".", $realif);
51
		}
52
	}
53
}
54

    
55
function vpn_pppoes_configure() {
56
	global $config;
57

    
58
	if (is_array($config['pppoes']['pppoe'])) {
59
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
60
			vpn_pppoe_configure($pppoe);
61
		}
62
	}
63
}
64

    
65
function vpn_pppoe_configure(&$pppoecfg) {
66
	global $config, $g;
67

    
68
	$syscfg = $config['system'];
69

    
70
	/* create directory if it does not exist */
71
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
72
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
73
	}
74

    
75
	if (platform_booting()) {
76
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
77
			return 0;
78
		}
79

    
80
		echo gettext("Configuring PPPoE Server service... ");
81
	} else {
82
		/* kill mpd */
83
		if (isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
84
			killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
85
		}
86

    
87
		/* wait for process to die */
88
		sleep(2);
89

    
90
	}
91

    
92
	switch ($pppoecfg['mode']) {
93

    
94
		case 'server':
95

    
96
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
97

    
98
			if ($pppoecfg['paporchap'] == "chap") {
99
				$paporchap = "set link enable chap";
100
			} else {
101
				$paporchap = "set link enable pap";
102
			}
103

    
104
			/* write mpd.conf */
105
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
106
			if (!$fd) {
107
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
108
				return 1;
109
			}
110

    
111
			$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 ";
112
			if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
113
				$issue_ip_type .= "0.0.0.0/0";
114
			} else {
115
				$issue_ip_type .= "ippool p0";
116
			}
117

    
118
			$ippool_p0 = ip_after($pppoecfg['remoteip'], $pppoecfg['n_pppoe_units'] - 1);
119

    
120
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
121
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
122
			} else {
123
				$pppoemaxlogins = 1;
124
			}
125

    
126
			$ipcp_dns = '';
127
			if (!empty($pppoecfg['dns1'])) {
128
				$ipcp_dns = "set ipcp dns " . $pppoecfg['dns1'];
129
				if (!empty($pppoecfg['dns2'])) {
130
					$ipcp_dns .= " " . $pppoecfg['dns2'];
131
				}
132
			} elseif (isset($config['dnsmasq']['enable']) ||
133
			    isset ($config['unbound']['enable'])) {
134
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
135
				if ($syscfg['dnsserver'][0]) {
136
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
137
				}
138
			} elseif (is_array($syscfg['dnsserver']) &&
139
			    ($syscfg['dnsserver'][0])) {
140
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
141
			}
142

    
143
			$mpdconf = <<<EOD
144
startup:
145

    
146
poes:
147
	set ippool add p0 {$pppoecfg['remoteip']} {$ippool_p0}
148

    
149
	create bundle template poes_b
150
	set bundle enable compression
151

    
152
	set ccp yes mppc
153
	set mppc yes e40
154
	set mppc yes e128
155
	set mppc yes stateless
156

    
157
	set iface group pppoe
158
	set iface up-script /usr/local/sbin/vpn-linkup-poes
159
	set iface down-script /usr/local/sbin/vpn-linkdown-poes
160
	set iface idle 0
161
	set iface disable on-demand
162
	set iface disable proxy-arp
163
	set iface enable tcpmssfix
164
	set iface mtu 1500
165

    
166
	set ipcp no vjcomp
167
	{$issue_ip_type}
168
	{$ipcp_dns}
169

    
170
	create link template poes_l pppoe
171
	set link action bundle poes_b
172

    
173
	set auth max-logins {$pppoemaxlogins}
174

    
175
	set pppoe iface {$pppoe_interface}
176

    
177
	set link no multilink
178
	set link no pap chap
179
	{$paporchap}
180
	set link keep-alive 60 180
181
	set link max-redial -1
182
	set link mru 1492
183
	set link latency 1
184
	set link enable incoming
185

    
186
EOD;
187

    
188
			if (isset ($pppoecfg['radius']['server']['enable'])) {
189
				$radiusport = "";
190
				$radiusacctport = "";
191
				if (isset($pppoecfg['radius']['server']['port'])) {
192
					$radiusport = $pppoecfg['radius']['server']['port'];
193
				}
194
				if (isset($pppoecfg['radius']['server']['acctport'])) {
195
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
196
				}
197
				$mpdconf .= "\tset radius server {$pppoecfg['radius']['server']['ip']} \"{$pppoecfg['radius']['server']['secret']}\" {$radiusport} {$radiusacctport}\n";
198
				if (isset($pppoecfg['radius']['server2']['enable'])) {
199
					$radiusport = "";
200
					$radiusacctport = "";
201
					if (isset($pppoecfg['radius']['server2']['port'])) {
202
						$radiusport = $pppoecfg['radius']['server2']['port'];
203
					}
204
					if (isset($pppoecfg['radius']['server2']['acctport'])) {
205
						$radiusacctport = $pppoecfg['radius']['server2']['acctport'];
206
					}
207
					$mpdconf .= "\tset radius server {$pppoecfg['radius']['server2']['ip']} \"{$pppoecfg['radius']['server2']['secret2']}\" {$radiusport} {$radiusacctport}\n";
208
				}
209

    
210
				$mpdconf .=<<<EOD
211
	set radius retries 3
212
	set radius timeout 10
213
	set auth enable radius-auth
214

    
215
EOD;
216

    
217
				if (isset ($pppoecfg['radius']['accounting'])) {
218
					$mpdconf .=<<<EOD
219
	set auth enable radius-acct
220

    
221
EOD;
222
				}
223
				if (!empty($pppoecfg['radius']['acct_update'])) {
224
					$mpdconf .= "\tset auth acct-update {$pppoecfg['radius']['acct_update']}\n";
225
				}
226
				if (!empty($pppoecfg['radius']['nasip'])) {
227
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
228
				}
229
			}
230

    
231
			fwrite($fd, $mpdconf);
232
			fclose($fd);
233
			unset($mpdconf);
234

    
235
			if ($pppoecfg['username']) {
236
				/* write mpd.secret */
237
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
238
				if (!$fd) {
239
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
240
					return 1;
241
				}
242

    
243
				$mpdsecret = "\n\n";
244

    
245
				if (!empty($pppoecfg['username'])) {
246
					$item = explode(" ", $pppoecfg['username']);
247
					foreach ($item as $userdata) {
248
						$data = explode(":", $userdata);
249
						/* Escape double quotes, do not allow password to start with '!'
250
						 * https://redmine.pfsense.org/issues/10275 */
251
						$pass = str_replace('"', '\"', ltrim(base64_decode($data[1]), '!'));
252
						$mpdsecret .= "{$data[0]} \"{$pass}\" {$data[2]}\n";
253
					}
254
				}
255

    
256
				fwrite($fd, $mpdsecret);
257
				fclose($fd);
258
				unset($mpdsecret);
259
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
260
			}
261

    
262
			/* Check if previous instance is still up */
263
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
264
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
265
			}
266

    
267
			/* Get support for netgraph(4) from the nic */
268
			pfSense_ngctl_attach(".", $pppoe_interface);
269
			/* fire up mpd */
270
			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");
271

    
272
			break;
273
	}
274

    
275
	if (platform_booting()) {
276
		echo gettext("done") . "\n";
277
	}
278

    
279
	return 0;
280
}
281

    
282
function vpn_l2tp_configure() {
283
	global $config, $g;
284

    
285
	$syscfg = $config['system'];
286
	$l2tpcfg = $config['l2tp'];
287

    
288
	/* create directory if it does not exist */
289
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
290
		mkdir("{$g['varetc_path']}/l2tp-vpn");
291
	}
292

    
293
	if (platform_booting()) {
294
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
295
			return 0;
296
		}
297

    
298
		echo gettext("Configuring l2tp VPN service... ");
299
	} else {
300
		/* kill mpd */
301
		if (isvalidpid("{$g['varrun_path']}/l2tp-vpn.pid")) {
302
			killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
303
		}
304

    
305
		/* wait for process to die */
306
		sleep(8);
307

    
308
	}
309

    
310
	/* make sure l2tp-vpn directory exists */
311
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
312
		mkdir("{$g['varetc_path']}/l2tp-vpn");
313
	}
314

    
315
	switch ($l2tpcfg['mode']) {
316

    
317
		case 'server':
318
			$l2tp_listen="";
319
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
320
			if (is_ipaddrv4($ipaddr)) {
321
				$l2tp_listen="set l2tp self $ipaddr";
322
			}
323

    
324
			switch ($l2tpcfg['paporchap']) {
325
				case 'chap':
326
					$paporchap = "set link enable chap";
327
					break;
328
				case 'chap-msv2':
329
					$paporchap = "set link enable chap-msv2";
330
					break;
331
				default:
332
					$paporchap = "set link enable pap";
333
					break;
334
			}
335

    
336
			/* write mpd.conf */
337
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
338
			if (!$fd) {
339
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
340
				return 1;
341
			}
342

    
343
			$ippool_p0 = ip_after($l2tpcfg['remoteip'], $l2tpcfg['n_l2tp_units'] - 1);
344

    
345
			$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 ";
346
			if (isset($l2tpcfg['radius']['radiusissueips']) && isset($l2tpcfg['radius']['enable'])) {
347
				$issue_ip_type .= "0.0.0.0/0";
348
				$ippool = "";
349
			} else {
350
				$issue_ip_type .= "ippool p0";
351
				$ippool = "set ippool add p0 {$l2tpcfg['remoteip']} {$ippool_p0}";
352
			}
353

    
354
			$ipcp_dns = '';
355
			if (is_ipaddr($l2tpcfg['dns1'])) {
356
				$ipcp_dns = "set ipcp dns " . $l2tpcfg['dns1'];
357
				if (is_ipaddr($l2tpcfg['dns2'])) {
358
					$ipcp_dns .= " " . $l2tpcfg['dns2'];
359
				}
360
			} elseif (isset ($config['dnsmasq']['enable']) ||
361
			    isset ($config['unbound']['enable'])) {
362
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
363
				if ($syscfg['dnsserver'][0]) {
364
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
365
				}
366
			} elseif (is_array($syscfg['dnsserver']) &&
367
			    ($syscfg['dnsserver'][0])) {
368
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
369
			}
370

    
371
			$mpdconf =<<<EOD
372

    
373
startup:
374

    
375
l2tps:
376
	{$ippool}
377

    
378
	create bundle template l2tp_b
379
	set bundle enable compression
380
	set bundle yes crypt-reqd
381

    
382
	set ccp yes mppc
383

    
384
	set iface name l2tp
385
	set iface group l2tp
386
	set iface up-script /usr/local/sbin/vpn-linkup-l2tp
387
	set iface down-script /usr/local/sbin/vpn-linkdown-l2tp
388
	set iface disable on-demand
389
	set iface enable proxy-arp
390

    
391
	set ipcp yes vjcomp
392
	{$issue_ip_type}
393
	{$ipcp_dns}
394

    
395
	create link template l2tp_l l2tp
396
	set link action bundle l2tp_b
397

    
398
	set link yes acfcomp protocomp
399
	set link enable multilink
400
	set link no pap chap chap-msv2
401
	{$paporchap}
402
	{$l2tp_listen}
403
	set link keep-alive 10 180
404
	set link enable incoming
405

    
406
EOD;
407
			if (!empty($l2tpcfg['secret'])) {
408
				$secret = str_replace('"', '\"', $l2tpcfg['secret']);
409
				$mpdconf .=<<<EOD
410
	set l2tp secret "{$secret}"
411

    
412
EOD;
413
			}
414

    
415

    
416
			if (isset ($l2tpcfg['radius']['enable'])) {
417
				$mpdconf .=<<<EOD
418
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
419
	set radius retries 3
420
	set radius timeout 10
421
	set auth disable internal
422
	set auth enable radius-auth
423

    
424
EOD;
425

    
426
				if (isset ($l2tpcfg['radius']['accounting'])) {
427
					$mpdconf .=<<<EOD
428
	set auth enable radius-acct
429

    
430
EOD;
431
				}
432
			}
433

    
434
			fwrite($fd, $mpdconf);
435
			fclose($fd);
436
			unset($mpdconf);
437

    
438
			vpn_l2tp_updatesecret();
439
			vpn_netgraph_support();
440

    
441
			/* fire up mpd */
442
			mwexec("/usr/local/sbin/mpd5 -b -d {$g['varetc_path']}/l2tp-vpn -p {$g['varrun_path']}/l2tp-vpn.pid -s l2tps l2tps");
443

    
444
			break;
445

    
446
		case 'redir':
447
			break;
448
	}
449

    
450
	if (platform_booting()) {
451
		echo "done\n";
452
	}
453

    
454
	return 0;
455
}
456

    
457
function vpn_l2tp_updatesecret() {
458
	global $config, $g;
459
	$l2tpcfg = $config['l2tp'];
460

    
461
	$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
462
	if (!$fd) {
463
		printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_updatesecret().") . "\n");
464
		return 1;
465
	}
466

    
467
	$mpdsecret = "\n\n";
468

    
469
	if (is_array($l2tpcfg['user'])) {
470
		foreach ($l2tpcfg['user'] as $user) {
471
			/* Escape double quotes, do not allow password to start with '!'
472
			 * https://redmine.pfsense.org/issues/10275 */
473
			$pass = str_replace('"', '\"', ltrim($user['password'], '!'));
474
			$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
475
		}
476
	}
477

    
478
	fwrite($fd, $mpdsecret);
479
	fclose($fd);
480
	unset($mpdsecret);
481
	chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
482

    
483
	return 0;
484
}
485

    
486
?>
(55-55/61)