firewall: allow NPT logging; closes #5228

We will be adding NPT logging support because the infrastructure
already supports it.  1:1 is a bit harder to deal with so hands
off for now and see how this works out.
This commit is contained in:
Franco Fichtner 2022-06-14 13:43:46 +02:00
parent 22e376a9a8
commit d8553a0e7f
4 changed files with 60 additions and 50 deletions

View File

@ -79,7 +79,7 @@ class FirewallController extends ApiControllerBase
}
sort($interfaces, SORT_NATURAL | SORT_FLAG_CASE);
return [
'action' => ['pass', 'block', 'rdr', 'nat'], /* XXX binat is possible but not yet supported in rules */
'action' => ['pass', 'block', 'rdr', 'nat', 'binat'],
'interface_name' => $interfaces,
'dir' => ['in', 'out'],
];

View File

@ -1,7 +1,7 @@
<?php
/*
* Copyright (C) 2017 Deciso B.V.
* Copyright (C) 2017-2022 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,16 +34,15 @@ namespace OPNsense\Firewall;
*/
class NptRule extends Rule
{
private $procorder = array(
'binat_1' => array(
'disabled' => 'parseIsComment',
'binat' => 'parseStaticText,binat ',
'interface' => 'parseInterface',
'from' => 'parsePlain,from , to any',
'to' => 'parsePlain, -> ',
'descr' => 'parseComment'
),
);
private $procorder = [
'disabled' => 'parseIsComment',
'binat' => 'parseStaticText,binat ',
'log' => 'parseBool,log',
'interface' => 'parseInterface',
'from' => 'parsePlain,from , to any',
'to' => 'parsePlain, -> ',
'descr' => 'parseComment'
];
/**
* search interfaces without a gateway other then the one provided
@ -52,7 +51,7 @@ class NptRule extends Rule
*/
private function reflectionInterfaces($interface)
{
$result = array();
$result = [];
foreach ($this->interfaceMapping as $intfk => $intf) {
if (
empty($intf['gateway']) && empty($intf['gatewayv6']) && $interface != $intfk
@ -72,7 +71,6 @@ class NptRule extends Rule
private function parseNptRules()
{
foreach ($this->reader('npt') as $rule) {
$rule['rule_type'] = "binat_1";
yield $rule;
}
}
@ -85,7 +83,7 @@ class NptRule extends Rule
{
$ruleTxt = '';
foreach ($this->parseNptRules() as $rule) {
$ruleTxt .= $this->ruleToText($this->procorder[$rule['rule_type']], $rule) . "\n";
$ruleTxt .= $this->ruleToText($this->procorder, $rule) . "\n";
}
return $ruleTxt;
}

View File

@ -29,8 +29,13 @@
$( document ).ready(function() {
var field_type_icons = {
'pass': 'fa-play', 'block': 'fa-ban', 'in': 'fa-arrow-right',
'out': 'fa-arrow-left', 'rdr': 'fa-exchange', 'nat': 'fa-exchange'
'binat': 'fa-exchange',
'block': 'fa-ban',
'in': 'fa-arrow-right',
'nat': 'fa-exchange',
'out': 'fa-arrow-left',
'pass': 'fa-play',
'rdr': 'fa-exchange'
};
var interface_descriptions = {};
let hostnameMap = {};
@ -280,7 +285,7 @@
log_tr.addClass('fw_pass');
} else if (record['action'] == 'block') {
log_tr.addClass('fw_block');
} else if (record['action'] == 'rdr' || record['action'] == 'nat') {
} else if (record['action'] == 'rdr' || record['action'] == 'nat' || record['action'] == 'binat') {
log_tr.addClass('fw_nat');
}
$("#grid-log > tbody > tr:first").before(log_tr);

View File

@ -43,10 +43,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$pconfig = array();
// set defaults
$pconfig['interface'] = "wan";
$pconfig['interface'] = 'wan';
if (isset($configId)) {
// copy 1-to-1 attributes
foreach (array('disabled','interface','descr', 'category') as $fieldname) {
foreach (array('disabled','interface','descr','log','category') as $fieldname) {
if (isset($a_npt[$configId][$fieldname])) {
$pconfig[$fieldname] = $a_npt[$configId][$fieldname];
}
@ -64,7 +64,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
// initialize empty form values
foreach (array('disabled','interface','descr','src','srcmask','dst') as $fieldname) {
foreach (array('disabled','interface','descr','src','srcmask','dst','log') as $fieldname) {
if (!isset($pconfig[$fieldname])) {
$pconfig[$fieldname] = null;
}
@ -100,37 +100,37 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
if (count($input_errors) == 0) {
$natent = array();
$natent = [];
$natent['disabled'] = isset($pconfig['disabled']) ? true:false;
$natent['category'] = !empty($pconfig['category']) ? implode(",", $pconfig['category']) : null;
$natent['descr'] = $pconfig['descr'];
$natent['interface'] = $pconfig['interface'];
pconfig_to_address(
$natent['source'], trim($pconfig['src']), $pconfig['srcmask']
);
$natent['disabled'] = isset($pconfig['disabled']) ? true : false;
$natent['category'] = !empty($pconfig['category']) ? implode(",", $pconfig['category']) : null;
$natent['descr'] = $pconfig['descr'];
$natent['interface'] = $pconfig['interface'];
$natent['log'] = !empty($pconfig['log']);
pconfig_to_address(
$natent['destination'], trim($pconfig['dst']), $pconfig['srcmask']
);
pconfig_to_address($natent['source'], trim($pconfig['src']), $pconfig['srcmask']);
pconfig_to_address($natent['destination'], trim($pconfig['dst']), $pconfig['srcmask']);
if (isset($id)) {
$a_npt[$id] = $natent;
} elseif (isset($after)) {
array_splice($a_npt, $after+1, 0, array($natent));
} else {
$a_npt[] = $natent;
}
OPNsense\Core\Config::getInstance()->fromArray($config);
$catmdl = new OPNsense\Firewall\Category();
if ($catmdl->sync()) {
$catmdl->serializeToConfig();
$config = OPNsense\Core\Config::getInstance()->toArray(listtags());
}
write_config();
mark_subsystem_dirty('natconf');
header(url_safe('Location: /firewall_nat_npt.php'));
exit;
if (isset($id)) {
$a_npt[$id] = $natent;
} elseif (isset($after)) {
array_splice($a_npt, $after+1, 0, array($natent));
} else {
$a_npt[] = $natent;
}
OPNsense\Core\Config::getInstance()->fromArray($config);
$catmdl = new OPNsense\Firewall\Category();
if ($catmdl->sync()) {
$catmdl->serializeToConfig();
$config = OPNsense\Core\Config::getInstance()->toArray(listtags());
}
write_config();
mark_subsystem_dirty('natconf');
header(url_safe('Location: /firewall_nat_npt.php'));
exit;
}
}
@ -168,8 +168,8 @@ $( document ).ready(function() {
<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">
<strong><?=gettext("Disable this rule"); ?></strong><br />
<?=gettext("Set this option to disable this rule without removing it from the list."); ?>
</div>
</td>
@ -224,6 +224,13 @@ $( document ).ready(function() {
</div>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=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') ?><br/>
</td>
</tr>
<tr>
<td><a id="help_for_category" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Category"); ?></td>
<td>