Project

General

Profile

Download (15.1 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_once('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

    
357
	// If the enable checkbox is not checked, disable the next three checkboxes
358
	function disableDHCP() {
359
		var hide = ! $('#enable').prop('checked');
360

    
361
		disableInput('port', hide);
362
		disableInput('active_interface', hide);
363
		disableInput('outgoing_interface', hide);
364
		disableInput('regdhcpstatic', hide);
365
		disableInput('dnssec', hide);
366
		disableInput('forwarding', hide);
367
		disableInput('regdhcp', hide);
368
		disableInput('regdhcpstatic', hide);
369
		disableInput('txtsupport', hide);
370
		disableInput('btnadvdns', hide);
371
	}
372

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

    
376
	// Un-hide aditional  controls
377
	$("#btnadvdns").click(function() {
378
		hideInput('custom_options', false);
379

    
380
	});
381

    
382
	// When 'enable' is clicked, diable/enable the following three checkboxes
383
	$('#enable').click(function() {
384
		disableDHCP();
385
	});
386

    
387
	// On initial load
388
	hideInput('custom_options', true);
389
	disableDHCP();
390

    
391
});
392
//]]>
393
</script>
394

    
395
<div class="panel panel-default">
396
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Host Overrides")?></h2></div>
397
	<div class="panel-body table-responsive">
398
		<table class="table table-striped table-hover table-condensed">
399
			<thead>
400
				<tr>
401
					<th><?=gettext("Host")?></th>
402
					<th><?=gettext("Domain")?></th>
403
					<th><?=gettext("IP")?></th>
404
					<th><?=gettext("Description")?></th>
405
					<th></th>
406
				</tr>
407
			</thead>
408
			<tbody>
409
<?php
410
$i = 0;
411
foreach ($a_hosts as $hostent):
412
?>
413
				<tr>
414
					<td>
415
						<?=strtolower($hostent['host'])?>
416
					</td>
417
					<td>
418
						<?=strtolower($hostent['domain'])?>
419
					</td>
420
					<td>
421
						<?=$hostent['ip']?>&nbsp;
422
					</td>
423
					<td>
424
						<?=htmlspecialchars($hostent['descr'])?>
425
					</td>
426
					<td>
427
						<a href="services_unbound_host_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
428
						<a href="services_unbound.php?type=host&amp;act=del&amp;id=<?=$i?>" class="btn btn-xs btn-danger"><?=gettext('Delete')?></a>
429
					</td>
430
				</tr>
431

    
432
<?php
433
	if ($hostent['aliases']['item'] && is_array($hostent['aliases']['item'])):
434
		foreach ($hostent['aliases']['item'] as $alias):
435
?>
436
				<tr>
437
					<td>
438
						<?=strtolower($alias['host'])?>
439
					</td>
440
					<td>
441
						<?=strtolower($alias['domain'])?>
442
					</td>
443
					<td>
444
						Alias for <?=$hostent['host'] ? $hostent['host'] . '.' . $hostent['domain'] : $hostent['domain']?>
445
					</td>
446
					<td>
447
						<?=htmlspecialchars($alias['description'])?>
448
					</td>
449
					<td>
450
						<a href="services_unbound_host_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
451
					</td>
452
				</tr>
453
<?php
454
		endforeach;
455
	endif;
456
	$i++;
457
endforeach;
458
?>
459
			</tbody>
460
		</table>
461
	</div>
462
</div>
463

    
464
<nav class="action-buttons">
465
	<a href="services_unbound_host_edit.php" class="btn btn-sm btn-success"><?=gettext('Add')?></a>
466
</nav>
467

    
468
<div class="panel panel-default">
469
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Domain Overrides")?></h2></div>
470
	<div class="panel-body table-responsive">
471
		<table class="table table-striped table-hover table-condensed">
472
			<thead>
473
				<tr>
474
					<th><?=gettext("Domain")?></th>
475
					<th><?=gettext("IP")?></th>
476
					<th><?=gettext("Description")?></th>
477
					<th></th>
478
				</tr>
479
			</thead>
480

    
481
			<tbody>
482
<?php
483
$i = 0;
484
foreach ($a_domainOverrides as $doment):
485
?>
486
				<tr>
487
					<td>
488
						<?=strtolower($doment['domain'])?>&nbsp;
489
					</td>
490
					<td>
491
						<?=$doment['ip']?>&nbsp;
492
					</td>
493
					<td>
494
						<?=htmlspecialchars($doment['descr'])?>&nbsp;
495
					</td>
496
					<td>
497
						<a href="services_unbound_domainoverride_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
498
						<a href="services_unbound.php?act=del&amp;type=doverride&amp;id=<?=$i?>" class="btn btn-xs btn-danger"><?=gettext('Delete')?></a>
499
					</td>
500
				</tr>
501
<?php
502
	$i++;
503
endforeach;
504
?>
505
			</tbody>
506
		</table>
507
	</div>
508
</div>
509

    
510
<nav class="action-buttons">
511
	<a href="services_unbound_domainoverride_edit.php" class="btn btn-sm btn-success"><?=gettext('Add')?></a>
512
</nav>
513
<?php include("foot.inc");
(153-153/235)