Project

General

Profile

Download (15.5 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	services_unbound.php
5
	part of the pfSense project (https://www.pfsense.org)
6
	Copyright (C) 2014	Warren Baker (warren@pfsense.org)
7
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
8
	All rights reserved.
9

    
10
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12

    
13
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15

    
16
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in the
18
	   documentation and/or other materials provided with the distribution.
19

    
20
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
	POSSIBILITY OF SUCH DAMAGE.
30
*/
31
/*
32
	pfSense_MODULE: dnsresolver
33
*/
34

    
35
##|+PRIV
36
##|*IDENT=page-services-unbound
37
##|*NAME=Services: DNS Resolver page
38
##|*DESCR=Allow access to the 'Services: DNS Resolver' page.
39
##|*MATCH=services_unbound.php*
40
##|-PRIV
41

    
42
require_once("guiconfig.inc");
43
require_once("unbound.inc");
44
require_once("system.inc");
45

    
46
if (!is_array($config['unbound'])) {
47
	$config['unbound'] = array();
48
}
49

    
50
$a_unboundcfg =& $config['unbound'];
51

    
52
if (!is_array($config['unbound']['hosts'])) {
53
	$config['unbound']['hosts'] = array();
54
}
55

    
56
$a_hosts =& $config['unbound']['hosts'];
57

    
58
if (!is_array($config['unbound']['domainoverrides'])) {
59
	$config['unbound']['domainoverrides'] = array();
60
}
61

    
62
$a_domainOverrides = &$config['unbound']['domainoverrides'];
63

    
64
if (isset($config['unbound']['enable'])) {
65
	$pconfig['enable'] = true;
66
}
67
if (isset($config['unbound']['dnssec'])) {
68
	$pconfig['dnssec'] = true;
69
}
70
if (isset($config['unbound']['forwarding'])) {
71
	$pconfig['forwarding'] = true;
72
}
73
if (isset($config['unbound']['regdhcp'])) {
74
	$pconfig['regdhcp'] = true;
75
}
76
if (isset($config['unbound']['regdhcpstatic'])) {
77
	$pconfig['regdhcpstatic'] = true;
78
}
79
if (isset($config['unbound']['txtsupport'])) {
80
	$pconfig['txtsupport'] = true;
81
}
82

    
83
$pconfig['port'] = $config['unbound']['port'];
84
$pconfig['custom_options'] = base64_decode($config['unbound']['custom_options']);
85

    
86
if (empty($config['unbound']['active_interface'])) {
87
	$pconfig['active_interface'] = array();
88
} else {
89
	$pconfig['active_interface'] = explode(",", $config['unbound']['active_interface']);
90
}
91

    
92
if (empty($config['unbound']['outgoing_interface'])) {
93
	$pconfig['outgoing_interface'] = array();
94
} else {
95
	$pconfig['outgoing_interface'] = explode(",", $config['unbound']['outgoing_interface']);
96
}
97

    
98
if ($_POST) {
99
	$pconfig = $_POST;
100
	unset($input_errors);
101

    
102
	if ($_POST['apply']) {
103
		$retval = services_unbound_configure();
104
		$savemsg = get_std_save_message($retval);
105
		if ($retval == 0) {
106
			clear_subsystem_dirty('unbound');
107
		}
108
		/* Update resolv.conf in case the interface bindings exclude localhost. */
109
		system_resolvconf_generate();
110
		/* Start or restart dhcpleases when it's necessary */
111
		system_dhcpleases_configure();
112
	} else {
113
		if (isset($_POST['enable']) && isset($config['dnsmasq']['enable'])) {
114
			if ($_POST['port'] == $config['dnsmasq']['port']) {
115
				$input_errors[] = "The DNS Forwarder is enabled using this port. Choose a non-conflicting port, or disable the DNS Forwarder.";
116
			}
117
		}
118

    
119
		if (empty($_POST['active_interface'])) {
120
			$input_errors[] = "One or more Network Interfaces must be selected for binding.";
121
		} else if (!isset($config['system']['dnslocalhost']) && (!in_array("lo0", $_POST['active_interface']) && !in_array("all", $_POST['active_interface']))) {
122
			$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.";
123
		}
124

    
125
		if (empty($_POST['outgoing_interface'])) {
126
			$input_errors[] = "One or more Outgoing Network Interfaces must be selected.";
127
		}
128

    
129
		if ($_POST['port']) {
130
			if (is_port($_POST['port'])) {
131
				$a_unboundcfg['port'] = $_POST['port'];
132
			} else {
133
				$input_errors[] = gettext("You must specify a valid port number.");
134
			}
135
		} else if (isset($config['unbound']['port'])) {
136
			unset($config['unbound']['port']);
137
		}
138

    
139
		if (isset($_POST['enable'])) {
140
			$a_unboundcfg['enable'] = true;
141
		} else {
142
			unset($a_unboundcfg['enable']);
143
		}
144
		if (isset($_POST['dnssec'])) {
145
			$a_unboundcfg['dnssec'] = true;
146
		} else {
147
			unset($a_unboundcfg['dnssec']);
148
		}
149
		if (isset($_POST['forwarding'])) {
150
			$a_unboundcfg['forwarding'] = true;
151
		} else {
152
			unset($a_unboundcfg['forwarding']);
153
		}
154
		if (isset($_POST['regdhcp'])) {
155
			$a_unboundcfg['regdhcp'] = true;
156
		} else {
157
			unset($a_unboundcfg['regdhcp']);
158
		}
159
		if (isset($_POST['regdhcpstatic'])) {
160
			$a_unboundcfg['regdhcpstatic'] = true;
161
		} else {
162
			unset($a_unboundcfg['regdhcpstatic']);
163
		}
164
		if (isset($_POST['txtsupport'])) {
165
			$a_unboundcfg['txtsupport'] = true;
166
		} else {
167
			unset($a_unboundcfg['txtsupport']);
168
		}
169
		if (is_array($_POST['active_interface']) && !empty($_POST['active_interface'])) {
170
			$a_unboundcfg['active_interface'] = implode(",", $_POST['active_interface']);
171
		}
172

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

    
177
		$a_unboundcfg['custom_options'] = base64_encode(str_replace("\r\n", "\n", $_POST['custom_options']));
178

    
179
		if (!$input_errors) {
180
			write_config("DNS Resolver configured.");
181
			mark_subsystem_dirty('unbound');
182
		}
183
	}
184
}
185

    
186
if ($_GET['act'] == "del") {
187
	if ($_GET['type'] == 'host') {
188
		if ($a_hosts[$_GET['id']]) {
189
			unset($a_hosts[$_GET['id']]);
190
			write_config();
191
			mark_subsystem_dirty('unbound');
192
			header("Location: services_unbound.php");
193
			exit;
194
		}
195
	} elseif ($_GET['type'] == 'doverride') {
196
		if ($a_domainOverrides[$_GET['id']]) {
197
			unset($a_domainOverrides[$_GET['id']]);
198
			write_config();
199
			mark_subsystem_dirty('unbound');
200
			header("Location: services_unbound.php");
201
			exit;
202
		}
203
	}
204
}
205

    
206
function build_if_list() {
207
	$interface_addresses = get_possible_listen_ips(true);
208
	$iflist = array('options' => array(), 'selected' => array());
209

    
210
	$iflist['options']['all']	= "All";
211
	if (empty($pconfig['interface']) || empty($pconfig['interface'][0]))
212
		array_push($iflist['selected'], "all");
213

    
214
	foreach ($interface_addresses as $laddr => $ldescr) {
215
		$iflist['options'][$laddr] = htmlspecialchars($ldescr);
216

    
217
		if ($pconfig['interface'] && in_array($laddr, $pconfig['interface']))
218
			array_push($iflist['selected'], $laddr);
219
	}
220

    
221
	unset($interface_addresses);
222

    
223
	return($iflist);
224
}
225

    
226
$closehead = false;
227
$pgtitle = array(gettext("Services"), gettext("DNS Resolver"));
228
$shortcut_section = "resolver";
229

    
230
include_once("head.inc");
231

    
232
if ($input_errors)
233
	print_input_errors($input_errors);
234

    
235
if ($savemsg)
236
	print_info_box($savemsg, 'success');
237

    
238
$tab_array = array();
239
$tab_array[] = array(gettext("General settings"), true, "services_unbound.php");
240
$tab_array[] = array(gettext("Advanced settings"), false, "services_unbound_advanced.php");
241
$tab_array[] = array(gettext("Access Lists"), false, "/services_unbound_acls.php");
242
display_top_tabs($tab_array, true);
243

    
244
require('classes/Form.class.php');
245

    
246
$form = new Form();
247

    
248
$section = new Form_Section('General DNS Resolver Options');
249

    
250
$section->addInput(new Form_Checkbox(
251
	'enable',
252
	'Enable',
253
	'Enable DNS resolver',
254
	$pconfig['enable']
255
));
256

    
257
$section->addInput(new Form_Input(
258
	'port',
259
	'Listen Port',
260
	'text',
261
	$pconfig['port']
262
))->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.');
263

    
264
$iflist = build_if_list();
265

    
266
$section->addInput(new Form_Select(
267
	'active_interface',
268
	'Network Interfaces',
269
	$iflist['selected'],
270
	$iflist['options'],
271
	true
272
))->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. ' .
273
			'The default behavior is to respond to queries on every available IPv4 and IPv6 address.');
274

    
275
$section->addInput(new Form_Select(
276
	'outgoing_interface',
277
	'Outgoing Network Interfaces',
278
	$iflist['selected'],
279
	$iflist['options'],
280
	true
281
))->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.');
282

    
283
$section->addInput(new Form_Checkbox(
284
	'dnssec',
285
	'DNSSEC',
286
	'Enable DNSSEC Support',
287
	$pconfig['dnssec']
288
));
289

    
290
$section->addInput(new Form_Checkbox(
291
	'forwarding',
292
	'DNS Query Forwarding',
293
	'Enable Forwarding Mode',
294
	$pconfig['forwarding']
295
));
296

    
297
$section->addInput(new Form_Checkbox(
298
	'regdhcp',
299
	'DHCP Registration',
300
	'Register DHCP leases in the DNS Resolver',
301
	$pconfig['regdhcp']
302
))->setHelp(sprintf('If this option is set, then machines that specify their hostname when requesting a DHCP lease will be registered'.
303
					' in the DNS Resolver, so that their name can be resolved.'.
304
					' You should also set the domain in %sSystem: General setup%s to the proper value.','<a href="system.php">','</a>'));
305

    
306
$section->addInput(new Form_Checkbox(
307
	'regdhcpstatic',
308
	'Static DHCP',
309
	'Register DHCP static mappings in the DNS Resolver',
310
	$pconfig['regdhcpstatic']
311
))->setHelp(sprintf('If this option is set, then DHCP static mappings will be registered in the DNS Resolver, so that their name can be '.
312
					'resolved. You should also set the domain in %s'.
313
					'System: General setup%s to the proper value.','<a href="system.php">','</a>'));
314

    
315
$section->addInput(new Form_Checkbox(
316
	'txtsupport',
317
	'TXT Comment Support',
318
	'Register DHCP static mappings in the DNS Resolver',
319
	$pconfig['txtsupport']
320
))->setHelp('Any descriptions associated with Host entries and DHCP Static mappings will create a corresponding TXT record.');
321

    
322
$btnadvdns = new Form_Button(
323
	'btnadvdns',
324
	'Advanced'
325
);
326

    
327
$btnadvdns->removeClass('btn-primary')->addClass('btn-default btn-sm');
328

    
329
$section->addInput(new Form_StaticText(
330
	'Advanced',
331
	$btnadvdns . '&nbsp;' . 'Show advanced optionss'
332
));
333

    
334
$section->addInput(new Form_TextArea (
335
	'custom_options',
336
	'Custom options',
337
	$pconfig['custom_options']
338
))->setHelp('Enter any additional configuration parameters to add to the DNS Resolver configuration here, separated by a newline');
339

    
340
$form->add($section);
341
print($form);
342

    
343
print_info_box(sprintf(gettext("If the DNS Resolver is enabled, the DHCP".
344
" service (if enabled) will automatically serve the LAN IP".
345
" address as a DNS server to DHCP clients so they will use".
346
" the DNS Resolver. If Forwarding, is enabled, the DNS Resolver will use the DNS servers".
347
" entered in %sSystem: General setup%s".
348
" or those obtained via DHCP or PPP on WAN if the &quot;Allow".
349
" DNS server list to be overridden by DHCP/PPP on WAN&quot;".
350
" is checked."),'<a href="system.php">','</a>'));
351
?>
352

    
353
<script>
354
//<![CDATA[
355
events.push(function(){
356
	// Hides the <div> in which the specified input element lives so that the input, its label and help text are hidden
357
	function hideInput(id, hide) {
358
		if(hide)
359
			$('#' + id).parent().parent('div').addClass('hidden');
360
		else
361
			$('#' + id).parent().parent('div').removeClass('hidden');
362
	}
363

    
364
	// Disables the specified input element
365
	function disableInput(id, disable) {
366
		$('#' + id).prop("disabled", disable);
367
	}
368

    
369
	// If hte enable checkbox is not checked, disable the next three checkboxes
370
	function disableDHCP() {
371
		var hide = ! $('#enable').prop('checked');
372

    
373
		disableInput('port', hide);
374
		disableInput('active_interface', hide);
375
		disableInput('outgoing_interface', hide);
376
		disableInput('regdhcpstatic', hide);
377
		disableInput('dnssec', hide);
378
		disableInput('forwarding', hide);
379
		disableInput('regdhcp', hide);
380
		disableInput('regdhcpstatic', hide);
381
		disableInput('txtsupport', hide);
382
		disableInput('btnadvdns', hide);
383
	}
384

    
385
	// Make the ‘aditional options’ button a plain button, not a submit button
386
	$("#btnadvdns").prop('type','button');
387

    
388
	// Un-hide aditional  controls
389
	$("#btnadvdns").click(function() {
390
		hideInput('custom_options', false);
391

    
392
	});
393

    
394
	// When 'enable' is clicked, diable/enable the following three checkboxes
395
	$('#enable').click(function() {
396
		disableDHCP();
397
	});
398

    
399
	// On initial load
400
	hideInput('custom_options', true);
401
	disableDHCP();
402

    
403
});
404
//]]>
405
</script>
406

    
407
<div class="panel panel-default">
408
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Host Overrides")?></h2></div>
409
	<div class="panel-body table-responsive">
410
		<table class="table table-striped table-hover table-condensed">
411
			<thead>
412
				<tr>
413
					<th><?=gettext("Host")?></th>
414
					<th><?=gettext("Domain")?></th>
415
					<th><?=gettext("IP")?></th>
416
					<th><?=gettext("Description")?></th>
417
					<th></th>
418
				</tr>
419
			</thead>
420
			<tbody>
421
<?php
422
$i = 0;
423
foreach ($a_hosts as $hostent):
424
?>
425
				<tr>
426
					<td>
427
						<?=strtolower($hostent['host'])?>
428
					</td>
429
					<td>
430
						<?=strtolower($hostent['domain'])?>
431
					</td>
432
					<td>
433
						<?=$hostent['ip']?>&nbsp;
434
					</td>
435
					<td>
436
						<?=htmlspecialchars($hostent['descr'])?>
437
					</td>
438
					<td>
439
						<a href="services_dnsmasq_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
440
						<a href="services_dnsmasq.php?type=host&amp;act=del&amp;id=<?=$i?>" class="btn btn-xs btn-danger"><?=gettext('Delete')?></a>
441
					</td>
442
				</tr>
443

    
444
<?php
445
	if ($hostent['aliases']['item'] && is_array($hostent['aliases']['item'])):
446
		foreach ($hostent['aliases']['item'] as $alias):
447
?>
448
				<tr>
449
					<td>
450
						<?=strtolower($alias['host'])?>
451
					</td>
452
					<td>
453
						<?=strtolower($alias['domain'])?>
454
					</td>
455
					<td>
456
						Alias for <?=$hostent['host'] ? $hostent['host'] . '.' . $hostent['domain'] : $hostent['domain']?>
457
					</td>
458
					<td>
459
						<?=htmlspecialchars($alias['description'])?>
460
					</td>
461
					<td>
462
						<a href="services_dnsmasq_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
463
					</td>
464
				</tr>
465
<?php
466
		endforeach;
467
	endif;
468
	$i++;
469
endforeach;
470
?>
471
			</tbody>
472
		</table>
473
	</div>
474
</div>
475

    
476
<nav class="action-buttons">
477
	<a href="services_dnsmasq_edit.php" class="btn btn-sm btn-success"><?=gettext('Add')?></a>
478
</nav>
479

    
480
<div class="panel panel-default">
481
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Domain Overrides")?></h2></div>
482
	<div class="panel-body table-responsive">
483
		<table class="table table-striped table-hover table-condensed">
484
			<thead>
485
				<tr>
486
					<th><?=gettext("Domain")?></th>
487
					<th><?=gettext("IP")?></th>
488
					<th><?=gettext("Description")?></th>
489
					<th></th>
490
				</tr>
491
			</thead>
492

    
493
			<tbody>
494
<?php
495
$i = 0;
496
foreach ($a_domainOverrides as $doment):
497
?>
498
				<tr>
499
					<td>
500
						<?=strtolower($doment['domain'])?>&nbsp;
501
					</td>
502
					<td>
503
						<?=$doment['ip']?>&nbsp;
504
					</td>
505
					<td>
506
						<?=htmlspecialchars($doment['descr'])?>&nbsp;
507
					</td>
508
					<td>
509
						<a href="services_unbound_domainoverride_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
510
						<a href="services_unbound.php?act=del&amp;type=doverride&amp;id=<?=$i?>" class="btn btn-xs btn-danger"><?=gettext('Delete')?></a>
511
					</td>
512
				</tr>
513
<?php
514
	$i++;
515
endforeach;
516
?>
517
			</tbody>
518
		</table>
519
	</div>
520
</div>
521

    
522
<nav class="action-buttons">
523
	<a href="services_unbound_domainoverride_edit.php" class="btn btn-sm btn-success"><?=gettext('Add')?></a>
524
</nav>
525
<?php include("foot.inc");
(152-152/237)