mirror of
https://github.com/opnsense/core.git
synced 2026-10-12 02:20:36 +00:00
firewall: outbound NAT moves to legacy plugin
Rules still work, but not visible from DNAT. Migration assistant will know that these still exist. Will be documented a bit but low risk move in general.
This commit is contained in:
@@ -2588,8 +2588,6 @@
|
||||
/usr/local/www/diag_authentication.php
|
||||
/usr/local/www/diag_backup.php
|
||||
/usr/local/www/fbegin.inc
|
||||
/usr/local/www/firewall_nat_out.php
|
||||
/usr/local/www/firewall_nat_out_edit.php
|
||||
/usr/local/www/firewall_rule_lookup.php
|
||||
/usr/local/www/firewall_schedule.php
|
||||
/usr/local/www/firewall_schedule_edit.php
|
||||
|
||||
@@ -1,643 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Deciso B.V.
|
||||
* Copyright (C) 2004 Scott Ullrich <[email protected]>
|
||||
* Copyright (C) 2003-2004 Manuel Kasper <[email protected]>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("filter.inc");
|
||||
require_once("interfaces.inc");
|
||||
|
||||
$a_out = &config_read_array('nat', 'outbound', 'rule');
|
||||
if (!isset($config['nat']['outbound']['mode'])) {
|
||||
$config['nat']['outbound']['mode'] = "automatic";
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$pconfig = $_POST;
|
||||
if (isset($pconfig['id']) && isset($a_out[$pconfig['id']])) {
|
||||
// id found and valid
|
||||
$id = $pconfig['id'];
|
||||
}
|
||||
if (isset($pconfig['apply'])) {
|
||||
if (write_config()) {
|
||||
configd_run('filter reload');
|
||||
clear_subsystem_dirty('natconf');
|
||||
clear_subsystem_dirty('filter');
|
||||
}
|
||||
} elseif (isset($pconfig['save']) && $pconfig['save'] == "Save") {
|
||||
$mode = $config['nat']['outbound']['mode'];
|
||||
$config['nat']['outbound']['mode'] = $pconfig['mode'];
|
||||
if (write_config()) {
|
||||
mark_subsystem_dirty('natconf');
|
||||
}
|
||||
header(url_safe('Location: /firewall_nat_out.php'));
|
||||
exit;
|
||||
} elseif (isset($pconfig['act']) && $pconfig['act'] == 'del' && isset($id)) {
|
||||
// delete single record
|
||||
unset($a_out[$id]);
|
||||
if (write_config()) {
|
||||
mark_subsystem_dirty('natconf');
|
||||
}
|
||||
header(url_safe('Location: /firewall_nat_out.php'));
|
||||
exit;
|
||||
} elseif (isset($pconfig['act']) && $pconfig['act'] == 'del_x' && isset($pconfig['rule']) && count($pconfig['rule']) > 0) {
|
||||
/* delete selected rules */
|
||||
foreach ($pconfig['rule'] as $rulei) {
|
||||
if (isset($a_out[$rulei])) {
|
||||
unset($a_out[$rulei]);
|
||||
}
|
||||
}
|
||||
if (write_config()) {
|
||||
mark_subsystem_dirty('natconf');
|
||||
}
|
||||
header(url_safe('Location: /firewall_nat_out.php'));
|
||||
exit;
|
||||
} elseif (isset($pconfig['act']) && in_array($pconfig['act'], array('toggle_enable', 'toggle_disable')) && isset($pconfig['rule']) && count($pconfig['rule']) > 0) {
|
||||
foreach ($pconfig['rule'] as $rulei) {
|
||||
$a_out[$rulei]['disabled'] = $pconfig['act'] == 'toggle_disable';
|
||||
}
|
||||
if (write_config()) {
|
||||
mark_subsystem_dirty('filter');
|
||||
}
|
||||
header(url_safe('Location: /firewall_nat_out.php'));
|
||||
exit;
|
||||
} elseif (isset($pconfig['act']) && $pconfig['act'] == 'move' && isset($pconfig['rule']) && count($pconfig['rule']) > 0) {
|
||||
// if rule not set/found, move to end
|
||||
if (!isset($id)) {
|
||||
$id = count($a_out);
|
||||
}
|
||||
$a_out = legacy_move_config_list_items($a_out, $id, $pconfig['rule']);
|
||||
if (write_config()) {
|
||||
mark_subsystem_dirty('natconf');
|
||||
}
|
||||
header(url_safe('Location: /firewall_nat_out.php'));
|
||||
exit;
|
||||
} elseif (isset($pconfig['act']) && $pconfig['act'] == 'toggle' && isset($id)) {
|
||||
// toggle item disabled / enabled
|
||||
if(isset($a_out[$id]['disabled'])) {
|
||||
unset($a_out[$id]['disabled']);
|
||||
} else {
|
||||
$a_out[$id]['disabled'] = true;
|
||||
}
|
||||
if (write_config('Firewall: NAT: Outbound, toggle NAT rule')) {
|
||||
mark_subsystem_dirty('natconf');
|
||||
}
|
||||
header(url_safe('Location: /firewall_nat_out.php'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$mode = $config['nat']['outbound']['mode'];
|
||||
|
||||
$interface_names = [];
|
||||
foreach (config_read_array('interfaces', false) as $intf => $intfdata) {
|
||||
if (is_ipaddrv4($intfdata['ipaddr'] ?? 'none')) {
|
||||
$interface_names[$intfdata['ipaddr']] = sprintf(gettext('%s address'), !empty($intfdata['descr']) ? $intfdata['descr'] : $intf );
|
||||
}
|
||||
}
|
||||
|
||||
include("head.inc");
|
||||
|
||||
?>
|
||||
<body>
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
// link delete buttons
|
||||
$(".act_delete").click(function(event){
|
||||
event.preventDefault();
|
||||
var id = $(this).attr("id").split('_').pop(-1);
|
||||
if (id != 'x') {
|
||||
// delete single
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_DANGER,
|
||||
title: "<?= gettext("Nat")." ".gettext("Outbound");?>",
|
||||
message: "<?=gettext("Do you really want to delete this rule?");?>",
|
||||
buttons: [{
|
||||
label: "<?= gettext("No");?>",
|
||||
action: function(dialogRef) {
|
||||
dialogRef.close();
|
||||
}}, {
|
||||
label: "<?= gettext("Yes");?>",
|
||||
action: function(dialogRef) {
|
||||
$("#id").val(id);
|
||||
$("#action").val("del");
|
||||
$("#iform").submit()
|
||||
}
|
||||
}]
|
||||
});
|
||||
} else {
|
||||
// delete selected
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_DANGER,
|
||||
title: "<?=gettext("Nat")." ".gettext("Outbound");?>",
|
||||
message: "<?=gettext("Do you really want to delete the selected rules?");?>",
|
||||
buttons: [{
|
||||
label: "<?= gettext("No");?>",
|
||||
action: function(dialogRef) {
|
||||
dialogRef.close();
|
||||
}}, {
|
||||
label: "<?= gettext("Yes");?>",
|
||||
action: function(dialogRef) {
|
||||
$("#id").val("");
|
||||
$("#action").val("del_x");
|
||||
$("#iform").submit()
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// enable/disable selected
|
||||
$(".act_toggle_enable").click(function(event){
|
||||
event.preventDefault();
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_DANGER,
|
||||
title: "<?= gettext("Rules");?>",
|
||||
message: "<?=gettext("Enable selected rules?");?>",
|
||||
buttons: [{
|
||||
label: "<?= gettext("No");?>",
|
||||
action: function(dialogRef) {
|
||||
dialogRef.close();
|
||||
}}, {
|
||||
label: "<?= gettext("Yes");?>",
|
||||
action: function(dialogRef) {
|
||||
$("#id").val("");
|
||||
$("#action").val("toggle_enable");
|
||||
$("#iform").submit()
|
||||
}
|
||||
}]
|
||||
});
|
||||
});
|
||||
$(".act_toggle_disable").click(function(event){
|
||||
event.preventDefault();
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_DANGER,
|
||||
title: "<?= gettext("Rules");?>",
|
||||
message: "<?=gettext("Disable selected rules?");?>",
|
||||
buttons: [{
|
||||
label: "<?= gettext("No");?>",
|
||||
action: function(dialogRef) {
|
||||
dialogRef.close();
|
||||
}}, {
|
||||
label: "<?= gettext("Yes");?>",
|
||||
action: function(dialogRef) {
|
||||
$("#id").val("");
|
||||
$("#action").val("toggle_disable");
|
||||
$("#iform").submit()
|
||||
}
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
// link move buttons
|
||||
$(".act_move").click(function(event){
|
||||
event.preventDefault();
|
||||
var id = $(this).attr("id").split('_').pop(-1);
|
||||
$("#id").val(id);
|
||||
$("#action").val("move");
|
||||
$("#iform").submit();
|
||||
});
|
||||
|
||||
// link toggle buttons
|
||||
$(".act_toggle").click(function(event){
|
||||
event.preventDefault();
|
||||
var id = $(this).attr("id").split('_').pop(-1);
|
||||
$("#id").val(id);
|
||||
$("#action").val("toggle");
|
||||
$("#iform").submit();
|
||||
});
|
||||
|
||||
// select All
|
||||
$("#selectAll").click(function(){
|
||||
$(".rule_select:not(:disabled)").prop("checked", $(this).prop("checked"));
|
||||
});
|
||||
|
||||
// watch scroll position and set to last known on page load
|
||||
watchScrollPosition();
|
||||
|
||||
// our usual zebra striping doesn't respect hidden rows, hook repaint on .opnsense-rules change() and fire initially
|
||||
$(".opnsense-rules > tbody > tr").each(function(){
|
||||
// save zebra color
|
||||
let tr_color = $(this).children(0).css("background-color");
|
||||
if (tr_color != 'transparent' && !tr_color.includes('(0, 0, 0')) {
|
||||
$("#fw_category").data('stripe_color', tr_color);
|
||||
}
|
||||
});
|
||||
$(".opnsense-rules").removeClass("table-striped");
|
||||
$(".opnsense-rules").change(function(){
|
||||
$(".opnsense-rules > tbody > tr:visible").each(function (index) {
|
||||
$(this).css("background-color", "inherit");
|
||||
if ( index % 2 == 0) {
|
||||
$(this).css("background-color", $("#fw_category").data('stripe_color'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// hook category functionality
|
||||
hook_firewall_categories();
|
||||
|
||||
});
|
||||
</script>
|
||||
<?php include("fbegin.inc"); ?>
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<?php
|
||||
print_firewall_banner();
|
||||
if (isset($savemsg))
|
||||
print_info_box($savemsg);
|
||||
if (is_subsystem_dirty('natconf'))
|
||||
print_info_box_apply(gettext("The NAT configuration has been changed.")."<br />".gettext("You must apply the changes in order for them to take effect."));
|
||||
print_info_box(
|
||||
gettext("This legacy outbound NAT page is deprecated and will be replaced by the new Source NAT rules interface.") . "<br />" .
|
||||
gettext("Use the migration assistant to export existing legacy outbound NAT rules and import them into the new interface.") . "<br /><br />" .
|
||||
'<a class="btn btn-primary" href="/ui/firewall/migration">' .
|
||||
'<i class="fa fa-external-link fa-fw"></i> ' . gettext("Open migration assistant") .
|
||||
'</a> '
|
||||
);
|
||||
?>
|
||||
<form method="post" name="iform" id="iform">
|
||||
<input type="hidden" id="id" name="id" value="" />
|
||||
<input type="hidden" id="action" name="act" value="" />
|
||||
<section class="col-xs-12">
|
||||
<div class="content-box">
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="4"><?=gettext("Mode"); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<input name="mode" type="radio" id="mode_automatic"
|
||||
value="automatic" <?= $mode == "automatic" ? "checked=\"checked\"" : "";?> />
|
||||
</td>
|
||||
<td>
|
||||
<label for="mode_automatic">
|
||||
<strong>
|
||||
<?=gettext("Automatic outbound NAT rule generation"); ?><br />
|
||||
<?=gettext("(no manual rules can be used)");?>
|
||||
</strong>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<input name="mode" type="radio" id="mode_hybrid"
|
||||
value="hybrid" <?= $mode == "hybrid" ? "checked=\"checked\"" : "";?> />
|
||||
</td>
|
||||
<td>
|
||||
<label for="mode_hybrid">
|
||||
<strong>
|
||||
<?=gettext("Hybrid outbound NAT rule generation"); ?><br />
|
||||
<?=gettext("(automatically generated rules are applied after manual rules)");?>
|
||||
</strong>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input name="mode" type="radio" id="mode_advanced"
|
||||
value="advanced" <?= $mode == "advanced" ? "checked=\"checked\"" : "";?> />
|
||||
</td>
|
||||
<td>
|
||||
<label for="mode_advanced">
|
||||
<strong>
|
||||
<?=gettext("Manual outbound NAT rule generation"); ?><br />
|
||||
<?=gettext("(no automatic rules are being generated)");?>
|
||||
</strong>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<input name="mode" type="radio" id="mode_disabled"
|
||||
value="disabled" <?= $mode == "disabled" ? "checked=\"checked\"" : "";?> />
|
||||
</td>
|
||||
<td>
|
||||
<label for="mode_disabled">
|
||||
<strong>
|
||||
<?=gettext("Disable outbound NAT rule generation"); ?><br />
|
||||
<?=gettext("(outbound NAT is disabled)");?>
|
||||
</strong>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<button name="save" type="submit" class="btn btn-primary" value="Save"><?= gettext('Save') ?></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<?php if ($mode == 'advanced' || $mode == 'hybrid'): ?>
|
||||
<section class="col-xs-12">
|
||||
<div class="__mb"></div>
|
||||
<div class="table-responsive content-box">
|
||||
<table class="table table-striped table-condensed opnsense-rules">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="12">
|
||||
<?=gettext("Manual rules"); ?>
|
||||
<div id="category_block" class="pull-right">
|
||||
<select class="selectpicker hidden-xs hidden-sm hidden-md" data-live-search="true" data-size="5" multiple title="<?=gettext("Select category");?>" id="fw_category">
|
||||
</select>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><input type="checkbox" id="selectAll"></th>
|
||||
<th> </th>
|
||||
<th><?=gettext("Interface");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("Source");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("Source Port");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("Destination");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("Destination Port");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("NAT Address");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("NAT Port");?></th>
|
||||
<th><?=gettext("Static Port");?></th>
|
||||
<th><?=gettext("Description");?></th>
|
||||
<th class="text-nowrap">
|
||||
<a href="firewall_nat_out_edit.php" class="btn btn-primary btn-xs" data-toggle="tooltip" title="<?= html_safe(gettext('Add')) ?>">
|
||||
<i class="fa fa-plus fa-fw"></i>
|
||||
</a>
|
||||
<?php if (count($a_out)): ?>
|
||||
<button id="move_<?= count($a_out) ?>" name="move_<?= count($a_out) ?>_x" data-toggle="tooltip" title="<?=html_safe(gettext('Move selected rules to end'))?>" class="act_move btn btn-default btn-xs">
|
||||
<i class="fa fa-arrow-left fa-fw"></i>
|
||||
</button>
|
||||
<button id="del_x" title="<?= html_safe(gettext('Delete selected')) ?>" data-toggle="tooltip" class="act_delete btn btn-default btn-xs">
|
||||
<i class="fa fa-trash fa-fw"></i>
|
||||
</button>
|
||||
<button title="<?= html_safe(gettext('Enable selected')) ?>" data-toggle="tooltip" class="act_toggle_enable btn btn-default btn-xs">
|
||||
<i class="fa fa-check-square-o fa-fw"></i>
|
||||
</button>
|
||||
<button title="<?= html_safe(gettext('Disable selected')) ?>" data-toggle="tooltip" class="act_toggle_disable btn btn-default btn-xs">
|
||||
<i class="fa fa-square-o fa-fw"></i>
|
||||
</button>
|
||||
<?php endif ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$i = 0;
|
||||
foreach ($a_out as $natent):
|
||||
?>
|
||||
<tr class="rule <?=$mode == "disabled" || $mode == "automatic" || isset($natent['disabled'])?"text-muted":"";?>" data-category="<?=!empty($natent['category']) ? $natent['category'] : "";?>" ondblclick="document.location='firewall_nat_out_edit.php?id=<?=$i;?>';">
|
||||
<td>
|
||||
<input class="rule_select" type="checkbox" name="rule[]" value="<?=$i;?>" />
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
if ($mode == "disabled" || $mode == "automatic"):
|
||||
?>
|
||||
<span data-toggle="tooltip" title="<?=gettext("All manual rules are being ignored");?>" class="fa fa-play <?=$mode == "disabled" || $mode == "automatic" || isset($natent['disabled']) ? "text-muted" : "text-success";?>"></span>
|
||||
<?php
|
||||
else:
|
||||
?>
|
||||
<a href="#" class="act_toggle" id="toggle_<?=$i;?>" data-toggle="tooltip" title="<?=(!isset($natent['disabled'])) ? gettext("Disable") : gettext("Enable");?>" class="btn btn-default btn-xs <?=isset($natent['disabled']) ? "text-muted" : "text-success";?>">
|
||||
<span class="fa fa-play <?=isset($natent['disabled']) ? "text-muted" : "text-success";?> "></span>
|
||||
</a>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?=htmlspecialchars(convert_friendly_interface_to_friendly_descr($natent['interface'])); ?>
|
||||
</td>
|
||||
<td class="hidden-xs hidden-sm">
|
||||
<?= isset($natent['source']['not']) ? '!' : '' ?>
|
||||
<?php if (isset($natent['source']['network']) && is_alias($natent['source']['network'])): ?>
|
||||
<span title="<?=htmlspecialchars(get_alias_description($natent['source']['network']));?>" data-toggle="tooltip" data-html="true">
|
||||
<?=htmlspecialchars($natent['source']['network']);?>
|
||||
</span>
|
||||
<a href="/ui/firewall/alias/index/<?=htmlspecialchars($natent['source']['network']);?>"
|
||||
title="<?=gettext("edit alias");?>" data-toggle="tooltip">
|
||||
<i class="fa fa-list"></i>
|
||||
</a>
|
||||
<?php elseif (is_specialnet($natent['source']['network'])):?>
|
||||
<?=htmlspecialchars(get_specialnets()[$natent['source']['network']]); ?>
|
||||
<?php else: ?>
|
||||
<?=$natent['source']['network'] == "(self)" ? gettext("This Firewall") : htmlspecialchars($natent['source']['network']); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="hidden-xs hidden-sm">
|
||||
<?=!empty($natent['protocol']) ? $natent['protocol'] . '/' : "" ;?>
|
||||
<?php
|
||||
if (empty($natent['sourceport'])):?>
|
||||
*
|
||||
<?php
|
||||
elseif (isset($natent['sourceport']) && is_alias($natent['sourceport'])):?>
|
||||
<span title="<?=htmlspecialchars(get_alias_description($natent['sourceport']));?>" data-toggle="tooltip" data-html="true">
|
||||
<?=htmlspecialchars(pprint_port($natent['sourceport'])); ?>
|
||||
</span>
|
||||
<a href="/ui/firewall/alias/index/<?=htmlspecialchars($natent['sourceport']);?>"
|
||||
title="<?=gettext("edit alias");?>" data-toggle="tooltip">
|
||||
<i class="fa fa-list"></i>
|
||||
</a>
|
||||
<?php
|
||||
else:?>
|
||||
<?=htmlspecialchars($natent['sourceport'])?>
|
||||
<?php
|
||||
endif;?>
|
||||
</td>
|
||||
<td class="hidden-xs hidden-sm">
|
||||
<?= isset($natent['destination']['not']) ? '!' : '' ?>
|
||||
<?php if (isset($natent['destination']['network']) && is_alias($natent['destination']['network'])): ?>
|
||||
<span title="<?=htmlspecialchars(get_alias_description($natent['destination']['network']));?>" data-toggle="tooltip" data-html="true">
|
||||
<?=htmlspecialchars($natent['destination']['network']);?>
|
||||
</span>
|
||||
<a href="/ui/firewall/alias/index/<?=htmlspecialchars($natent['destination']['network']);?>"
|
||||
title="<?=gettext("edit alias");?>" data-toggle="tooltip">
|
||||
<i class="fa fa-list"></i>
|
||||
</a>
|
||||
<?php elseif (is_specialnet($natent['destination']['network'])):?>
|
||||
<?=htmlspecialchars(get_specialnets()[$natent['destination']['network']]); ?>
|
||||
<?php else: ?>
|
||||
<?=isset($natent['destination']['any']) ? "*" : htmlspecialchars($natent['destination']['address']);?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="hidden-xs hidden-sm">
|
||||
<?=!empty($natent['protocol']) ? $natent['protocol'] . '/' : "" ;?>
|
||||
<?php
|
||||
if (empty($natent['dstport'])):?>
|
||||
*
|
||||
<?php
|
||||
elseif (isset($natent['dstport']) && is_alias($natent['dstport'])):?>
|
||||
<span title="<?=htmlspecialchars(get_alias_description($natent['dstport']));?>" data-toggle="tooltip" data-html="true">
|
||||
<?=htmlspecialchars(pprint_port($natent['dstport'])); ?>
|
||||
</span>
|
||||
<a href="/ui/firewall/alias/index/<?=htmlspecialchars($natent['dstport']);?>"
|
||||
title="<?=gettext("edit alias");?>" data-toggle="tooltip">
|
||||
<i class="fa fa-list"></i>
|
||||
</a>
|
||||
<?php
|
||||
else:?>
|
||||
<?=htmlspecialchars($natent['dstport'])?>
|
||||
<?php
|
||||
endif;?>
|
||||
</td>
|
||||
<td class="hidden-xs hidden-sm">
|
||||
<?php
|
||||
|
||||
if (isset($natent['nonat'])) {
|
||||
$nat_address = '<I>NO NAT</I>';
|
||||
} elseif (empty($natent['target'])) {
|
||||
$nat_address = gettext("Interface address");
|
||||
} elseif (is_specialnet($natent['target'])) {
|
||||
$nat_address = htmlspecialchars(get_specialnets()[$natent['target']]);
|
||||
} elseif ($natent['target'] == "other-subnet") {
|
||||
$nat_address = $natent['targetip'] . '/' . $natent['targetip_subnet'];
|
||||
} else {
|
||||
$nat_address = htmlspecialchars($natent['target']);
|
||||
}
|
||||
?>
|
||||
<?php if (isset($natent['target']) && is_alias($natent['target'])): ?>
|
||||
<span title="<?=htmlspecialchars(get_alias_description($natent['target']));?>" data-toggle="tooltip" data-html="true">
|
||||
<?=$nat_address;?>
|
||||
</span>
|
||||
<a href="/ui/firewall/alias/index/<?=htmlspecialchars($natent['target']);?>"
|
||||
title="<?=gettext("edit alias");?>" data-toggle="tooltip">
|
||||
<i class="fa fa-list"></i>
|
||||
</a>
|
||||
<?php elseif (!empty($interface_names[$nat_address])): ?>
|
||||
<?=$interface_names[$nat_address];?>
|
||||
<?php else: ?>
|
||||
<?=$nat_address;?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="hidden-xs hidden-sm">
|
||||
<?=empty($natent['natport']) ? "*" : htmlspecialchars($natent['natport']);?>
|
||||
</td>
|
||||
<td>
|
||||
<?=isset($natent['staticnatport']) ? gettext("YES") : gettext("NO");?>
|
||||
</td>
|
||||
<td class="rule-description">
|
||||
<?=htmlspecialchars($natent['descr']);?>
|
||||
</td>
|
||||
<td>
|
||||
<a type="submit" id="move_<?=$i;?>" name="move_<?=$i;?>_x" data-toggle="tooltip" title="<?= html_safe(gettext('Move selected rules before this rule')) ?>" class="act_move btn btn-default btn-xs">
|
||||
<i class="fa fa-arrow-left fa-fw"></i>
|
||||
</a>
|
||||
<a href="firewall_nat_out_edit.php?id=<?=$i;?>" data-toggle="tooltip" title="<?= html_safe(gettext('Edit')) ?>" class="btn btn-default btn-xs">
|
||||
<i class="fa fa-pencil fa-fw"></i>
|
||||
</a>
|
||||
<a id="del_<?=$i;?>" title="<?= html_safe(gettext('Delete')) ?>" data-toggle="tooltip" class="act_delete btn btn-default btn-xs">
|
||||
<i class="fa fa-trash fa-fw"></i>
|
||||
</a>
|
||||
<a href="firewall_nat_out_edit.php?dup=<?=$i;?>" class="btn btn-default btn-xs" data-toggle="tooltip" title="<?= html_safe(gettext('Clone')) ?>">
|
||||
<i class="fa fa-clone fa-fw"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
$i++;
|
||||
endforeach;
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td style="width:16px"><span class="fa fa-play text-success"></span></td>
|
||||
<td colspan="11"><?=gettext("Enabled rule"); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="fa fa-play text-muted"></span></td>
|
||||
<td colspan="11"><?=gettext("Disabled rule"); ?></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif ?>
|
||||
<?php if ($mode == 'automatic' || $mode == 'hybrid'): ?>
|
||||
<section class="col-xs-12">
|
||||
<div class="__mb"></div>
|
||||
<div class="table-responsive content-box">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="11"><?=gettext("Automatic rules"); ?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th><?=gettext("Interface");?></th>
|
||||
<th><?=gettext("Source Networks");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("Source Port");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("Destination");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("Destination Port");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("NAT Address");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("NAT Port");?></th>
|
||||
<th class="hidden-xs hidden-sm"><?=gettext("Static Port");?></th>
|
||||
<th><?=gettext("Description");?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach (filter_auto_source_nat() as $natintf => $networks): ?>
|
||||
<?php $networks_safe = html_safe(implode(', ', array_values($networks))); ?>
|
||||
<?php $natintf_safe = html_safe(convert_friendly_interface_to_friendly_descr($natintf)); ?>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<span class="fa fa-play text-success" data-toggle="tooltip" title="<?=gettext("automatic outbound nat");?>"></span>
|
||||
</td>
|
||||
<td><?= $natintf_safe ?></td>
|
||||
<td><?= $networks_safe ?></td>
|
||||
<td class="hidden-xs hidden-sm">*</td>
|
||||
<td class="hidden-xs hidden-sm">*</td>
|
||||
<td class="hidden-xs hidden-sm">500</td>
|
||||
<td class="hidden-xs hidden-sm"><?= $natintf_safe ?></td>
|
||||
<td class="hidden-xs hidden-sm">*</td>
|
||||
<td class="hidden-xs hidden-sm"><?=gettext("YES");?></td>
|
||||
<td><?=gettext('Auto created rule for ISAKMP');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<span class="fa fa-play text-success" data-toggle="tooltip" title="<?=gettext("automatic outbound nat");?>"></span>
|
||||
</td>
|
||||
<td><?= $natintf_safe ?></td>
|
||||
<td><?= $networks_safe ?></td>
|
||||
<td class="hidden-xs hidden-sm">*</td>
|
||||
<td class="hidden-xs hidden-sm">*</td>
|
||||
<td class="hidden-xs hidden-sm">*</td>
|
||||
<td class="hidden-xs hidden-sm"><?= $natintf_safe ?></td>
|
||||
<td class="hidden-xs hidden-sm">*</td>
|
||||
<td class="hidden-xs hidden-sm"><?=gettext("NO");?></td>
|
||||
<td><?=gettext('Auto created rule');?></td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php include("foot.inc"); ?>
|
||||
@@ -1,892 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Deciso B.V.
|
||||
* Copyright (C) 2004 Scott Ullrich <[email protected]>
|
||||
* Copyright (C) 2003-2004 Manuel Kasper <[email protected]>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("filter.inc");
|
||||
|
||||
/**
|
||||
* return option array for valid translation networks
|
||||
*/
|
||||
function formTranslateAddresses()
|
||||
{
|
||||
$retval = [];
|
||||
|
||||
foreach (legacy_config_get_interfaces(['virtual' => false, 'enable' => true]) as $intf => $intfdata) {
|
||||
$retval[$intf."ip"] = (!empty($intfdata['descr']) ? $intfdata['descr'] : $intf ) . " " . gettext("address");
|
||||
}
|
||||
|
||||
foreach (config_read_array('virtualip', 'vip', false) as $sn) {
|
||||
if (!empty($sn['noexpand'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($sn['mode'] == "proxyarp") {
|
||||
$start = ip2long32(gen_subnet($sn['subnet'], $sn['subnet_bits']));
|
||||
$end = ip2long32(gen_subnet_max($sn['subnet'], $sn['subnet_bits']));
|
||||
$len = $end - $start;
|
||||
$retval[$sn['subnet'].'/'.$sn['subnet_bits']] = htmlspecialchars("Subnet: {$sn['subnet']}/{$sn['subnet_bits']} ({$sn['descr']})");
|
||||
for ($i = 0; $i <= $len; $i++) {
|
||||
$snip = long2ip32($start+$i);
|
||||
$retval[$snip] = htmlspecialchars("{$snip} ({$sn['descr']})");
|
||||
}
|
||||
} else {
|
||||
$retval[$sn['subnet']] = htmlspecialchars("{$sn['subnet']} ({$sn['descr']})");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (legacy_list_aliases("network") as $alias) {
|
||||
if ($alias['type'] == "host") {
|
||||
$retval[$alias['name']] = $alias['name'];
|
||||
}
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
$a_out = &config_read_array('nat', 'outbound', 'rule');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
// input record id, if valid
|
||||
if (isset($_GET['dup']) && isset($a_out[$_GET['dup']])) {
|
||||
$configId = $_GET['dup'];
|
||||
$after = $configId;
|
||||
} elseif (isset($_GET['id']) && isset($a_out[$_GET['id']])) {
|
||||
$id = $_GET['id'];
|
||||
$configId = $id;
|
||||
}
|
||||
|
||||
// init form data
|
||||
$pconfig = array();
|
||||
// set defaults
|
||||
$pconfig['source'] = 'any';
|
||||
$pconfig['source_subnet'] = 24;
|
||||
$pconfig['destination'] = "any";
|
||||
$pconfig['destination_subnet'] = 24;
|
||||
$pconfig['interface'] = "wan";
|
||||
|
||||
if (isset($configId)) {
|
||||
// load data from config
|
||||
foreach (array('protocol','sourceport','dstport','natport','target','targetip'
|
||||
,'targetip_subnet','poolopts','poolopts_sourcehashkey','interface','descr','nonat','log'
|
||||
,'disabled','staticnatport','nosync','ipprotocol','tag','tagged', 'category') as $fieldname) {
|
||||
if (isset($a_out[$configId][$fieldname])) {
|
||||
$pconfig[$fieldname] = $a_out[$configId][$fieldname];
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($a_out[$configId]['source']['network'], "/") !== false) {
|
||||
list($pconfig['source'],$pconfig['source_subnet']) = explode('/', $a_out[$configId]['source']['network']);
|
||||
} else {
|
||||
$pconfig['source'] = $a_out[$configId]['source']['network'];
|
||||
}
|
||||
$pconfig['source_not'] = !empty($a_out[$configId]['source']['not']);
|
||||
|
||||
if (!is_numeric($pconfig['source_subnet'])) {
|
||||
$pconfig['source_subnet'] = 32;
|
||||
}
|
||||
address_to_pconfig($a_out[$configId]['destination'], $pconfig['destination'],
|
||||
$pconfig['destination_subnet'], $pconfig['destination_not'],
|
||||
$none, $none);
|
||||
}
|
||||
|
||||
// initialize unused elements
|
||||
foreach (array('protocol','sourceport','dstport','natport','target','targetip',
|
||||
'targetip_subnet','poolopts','poolopts_sourcehashkey','interface','descr','nonat','tag','tagged',
|
||||
'disabled','staticnatport','nosync','source','source_subnet','ipprotocol') as $fieldname) {
|
||||
if (!isset($pconfig[$fieldname])) {
|
||||
$pconfig[$fieldname] = null;
|
||||
}
|
||||
}
|
||||
if (empty($pconfig['ipprotocol'])) {
|
||||
if (strpos($pconfig['source'].$pconfig['destination'].$pconfig['targetip'], ":") !== false) {
|
||||
$pconfig['ipprotocol'] = 'inet6';
|
||||
} else {
|
||||
$pconfig['ipprotocol'] = 'inet';
|
||||
}
|
||||
}
|
||||
if (empty($pconfig['targetip'])) {
|
||||
$pconfig['targetip'] = $pconfig['target'];
|
||||
}
|
||||
$pconfig['category'] = !empty($pconfig['category']) ? explode(",", $pconfig['category']) : [];
|
||||
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$input_errors = array();
|
||||
$pconfig = $_POST;
|
||||
// input record id, if valid
|
||||
if (isset($pconfig['id']) && isset($a_out[$pconfig['id']])) {
|
||||
$id = $pconfig['id'];
|
||||
}
|
||||
if (isset($pconfig['after']) && isset($a_out[$pconfig['after']])) {
|
||||
$after = $pconfig['after'];
|
||||
}
|
||||
|
||||
/* input validation */
|
||||
$reqdfields = explode(" ", "interface protocol source destination");
|
||||
$reqdfieldsn = array(gettext("Interface"),gettext("Protocol"),gettext("Source"),gettext("Destination"));
|
||||
|
||||
do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors);
|
||||
|
||||
if (in_array($pconfig['protocol'], explode(" ", "any tcp udp tcp/udp"))) {
|
||||
if(!empty($pconfig['sourceport']) && !is_portrange($pconfig['sourceport']) && !is_portoralias($pconfig['sourceport'])) {
|
||||
$input_errors[] = gettext("You must supply either a valid port or port alias for the source port entry.");
|
||||
}
|
||||
if(!empty($pconfig['dstport']) && !is_portrange($pconfig['dstport']) && !is_portoralias($pconfig['dstport'])) {
|
||||
$input_errors[] = gettext("You must supply either a valid port or port alias for the destination port entry.");
|
||||
}
|
||||
if (!empty($pconfig['natport']) && !(is_port($pconfig['natport']) || is_portrange($pconfig['natport'])) && empty($pconfig['nonat'])) {
|
||||
$input_errors[] = gettext("You must supply a valid port for the NAT port entry.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_specialnet($pconfig['source']) && !is_ipaddroralias($pconfig['source'])) {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid source IP address or alias."), $pconfig['source']);
|
||||
}
|
||||
|
||||
if (!empty($pconfig['source_subnet']) && !is_numericint($pconfig['source_subnet'])) {
|
||||
$input_errors[] = gettext("A valid source bit count must be specified.");
|
||||
}
|
||||
if ($pconfig['source'] == "any" && !empty($pconfig['source_not'])) {
|
||||
$input_errors[] = gettext("Negating source address of \"any\" is invalid.");
|
||||
}
|
||||
if (!is_specialnet($pconfig['destination']) && !is_ipaddroralias($pconfig['destination'])) {
|
||||
$input_errors[] = gettext("A valid destination must be specified.");
|
||||
}
|
||||
if (!empty($pconfig['destination_subnet']) && !is_numericint($pconfig['destination_subnet'])) {
|
||||
$input_errors[] = gettext("A valid destination bit count must be specified.");
|
||||
}
|
||||
if ($pconfig['destination'] == "any" && !empty($pconfig['destination_not'])) {
|
||||
$input_errors[] = gettext("Negating destination address of \"any\" is invalid.");
|
||||
}
|
||||
|
||||
if (!empty($pconfig['targetip']) && !is_ipaddr($pconfig['targetip']) && !is_subnet($pconfig['targetip'])
|
||||
&& !is_specialnet($pconfig['targetip']) && !is_alias($pconfig['targetip']) && empty($pconfig['nonat'])) {
|
||||
$input_errors[] = gettext("A valid target IP address must be specified.");
|
||||
}
|
||||
/* Verify Pool Options */
|
||||
if (!empty($pconfig['targetip']) && is_alias($pconfig['targetip']) && !empty($pconfig['poolopts']) && substr($pconfig['poolopts'], 0, 11) != 'round-robin') {
|
||||
$input_errors[] = gettext("Only Round Robin pool options may be chosen when selecting an alias.");
|
||||
}
|
||||
/* Verify Source Hash Key if provided */
|
||||
if (!empty($pconfig['poolopts_sourcehashkey'])){
|
||||
if (empty($pconfig['poolopts']) || $pconfig['poolopts'] != 'source-hash') {
|
||||
$input_errors[] = gettext("Source Hash Key is only valid for Source Hash type");
|
||||
}
|
||||
if (substr($pconfig['poolopts_sourcehashkey'], 0, 2) != "0x" || !ctype_xdigit(substr($pconfig['poolopts_sourcehashkey'], 2, 32)) ){
|
||||
$input_errors[] = gettext("Source Hash Key must be 0x followed by 32 hexadecimal digits");
|
||||
}
|
||||
}
|
||||
// validate ipv4/v6, addresses should use selected address family
|
||||
foreach (array('source', 'destination', 'targetip') as $fieldname) {
|
||||
if (is_ipaddrv6($pconfig[$fieldname]) && $pconfig['ipprotocol'] != 'inet6') {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid IPv4 address."), $pconfig[$fieldname]);
|
||||
}
|
||||
if (is_ipaddrv4($pconfig[$fieldname]) && $pconfig['ipprotocol'] != 'inet') {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid IPv6 address."), $pconfig[$fieldname]);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($input_errors) == 0) {
|
||||
$natent = array();
|
||||
$natent['source'] = array();
|
||||
$natent['destination'] = array();
|
||||
$natent['descr'] = $pconfig['descr'];
|
||||
$natent['category'] = !empty($pconfig['category']) ? implode(",", $pconfig['category']) : null;
|
||||
$natent['interface'] = $pconfig['interface'];
|
||||
$natent['tag'] = $pconfig['tag'];
|
||||
$natent['tagged'] = $pconfig['tagged'];
|
||||
$natent['poolopts'] = $pconfig['poolopts'];
|
||||
$natent['poolopts_sourcehashkey'] = $pconfig['poolopts_sourcehashkey'];
|
||||
$natent['ipprotocol'] = $pconfig['ipprotocol'];
|
||||
|
||||
if (isset($a_out[$id]['created']) && is_array($a_out[$id]['created']) ){
|
||||
$natent['created'] = $a_out[$id]['created'];
|
||||
}
|
||||
|
||||
// target ip/net
|
||||
if (empty($pconfig['targetip'])) {
|
||||
// empty target "Interface address"
|
||||
$natent['target'] = $pconfig['targetip'];
|
||||
$natent['targetip_subnet'] = 0;
|
||||
} elseif (!array_key_exists($pconfig['targetip'], formTranslateAddresses())) {
|
||||
// a bit vague behaviour in "target" and "targetip", if a custom net is given
|
||||
// the backend code wants target to be filled with "other-subnet".
|
||||
// if any other known net is given, target is used to provide the actual address....
|
||||
// -- can't remove this behaviour now without breaking old config, so let's reimplement
|
||||
$natent['target'] = 'other-subnet';
|
||||
$natent['targetip'] = trim($pconfig['targetip']);
|
||||
$natent['targetip_subnet'] = $pconfig['targetip_subnet'];
|
||||
} else {
|
||||
$natent['target'] = $pconfig['targetip'];
|
||||
}
|
||||
|
||||
// handle fields containing port numbers
|
||||
if (in_array($pconfig['protocol'], explode(" ", "any tcp udp tcp/udp"))) {
|
||||
if (isset($pconfig['staticnatport']) && empty($pconfig['nonat'])) {
|
||||
$natent['staticnatport'] = true;
|
||||
}
|
||||
$natent['sourceport'] = trim($pconfig['sourceport']);
|
||||
if (!empty($pconfig['natport']) && empty($pconfig['nonat'])) {
|
||||
$natent['natport'] = trim($pconfig['natport']);
|
||||
}
|
||||
if (!empty($pconfig['dstport'])) {
|
||||
$natent['dstport'] = trim($pconfig['dstport']);
|
||||
}
|
||||
} else {
|
||||
$natent['sourceport'] = "";
|
||||
}
|
||||
|
||||
if (!empty($pconfig['protocol']) && $pconfig['protocol'] != "any") {
|
||||
$natent['protocol'] = $pconfig['protocol'];
|
||||
}
|
||||
|
||||
/* parse source entry */
|
||||
if($pconfig['source'] == "any") {
|
||||
$natent['source']['network'] = "any";
|
||||
} else if($pconfig['source'] == "(self)") {
|
||||
$natent['source']['network'] = "(self)";
|
||||
} else if(is_alias($pconfig['source']) || is_specialnet($pconfig['source'])) {
|
||||
$natent['source']['network'] = trim($pconfig['source']);
|
||||
} else {
|
||||
if (is_ipaddrv6($pconfig['source'])) {
|
||||
$natent['source']['network'] = gen_subnetv6(trim($pconfig['source']), $pconfig['source_subnet']) . "/" . $pconfig['source_subnet'];
|
||||
} else {
|
||||
$natent['source']['network'] = gen_subnet(trim($pconfig['source']), $pconfig['source_subnet']) . "/" . $pconfig['source_subnet'];
|
||||
}
|
||||
}
|
||||
|
||||
// destination address
|
||||
if ($pconfig['destination'] == "any") {
|
||||
$natent['destination']['any'] = true;
|
||||
} elseif (is_alias($pconfig['destination']) || is_specialnet($pconfig['destination'])){
|
||||
$natent['destination']['network'] = trim($pconfig['destination']) ;
|
||||
} else {
|
||||
if (is_ipaddrv6($pconfig['destination'])) {
|
||||
$natent['destination']['address'] = gen_subnetv6(trim($pconfig['destination']), $pconfig['destination_subnet']) . "/" . $pconfig['destination_subnet'];
|
||||
} else {
|
||||
$natent['destination']['address'] = gen_subnet(trim($pconfig['destination']), $pconfig['destination_subnet']) . "/" . $pconfig['destination_subnet'];
|
||||
}
|
||||
}
|
||||
|
||||
// boolean fields
|
||||
if(!empty($pconfig['disabled'])) {
|
||||
$natent['disabled'] = true;
|
||||
}
|
||||
if(!empty($pconfig['nonat'])) {
|
||||
$natent['nonat'] = true;
|
||||
}
|
||||
if (!empty($pconfig['log'])) {
|
||||
$natent['log'] = true;
|
||||
}
|
||||
|
||||
if(isset($pconfig['nosync'] ) && $pconfig['nosync'] == "yes") {
|
||||
$natent['nosync'] = true;
|
||||
}
|
||||
if (isset($pconfig['destination_not']) && $pconfig['destination'] != "any") {
|
||||
$natent['destination']['not'] = true;
|
||||
}
|
||||
if (isset($pconfig['source_not']) && $pconfig['source'] != "any") {
|
||||
$natent['source']['not'] = true;
|
||||
}
|
||||
|
||||
$natent['updated'] = make_config_revision_entry();
|
||||
if (isset($id)) {
|
||||
$a_out[$id] = $natent;
|
||||
} else {
|
||||
$natent['created'] = make_config_revision_entry();
|
||||
if (isset($after)) {
|
||||
array_splice($a_out, $after+1, 0, array($natent));
|
||||
} else {
|
||||
$a_out[] = $natent;
|
||||
}
|
||||
}
|
||||
OPNsense\Core\Config::getInstance()->fromArray($config);
|
||||
$catmdl = new OPNsense\Firewall\Category();
|
||||
if ($catmdl->sync()) {
|
||||
$catmdl->serializeToConfig();
|
||||
$config = OPNsense\Core\Config::getInstance()->toArray(listtags());
|
||||
}
|
||||
if (write_config()) {
|
||||
mark_subsystem_dirty('natconf');
|
||||
}
|
||||
header(url_safe('Location: /firewall_nat_out.php'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
legacy_html_escape_form_data($pconfig);
|
||||
|
||||
include("head.inc");
|
||||
|
||||
?>
|
||||
<body>
|
||||
<script src="<?= cache_safe('/ui/js/tokenize2.js') ?>"></script>
|
||||
<link rel="stylesheet" type="text/css" href="<?= cache_safe(get_themed_filename('/css/tokenize2.css')) ?>">
|
||||
<script src="<?= cache_safe('/ui/js/opnsense_ui.js') ?>"></script>
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
|
||||
// select / input combination, link behaviour
|
||||
// when the data attribute "data-other" is selected, display related input item(s)
|
||||
// push changes from input back to selected option value
|
||||
$('[for!=""][for]').each(function(){
|
||||
var refObj = $("#"+$(this).attr("for"));
|
||||
if (refObj.is("select")) {
|
||||
// connect on change event to select box (show/hide)
|
||||
refObj.change(function(){
|
||||
if ($(this).find(":selected").attr("data-other") == "true") {
|
||||
// show related controls
|
||||
$('*[for="'+$(this).attr("id")+'"]').each(function(){
|
||||
if ($(this).hasClass("selectpicker")) {
|
||||
$(this).selectpicker('show');
|
||||
} else {
|
||||
$(this).removeClass("hidden");
|
||||
}
|
||||
$(this).prop('disabled', false);
|
||||
});
|
||||
} else {
|
||||
// hide related controls
|
||||
$('*[for="'+$(this).attr("id")+'"]').each(function(){
|
||||
if ($(this).hasClass("selectpicker")) {
|
||||
$(this).selectpicker('hide');
|
||||
} else {
|
||||
$(this).addClass("hidden");
|
||||
}
|
||||
$(this).prop('disabled', true);
|
||||
});
|
||||
}
|
||||
});
|
||||
// update initial
|
||||
refObj.change();
|
||||
|
||||
// connect on change to input to save data to selector
|
||||
if ($(this).attr("name") == undefined) {
|
||||
$(this).change(function(){
|
||||
var otherOpt = $('#'+$(this).attr('for')+' > option[data-other="true"]') ;
|
||||
otherOpt.attr("value",$(this).val());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// IPv4/IPv6 select
|
||||
hook_ipv4v6('ipv4v6net', 'network-id');
|
||||
formatTokenizersUI();
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include("fbegin.inc"); ?>
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<?php if (isset($input_errors) && count($input_errors) > 0) print_input_errors($input_errors); ?>
|
||||
<section class="col-xs-12">
|
||||
<div class="content-box">
|
||||
<form method="post" name="iform" id="iform">
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<table>
|
||||
<tr>
|
||||
<td><?=gettext("Edit Advanced Outbound NAT entry");?></td>
|
||||
<td colspan="2" style="text-align:right">
|
||||
<small><?=gettext("full help"); ?> </small>
|
||||
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page"></i>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_disabled" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Disabled"); ?></td>
|
||||
<td>
|
||||
<input name="disabled" type="checkbox" id="disabled" value="yes" <?= !empty($pconfig['disabled']) ? "checked=\"checked\"" : ""; ?> />
|
||||
<?= gettext('Disable this rule') ?>
|
||||
<div class="hidden" data-for="help_for_disabled">
|
||||
<?=gettext("Set this option to disable this rule without removing it from the list."); ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_do_not_nat" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Do not NAT");?></td>
|
||||
<td style="width:78%" class="vtable">
|
||||
<input type="checkbox" name="nonat" <?=!empty($pconfig['nonat']) ? " checked=\"checked\"" : ""; ?> />
|
||||
<div class="hidden" data-for="help_for_do_not_nat">
|
||||
<?=gettext("Enabling this option will disable NAT for traffic matching this rule and stop processing Outbound NAT rules.");?><br />
|
||||
<?=gettext("Hint: in most cases, you won't use this option.");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_interface" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Interface"); ?></td>
|
||||
<td>
|
||||
<select name="interface" class="selectpicker" data-width="348px" data-live-search="true">
|
||||
<?php foreach (legacy_config_get_interfaces(["enable" => true], ['lo0']) as $iface => $ifdetail): ?>
|
||||
<option value="<?=$iface;?>" <?= $iface == $pconfig['interface'] ? "selected=\"selected\"" : ""; ?>>
|
||||
<?=htmlspecialchars($ifdetail['descr']);?>
|
||||
</option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
<div class="hidden" data-for="help_for_interface">
|
||||
<?=gettext('Choose which interface this rule applies to.') ?><br />
|
||||
<?=gettext("Hint: in most cases, you'll want to use WAN here"); ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_ipv46" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("TCP/IP Version");?></td>
|
||||
<td>
|
||||
<select name="ipprotocol" class="selectpicker" data-width="348px" data-live-search="true" data-size="5" >
|
||||
<?php
|
||||
foreach (array('inet' => 'IPv4','inet6' => 'IPv6') as $proto => $name): ?>
|
||||
<option value="<?=$proto;?>" <?= $proto == $pconfig['ipprotocol'] ? "selected=\"selected\"" : "";?>>
|
||||
<?=$name;?>
|
||||
</option>
|
||||
<?php
|
||||
endforeach; ?>
|
||||
</select>
|
||||
<div class="hidden" data-for="help_for_ipv46">
|
||||
<?=gettext("Select the Internet Protocol version this rule applies to");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_proto" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Protocol"); ?></td>
|
||||
<td>
|
||||
<select id="proto" name="protocol" class="selectpicker" data-live-search="true" data-size="5" data-width="348px">
|
||||
<?php foreach (get_protocols() as $proto): ?>
|
||||
<option value="<?=strtolower($proto);?>" <?= strtolower($proto) == $pconfig['protocol'] ? "selected=\"selected\"" : ""; ?>><?=$proto;?></option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
<div class="hidden" data-for="help_for_proto">
|
||||
<?=gettext("Choose which IP protocol this rule should match."); ?><br/>
|
||||
<?=gettext("Hint: in most cases, you should specify"); ?> <em><?=gettext("TCP"); ?></em> <?=gettext("here."); ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <a id="help_for_src_invert" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Source invert') ?></td>
|
||||
<td>
|
||||
<input name="source_not" type="checkbox" value="yes" <?= !empty($pconfig['source_not']) ? 'checked="checked"' : '' ?> />
|
||||
<div class="hidden" data-for="help_for_src_invert">
|
||||
<?=gettext("Use this option to invert the sense of the match."); ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_source" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Source address') ?></td>
|
||||
<td>
|
||||
<table style="max-width: 348px">
|
||||
<tr>
|
||||
<td>
|
||||
<select name="source" id="source" class="selectpicker" data-live-search="true" data-size="5" data-width="348px">
|
||||
<option data-other=true value="<?=$pconfig['source'];?>" <?=!is_alias($pconfig['source']) && !in_array($pconfig['source'],array('(self)','any')) ? "selected=\"selected\"" : "";?>><?=gettext("Single host or Network"); ?></option>
|
||||
<optgroup label="<?=gettext("Aliases");?>">
|
||||
<?php foreach (legacy_list_aliases("network") as $alias):
|
||||
?>
|
||||
<option value="<?=$alias['name'];?>" <?=$alias['name'] == $pconfig['source'] ? "selected=\"selected\"" : "";?>><?=htmlspecialchars($alias['name']);?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<optgroup label="<?=gettext("Networks");?>">
|
||||
<?php foreach (get_specialnets(true) as $ifent => $ifdesc):
|
||||
?>
|
||||
<option value="<?=$ifent;?>" <?= $pconfig['source'] == $ifent ? "selected=\"selected\"" : ""; ?>><?=$ifdesc;?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- updates to "other" option in source -->
|
||||
<table style="max-width: 348px">
|
||||
<tr>
|
||||
<td style="width: 285px">
|
||||
<input type="text" for="source" id="src_address" value="<?=$pconfig['source'];?>" aria-label="<?=gettext("Source address");?>"/>
|
||||
</td>
|
||||
<td>
|
||||
<select name="source_subnet" data-network-id="src_address" class="selectpicker ipv4v6net" data-size="5" id="srcmask" data-width="70px" for="source">
|
||||
<?php for ($i = 128; $i > 0; $i--): ?>
|
||||
<option value="<?=$i;?>" <?= $i == $pconfig['source_subnet'] ? "selected=\"selected\"" : ""; ?>><?=$i;?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="hidden" data-for="help_for_source">
|
||||
<?=gettext("Enter the source network for the outbound NAT mapping.");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_src_port" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Source port') ?></td>
|
||||
<td>
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<select id="sourceport" name="sourceport" class="selectpicker" data-live-search="true" data-size="5" data-width="auto">
|
||||
<option data-other=true value="<?=$pconfig['sourceport'];?>">(<?=gettext("other"); ?>)</option>
|
||||
<optgroup label="<?=gettext("Aliases");?>">
|
||||
<?php foreach (legacy_list_aliases("port") as $alias):
|
||||
?>
|
||||
<option value="<?=$alias['name'];?>" <?= $pconfig['sourceport'] == $alias['name'] ? "selected=\"selected\"" : ""; ?> ><?=htmlspecialchars($alias['name']);?> </option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<optgroup label="<?=gettext("Well-known ports");?>">
|
||||
<option value="" <?= $pconfig['sourceport'] == "" ? "selected=\"selected\"" : ""; ?>><?=gettext("any"); ?></option>
|
||||
<?php foreach ($wkports as $wkport => $wkportdesc): ?>
|
||||
<option value="<?=$wkport;?>" <?= $wkport == $pconfig['sourceport'] ? "selected=\"selected\"" : "" ;?>><?=htmlspecialchars($wkportdesc);?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" value="<?=$pconfig['sourceport'];?>" for="sourceport"> <!-- updates to "other" option in localbeginport -->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="hidden" data-for="help_for_src_port">
|
||||
<?=gettext("(leave blank for any)");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <a id="help_for_dst_invert" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Destination invert') ?></td>
|
||||
<td>
|
||||
<input name="destination_not" type="checkbox" value="yes" <?= !empty($pconfig['destination_not']) ? 'checked="checked"' : '' ?> />
|
||||
<div class="hidden" data-for="help_for_dst_invert">
|
||||
<?=gettext("Use this option to invert the sense of the match."); ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_destination" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Destination address') ?></td>
|
||||
<td>
|
||||
<table style="max-width: 348px">
|
||||
<tr>
|
||||
<td>
|
||||
<select name="destination" id="destination" class="selectpicker" data-live-search="true" data-size="5" data-width="348px">
|
||||
<option data-other=true value="<?=$pconfig['destination'];?>" <?=!is_alias($pconfig['destination']) && $pconfig['destination'] != 'any' ? "selected=\"selected\"" : "";?>><?=gettext("Single host or Network"); ?></option>
|
||||
<optgroup label="<?=gettext("Aliases");?>">
|
||||
<?php foreach (legacy_list_aliases("network") as $alias):
|
||||
?>
|
||||
<option value="<?=$alias['name'];?>" <?=$alias['name'] == $pconfig['destination'] ? "selected=\"selected\"" : "";?>><?=htmlspecialchars($alias['name']);?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<optgroup label="<?=gettext("Networks");?>">
|
||||
<?php foreach (get_specialnets(true) as $ifent => $ifdesc):
|
||||
?>
|
||||
<option value="<?=$ifent;?>" <?= $pconfig['destination'] == $ifent ? "selected=\"selected\"" : ""; ?>><?=$ifdesc;?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- updates to "other" option in source -->
|
||||
<table style="max-width: 348px">
|
||||
<tr>
|
||||
<td style="width:285px">
|
||||
<input type="text" id="dst_address" for="destination" value="<?=$pconfig['destination'];?>" aria-label="<?=gettext("Destination address");?>"/>
|
||||
</td>
|
||||
<td>
|
||||
<select name="destination_subnet" data-network-id="dst_address" class="selectpicker ipv4v6net" id="dstmask" data-size="5" data-width="auto" for="destination" >
|
||||
<?php for ($i = 128; $i > 0; $i--): ?>
|
||||
<option value="<?=$i;?>" <?= $i == $pconfig['destination_subnet'] ? "selected=\"selected\"" : ""; ?>><?=$i;?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="hidden" data-for="help_for_destination">
|
||||
<?=gettext("Enter the destination network for the outbound NAT mapping.");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_dstport" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Destination port') ?></td>
|
||||
<td>
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<select id="dstport" name="dstport" class="selectpicker" data-live-search="true" data-size="5" data-width="auto">
|
||||
<option data-other=true value="<?=$pconfig['dstport'];?>">(<?=gettext("other"); ?>)</option>
|
||||
<optgroup label="<?=gettext("Aliases");?>">
|
||||
<?php foreach (legacy_list_aliases("port") as $alias):
|
||||
?>
|
||||
<option value="<?=$alias['name'];?>" <?= $pconfig['dstport'] == $alias['name'] ? "selected=\"selected\"" : ""; ?> ><?=htmlspecialchars($alias['name']);?> </option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<optgroup label="<?=gettext("Well-known ports");?>">
|
||||
<option value="" <?= $pconfig['dstport'] == "" ? "selected=\"selected\"" : ""; ?>><?=gettext("any"); ?></option>
|
||||
<?php foreach ($wkports as $wkport => $wkportdesc): ?>
|
||||
<option value="<?=$wkport;?>" <?= $wkport == $pconfig['dstport'] ? "selected=\"selected\"" : "" ;?>><?=htmlspecialchars($wkportdesc);?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" value="<?=$pconfig['dstport'];?>" for="dstport"> <!-- updates to "other" option in localbeginport -->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="hidden" data-for="help_for_dstport">
|
||||
<?=gettext("(leave blank for any)");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_target" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Translation / target"); ?></td>
|
||||
<td>
|
||||
<table style="max-width: 348px">
|
||||
<tr>
|
||||
<td>
|
||||
<select name="targetip" id="targetip" class="selectpicker" data-live-search="true" data-size="5" data-width="348px">
|
||||
<option value="" <?= empty($pconfig['targetip']) ? "selected=\"selected\"" : "";?> > <?=gettext("Interface address");?> </option>
|
||||
<option data-other=true value="<?=$pconfig['targetip'];?>" <?= !empty($pconfig['targetip']) && !array_key_exists($pconfig['targetip'], formTranslateAddresses() ) ? "selected=\"selected\"" : "";?>><?=gettext("Single host or Network"); ?></option>
|
||||
<?php foreach (formTranslateAddresses() as $optKey => $optValue): ?>
|
||||
<option value="<?=$optKey;?>" <?= $pconfig['targetip'] == $optKey ? "selected=\"selected\"" : ""; ?>>
|
||||
<?=$optValue;?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- updates to "other" option in source -->
|
||||
<table style="max-width: 348px">
|
||||
<tr>
|
||||
<td style="width:285px">
|
||||
<input type="text" id="targetip_text" for="targetip" value="<?=$pconfig['targetip'];?>" aria-label="<?=gettext("Translation address");?>"/>
|
||||
</td>
|
||||
<td>
|
||||
<select name="targetip_subnet" data-network-id="targetip_text" class="selectpicker ipv4v6net" id="targetip_subnet" data-size="5" data-width="70px" for="targetip" >
|
||||
<?php for ($i = 128; $i > 0; $i--): ?>
|
||||
<option value="<?=$i;?>" <?= $i == $pconfig['targetip_subnet'] ? "selected=\"selected\"" : ""; ?>><?=$i;?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="hidden" data-for="help_for_target">
|
||||
<?=gettext("Packets matching this rule will be mapped to the IP address given here.");?><br />
|
||||
<?=sprintf(gettext("If you want this rule to apply to another IP address rather than the IP address of the interface chosen above, ".
|
||||
"select it here (you will need to define %sVirtual IP addresses%s on the interface first)."),'<a href="ui/interfaces/vip">','</a>')?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_log" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Log");?></td>
|
||||
<td>
|
||||
<input name="log" type="checkbox" id="log" value="yes" <?= !empty($pconfig['log']) ? "checked=\"checked\"" : ""; ?> />
|
||||
<?= gettext('Log packets that are handled by this rule') ?>
|
||||
<div class="hidden" data-for="help_for_log">
|
||||
<?=sprintf(gettext("Hint: the firewall has limited local log space. Don't turn on logging for everything. If you want to do a lot of logging, consider using a %sremote syslog server%s."),'<a href="ui/syslog/">','</a>') ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_natport" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Translation") . " / " .gettext("port:");?></td>
|
||||
<td>
|
||||
<input name="natport" type="text" value="<?=$pconfig['natport'];?>" />
|
||||
<div class="hidden" data-for="help_for_natport">
|
||||
<?=gettext("Enter the source port for the outbound NAT mapping.");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Static-port:");?></td>
|
||||
<td>
|
||||
<input name="staticnatport" type="checkbox" <?=!empty($pconfig['staticnatport']) ? " checked=\"checked\"" : "";?> >
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_poolopts" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Pool Options:");?></td>
|
||||
<td>
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<select name="poolopts" id="poolopts" class="selectpicker">
|
||||
<option value="" <?=empty($pconfig['poolopts']) ? "selected=\"selected\"" : ""; ?>>
|
||||
<?=gettext("Default");?>
|
||||
</option>
|
||||
<option value="round-robin" <?=$pconfig['poolopts'] == "round-robin" ? "selected=\"selected\"" : ""; ?>>
|
||||
<?=gettext("Round Robin");?>
|
||||
</option>
|
||||
<option value="round-robin sticky-address" <?=$pconfig['poolopts'] == "round-robin sticky-address" ? "selected=\"selected\"" : ""; ?>>
|
||||
<?=gettext("Round Robin with Sticky Address");?>
|
||||
</option>
|
||||
<option value="random" <?=$pconfig['poolopts'] == "random" ? "selected=\"selected\"" : ""; ?>>
|
||||
<?=gettext("Random");?>
|
||||
</option>
|
||||
<option value="random sticky-address" <?=$pconfig['poolopts'] == "random sticky-address" ? "selected=\"selected\"" : ""; ?>>
|
||||
<?=gettext("Random with Sticky Address");?>
|
||||
</option>
|
||||
<option value="source-hash" data-other="true" <?=$pconfig['poolopts'] == "source-hash" ? "selected=\"selected\"" : ""; ?>>
|
||||
<?=gettext("Source Hash");?>
|
||||
</option>
|
||||
<option value="bitmask" <?=$pconfig['poolopts'] == "bitmask" ? "selected=\"selected\"" : ""; ?>>
|
||||
<?=gettext("Bitmask");?>
|
||||
</option>
|
||||
</select>
|
||||
<div class="hidden" data-for="help_for_poolopts">
|
||||
<?=gettext("Only Round Robin types work with Host Aliases. Any type can be used with a Subnet.");?><br />
|
||||
<ul>
|
||||
<li> <?=gettext("Round Robin: Loops through the translation addresses.");?></li>
|
||||
<li> <?=gettext("Random: Selects an address from the translation address pool at random.");?></li>
|
||||
<li> <?=gettext("Source Hash: Uses a hash of the source address to determine the translation address, ensuring that the redirection address is always the same for a given source. Optionally provide a Source Hash Key to make it persist when the ruleset is reloaded. Must be 0x followed by 32 hexadecimal digits.");?></li>
|
||||
<li> <?=gettext("Bitmask: Applies the subnet mask and keeps the last portion identical; 10.0.1.50 -> x.x.x.50.");?></li>
|
||||
<li> <?=gettext("Sticky Address: The Sticky Address option can be used with the Random and Round Robin pool types to ensure that a particular source address is always mapped to the same translation address.");?></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" id="poolopts_sourcehashkey" name="poolopts_sourcehashkey" for="poolopts" placeholder="Source Hash Key" value="<?=$pconfig['poolopts_sourcehashkey']?>"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_tag" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Set local tag"); ?></td>
|
||||
<td>
|
||||
<input name="tag" type="text" value="<?=$pconfig['tag'];?>" />
|
||||
<div class="hidden" data-for="help_for_tag">
|
||||
<?= gettext("You can mark a packet matching this rule and use this mark to match on other NAT/filter rules.") ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_tagged" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Match local tag"); ?> </td>
|
||||
<td>
|
||||
<input name="tagged" type="text" value="<?=$pconfig['tagged'];?>" />
|
||||
<div class="hidden" data-for="help_for_tagged">
|
||||
<?=gettext("You can match packet on a mark placed before on another rule.")?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_nosync" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("No XMLRPC Sync"); ?></td>
|
||||
<td>
|
||||
<input type="checkbox" value="yes" name="nosync" <?=!empty($pconfig['nosync']) ? "checked=\"checked\"" :"";?> />
|
||||
<div class="hidden" data-for="help_for_nosync">
|
||||
<?=gettext("Hint: This prevents the rule on Master from automatically syncing to other CARP members. This does NOT prevent the rule from being overwritten on Slave.");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_category" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Category"); ?></td>
|
||||
<td>
|
||||
<select name="category[]" id="category" multiple="multiple" class="tokenize" data-allownew="true" data-width="348px" data-live-search="true">
|
||||
<?php
|
||||
foreach ((new OPNsense\Firewall\Category())->iterateCategories() as $category):
|
||||
$catname = htmlspecialchars($category['name'], ENT_QUOTES | ENT_HTML401);?>
|
||||
<option value="<?=$catname;?>" <?=!empty($pconfig['category']) && in_array($catname, $pconfig['category']) ? 'selected="selected"' : '';?> ><?=$catname;?></option>
|
||||
<?php
|
||||
endforeach;?>
|
||||
</select>
|
||||
<div class="hidden" data-for="help_for_category">
|
||||
<?=gettext("You may enter or select a category here to group firewall rules (not parsed)."); ?>
|
||||
</div>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_descr" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Description"); ?></td>
|
||||
<td>
|
||||
<input name="descr" type="text" id="descr" size="40" value="<?=$pconfig['descr'];?>" />
|
||||
<div class="hidden" data-for="help_for_descr">
|
||||
<?=gettext("You may enter a description here for your reference (not parsed)."); ?>
|
||||
</div>
|
||||
</tr>
|
||||
<?php
|
||||
$has_created_time = (isset($a_out[$id]['created']) && is_array($a_out[$id]['created']));
|
||||
$has_updated_time = (isset($a_out[$id]['updated']) && is_array($a_out[$id]['updated']));
|
||||
if ($has_created_time || $has_updated_time):
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="2"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><?=gettext("Rule Information");?></td>
|
||||
</tr>
|
||||
<?php
|
||||
if ($has_created_time):
|
||||
?>
|
||||
<tr>
|
||||
<td><?=gettext("Created");?></td>
|
||||
<td>
|
||||
<?= date(gettext('n/j/y H:i:s'), (int)$a_out[$id]['created']['time']) ?> (<?= $a_out[$id]['created']['username'] ?>)
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
endif;
|
||||
if ($has_updated_time):
|
||||
?>
|
||||
<tr>
|
||||
<td><?=gettext("Updated");?></td>
|
||||
<td>
|
||||
<?= date(gettext('n/j/y H:i:s'), (int)$a_out[$id]['updated']['time']) ?> (<?= $a_out[$id]['updated']['username'] ?>)
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
endif;
|
||||
endif;
|
||||
?>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<input name="Submit" type="submit" class="btn btn-primary" value="<?=html_safe(gettext('Save')); ?>" />
|
||||
<input type="button" class="btn btn-default" value="<?=html_safe(gettext('Cancel'));?>" onclick="window.location.href='/firewall_nat_out.php'" />
|
||||
<?php
|
||||
if (isset($id)):
|
||||
?>
|
||||
<input name="id" type="hidden" value="<?=$id;?>" />
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<input name="after" type="hidden" value="<?=isset($after) ? $after : "";?>" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php include("foot.inc"); ?>
|
||||
Reference in New Issue
Block a user