Project

General

Profile

Download (11.5 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
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
84

    
85
		/* wait for process to die */
86
		sleep(2);
87

    
88
	}
89

    
90
	switch ($pppoecfg['mode']) {
91

    
92
		case 'server':
93

    
94
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
95

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

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

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

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

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

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

    
141
			$mpdconf = <<<EOD
142
startup:
143

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

    
147
	create bundle template poes_b
148
	set bundle enable compression
149

    
150
	set ccp yes mppc
151
	set mppc yes e40
152
	set mppc yes e128
153
	set mppc yes stateless
154

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

    
164
	set ipcp no vjcomp
165
	{$issue_ip_type}
166
	{$ipcp_dns}
167

    
168
	create link template poes_l pppoe
169
	set link action bundle poes_b
170

    
171
	set auth max-logins {$pppoemaxlogins}
172

    
173
	set pppoe iface {$pppoe_interface}
174

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

    
184
EOD;
185

    
186
			if (isset ($pppoecfg['radius']['server']['enable'])) {
187
				$radiusport = "";
188
				$radiusacctport = "";
189
				if (isset($pppoecfg['radius']['server']['port'])) {
190
					$radiusport = $pppoecfg['radius']['server']['port'];
191
				}
192
				if (isset($pppoecfg['radius']['server']['acctport'])) {
193
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
194
				}
195
				$mpdconf .=<<<EOD
196
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
197
	set radius retries 3
198
	set radius timeout 10
199
	set auth enable radius-auth
200

    
201
EOD;
202

    
203
				if (isset ($pppoecfg['radius']['accounting'])) {
204
					$mpdconf .=<<<EOD
205
	set auth enable radius-acct
206

    
207
EOD;
208
				}
209
				if (!empty($pppoecfg['radius']['nasip'])) {
210
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
211
				}
212
			}
213

    
214
			fwrite($fd, $mpdconf);
215
			fclose($fd);
216
			unset($mpdconf);
217

    
218
			if ($pppoecfg['username']) {
219
				/* write mpd.secret */
220
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
221
				if (!$fd) {
222
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
223
					return 1;
224
				}
225

    
226
				$mpdsecret = "\n\n";
227

    
228
				if (!empty($pppoecfg['username'])) {
229
					$item = explode(" ", $pppoecfg['username']);
230
					foreach ($item as $userdata) {
231
						$data = explode(":", $userdata);
232
						/* Escape double quotes, do not allow password to start with '!'
233
						 * https://redmine.pfsense.org/issues/10275 */
234
						$pass = str_replace('"', '\"', ltrim(base64_decode($data[1]), '!'));
235
						$mpdsecret .= "{$data[0]} \"{$pass}\" {$data[2]}\n";
236
					}
237
				}
238

    
239
				fwrite($fd, $mpdsecret);
240
				fclose($fd);
241
				unset($mpdsecret);
242
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
243
			}
244

    
245
			/* Check if previous instance is still up */
246
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
247
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
248
			}
249

    
250
			/* Get support for netgraph(4) from the nic */
251
			pfSense_ngctl_attach(".", $pppoe_interface);
252
			/* fire up mpd */
253
			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");
254

    
255
			break;
256
	}
257

    
258
	if (platform_booting()) {
259
		echo gettext("done") . "\n";
260
	}
261

    
262
	return 0;
263
}
264

    
265
function vpn_l2tp_configure() {
266
	global $config, $g;
267

    
268
	$syscfg = $config['system'];
269
	$l2tpcfg = $config['l2tp'];
270

    
271
	/* create directory if it does not exist */
272
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
273
		mkdir("{$g['varetc_path']}/l2tp-vpn");
274
	}
275

    
276
	if (platform_booting()) {
277
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
278
			return 0;
279
		}
280

    
281
		echo gettext("Configuring l2tp VPN service... ");
282
	} else {
283
		/* kill mpd */
284
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
285

    
286
		/* wait for process to die */
287
		sleep(8);
288

    
289
	}
290

    
291
	/* make sure l2tp-vpn directory exists */
292
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
293
		mkdir("{$g['varetc_path']}/l2tp-vpn");
294
	}
