Project

General

Profile

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

    
63
##|+PRIV
64
##|*IDENT=page-services-dnsforwarder
65
##|*NAME=Services: DNS Forwarder page
66
##|*DESCR=Allow access to the 'Services: DNS Forwarder' page.
67
##|*MATCH=services_dnsmasq.php*
68
##|-PRIV
69

    
70
require("guiconfig.inc");
71
require_once("functions.inc");
72
require_once("filter.inc");
73
require_once("shaper.inc");
74
require_once("system.inc");
75

    
76
$pconfig['enable'] = isset($config['dnsmasq']['enable']);
77
$pconfig['regdhcp'] = isset($config['dnsmasq']['regdhcp']);
78
$pconfig['regdhcpstatic'] = isset($config['dnsmasq']['regdhcpstatic']);
79
$pconfig['dhcpfirst'] = isset($config['dnsmasq']['dhcpfirst']);
80
$pconfig['strict_order'] = isset($config['dnsmasq']['strict_order']);
81
$pconfig['domain_needed'] = isset($config['dnsmasq']['domain_needed']);
82
$pconfig['no_private_reverse'] = isset($config['dnsmasq']['no_private_reverse']);
83
$pconfig['port'] = $config['dnsmasq']['port'];
84
$pconfig['custom_options'] = $config['dnsmasq']['custom_options'];
85

    
86
$pconfig['strictbind'] = isset($config['dnsmasq']['strictbind']);
87
if (!empty($config['dnsmasq']['interface'])) {
88
	$pconfig['interface'] = explode(",", $config['dnsmasq']['interface']);
89
} else {
90
	$pconfig['interface'] = array();
91
}
92

    
93
if (!is_array($config['dnsmasq']['hosts'])) {
94
	$config['dnsmasq']['hosts'] = array();
95
}
96

    
97
if (!is_array($config['dnsmasq']['domainoverrides'])) {
98
	$config['dnsmasq']['domainoverrides'] = array();
99
}
100

    
101
$a_hosts = &$config['dnsmasq']['hosts'];
102
$a_domainOverrides = &$config['dnsmasq']['domainoverrides'];
103

    
104
if ($_POST) {
105
	$pconfig = $_POST;
106
	unset($input_errors);
107

    
108
	$config['dnsmasq']['enable'] = ($_POST['enable']) ? true : false;
109
	$config['dnsmasq']['regdhcp'] = ($_POST['regdhcp']) ? true : false;
110
	$config['dnsmasq']['regdhcpstatic'] = ($_POST['regdhcpstatic']) ? true : false;
111
	$config['dnsmasq']['dhcpfirst'] = ($_POST['dhcpfirst']) ? true : false;
112
	$config['dnsmasq']['strict_order'] = ($_POST['strict_order']) ? true : false;
113
	$config['dnsmasq']['domain_needed'] = ($_POST['domain_needed']) ? true : false;
114
	$config['dnsmasq']['no_private_reverse'] = ($_POST['no_private_reverse']) ? true : false;
115
	$config['dnsmasq']['custom_options'] = str_replace("\r\n", "\n", $_POST['custom_options']);
116
	$config['dnsmasq']['strictbind'] = ($_POST['strictbind']) ? true : false;
117

    
118
	if (isset($_POST['enable']) && isset($config['unbound']['enable'])) {
119
		if ($_POST['port'] == $config['unbound']['port']) {
120
			$input_errors[] = "The DNS Resolver is enabled using this port. Choose a non-conflicting port, or disable DNS Resolver.";
121
		}
122
	}
123

    
124
	if ($_POST['port']) {
125
		if (is_port($_POST['port'])) {
126
			$config['dnsmasq']['port'] = $_POST['port'];
127
		} else {
128
			$input_errors[] = gettext("You must specify a valid port number");
129
		}
130
	} else if (isset($config['dnsmasq']['port'])) {
131
		unset($config['dnsmasq']['port']);
132
	}
133

    
134
	if (is_array($_POST['interface'])) {
135
		$config['dnsmasq']['interface'] = implode(",", $_POST['interface']);
136
	} elseif (isset($config['dnsmasq']['interface'])) {
137
		unset($config['dnsmasq']['interface']);
138
	}
139

    
140
	if ($config['dnsmasq']['custom_options']) {
141
		$args = '';
142
		foreach (preg_split('/\s+/', $config['dnsmasq']['custom_options']) as $c) {
143
			$args .= escapeshellarg("--{$c}") . " ";
144
		}
145
		exec("/usr/local/sbin/dnsmasq --test $args", $output, $rc);
146
		if ($rc != 0) {
147
			$input_errors[] = gettext("Invalid custom options");
148
		}
149
	}
150

    
151
	if (!$input_errors) {
152
		write_config();
153

    
154
		$retval = 0;
155
		$retval = services_dnsmasq_configure();
156
		$savemsg = get_std_save_message($retval);
157

    
158
		// Reload filter (we might need to sync to CARP hosts)
159
		filter_configure();
160
		/* Update resolv.conf in case the interface bindings exclude localhost. */
161
		system_resolvconf_generate();
162
		/* Start or restart dhcpleases when it's necessary */
163
		system_dhcpleases_configure();
164

    
165
		if ($retval == 0) {
166
			clear_subsystem_dirty('hosts');
167
		}
168
	}
169
}
170

    
171
if ($_GET['act'] == "del") {
172
	if ($_GET['type'] == 'host') {
173
		if ($a_hosts[$_GET['id']]) {
174
			unset($a_hosts[$_GET['id']]);
175
			write_config();
176
			mark_subsystem_dirty('hosts');
177
			header("Location: services_dnsmasq.php");
178
			exit;
179
		}
180
	}
181
	elseif ($_GET['type'] == 'doverride') {
182
		if ($a_domainOverrides[$_GET['id']]) {
183
			unset($a_domainOverrides[$_GET['id']]);
184
			write_config();
185
			mark_subsystem_dirty('hosts');
186
			header("Location: services_dnsmasq.php");
187
			exit;
188
		}
189
	}
190
}
191

    
192
function build_if_list() {
193
	$interface_addresses = get_possible_listen_ips(true);
194
	$iflist = array('options' => array(), 'selected' => array());
195

    
196
	$iflist['options'][""]	= "All";
197
	if (empty($pconfig['interface']) || empty($pconfig['interface'][0]))
198
		array_push($iflist['selected'], "");
199

    
200
	foreach ($interface_addresses as $laddr => $ldescr) {
201
		$iflist['options'][$laddr] = htmlspecialchars($ldescr);
202

    
203
		if ($pconfig['interface'] && in_array($laddr, $pconfig['interface']))
204
			array_push($iflist['selected'], $laddr);
205
	}
206

    
207
	unset($interface_addresses);
208

    
209
	return($iflist);
210
}
211

    
212
$closehead = false;
213
$pgtitle = array(gettext("Services"), gettext("DNS Forwarder"));
214
$shortcut_section = "forwarder";
215
include("head.inc");
216

    
217
if ($input_errors)
218
	print_input_errors($input_errors);
