Project

General

Profile

Download (12.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	firewall_nat.php
5
*/
6
/* ====================================================================
7
 *  Copyright (c)  2004-2015  Electric Sheep Fencing, LLC. All rights reserved. 
8
 *  Copyright (c)  2004 Scott Ullrich
9
 *	Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>
10
 *	originally part of m0n0wall (http://m0n0.ch/wall)
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: nat
61
*/
62

    
63
##|+PRIV
64
##|*IDENT=page-firewall-nat-portforward
65
##|*NAME=Firewall: NAT: Port Forward page
66
##|*DESCR=Allow access to the 'Firewall: NAT: Port Forward' page.
67
##|*MATCH=firewall_nat.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("itemid.inc");
75

    
76
if (!is_array($config['nat']['rule'])) {
77
	$config['nat']['rule'] = array();
78
}
79

    
80
$a_nat = &$config['nat']['rule'];
81

    
82
/* update rule order, POST[rule] is an array of ordered IDs */
83
if (is_array($_POST['rule']) && !empty($_POST['rule'])) {
84
	$a_nat_new = array();
85

    
86
	// if a rule is not in POST[rule], it has been deleted by the user
87
	foreach ($_POST['rule'] as $id)
88
		$a_nat_new[] = $a_nat[$id];
89

    
90
	$a_nat = $a_nat_new;
91

    
92
	if (write_config())
93
		mark_subsystem_dirty('filter');
94

    
95
	header("Location: firewall_nat.php");
96
	exit;
97
}
98

    
99
/* if a custom message has been passed along, lets process it */
100
if ($_GET['savemsg']) {
101
	$savemsg = $_GET['savemsg'];
102
}
103

    
104
if ($_POST) {
105

    
106
	$pconfig = $_POST;
107

    
108
	if ($_POST['apply']) {
109

    
110
		$retval = 0;
111

    
112
		$retval |= filter_configure();
113
		$savemsg = get_std_save_message($retval);
114

    
115
		pfSense_handle_custom_code("/usr/local/pkg/firewall_nat/apply");
116

    
117
		if ($retval == 0) {
118
			clear_subsystem_dirty('natconf');
119
			clear_subsystem_dirty('filter');
120
		}
121

    
122
	}
123
}
124

    
125
if ($_GET['act'] == "del") {
126
	if ($a_nat[$_GET['id']]) {
127

    
128
		if (isset($a_nat[$_GET['id']]['associated-rule-id'])) {
129
			delete_id($a_nat[$_GET['id']]['associated-rule-id'], $config['filter']['rule']);
130
			$want_dirty_filter = true;
131
		}
132
		unset($a_nat[$_GET['id']]);
133

    
134
		if (write_config()) {
135
			mark_subsystem_dirty('natconf');
136
			if ($want_dirty_filter) {
137
				mark_subsystem_dirty('filter');
138
			}
139
		}
140

    
141
		header("Location: firewall_nat.php");
142
		exit;
143
	}
144
}
145

    
146
if (isset($_POST['del_x'])) {
147
	/* delete selected rules */
148
	if (is_array($_POST['rule']) && count($_POST['rule'])) {
149
		foreach ($_POST['rule'] as $rulei) {
150
		$target = $rule['target'];
151
			// Check for filter rule associations
152
			if (isset($a_nat[$rulei]['associated-rule-id'])) {
153
				delete_id($a_nat[$rulei]['associated-rule-id'], $config['filter']['rule']);
154

    
155
				mark_subsystem_dirty('filter');
156
			}
157
			unset($a_nat[$rulei]);
158
		}
159
		if (write_config()) {
160
			mark_subsystem_dirty('natconf');
161
		}
162
		header("Location: firewall_nat.php");
163
		exit;
164
	}
165

    
166
} else {
167
		/* yuck - IE won't send value attributes for image buttons, while Mozilla does - so we use .x/.y to find move button clicks instead... */
168
		unset($movebtn);
169
		foreach ($_POST as $pn => $pd) {
170
			if (preg_match("/move_(\d+)_x/", $pn, $matches)) {
171
				$movebtn = $matches[1];
172
				break;
173
			}
174
		}
175
		/* move selected rules before this rule */
176
		if (isset($movebtn) && is_array($_POST['rule']) && count($_POST['rule'])) {
177
			$a_nat_new = array();
178

    
179
			/* copy all rules < $movebtn and not selected */
180
			for ($i = 0; $i < $movebtn; $i++) {
181
				if (!in_array($i, $_POST['rule'])) {
182
					$a_nat_new[] = $a_nat[$i];
183
				}
184
			}
185

    
186
			/* copy all selected rules */
187
			for ($i = 0; $i < count($a_nat); $i++) {
188
				if ($i == $movebtn) {
189
					continue;
190
				}
191
				if (in_array($i, $_POST['rule'])) {
192
					$a_nat_new[] = $a_nat[$i];
193
				}
194
			}
195

    
196
			/* copy $movebtn rule */
197
			if ($movebtn < count($a_nat)) {
198
				$a_nat_new[] = $a_nat[$movebtn];
199
			}
200

    
201
			/* copy all rules > $movebtn and not selected */
202
			for ($i = $movebtn+1; $i < count($a_nat); $i++) {
203
				if (!in_array($i, $_POST['rule'])) {
204
					$a_nat_new[] = $a_nat[$i];
205
				}
206
			}
207
			$a_nat = $a_nat_new;
208
			if (write_config()) {
209
				mark_subsystem_dirty('natconf');
210
			}
211
			header("Location: firewall_nat.php");
212
			exit;
213
		}
214
}
215

    
216
$closehead = false;
217
$pgtitle = array(gettext("Firewall"), gettext("NAT"), gettext("Port Forward"));
218
include("head.inc");
219

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

    
223
if (is_subsystem_dirty('natconf'))
224
	print_info_box_np(gettext('The NAT configuration has been changed.') . '<br />' .
225
					  gettext('You must apply the changes in order for them to take effect.') . '<br />');
226

    
227
$tab_array = array();
228
$tab_array[] = array(gettext("Port Forward"), true, "firewall_nat.php");
229
$tab_array[] = array(gettext("1:1"), false, "firewall_nat_1to1.php");
230
$tab_array[] = array(gettext("Outbound"), false, "firewall_nat_out.php");
231
$tab_array[] = array(gettext("NPt"), false, "firewall_nat_npt.php");
232
display_top_tabs($tab_array);
233
?>
234

    
235
<form action="firewall_nat.php" method="post" name="iform">
236
	<div class="panel panel-default">
237
		<div class="panel-heading"><?=gettext('Rules')?></div>
238
		<div class="panel-body table-responsive">
239
			<table class="table table-striped table-hover table-condensed">
240
				<thead>
241
					<tr>
242
						<th><!-- Rule type --></th>
243
						<th><?=gettext("If")?></th>
244
						<th><?=gettext("Proto")?></th>
245
						<th><?=gettext("Src. addr")?></th>
246
						<th><?=gettext("Src. ports")?></th>
247
						<th><?=gettext("Dest. addr")?></th>
248
						<th><?=gettext("Dest. ports")?></th>
249
						<th><?=gettext("NAT IP")?></th>
250
						<th><?=gettext("NAT Ports")?></th>
251
						<th><?=gettext("Description")?></th>
252
						<th><?=gettext("Actions")?></th>
253
					</tr>
254
				</thead>
255
				<tbody class='user-entries'>
256
<?php
257

    
258
$nnats = $i = 0;
259

    
260
foreach ($a_nat as $natent):
261

    
262
	$alias = rule_columns_with_alias(
263
		$natent['source']['address'],
264
		pprint_port($natent['source']['port']),
265
		$natent['destination']['address'],
266
		pprint_port($natent['destination']['port'])
267
	);
268

    
269
	/* if user does not have access to edit an interface skip on to the next record */
270
	if(!have_natpfruleint_access($natent['interface']))
271
		continue;
272
?>
273
					
274
					<tr id="fr<?=$nnats?>">
275
						<td>
276
<?php
277
	if($natent['associated-rule-id'] == "pass"):
278
?>
279
							<i class="icon-play" title="<?=gettext("All traffic matching this NAT entry is passed")?>"></i>
280
<?php
281
	elseif (!empty($natent['associated-rule-id'])):
282
?>
283
							<i class="icon-random" title="<?=gettext("Firewall rule ID ")?><?=htmlspecialchars($nnatid)?> . <?=gettext('is managed by this rule')?>"></i>
284
<?php
285
	endif;
286
?>
287
						</td>
288
						<td>
289
							<?=$textss?>
290
<?php
291
	if (!$natent['interface'])
292
		echo htmlspecialchars(convert_friendly_interface_to_friendly_descr("wan"));
293
	else
294
		echo htmlspecialchars(convert_friendly_interface_to_friendly_descr($natent['interface']));
295
?>
296
							<?=$textse?>
297
						</td>
298

    
299
						<td>
300
							<input type="hidden" name="rule[]" value="<?=$i?>" />
301
							<?=$textss?><?=strtoupper($natent['protocol'])?><?=$textse?>
302
						</td>
303

    
304
						<td>
305

    
306

    
307
<?php
308
	if (isset($alias['src'])):
309
?>
310
							<a href="/firewall_aliases_edit.php?id=<?=$alias['src']?>" data-toggle="popover" data-trigger="hover focus" title="Alias details" data-content="<?=alias_info_popup($alias['src'])?>" data-html="true">
311
<?php
312
	endif;
313
?>
314
							<?=htmlspecialchars(pprint_address($natent['source']))?>
315
<?php
316
	if (isset($alias['src'])):
317
?>
318
							<i class='icon icon-pencil'></i></a>
319
<?php
320
	endif;
321
?>
322
						</td>
323
						<td>
324
<?php
325
	if (isset($alias['srcport'])):
326
?>
327
							<a href="/firewall_aliases_edit.php?id=<?=$alias['srcport']?>" data-toggle="popover" data-trigger="hover focus" title="Alias details" data-content="<?=alias_info_popup($alias['srcport'])?>" data-html="true">
328
<?php
329
	endif;
330
?>
331
							<?=htmlspecialchars(pprint_port($natent['source']['port']))?>
332
<?php
333
	if (isset($alias['srcport'])):
334
?>
335
							<i class='icon icon-pencil'></i></a>
336
<?php
337
	endif;
338
?>
339
						</td>
340

    
341
						<td>
342
<?php
343
	if (isset($alias['dst'])):
344
?>
345
							<a href="/firewall_aliases_edit.php?id=<?=$alias['dst']?>" data-toggle="popover" data-trigger="hover focus" title="Alias details" data-content="<?=alias_info_popup($alias['dst'])?>" data-html="true">
346
<?php
347
	endif;
348
?>
349
							<?=htmlspecialchars(pprint_address($natent['destination']))?>
350
<?php
351
	if (isset($alias['dst'])):
352
?>
353
							<i class='icon icon-pencil'></i></a>
354
<?php
355
	endif;
356
?>
357
						</td>
358
						<td>
359
<?php
360
	if (isset($alias['dstport'])):
361
?>
362
							<a href="/firewall_aliases_edit.php?id=<?=$alias['dstport']?>" data-toggle="popover" data-trigger="hover focus" title="Alias details" data-content="<?=alias_info_popup($alias['dstport'])?>" data-html="true">
363
<?php
364
	endif;
365
?>
366
							<?=htmlspecialchars(pprint_port($natent['destination']['port']))?>
367
<?php
368
	if (isset($alias['dstport'])):
369
?>
370
							<i class='icon icon-pencil'></i></a>
371
<?php
372
	endif;
373
?>
374
						</td>
375

    
376
						<td >
377
							<?=htmlspecialchars($natent['target'])?>
378
						</td>
379
						<td>
380
<?php
381
	$localport = $natent['local-port'];
382

    
383
	list($dstbeginport, $dstendport) = explode("-", $natent['destination']['port']);
384

    
385
	if ($dstendport) {
386
		$localendport = $natent['local-port'] + $dstendport - $dstbeginport;
387
		$localport	 .= '-' . $localendport;
388
	}
389
?>
390
							<?=htmlspecialchars(pprint_port($localport))?>
391
						</td>
392

    
393
						<td>
394
							<?=htmlspecialchars($natent['descr'])?>
395
						</td>
396
						<td>
397
							<a class="btn btn-xs btn-info"	title="<?=gettext("Edit rule"); ?>" href="firewall_nat_edit.php?id=<?=$i?>"><?=gettext("Edit"); ?></a>
398
							<a class="btn btn-xs btn-danger"  title="<?=gettext("Delete rule")?>" href="firewall_nat.php?act=del&amp;id=<?=$i?>"><?=gettext("Del")?></a>
399
							<a class="btn btn-xs btn-success"	  title="<?=gettext("Add a new NAT based on this one")?>" href="firewall_nat_edit.php?dup=<?=$i?>"><?=gettext("Clone")?></a>
400
						</td>
401
					</tr>
402
<?php
403
	$i++;
404
	$nnats++;
405
endforeach;
406
?>
407
				</tbody>
408
			</table>
409
		</div>
410
	</div>
411

    
412
	<div class="pull-right">
413
		<a href="firewall_nat_edit.php?after=-1" class="btn btn-sm btn-success" title="<?=gettext('Add new rule')?>"><?=gettext('Add new rule')?></a>
414
		<input type="submit" id="order-store" class="btn btn-primary btn-sm" value="store changes" disabled="disabled" />
415
	</div>
416
</form>
417

    
418
<script>
419
events.push(function() {
420
	// Make rules draggable/sortable
421
	$('table tbody.user-entries').sortable({
422
		cursor: 'grabbing',
423
		update: function(event, ui) {
424
			$('#order-store').removeAttr('disabled');
425
		}
426
	});
427
});
428
</script>
429
<?php
430

    
431
if(count($a_nat) > 0) {
432
?>
433
<!-- Legend -->
434
<div>
435
	<dl class="dl-horizontal responsive">
436
		<dt><?=gettext('Legend')?></dt>					<dd></dd>
437
		<dt><i class="icon icon-play"></i></dt>			<dd><?=gettext('Pass')?></dd>
438
		<dt><i class="icon icon-random"></i></dt>		<dd><?=gettext('Linked rule')?></dd>
439
	</dl>
440
</div>
441

    
442
<?php
443
}
444

    
445
include("foot.inc");
(53-53/238)