295

    
296
	switch ($l2tpcfg['mode']) {
297

    
298
		case 'server':
299
			$l2tp_listen="";
300
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
301
			if (is_ipaddrv4($ipaddr)) {
302
				$l2tp_listen="set l2tp self $ipaddr";
303
			}
304

    
305
			switch ($l2tpcfg['paporchap']) {
306
				case 'chap':
307
					$paporchap = "set link enable chap";
308
					break;
309
				case 'chap-msv2':
310
					$paporchap = "set link enable chap-msv2";
311
					break;
312
				default:
313
					$paporchap = "set link enable pap";
314
					break;
315
			}
316

    
317
			/* write mpd.conf */
318
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
319
			if (!$fd) {
320
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
321
				return 1;
322
			}
323

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

    
326
			$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 ";
327
			if (isset($l2tpcfg['radius']['radiusissueips']) && isset($l2tpcfg['radius']['server']['enable'])) {
328
				$issue_ip_type .= "0.0.0.0/0";
329
			} else {
330
				$issue_ip_type .= "ippool p0";
331
			}
332

    
333
			$ipcp_dns = '';
334
			if (is_ipaddr($l2tpcfg['dns1'])) {
335
				$ipcp_dns = "set ipcp dns " . $l2tpcfg['dns1'];
336
				if (is_ipaddr($l2tpcfg['dns2'])) {
337
					$ipcp_dns .= " " . $l2tpcfg['dns2'];
338
				}
339
			} elseif (isset ($config['dnsmasq']['enable']) ||
340
			    isset ($config['unbound']['enable'])) {
341
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
342
				if ($syscfg['dnsserver'][0]) {
343
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
344
				}
345
			} elseif (is_array($syscfg['dnsserver']) &&
346
			    ($syscfg['dnsserver'][0])) {
347
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
348
			}
349

    
350
			$mpdconf =<<<EOD
351

    
352
startup:
353

    
354
l2tps:
355
	set ippool add p0 {$l2tpcfg['remoteip']} {$ippool_p0}
356

    
357
	create bundle template l2tp_b
358
	set bundle enable compression
359
	set bundle yes crypt-reqd
360

    
361
	set ccp yes mppc
362

    
363
	set iface name l2tp
364
	set iface group l2tp
365
	set iface up-script /usr/local/sbin/vpn-linkup-l2tp
366
	set iface down-script /usr/local/sbin/vpn-linkdown-l2tp
367
	set iface disable on-demand
368
	set iface enable proxy-arp
369

    
370
	set ipcp yes vjcomp
371
	{$issue_ip_type}
372
	{$ipcp_dns}
373

    
374
	create link template l2tp_l l2tp
375
	set link action bundle l2tp_b
376

    
377
	set link yes acfcomp protocomp
378
	set link enable multilink
379
	set link no pap chap chap-msv2
380
	{$paporchap}
381
	{$l2tp_listen}
382
	set link keep-alive 10 180
383
	set link enable incoming
384

    
385
EOD;
386

    
387

    
388
			if (isset ($l2tpcfg['radius']['enable'])) {
389
				$mpdconf .=<<<EOD
390
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
391
	set radius retries 3
392
	set radius timeout 10
393
	set auth disable internal
394
	set auth enable radius-auth
395

    
396
EOD;
397

    
398
				if (isset ($l2tpcfg['radius']['accounting'])) {
399
					$mpdconf .=<<<EOD
400
	set auth enable radius-acct
401

    
402
EOD;
403
				}
404
			}
405

    
406
			fwrite($fd, $mpdconf);
407
			fclose($fd);
408
			unset($mpdconf);
409

    
410
			/* write mpd.secret */
411
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
412
			if (!$fd) {
413
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
414
				return 1;
415
			}
416

    
417
			$mpdsecret = "\n\n";
418

    
419
			if (is_array($l2tpcfg['user'])) {
420
				foreach ($l2tpcfg['user'] as $user) {
421
					/* Escape double quotes, do not allow password to start with '!'
422
					 * https://redmine.pfsense.org/issues/10275 */
423
					$pass = str_replace('"', '\"', ltrim($user['password'], '!'));
424
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
425
				}
426
			}
427

    
428
			fwrite($fd, $mpdsecret);
429
			fclose($fd);
430
			unset($mpdsecret);
431
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
432

    
433
			vpn_netgraph_support();
434

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

    
438
			break;
439

    
440
		case 'redir':
441
			break;
442
	}
443

    
444
	if (platform_booting()) {
445
		echo "done\n";
446
	}
447

    
448
	return 0;
449
}
450

    
451
?>
(55-55/60)