mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
net/firewall - add NPTv6 for https://github.com/opnsense/core/issues/6383
This commit is contained in:
@@ -42,4 +42,7 @@ function pfplugin_firewall($fw)
|
||||
foreach ($mdlFilter->snatrules->rule->sortedBy(["sequence"]) as $key => $rule) {
|
||||
$fw->registerSNatRule(50, $rule->serialize());
|
||||
}
|
||||
foreach ($mdlFilter->npt->rule->sortedBy(["sequence"]) as $key => $rule) {
|
||||
$fw->registerNptRule(50, $rule->serialize());
|
||||
}
|
||||
}
|
||||
|
||||
+40
@@ -30,6 +30,7 @@ namespace OPNsense\Firewall\Api;
|
||||
use OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
use OPNsense\Firewall\Category;
|
||||
|
||||
/**
|
||||
* Class FilterBaseController implements actions for various types
|
||||
@@ -39,6 +40,45 @@ abstract class FilterBaseController extends ApiMutableModelControllerBase
|
||||
{
|
||||
protected static $internalModelName = 'filter';
|
||||
protected static $internalModelClass = 'OPNsense\Firewall\Filter';
|
||||
protected static $categorysource = null;
|
||||
|
||||
/**
|
||||
* list categories and usage
|
||||
* @return array
|
||||
*/
|
||||
public function listCategoriesAction()
|
||||
{
|
||||
$response = ['rows' => []];
|
||||
$catcount = [];
|
||||
if (!empty(static::$categorysource)) {
|
||||
$node = $this->getModel();
|
||||
foreach (explode('.', static::$categorysource) as $ref) {
|
||||
$node = $node->$ref;
|
||||
}
|
||||
foreach ($node->iterateItems() as $item) {
|
||||
if (!empty((string)$item->categories)) {
|
||||
foreach (explode(',', (string)$item->categories) as $cat) {
|
||||
if (!isset($catcount[$cat])) {
|
||||
$catcount[$cat] = 0;
|
||||
}
|
||||
$catcount[$cat] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ((new Category())->categories->category->iterateItems() as $key => $category) {
|
||||
$response['rows'][] = [
|
||||
"uuid" => $key,
|
||||
"name" => (string)$category->name,
|
||||
"color" => (string)$category->color,
|
||||
"used" => isset($catcount[$key]) ? $catcount[$key] : 0
|
||||
];
|
||||
}
|
||||
array_multisort(array_column($response['rows'], "name"), SORT_ASC, SORT_NATURAL, $response['rows']);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
public function applyAction($rollback_revision = null)
|
||||
{
|
||||
|
||||
+7
-1
@@ -29,9 +29,15 @@ namespace OPNsense\Firewall\Api;
|
||||
|
||||
class FilterController extends FilterBaseController
|
||||
{
|
||||
protected static $categorysource = "rules.rule";
|
||||
|
||||
public function searchRuleAction()
|
||||
{
|
||||
return $this->searchBase("rules.rule", array('enabled', 'sequence', 'description'), "sequence");
|
||||
$category = $this->request->get('category');
|
||||
$filter_funct = function ($record) use ($category) {
|
||||
return empty($category) || array_intersect(explode(',', $record->categories), $category);
|
||||
};
|
||||
return $this->searchBase("rules.rule", ['enabled', 'sequence', 'description'], "sequence", $filter_funct);
|
||||
}
|
||||
|
||||
public function setRuleAction($uuid)
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Deciso B.V.
|
||||
* 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.
|
||||
*/
|
||||
namespace OPNsense\Firewall\Api;
|
||||
|
||||
class NptController extends FilterBaseController
|
||||
{
|
||||
protected static $categorysource = "npt.rule";
|
||||
|
||||
public function searchRuleAction()
|
||||
{
|
||||
$category = $this->request->get('category');
|
||||
$filter_funct = function ($record) use ($category) {
|
||||
return empty($category) || array_intersect(explode(',', $record->categories), $category);
|
||||
};
|
||||
return $this->searchBase("npt.rule", ['enabled', 'sequence', 'description'], "sequence", $filter_funct);
|
||||
}
|
||||
|
||||
public function setRuleAction($uuid)
|
||||
{
|
||||
return $this->setBase("rule", "npt.rule", $uuid);
|
||||
}
|
||||
|
||||
public function addRuleAction()
|
||||
{
|
||||
return $this->addBase("rule", "npt.rule");
|
||||
}
|
||||
|
||||
public function getRuleAction($uuid = null)
|
||||
{
|
||||
return $this->getBase("rule", "npt.rule", $uuid);
|
||||
}
|
||||
|
||||
public function delRuleAction($uuid)
|
||||
{
|
||||
return $this->delBase("npt.rule", $uuid);
|
||||
}
|
||||
|
||||
public function toggleRuleAction($uuid, $enabled = null)
|
||||
{
|
||||
return $this->toggleBase("npt.rule", $uuid, $enabled);
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -29,9 +29,15 @@ namespace OPNsense\Firewall\Api;
|
||||
|
||||
class SourceNatController extends FilterBaseController
|
||||
{
|
||||
protected static $categorysource = "snatrules.rule";
|
||||
|
||||
public function searchRuleAction()
|
||||
{
|
||||
return $this->searchBase("snatrules.rule", array('enabled', 'sequence', 'description'), "sequence");
|
||||
$category = $this->request->get('category');
|
||||
$filter_funct = function ($record) use ($category) {
|
||||
return empty($category) || array_intersect(explode(',', $record->categories), $category);
|
||||
};
|
||||
return $this->searchBase("snatrules.rule", ['enabled', 'sequence', 'description'], "sequence", $filter_funct);
|
||||
}
|
||||
|
||||
public function setRuleAction($uuid)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Deciso B.V.
|
||||
* 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.
|
||||
*/
|
||||
namespace OPNsense\Firewall;
|
||||
|
||||
class NptController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->pick('OPNsense/Firewall/filter');
|
||||
$this->view->ruleController = "npt";
|
||||
$this->view->formDialogFilterRule = $this->getForm("dialogNptRule");
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -99,7 +99,13 @@
|
||||
<type>checkbox</type>
|
||||
<help>Log packets that are handled by this rule</help>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<id>rule.categories</id>
|
||||
<label>Categories</label>
|
||||
<type>select_multiple</type>
|
||||
<style>tokenize</style>
|
||||
<help>For grouping purposes you may select multiple groups here to organize items.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.description</id>
|
||||
<label>Description</label>
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>rule.enabled</id>
|
||||
<label>enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable this rule</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.sequence</id>
|
||||
<label>Sequence</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.interface</id>
|
||||
<label>Interface</label>
|
||||
<type>dropdown</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.source_net</id>
|
||||
<label>Source</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.destination_net</id>
|
||||
<label>Destination</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.categories</id>
|
||||
<label>Categories</label>
|
||||
<type>select_multiple</type>
|
||||
<style>tokenize</style>
|
||||
<help>For grouping purposes you may select multiple groups here to organize items.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
</form>
|
||||
+7
@@ -86,6 +86,13 @@
|
||||
<type>checkbox</type>
|
||||
<help>Log packets that are handled by this rule</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.categories</id>
|
||||
<label>Categories</label>
|
||||
<type>select_multiple</type>
|
||||
<style>tokenize</style>
|
||||
<help>For grouping purposes you may select multiple groups here to organize items.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.description</id>
|
||||
<label>Description</label>
|
||||
|
||||
@@ -100,6 +100,17 @@
|
||||
<Default>0</Default>
|
||||
<Required>Y</Required>
|
||||
</log>
|
||||
<categories type="ModelRelationField">
|
||||
<Model>
|
||||
<rulesets>
|
||||
<source>OPNsense.Firewall.Category</source>
|
||||
<items>categories.category</items>
|
||||
<display>name</display>
|
||||
</rulesets>
|
||||
</Model>
|
||||
<Multiple>Y</Multiple>
|
||||
<ValidationMessage>Related category not found.</ValidationMessage>
|
||||
</categories>
|
||||
<description type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^([\t\n\v\f\r 0-9a-zA-Z.\-,_\x{00A0}-\x{FFFF}]){0,255}$/u</mask>
|
||||
@@ -184,6 +195,17 @@
|
||||
<Default>0</Default>
|
||||
<Required>Y</Required>
|
||||
</log>
|
||||
<categories type="ModelRelationField">
|
||||
<Model>
|
||||
<rulesets>
|
||||
<source>OPNsense.Firewall.Category</source>
|
||||
<items>categories.category</items>
|
||||
<display>name</display>
|
||||
</rulesets>
|
||||
</Model>
|
||||
<Multiple>Y</Multiple>
|
||||
<ValidationMessage>Related category not found.</ValidationMessage>
|
||||
</categories>
|
||||
<description type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^([\t\n\v\f\r 0-9a-zA-Z.\-,_\x{00A0}-\x{FFFF}]){0,255}$/u</mask>
|
||||
@@ -191,5 +213,38 @@
|
||||
</description>
|
||||
</rule>
|
||||
</snatrules>
|
||||
<npt>
|
||||
<rule type=".\SourceNatRuleField">
|
||||
<enabled type="BooleanField">
|
||||
<Default>1</Default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<interface type="InterfaceField">
|
||||
<Required>Y</Required>
|
||||
<Default>lan</Default>
|
||||
<AllowDynamic>Y</AllowDynamic>
|
||||
</interface>
|
||||
<source_net type="NetworkAliasField">
|
||||
<Required>Y</Required>
|
||||
</source_net>
|
||||
<destination_net type="NetworkAliasField"/>
|
||||
<categories type="ModelRelationField">
|
||||
<Model>
|
||||
<rulesets>
|
||||
<source>OPNsense.Firewall.Category</source>
|
||||
<items>categories.category</items>
|
||||
<display>name</display>
|
||||
</rulesets>
|
||||
</Model>
|
||||
<Multiple>Y</Multiple>
|
||||
<ValidationMessage>Related category not found.</ValidationMessage>
|
||||
</categories>
|
||||
<description type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^([\t\n\v\f\r 0-9a-zA-Z.\-,_\x{00A0}-\x{FFFF}]){0,255}$/u</mask>
|
||||
<ValidationMessage>Description should be a string between 1 and 255 characters</ValidationMessage>
|
||||
</description>
|
||||
</rule>
|
||||
</npt>
|
||||
</items>
|
||||
</model>
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
<SourceNat order="100" VisibleName="Source NAT" url="/ui/firewall/source_nat/">
|
||||
<FilterRef url="/ui/firewall/source_nat#*" visibility="hidden"/>
|
||||
</SourceNat>
|
||||
<Npt order="100" VisibleName="NPTv6" url="/ui/firewall/npt/">
|
||||
<FilterRef url="/ui/firewall/npt#*" visibility="hidden"/>
|
||||
</Npt>
|
||||
</Automation>
|
||||
</Firewall>
|
||||
</menu>
|
||||
|
||||
@@ -2,12 +2,47 @@
|
||||
$( document ).ready(function() {
|
||||
let initial_load = true;
|
||||
let grid = $("#grid-rules").UIBootgrid({
|
||||
search:'/api/firewall/{{ruleController}}/searchRule/',
|
||||
get:'/api/firewall/{{ruleController}}/getRule/',
|
||||
set:'/api/firewall/{{ruleController}}/setRule/',
|
||||
add:'/api/firewall/{{ruleController}}/addRule/',
|
||||
del:'/api/firewall/{{ruleController}}/delRule/',
|
||||
toggle:'/api/firewall/{{ruleController}}/toggleRule/'
|
||||
search:'/api/firewall/{{ruleController}}/search_rule/',
|
||||
get:'/api/firewall/{{ruleController}}/get_rule/',
|
||||
set:'/api/firewall/{{ruleController}}/set_rule/',
|
||||
add:'/api/firewall/{{ruleController}}/add_rule/',
|
||||
del:'/api/firewall/{{ruleController}}/del_rule/',
|
||||
toggle:'/api/firewall/{{ruleController}}/toggle_rule/',
|
||||
options:{
|
||||
requestHandler: function(request){
|
||||
if ( $('#category_filter').val().length > 0) {
|
||||
request['category'] = $('#category_filter').val();
|
||||
}
|
||||
return request;
|
||||
}
|
||||
}
|
||||
});
|
||||
grid.on("loaded.rs.jquery.bootgrid", function (e){
|
||||
// reload categories before grid load
|
||||
ajaxCall('/api/firewall/{{ruleController}}/list_categories', {}, function(data, status){
|
||||
if (data.rows !== undefined) {
|
||||
let current_selection = $("#category_filter").val();
|
||||
$("#category_filter").empty();
|
||||
for (i=0; i < data.rows.length ; ++i) {
|
||||
let row = data.rows[i];
|
||||
let opt_val = $('<div/>').html(row.name).text();
|
||||
let bgcolor = row.color != "" ? row.color : '31708f;'; // set category color
|
||||
let option = $("<option/>").val(row.uuid).html(row.name);
|
||||
if (row.used > 0) {
|
||||
option.attr(
|
||||
'data-content',
|
||||
"<span>"+opt_val + "</span>"+
|
||||
"<span style='background:#"+bgcolor+";' class='badge pull-right'>" + row.used + "</span>"
|
||||
);
|
||||
option.attr('id', row.uuid);
|
||||
}
|
||||
|
||||
$("#category_filter").append(option);
|
||||
}
|
||||
$("#category_filter").val(current_selection);
|
||||
$("#category_filter").selectpicker('refresh');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// open edit dialog when opened with a uuid reference
|
||||
@@ -62,6 +97,11 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
// move filter into action header
|
||||
$("#type_filter_container").detach().prependTo('#grid-rules-header > .row > .actionBar > .actions');
|
||||
$("#category_filter").change(function(){
|
||||
$('#grid-rules').bootgrid('reload');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -71,6 +111,13 @@
|
||||
</ul>
|
||||
<div class="tab-content content-box">
|
||||
<div id="rules" class="tab-pane fade in active">
|
||||
<div class="hidden">
|
||||
<!-- filter per type container -->
|
||||
<div id="type_filter_container" class="btn-group">
|
||||
<select id="category_filter" data-title="{{ lang._('Categories') }}" class="selectpicker" data-live-search="true" data-size="5" multiple data-width="200px">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- tab page "rules" -->
|
||||
<table id="grid-rules" class="table table-condensed table-hover table-striped" data-editDialog="DialogFilterRule" data-editAlert="FilterRuleChangeMessage">
|
||||
<thead>
|
||||
|
||||
Reference in New Issue
Block a user