219

    
220
if ($savemsg)
221
	print_info_box($savemsg, 'success');
222

    
223
if (is_subsystem_dirty('hosts'))
224
	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."));
225

    
226
require_once('classes/Form.class.php');
227

    
228
$form = new Form();
229

    
230
$section = new Form_Section('General DNS Forwarder Options');
231

    
232
$section->addInput(new Form_Checkbox(
233
	'enable',
234
	'Enable',
235
	'Enable DNS forwarder',
236
	$pconfig['enable']
237
))->toggles('.toggle-dhcp', 'disable');
238

    
239
$section->addInput(new Form_Checkbox(
240
	'regdhcp',
241
	'DHCP Registration',
242
	'Register DHCP leases in DNS forwarder',
243
	$pconfig['regdhcp']
244
))->setHelp(sprintf("If this option is set, then machines that specify".
245
			" their hostname when requesting a DHCP lease will be registered".
246
			" in the DNS forwarder, so that their name can be resolved.".
247
			" You should also set the domain in %sSystem:".
248
			" General setup%s to the proper value.",'<a href="system.php">','</a>'))
249
	->addClass('toggle-dhcp');
250

    
251
$section->addInput(new Form_Checkbox(
252
	'regdhcpstatic',
253
	'Static DHCP',
254
	'Register DHCP static mappings in DNS forwarder',
255
	$pconfig['regdhcpstatic']
256
))->setHelp(sprintf("If this option is set, then DHCP static mappings will ".
257
					"be registered in the DNS forwarder, so that their name can be ".
258
					"resolved. You should also set the domain in %s".
259
					"System: General setup%s to the proper value.",'<a href="system.php">','</a>'))
260
	->addClass('toggle-dhcp');
