Project

General

Profile

Download (15 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	services_dnsmasq.php
5
	part of m0n0wall (http://m0n0.ch/wall)
6

    
7
	Copyright (C) 2003-2004 Bob Zoller <bob@kludgebox.com> and Manuel Kasper <mk@neon1.net>.
8
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
9
	All rights reserved.
10

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

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

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

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

    
36
##|+PRIV
37
##|*IDENT=page-services-dnsforwarder
38
##|*NAME=Services: DNS Forwarder page
39
##|*DESCR=Allow access to the 'Services: DNS Forwarder' page.
40
##|*MATCH=services_dnsmasq.php*
41
##|-PRIV
42

    
43
require("guiconfig.inc");
44
require_once("functions.inc");
45
require_once("filter.inc");
46
require_once("shaper.inc");
47
require_once("system.inc");
48

    
49
$pconfig['enable'] = isset($config['dnsmasq']['enable']);
50
$pconfig['regdhcp'] = isset($config['dnsmasq']['regdhcp']);
51
$pconfig['regdhcpstatic'] = isset($config['dnsmasq']['regdhcpstatic']);
52
$pconfig['dhcpfirst'] = isset($config['dnsmasq']['dhcpfirst']);
53
$pconfig['strict_order'] = isset($config['dnsmasq']['strict_order']);
54
$pconfig['domain_needed'] = isset($config['dnsmasq']['domain_needed']);
55
$pconfig['no_private_reverse'] = isset($config['dnsmasq']['no_private_reverse']);
56
$pconfig['port'] = $config['dnsmasq']['port'];
57
$pconfig['custom_options'] = $config['dnsmasq']['custom_options'];
58

    
59
$pconfig['strictbind'] = isset($config['dnsmasq']['strictbind']);
60

    
61
if (!empty($config['dnsmasq']['interface']))
62
	$pconfig['interface'] = explode(",", $config['dnsmasq']['interface']);
63
else
64
	$pconfig['interface'] = array();
65

    
66
if (!is_array($config['dnsmasq']['hosts']))
67
	$config['dnsmasq']['hosts'] = array();
68

    
69
if (!is_array($config['dnsmasq']['domainoverrides']))
70
	$config['dnsmasq']['domainoverrides'] = array();
71

    
72
$a_hosts = &$config['dnsmasq']['hosts'];
73
$a_domainOverrides = &$config['dnsmasq']['domainoverrides'];
74

    
75
if ($_POST) {
76
	$pconfig = $_POST;
77
	unset($input_errors);
78

    
79
	$config['dnsmasq']['enable'] = ($_POST['enable']) ? true : false;
80
	$config['dnsmasq']['regdhcp'] = ($_POST['regdhcp']) ? true : false;
81
	$config['dnsmasq']['regdhcpstatic'] = ($_POST['regdhcpstatic']) ? true : false;
82
	$config['dnsmasq']['dhcpfirst'] = ($_POST['dhcpfirst']) ? true : false;
83
	$config['dnsmasq']['strict_order'] = ($_POST['strict_order']) ? true : false;
84
	$config['dnsmasq']['domain_needed'] = ($_POST['domain_needed']) ? true : false;
85
	$config['dnsmasq']['no_private_reverse'] = ($_POST['no_private_reverse']) ? true : false;
86
	$config['dnsmasq']['custom_options'] = str_replace("\r\n", "\n", $_POST['custom_options']);
87
	$config['dnsmasq']['strictbind'] = ($_POST['strictbind']) ? true : false;
88

    
89
	if (isset($_POST['enable']) && isset($config['unbound']['enable'])) {
90
		if ($_POST['port'] == $config['unbound']['port'])
91
			$input_errors[] = "The DNS Resolver is enabled using this port. Choose a non-conflicting port, or disable DNS Resolver.";
92
	}
93

    
94
	if ($_POST['port']) {
95
		if(is_port($_POST['port']))
96
			$config['dnsmasq']['port'] = $_POST['port'];
97
		else
98
			$input_errors[] = gettext("You must specify a valid port number");
99
	}
100
	else if (isset($config['dnsmasq']['port']))
101
		unset($config['dnsmasq']['port']);
102

    
103
	if (is_array($_POST['interface']))
104
		$config['dnsmasq']['interface'] = implode(",", $_POST['interface']);
105
	elseif (isset($config['dnsmasq']['interface']))
106
		unset($config['dnsmasq']['interface']);
107

    
108
	if ($config['dnsmasq']['custom_options']) {
109
		$args = '';
110
		foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c)
111
			$args .= escapeshellarg("--{$c}") . " ";
112
		exec("/usr/local/sbin/dnsmasq --test $args", $output, $rc);
113
		if ($rc != 0)
114
			$input_errors[] = gettext("Invalid custom options");
115
	}
116

    
117
	if (!$input_errors) {
118
		write_config();
119

    
120
		$retval = 0;
121
		$retval = services_dnsmasq_configure();
122
		$savemsg = get_std_save_message($retval);
123

    
124
		// Relaod filter (we might need to sync to CARP hosts)
125
		filter_configure();
126
		/* Update resolv.conf in case the interface bindings exclude localhost. */
127
		system_resolvconf_generate();
128
		/* Start or restart dhcpleases when it's necessary */
129
		system_dhcpleases_configure();
130

    
131
		if ($retval == 0)
132
			clear_subsystem_dirty('hosts');
133
	}
134
}
135

    
136
if ($_GET['act'] == "del") {
137
	if ($_GET['type'] == 'host') {
138
		if ($a_hosts[$_GET['id']]) {
139
			unset($a_hosts[$_GET['id']]);
140
			write_config();
141
			mark_subsystem_dirty('hosts');
142
			header("Location: services_dnsmasq.php");
143
			exit;
144
		}
145
	}
146
	elseif ($_GET['type'] == 'doverride') {
147
		if ($a_domainOverrides[$_GET['id']]) {
148
			unset($a_domainOverrides[$_GET['id']]);
149
			write_config();
150
			mark_subsystem_dirty('hosts');
151
			header("Location: services_dnsmasq.php");
152
			exit;
153
		}
154
	}
155
}
156

    
157
function build_if_list() {
158
	$interface_addresses = get_possible_listen_ips(true);
159
	$iflist = array('options' => array(), 'selected' => array());
160

    
161
	$iflist['options'][""]	= "All";
162
	if (empty($pconfig['interface']) || empty($pconfig['interface'][0]))
163
		array_push($iflist['selected'], "");
164

    
165
	foreach ($interface_addresses as $laddr => $ldescr) {
166
		$iflist['options'][$laddr] = htmlspecialchars($ldescr);
167

    
168
		if ($pconfig['interface'] && in_array($laddr, $pconfig['interface']))
169
			array_push($iflist['selected'], $laddr);
170
	}
171

    
172
	unset($interface_addresses);
173

    
174
	return($iflist);
175
}
176

    
177
$closehead = false;
178
$pgtitle = array(gettext("Services"),gettext("DNS forwarder"));
179
$shortcut_section = "forwarder";
180
include("head.inc");
181

    
182
if ($input_errors)
183
	print_input_errors($input_errors);
184

    
185
if ($savemsg)
186
	print_info_box($savemsg, 'success');
187

    
188
if (is_subsystem_dirty('hosts'))
189
	print_info_box_np(gettext("The DNS forwarder configuration has been changed") . ".<br />" . gettext("You must apply the changes in order for them to take effect."));
190

    
191
require('classes/Form.class.php');
192

    
193
$form = new Form();
194

    
195
$section = new Form_Section('General DNS Forwarder Options');
196

    
197
$section->addInput(new Form_Checkbox(
198
	'enable',
199
	'Enable',
200
	'Enable DNS forwarder',
201
	$pconfig['enable']
202
))->toggles('.toggle-dhcp', 'disable');
203

    
204
$section->addInput(new Form_Checkbox(
205
	'regdhcp',
206
	'DHCP Registration',
207
	'Register DHCP leases in DNS forwarder',
208
	$pconfig['regdhcp']
209
))->setHelp(sprintf("If this option is set, then machines that specify".
210
			" their hostname when requesting a DHCP lease will be registered".
211
			" in the DNS forwarder, so that their name can be resolved.".
212
			" You should also set the domain in %sSystem:".
213
			" General setup%s to the proper value.",'<a href="system.php">','</a>'))
214
	->addClass('toggle-dhcp');
215

    
216
$section->addInput(new Form_Checkbox(
217
	'regdhcpstatic',
218
	'Static DHCP',
219
	'Register DHCP static mappings in DNS forwarder',
220
	$pconfig['regdhcpstatic']
221
))->setHelp(sprintf("If this option is set, then DHCP static mappings will ".
222
					"be registered in the DNS forwarder, so that their name can be ".
223
					"resolved. You should also set the domain in %s".
224
					"System: General setup%s to the proper value.",'<a href="system.php">','</a>'))
225
	->addClass('toggle-dhcp');
226

    
227
$section->addInput(new Form_Checkbox(
228
	'dhcpfirst',
229
	'Prefer DHCP',
230
	'Resolve DHCP mappings first',
231
	$pconfig['dhcpfirst']
232
))->setHelp(sprintf("If this option is set, then DHCP mappings will ".
233
					"be resolved before the manual list of names below. This only ".
234
					"affects the name given for a reverse lookup (PTR)."))
235
	->addClass('toggle-dhcp');
236

    
237
$group = new Form_Group('DNS Query Forwarding');
238

    
239
$group->add(new Form_Checkbox(
240
	'strict_order',
241
	'DNS Query Forwarding',
242
	'Query DNS servers sequentially',
243
	$pconfig['strict_order']
244
))->setHelp(sprintf("If this option is set, %s DNS Forwarder (dnsmasq) will ".
245
					"query the DNS servers sequentially in the order specified (<i>System - General Setup - DNS Servers</i>), ".
246
					"rather than all at once in parallel. ", $g['product_name']));
247

    
248
$group->add(new Form_Checkbox(
249
	'domain_needed',
250
	null,
251
	'Require domain',
252
	$pconfig['domain_needed']
253
))->setHelp(sprintf("If this option is set, %s DNS Forwarder (dnsmasq) will ".
254
					"not forward A or AAAA queries for plain names, without dots or domain parts, to upstream name servers.	 ".
255
					"If the name is not known from /etc/hosts or DHCP then a \"not found\" answer is returned. ", $g['product_name']));
256

    
257
$group->add(new Form_Checkbox(
258
	'no_private_reverse',
259
	null,
260
	'Do not forward private reverse lookups',
261
	$pconfig['no_private_reverse']
262
))->setHelp(sprintf("If this option is set, %s DNS Forwarder (dnsmasq) will ".
263
					"not forward reverse DNS lookups (PTR) for private addresses (RFC 1918) to upstream name servers.  ".
264
					"Any entries in the Domain Overrides section forwarding private \"n.n.n.in-addr.arpa\" names to a specific server are still forwarded. ".
265
					"If the IP to name is not known from /etc/hosts, DHCP or a specific domain override then a \"not found\" answer is immediately returned. ", $g['product_name']));
266

    
267
$section->add($group);
268

    
269
$section->addInput(new Form_Input(
270
	'port',
271
	'Listen Port',
272
	'number',
273
	$pconfig['port'],
274
	['placeholder' => '53']
275
))->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.');
276

    
277
$iflist = build_if_list();
278

    
279
$section->addInput(new Form_Select(
280
	'interface',
281
	'Interfaces',
282
	$iflist['selected'],
283
	$iflist['options'],
284
	true
285
))->setHelp('Interface IPs used by the DNS Forwarder 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. ' .
286
			'The default behavior is to respond to queries on every available IPv4 and IPv6 address.');
287

    
288
$section->addInput(new Form_Checkbox(
289
	'strictbind',
290
	'Strict binding',
291
	'Strict interface binding',
292
	$pconfig['strictbind']
293
))->setHelp('If this option is set, the DNS forwarder will only bind to the interfaces containing the IP addresses selected above, ' .
294
					'rather than binding to all interfaces and discarding queries to other addresses.' . '<br /><br />' .
295
					'This option does NOT work with IPv6. If set, dnsmasq will not bind to IPv6 addresses.');
296

    
297
$section->addInput(new Form_TextArea(
298
	'custom_options',
299
	'Custom options',
300
	$pconfig['custom_options']
301
))->setHelp('Enter any additional options you would like to add to the dnsmasq configuration here, separated by a space or newline')
302
	->addClass('advanced');
303

    
304
$form->add($section);
305
print($form);
306

    
307
print_info_box(sprintf("If the DNS forwarder is enabled, the DHCP".
308
	" service (if enabled) will automatically serve the LAN IP".
309
	" address as a DNS server to DHCP clients so they will use".
310
	" the forwarder. The DNS forwarder will use the DNS servers".
311
	" entered in %sSystem: General setup%s".
312
	" or those obtained via DHCP or PPP on WAN if the &quot;Allow".
313
	" DNS server list to be overridden by DHCP/PPP on WAN&quot;".
314
	" is checked. If you don't use that option (or if you use".
315
	" a static IP address on WAN), you must manually specify at".
316
	" least one DNS server on the %sSystem:".
317
	"General setup%s page.",'<a href="system.php">','</a>','<a href="system.php">','</a>'));
318
?>
319

    
320
<div class="panel panel-default">
321
	<div class="panel-heading"><h2><?=gettext("Host Overrides")?></h2></div>
322
	<div class="panel-body table-responsive">
323
		<table class="table table-striped table-hover table-condensed">
324
			<thead>
325
				<tr>
326
					<th><?=gettext("Host")?></th>
327
					<th><?=gettext("Domain")?></th>
328
					<th><?=gettext("IP")?></th>
329
					<th><?=gettext("Description")?></th>
330
					<th></th>
331
				</tr>
332
			</thead>
333
			<tbody>
334
<?php
335
foreach ($a_hosts as $i => $hostent):
336
?>
337
				<tr>
338
					<td>
339
						<?=strtolower($hostent['host'])?>
340
					</td>
341
					<td>
342
						<?=strtolower($hostent['domain'])?>
343
					</td>
344
					<td>
345
						<?=$hostent['ip']?>
346
					</td>
347
					<td>
348
						<?=htmlspecialchars($hostent['descr'])?>
349
					</td>
350
					<td>
351
						<a href="services_dnsmasq_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
352
						<a href="services_dnsmasq.php?type=host&amp;act=del&amp;id=<?=$i?>" class="btn btn-xs btn-danger"><?=gettext('Delete')?></a>
353
					</td>
354
				</tr>
355

    
356
<?php
357
	if ($hostent['aliases']['item'] && is_array($hostent['aliases']['item'])):
358
		foreach ($hostent['aliases']['item'] as $i => $alias):
359
?>
360
				<tr>
361
					<td>
362
						<?=strtolower($alias['host'])?>
363
					</td>
364
					<td>
365
						<?=strtolower($alias['domain'])?>
366
					</td>
367
					<td>
368
						Alias for <?=$hostent['host'] ? $hostent['host'] . '.' . $hostent['domain'] : $hostent['domain']?>
369
					</td>
370
					<td>
371
						<?=htmlspecialchars($alias['description'])?>
372
					</td>
373
					<td>
374
						<a href="services_dnsmasq_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
375
					</td>
376
				</tr>
377
<?php
378
		endforeach;
379
	endif;
380
endforeach;
381
?>
382
			</tbody>
383
		</table>
384
	</div>
385
</div>
386

    
387
<nav class="action-buttons">
388
	<a href="services_dnsmasq_edit.php" class="btn btn-sm btn-success"><?=gettext('Add')?></a>
389
</nav>
390

    
391
<?php
392
print_info_box(gettext("Entries in this section override individual results from the forwarders.") .
393
				gettext("Use these for changing DNS results or for adding custom DNS records."));
394
?>
395

    
396
<div class="panel panel-default">
397
	<div class="panel-heading"><h2><?=gettext("Domain Overrides")?></h2></div>
398
	<div class="panel-body table-responsive">
399
		<table class="table table-striped table-hover table-condensed">
400
			<thead>
401
				<tr>
402
					<th><?=gettext("Domain")?></th>
403
					<th><?=gettext("IP")?></th>
404
					<th><?=gettext("Description")?></th>
405
					<th></th>
406
				</tr>
407
			</thead>
408

    
409
			<tbody>
410
<?php
411
foreach ($a_domainOverrides as $i => $doment):
412
?>
413
				<tr>
414
					<td>
415
						<?=strtolower($doment['domain'])?>
416
					</td>
417
					<td>
418
						<?=$doment['ip']?>
419
					</td>
420
					<td>
421
						<?=htmlspecialchars($doment['descr'])?>
422
					</td>
423
					<td>
424
						<a href="services_dnsmasq_domainoverride_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
425
						<a href="services_dnsmasq.php?act=del&amp;type=doverride&amp;id=<?=$i?>" class="btn btn-xs btn-danger"><?=gettext('Delete')?></a>
426
					</td>
427
				</tr>
428
<?php
429
endforeach;
430
?>
431
			</tbody>
432
		</table>
433
	</div>
434
</div>
435

    
436
<nav class="action-buttons">
437
	<a href="services_dnsmasq_domainoverride_edit.php" class="btn btn-sm btn-success"><?=gettext('Add')?></a>
438
</nav>
439

    
440
<?php
441
print_info_box(gettext("Entries in this area override an entire domain, and subdomains, by specifying an".
442
						" authoritative DNS server to be queried for that domain."));
443

    
444
include("foot.inc");
(138-138/237)