Project

General

Profile

Download (18.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	services_unbound.php
4
*/
5
/* ====================================================================
6
 *	Copyright (c)  2004-2015  Electric Sheep Fencing, LLC. All rights reserved.
7
 *	Copyright (c)  2014 Warren Baker (warren@pfsense.org)
8
 *
9
 *	Redistribution and use in source and binary forms, with or without modification,
10
 *	are permitted provided that the following conditions are met:
11
 *
12
 *	1. Redistributions of source code must retain the above copyright notice,
13
 *		this list of conditions and the following disclaimer.
14
 *
15
 *	2. Redistributions in binary form must reproduce the above copyright
16
 *		notice, this list of conditions and the following disclaimer in
17
 *		the documentation and/or other materials provided with the
18
 *		distribution.
19
 *
20
 *	3. All advertising materials mentioning features or use of this software
21
 *		must display the following acknowledgment:
22
 *		"This product includes software developed by the pfSense Project
23
 *		 for use in the pfSense software distribution. (http://www.pfsense.org/).
24
 *
25
 *	4. The names "pfSense" and "pfSense Project" must not be used to
26
 *		 endorse or promote products derived from this software without
27
 *		 prior written permission. For written permission, please contact
28
 *		 coreteam@pfsense.org.
29
 *
30
 *	5. Products derived from this software may not be called "pfSense"
31
 *		nor may "pfSense" appear in their names without prior written
32
 *		permission of the Electric Sheep Fencing, LLC.
33
 *
34
 *	6. Redistributions of any form whatsoever must retain the following
35
 *		acknowledgment:
36
 *
37
 *	"This product includes software developed by the pfSense Project
38
 *	for use in the pfSense software distribution (http://www.pfsense.org/).
39
 *
40
 *	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
41
 *	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 *	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43
 *	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
44
 *	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45
 *	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46
 *	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 *	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49
 *	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50
 *	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51
 *	OF THE POSSIBILITY OF SUCH DAMAGE.
52
 *
53
 *	====================================================================
54
 *
55
 */
56
/*
57
	pfSense_MODULE: dnsresolver
58
*/
59

    
60
##|+PRIV
61
##|*IDENT=page-services-dnsresolver
62
##|*NAME=Services: DNS Resolver
63
##|*DESCR=Allow access to the 'Services: DNS Resolver' page.
64
##|*MATCH=services_unbound.php*
65
##|-PRIV
66

    
67
require_once("guiconfig.inc");
68
require_once("unbound.inc");
69
require_once("system.inc");
70

    
71
if (!is_array($config['unbound'])) {
72
	$config['unbound'] = array();
73
}
74

    
75
$a_unboundcfg =& $config['unbound'];
76

    
77
if (!is_array($a_unboundcfg['hosts'])) {
78
	$a_unboundcfg['hosts'] = array();
79
}
80

    
81
$a_hosts =& $a_unboundcfg['hosts'];
82

    
83
if (!is_array($a_unboundcfg['domainoverrides'])) {
84
	$a_unboundcfg['domainoverrides'] = array();
85
}
86

    
87
$a_domainOverrides = &$a_unboundcfg['domainoverrides'];
88

    
89
if (isset($a_unboundcfg['enable'])) {
90
	$pconfig['enable'] = true;
91
}
92
if (isset($a_unboundcfg['dnssec'])) {
93
	$pconfig['dnssec'] = true;
94
}
95
if (isset($a_unboundcfg['forwarding'])) {
96
	$pconfig['forwarding'] = true;
97
}
98
if (isset($a_unboundcfg['regdhcp'])) {
99
	$pconfig['regdhcp'] = true;
100
}
101
if (isset($a_unboundcfg['regdhcpstatic'])) {
102
	$pconfig['regdhcpstatic'] = true;
103
}
104

    
105
$pconfig['port'] = $a_unboundcfg['port'];
106
$pconfig['custom_options'] = base64_decode($a_unboundcfg['custom_options']);
107

    
108
if (empty($a_unboundcfg['active_interface'])) {
109
	$pconfig['active_interface'] = array();
110
} else {
111
	$pconfig['active_interface'] = explode(",", $a_unboundcfg['active_interface']);
112
}
113

    
114
if (empty($a_unboundcfg['outgoing_interface'])) {
115
	$pconfig['outgoing_interface'] = array();
116
} else {
117
	$pconfig['outgoing_interface'] = explode(",", $a_unboundcfg['outgoing_interface']);
118
}
119

    
120
if (empty($a_unboundcfg['system_domain_local_zone_type'])) {
121
	$pconfig['system_domain_local_zone_type'] = "transparent";
122
} else {
123
	$pconfig['system_domain_local_zone_type'] = $a_unboundcfg['system_domain_local_zone_type'];
124
}
125

    
126
if ($_POST) {
127
	if ($_POST['apply']) {
128
		$retval = services_unbound_configure();
129
		$savemsg = get_std_save_message($retval);
130
		if ($retval == 0) {
131
			clear_subsystem_dirty('unbound');
132
		}
133
		/* Update resolv.conf in case the interface bindings exclude localhost. */
134
		system_resolvconf_generate();
135
		/* Start or restart dhcpleases when it's necessary */
136
		system_dhcpleases_configure();
137
	} else {
138
		$pconfig = $_POST;
139
		unset($input_errors);
140

    
141
		if (isset($pconfig['enable']) && isset($config['dnsmasq']['enable'])) {
142
			if ($pconfig['port'] == $config['dnsmasq']['port']) {
143
				$input_errors[] = "The DNS Forwarder is enabled using this port. Choose a non-conflicting port, or disable the DNS Forwarder.";
144
			}
145
		}
146

    
147
		if (empty($pconfig['active_interface'])) {
148
			$input_errors[] = "One or more Network Interfaces must be selected for binding.";
149
		} else if (!isset($config['system']['dnslocalhost']) && (!in_array("lo0", $pconfig['active_interface']) && !in_array("all", $pconfig['active_interface']))) {
150
			$input_errors[] = "This system is configured to use the DNS Resolver as its DNS server, so Localhost or All must be selected in Network Interfaces.";
151
		}
152

    
153
		if (empty($pconfig['outgoing_interface'])) {
154
			$input_errors[] = "One or more Outgoing Network Interfaces must be selected.";
155
		}
156

    
157
		if (empty($pconfig['system_domain_local_zone_type'])) {
158
			$input_errors[] = "A System Domain Local-Zone Type must be selected.";
159
		}
160

    
161
		if ($pconfig['port'] && !is_port($pconfig['port'])) {
162
			$input_errors[] = gettext("You must specify a valid port number.");
163
		}
164

    
165
		if (is_array($pconfig['active_interface']) && !empty($pconfig['active_interface'])) {
166
			$display_active_interface = $pconfig['active_interface'];
167
			$pconfig['active_interface'] = implode(",", $pconfig['active_interface']);
168
		}
169

    
170
		$display_custom_options = $pconfig['custom_options'];
171
		$pconfig['custom_options'] = base64_encode(str_replace("\r\n", "\n", $pconfig['custom_options']));
172

    
173
		if (is_array($pconfig['outgoing_interface']) && !empty($pconfig['outgoing_interface'])) {
174
			$display_outgoing_interface = $pconfig['outgoing_interface'];
175
			$pconfig['outgoing_interface'] = implode(",", $pconfig['outgoing_interface']);
176
		}
177

    
178
		if (isset($pconfig['system_domain_local_zone_type']) && !empty($pconfig['system_domain_local_zone_type'])) {
179
			$display_system_domain_local_zone_type = $pconfig['system_domain_local_zone_type'];
180
			$pconfig['system_domain_local_zone_type'] = $pconfig['system_domain_local_zone_type'];
181
		}
182

    
183
		$test_output = array();
184
		if (test_unbound_config($pconfig, $test_output)) {
185
			$input_errors[] = gettext("The generated config file cannot be parsed by unbound. Please correct the following errors:");
186
			$input_errors = array_merge($input_errors, $test_output);
187
		}
188

    
189
		if (!$input_errors) {
190
			$a_unboundcfg['enable'] = isset($pconfig['enable']);
191
			$a_unboundcfg['port'] = $pconfig['port'];
192
			$a_unboundcfg['dnssec'] = isset($pconfig['dnssec']);
193
			$a_unboundcfg['forwarding'] = isset($pconfig['forwarding']);
194
			$a_unboundcfg['regdhcp'] = isset($pconfig['regdhcp']);
195
			$a_unboundcfg['regdhcpstatic'] = isset($pconfig['regdhcpstatic']);
196
			$a_unboundcfg['active_interface'] = $pconfig['active_interface'];
197
			$a_unboundcfg['outgoing_interface'] = $pconfig['outgoing_interface'];
198
			$a_unboundcfg['system_domain_local_zone_type'] = $pconfig['system_domain_local_zone_type'];
199
			$a_unboundcfg['custom_options'] = $pconfig['custom_options'];
200

    
201
			write_config("DNS Resolver configured.");
202
			mark_subsystem_dirty('unbound');
203
		}
204

    
205
		$pconfig['active_interface'] = $display_active_interface;
206
		$pconfig['outgoing_interface'] = $display_outgoing_interface;
207
		$pconfig['system_domain_local_zone_type'] = $display_system_domain_local_zone_type;
208
		$pconfig['custom_options'] = $display_custom_options;
209
	}
210
}
211

    
212
if ($_GET['act'] == "del") {
213
	if ($_GET['type'] == 'host') {
214
		if ($a_hosts[$_GET['id']]) {
215
			unset($a_hosts[$_GET['id']]);
216
			write_config();
217
			mark_subsystem_dirty('unbound');
218
			header("Location: services_unbound.php");
219
			exit;
220
		}
221
	} elseif ($_GET['type'] == 'doverride') {
222
		if ($a_domainOverrides[$_GET['id']]) {
223
			unset($a_domainOverrides[$_GET['id']]);
224
			write_config();
225
			mark_subsystem_dirty('unbound');
226
			header("Location: services_unbound.php");
227
			exit;
228
		}
229
	}
230
}
231

    
232
function build_if_list($selectedifs) {
233
	$interface_addresses = get_possible_listen_ips(true);
234
	$iflist = array('options' => array(), 'selected' => array());
235

    
236
	$iflist['options']['all']	= "All";
237
	if (empty($selectedifs) || empty($selectedifs[0]) || in_array("all", $selectedifs)) {
238
		array_push($iflist['selected'], "all");
239
	}
240

    
241
	foreach ($interface_addresses as $laddr => $ldescr) {
242
		$iflist['options'][$laddr] = htmlspecialchars($ldescr);
243

    
244
		if ($selectedifs && in_array($laddr, $selectedifs))
245
			array_push($iflist['selected'], $laddr);
246
	}
247

    
248
	unset($interface_addresses);
249

    
250
	return($iflist);
251
}
252

    
253
$closehead = false;
254
$pgtitle = array(gettext("Services"), gettext("DNS Resolver"), gettext("General"));
255
$shortcut_section = "resolver";
256

    
257
include_once("head.inc");
258

    
259
if ($input_errors)
260
	print_input_errors($input_errors);
261

    
262
if ($savemsg)
263
	print_info_box($savemsg, 'success');
264

    
265
if (is_subsystem_dirty('unbound')) {
266
	print_info_box_np(gettext("The configuration of the DNS Resolver has been changed. You must apply changes for them to take effect."));
267
}
268

    
269
$tab_array = array();
270
$tab_array[] = array(gettext("General settings"), true, "services_unbound.php");
271
$tab_array[] = array(gettext("Advanced settings"), false, "services_unbound_advanced.php");
272
$tab_array[] = array(gettext("Access Lists"), false, "/services_unbound_acls.php");
273
display_top_tabs($tab_array, true);
274

    
275
$form = new Form();
276

    
277
$section = new Form_Section('General DNS Resolver Options');
278

    
279
$section->addInput(new Form_Checkbox(
280
	'enable',
281
	'Enable',
282
	'Enable DNS resolver',
283
	$pconfig['enable']
284
));
285

    
286
$section->addInput(new Form_Input(
287
	'port',
288
	'Listen Port',
289
	'number',
290
	$pconfig['port'],
291
	['placeholder' => '53']
292
))->setHelp('The port used for responding to DNS queries. It should normally be left blank unless another service needs to bind to TCP/UDP port 53.');
293

    
294
$activeiflist = build_if_list($pconfig['active_interface']);
295

    
296
$section->addInput(new Form_Select(
297
	'active_interface',
298
	'Network Interfaces',
299
	$activeiflist['selected'],
300
	$activeiflist['options'],
301
	true
302
))->setHelp('Interface IPs used by the DNS Resolver for responding to queries from clients. If an interface has both IPv4 and IPv6 IPs, both are used. Queries to other interface IPs not selected below are discarded. ' .
303
			'The default behavior is to respond to queries on every available IPv4 and IPv6 address.');
304

    
305
$outiflist = build_if_list($pconfig['outgoing_interface']);
306

    
307
$section->addInput(new Form_Select(
308
	'outgoing_interface',
309
	'Outgoing Network Interfaces',
310
	$outiflist['selected'],
311
	$outiflist['options'],
312
	true
313
))->setHelp('Utilize different network interface(s) that the DNS Resolver will use to send queries to authoritative servers and receive their replies. By default all interfaces are used.');
314

    
315
$unbound_local_zone_types = array("deny" => gettext("Deny"), "refuse" => gettext("Refuse"), "static" => gettext("Static"), "transparent" => gettext("Transparent"), "typetransparent" => gettext("Type Transparent"), "redirect" => gettext("Redirect"), "inform" => gettext("Inform"), "inform_deny" => gettext("Inform Deny"), "nodefault" => gettext("No Default"));
316

    
317
$section->addInput(new Form_Select(
318
	'system_domain_local_zone_type',
319
	'System Domain Local Zone Type',
320
	$pconfig['system_domain_local_zone_type'],
321
	$unbound_local_zone_types
322
))->setHelp('The local-zone type used for the pfSense system domain (System | General Setup | Domain).  Transparent is the default.  Local-Zone type descriptions are available in the unbound.conf(5) manual pages.');
323

    
324
$section->addInput(new Form_Checkbox(
325
	'dnssec',
326
	'DNSSEC',
327
	'Enable DNSSEC Support',
328
	$pconfig['dnssec']
329
));
330

    
331
$section->addInput(new Form_Checkbox(
332
	'forwarding',
333
	'DNS Query Forwarding',
334
	'Enable Forwarding Mode',
335
	$pconfig['forwarding']
336
));
337

    
338
$section->addInput(new Form_Checkbox(
339
	'regdhcp',
340
	'DHCP Registration',
341
	'Register DHCP leases in the DNS Resolver',
342
	$pconfig['regdhcp']
343
))->setHelp(sprintf('If this option is set, then machines that specify their hostname when requesting a DHCP lease will be registered'.
344
					' in the DNS Resolver, so that their name can be resolved.'.
345
					' You should also set the domain in %sSystem: General setup%s to the proper value.','<a href="system.php">','</a>'));
346

    
347
$section->addInput(new Form_Checkbox(
348
	'regdhcpstatic',
349
	'Static DHCP',
350
	'Register DHCP static mappings in the DNS Resolver',
351
	$pconfig['regdhcpstatic']
352
))->setHelp(sprintf('If this option is set, then DHCP static mappings will be registered in the DNS Resolver, so that their name can be '.
353
					'resolved. You should also set the domain in %s'.
354
					'System: General setup%s to the proper value.','<a href="system.php">','</a>'));
355

    
356
$btnadvdns = new Form_Button(
357
	'btnadvdns',
358
	'Custom options'
359
);
360

    
361
$btnadvdns->removeClass('btn-primary')->addClass('btn-default btn-sm');
362

    
363
$section->addInput(new Form_StaticText(
364
	'Custom options',
365
	$btnadvdns . '&nbsp;' . 'Show custom options'
366
));
367

    
368
$section->addInput(new Form_Textarea (
369
	'custom_options',
370
	'Custom options',
371
	$pconfig['custom_options']
372
))->setHelp('Enter any additional configuration parameters to add to the DNS Resolver configuration here, separated by a newline');
373

    
374
$form->add($section);
375
print($form);
376
?>
377

    
378
<script type="text/javascript">
379
//<![CDATA[
380
events.push(function(){
381

    
382
	// If the enable checkbox is not checked, disable the next three checkboxes
383
	function disableDHCP() {
384
		var hide = ! $('#enable').prop('checked');
385

    
386
		disableInput('port', hide);
387
		disableInput('active_interface', hide);
388
		disableInput('outgoing_interface', hide);
389
		disableInput('system_domain_local_zone_type', hide);
390
		disableInput('regdhcpstatic', hide);
391
		disableInput('dnssec', hide);
392
		disableInput('forwarding', hide);
393
		disableInput('regdhcp', hide);
394
		disableInput('regdhcpstatic', hide);
395
		disableInput('btnadvdns', hide);
396
	}
397

    
398
	// Make the 'additional options' button a plain button, not a submit button
399
	$("#btnadvdns").prop('type','button');
400

    
401
	// Un-hide additional  controls
402
	$("#btnadvdns").click(function() {
403
		hideInput('custom_options', false);
404

    
405
	});
406

    
407
	// When 'enable' is clicked, disable/enable the following three checkboxes
408
	$('#enable').click(function() {
409
		disableDHCP();
410
	});
411

    
412
	// On initial load
413
	if($('#custom_options').val().length == 0) {
414
		hideInput('custom_options', true);
415
	}
416

    
417
	disableDHCP();
418

    
419
});
420
//]]>
421
</script>
422

    
423
<div class="panel panel-default">
424
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Host Overrides")?></h2></div>
425
	<div class="panel-body table-responsive">
426
		<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap" data-sortable>
427
			<thead>
428
				<tr>
429
					<th><?=gettext("Host")?></th>
430
					<th><?=gettext("Domain")?></th>
431
					<th><?=gettext("IP")?></th>
432
					<th><?=gettext("Description")?></th>
433
					<th></th>
434
				</tr>
435
			</thead>
436
			<tbody>
437
<?php
438
$i = 0;
439
foreach ($a_hosts as $hostent):
440
?>
441
				<tr>
442
					<td>
443
						<?=$hostent['host']?>
444
					</td>
445
					<td>
446
						<?=$hostent['domain']?>
447
					</td>
448
					<td>
449
						<?=$hostent['ip']?>
450
					</td>
451
					<td>
452
						<?=htmlspecialchars($hostent['descr'])?>
453
					</td>
454
					<td>
455
						<a class="fa fa-pencil"	title="<?=gettext('Edit host override')?>" href="services_unbound_host_edit.php?id=<?=$i?>"></a>
456
						<a class="fa fa-trash"	title="<?=gettext('Delete host override')?>" href="services_unbound.php?type=host&amp;act=del&amp;id=<?=$i?>"></a>
457
					</td>
458
				</tr>
459

    
460
<?php
461
	if ($hostent['aliases']['item'] && is_array($hostent['aliases']['item'])):
462
		foreach ($hostent['aliases']['item'] as $alias):
463
?>
464
				<tr>
465
					<td>
466
						<?=$alias['host']?>
467
					</td>
468
					<td>
469
						<?=$alias['domain']?>
470
					</td>
471
					<td>
472
						Alias for <?=$hostent['host'] ? $hostent['host'] . '.' . $hostent['domain'] : $hostent['domain']?>
473
					</td>
474
					<td>
475
						<i class="fa fa-angle-double-right text-info"></i>
476
						<?=htmlspecialchars($alias['description'])?>
477
					</td>
478
					<td>
479
						<a a class="fa fa-pencil"	title="<?=gettext('Edit host override')?>" 	href="services_unbound_host_edit.php?id=<?=$i?>"></a>
480
					</td>
481
				</tr>
482
<?php
483
		endforeach;
484
	endif;
485
	$i++;
486
endforeach;
487
?>
488
			</tbody>
489
		</table>
490
	</div>
491
</div>
492

    
493
<nav class="action-buttons">
494
	<a href="services_unbound_host_edit.php" class="btn btn-sm btn-success">
495
		<i class="fa fa-plus icon-embed-btn"></i>
496
		<?=gettext('Add')?>
497
	</a>
498
</nav>
499

    
500
<div class="panel panel-default">
501
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Domain Overrides")?></h2></div>
502
	<div class="panel-body table-responsive">
503
		<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap" data-sortable>
504
			<thead>
505
				<tr>
506
					<th><?=gettext("Domain")?></th>
507
					<th><?=gettext("IP")?></th>
508
					<th><?=gettext("Description")?></th>
509
					<th></th>
510
				</tr>
511
			</thead>
512

    
513
			<tbody>
514
<?php
515
$i = 0;
516
foreach ($a_domainOverrides as $doment):
517
?>
518
				<tr>
519
					<td>
520
						<?=$doment['domain']?>&nbsp;
521
					</td>
522
					<td>
523
						<?=$doment['ip']?>&nbsp;
524
					</td>
525
					<td>
526
						<?=htmlspecialchars($doment['descr'])?>&nbsp;
527
					</td>
528
					<td>
529
						<a class="fa fa-pencil"	title="<?=gettext('Edit domain override')?>" href="services_unbound_domainoverride_edit.php?id=<?=$i?>"></a>
530
						<a class="fa fa-trash"	title="<?=gettext('Delete domain override')?>" href="services_unbound.php?act=del&amp;type=doverride&amp;id=<?=$i?>"></a>
531
					</td>
532
				</tr>
533
<?php
534
	$i++;
535
endforeach;
536
?>
537
			</tbody>
538
		</table>
539
	</div>
540
</div>
541

    
542
<nav class="action-buttons">
543
	<a href="services_unbound_domainoverride_edit.php" class="btn btn-sm btn-success">
544
		<i class="fa fa-plus icon-embed-btn"></i>
545
		<?=gettext('Add')?>
546
	</a>
547
</nav>
548

    
549
<div id="infoblock">
550
	<?=print_info_box(sprintf(gettext("If the DNS Resolver is enabled, the DHCP".
551
		" service (if enabled) will automatically serve the LAN IP".
552
		" address as a DNS server to DHCP clients so they will use".
553
		" the DNS Resolver. If Forwarding is enabled, the DNS Resolver will use the DNS servers".
554
		" entered in %sSystem: General setup%s".
555
		" or those obtained via DHCP or PPP on WAN if &quot;Allow".
556
		" DNS server list to be overridden by DHCP/PPP on WAN&quot;".
557
		" is checked."),'<a href="system.php">','</a>'), info)?>
558
</div>
559

    
560
<?php include("foot.inc");
(140-140/228)