261

    
262
$section->addInput(new Form_Checkbox(
263
	'dhcpfirst',
264
	'Prefer DHCP',
265
	'Resolve DHCP mappings first',
266
	$pconfig['dhcpfirst']
267
))->setHelp(sprintf("If this option is set, then DHCP mappings will ".
268
					"be resolved before the manual list of names below. This only ".
269
					"affects the name given for a reverse lookup (PTR)."))
270
	->addClass('toggle-dhcp');
271

    
272
$group = new Form_Group('DNS Query Forwarding');
273

    
274
$group->add(new Form_Checkbox(
275
	'strict_order',
276
	'DNS Query Forwarding',
277
	'Query DNS servers sequentially',
278
	$pconfig['strict_order']
279
))->setHelp(sprintf("If this option is set, %s DNS Forwarder (dnsmasq) will ".
280
					"query the DNS servers sequentially in the order specified (<i>System - General Setup - DNS Servers</i>), ".
281
					"rather than all at once in parallel. ", $g['product_name']));
282

    
283
$group->add(new Form_Checkbox(
284
	'domain_needed',
285
	null,
286
	'Require domain',
287
	$pconfig['domain_needed']
288
))->setHelp(sprintf("If this option is set, %s DNS Forwarder (dnsmasq) will ".
289
					"not forward A or AAAA queries for plain names, without dots or domain parts, to upstream name servers.	 ".
290
					"If the name is not known from /etc/hosts or DHCP then a \"not found\" answer is returned. ", $g['product_name']));
291

    
292
$group->add(new Form_Checkbox(
293
	'no_private_reverse',
294
	null,
295
	'Do not forward private reverse lookups',
296
	$pconfig['no_private_reverse']
297
))->setHelp(sprintf("If this option is set, %s DNS Forwarder (dnsmasq) will ".
298
					"not forward reverse DNS lookups (PTR) for private addresses (RFC 1918) to upstream name servers.  ".
299
					"Any entries in the Domain Overrides section forwarding private \"n.n.n.in-addr.arpa\" names to a specific server are still forwarded. ".
300
					"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']));
301

    
302
$section->add($group);
303

    
304
$section->addInput(new Form_Input(
305
	'port',
306
	'Listen Port',
307
	'number',
308
	$pconfig['port'],
309
	['placeholder' => '53']
310
))->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.');
311

    
312
$iflist = build_if_list();
313

    
314
$section->addInput(new Form_Select(
315
	'interface',
316
	'Interfaces',
317
	$iflist['selected'],
318
	$iflist['options'],
319
	true
320
))->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. ' .
321
			'The default behavior is to respond to queries on every available IPv4 and IPv6 address.');
322

    
323
$section->addInput(new Form_Checkbox(
324
	'strictbind',
325
	'Strict binding',
326
	'Strict interface binding',
327
	$pconfig['strictbind']
328
))->setHelp('If this option is set, the DNS forwarder will only bind to the interfaces containing the IP addresses selected above, ' .
329
					'rather than binding to all interfaces and discarding queries to other addresses.' . '<br /><br />' .
330
					'This option does NOT work with IPv6. If set, dnsmasq will not bind to IPv6 addresses.');
331

    
332
$section->addInput(new Form_TextArea(
333
	'custom_options',
334
	'Custom options',
335
	$pconfig['custom_options']
336
))->setHelp('Enter any additional options you would like to add to the dnsmasq configuration here, separated by a space or newline')
337
	->addClass('advanced');
338

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

    
342
print_info_box(sprintf("If the DNS forwarder is enabled, the DHCP".
343
	" service (if enabled) will automatically serve the LAN IP".
344
	" address as a DNS server to DHCP clients so they will use".
345
	" the forwarder. The DNS forwarder will use the DNS servers".
346
	" entered in %sSystem: General setup%s".
347
	" or those obtained via DHCP or PPP on WAN if the &quot;Allow".
348
	" DNS server list to be overridden by DHCP/PPP on WAN&quot;".
349
	" is checked. If you don't use that option (or if you use".
350
	" a static IP address on WAN), you must manually specify at".
351
	" least one DNS server on the %sSystem:".
352
	"General setup%s page.",'<a href="system.php">','</a>','<a href="system.php">','</a>'), info);
353
?>
354

    
355
<div class="panel panel-default">
356
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Host Overrides")?></h2></div>
357
	<div class="panel-body table-responsive">
358
		<table class="table table-striped table-hover table-condensed">
359
			<thead>
360
				<tr>
361
					<th><?=gettext("Host")?></th>
362
					<th><?=gettext("Domain")?></th>
363
					<th><?=gettext("IP")?></th>
364
					<th><?=gettext("Description")?></th>
365
					<th></th>
366
				</tr>
367
			</thead>
368
			<tbody>
369
<?php
370
foreach ($a_hosts as $i => $hostent):
371
?>
372
				<tr>
373
					<td>
374
						<?=strtolower($hostent['host'])?>
375
					</td>
376
					<td>
377
						<?=strtolower($hostent['domain'])?>
378
					</td>
379
					<td>
380
						<?=$hostent['ip']?>
381
					</td>
382
					<td>
383
						<?=htmlspecialchars($hostent['descr'])?>
384
					</td>
385
					<td>
386
						<a class="fa fa-pencil"	title="<?=gettext('Edit host override')?>" 	href="services_dnsmasq_edit.php?id=<?=$i?>"></a>
387
						<a class="fa fa-trash"	title="<?=gettext('Delete host override')?>"	href="services_dnsmasq.php?type=host&amp;act=del&amp;id=<?=$i?>"></a>
388
					</td>
389
				</tr>
390

    
391
<?php
392
	if ($hostent['aliases']['item'] && is_array($hostent['aliases']['item'])):
393
		foreach ($hostent['aliases']['item'] as $i => $alias):
394
?>
395
				<tr>
396
					<td>
397
						<?=strtolower($alias['host'])?>
398
					</td>
399
					<td>
400
						<?=strtolower($alias['domain'])?>
401
					</td>
402
					<td>
403
						Alias for <?=$hostent['host'] ? $hostent['host'] . '.' . $hostent['domain'] : $hostent['domain']?>
404
					</td>
405
					<td>
406
						<?=htmlspecialchars($alias['description'])?>
407
					</td>
408
					<td>
409
						<a class="fa fa-pencil"	title="<?=gettext('Edit host override')?>" 	href="services_dnsmasq_edit.php?id=<?=$i?>"></a>
410
					</td>
411
				</tr>
412
<?php
413
		endforeach;
414
	endif;
415
endforeach;
416
?>
417
			</tbody>
418
		</table>
419
	</div>
420
</div>
421

    
422
<nav class="action-buttons">
423
	<a href="services_dnsmasq_edit.php" class="btn btn-sm btn-success btn-sm">
424
		<i class="fa fa-plus icon-embed-btn"></i>
425
		<?=gettext('Add')?>
426
	</a>
427
</nav>
428

    
429
<?php
430
print_info_box(gettext("Entries in this section override individual results from the forwarders.") .
431
				gettext("Use these for changing DNS results or for adding custom DNS records."), info);
432
?>
433

    
434
<div class="panel panel-default">
435
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Domain Overrides")?></h2></div>
436
	<div class="panel-body table-responsive">
437
		<table class="table table-striped table-hover table-condensed">
438
			<thead>
439
				<tr>
440
					<th><?=gettext("Domain")?></th>
441
					<th><?=gettext("IP")?></th>
442
					<th><?=gettext("Description")?></th>
443
					<th></th>
444
				</tr>
445
			</thead>
446

    
447
			<tbody>
448
<?php
449
foreach ($a_domainOverrides as $i => $doment):
450
?>
451
				<tr>
452
					<td>
453
						<?=strtolower($doment['domain'])?>
454
					</td>
455
					<td>
456
						<?=$doment['ip']?>
457
					</td>
458
					<td>
459
						<?=htmlspecialchars($doment['descr'])?>
460
					</td>
461
					<td>
462
						<a class="fa fa-pencil"	title="<?=gettext('Edit domain override')?>" href="services_dnsmasq_domainoverride_edit.php?id=<?=$i?>"></a>
463
						<a class="fa fa-trash"	title="<?=gettext('Delete domain override')?>" href="services_dnsmasq.php?act=del&amp;type=doverride&amp;id=<?=$i?>"></a>
464
					</td>
465
				</tr>
466
<?php
467
endforeach;
468
?>
469
			</tbody>
470
		</table>
471
	</div>
472
</div>
473

    
474
<nav class="action-buttons">
475
	<a href="services_dnsmasq_domainoverride_edit.php" class="btn btn-sm btn-success btn-sm">
476
		<i class="fa fa-plus icon-embed-btn"></i>
477
		<?=gettext('Add')?>
478
	</a>
479
</nav>
480

    
481
<?php
482
print_info_box(gettext("Entries in this area override an entire domain, and subdomains, by specifying an".
483
						" authoritative DNS server to be queried for that domain."), info);
484

    
485
include("foot.inc");
(138-138/234)