Commit 3085e4d1 authored by Ad Schellevis's avatar Ad Schellevis

(plugins / firewall) first steps in moving static firewall rules to plugin registrations.

Te idea is simple, start parsing rules in a uniform way, so we're eventually able to display and alter all auto generated rules.
Because of the large set of legacy code rules, we're going to migrate step by step, leaving the current setup intact.
parent 0755bdac
......@@ -374,6 +374,7 @@ function filter_configure_sync()
// initialize fw plugin object
$fw = new \OPNsense\Firewall\Plugin();
$fw->setInterfaceMapping($FilterIflist);
if (function_exists('plugins_firewall')) {
plugins_firewall($fw);
......@@ -478,6 +479,7 @@ function filter_configure_sync()
$rules .= $fw->anchorToText('nat,binat,rdr', 'tail');
$rules .= $fw->anchorToText('fw', 'head');
$rules .= "anchor \"relayd/*\"\n"; // relayd
$rules .= $fw->outputFilterRules();
$rules .= "{$pfrules}\n";
$rules .= $fw->anchorToText('fw', 'tail');
......@@ -2494,19 +2496,9 @@ function filter_rules_generate(&$FilterIflist)
# BEGIN OF firewall rules
/* default block logging? */
$log = array("block"=>null,"pass"=>null);
if (!isset($config['syslog']['nologdefaultblock'])) {
$log['block'] = "log";
}
if (!isset($config['syslog']['nologdefaultpass'])) {
$log['pass'] = "log";
}
if (!isset($config['system']['ipv6allow'])) {
$ipfrules .= "\n# Block all IPv6 except loopback traffic\n";
$ipfrules .= "pass {$log['pass']} quick on \$loopback inet6\n";
$ipfrules .= "block {$log['block']} quick inet6 all label \"Block all IPv6\"\n";
}
$log = array();
$log['block'] = !isset($config['syslog']['nologdefaultblock']) ? "log" : "";
$log['pass'] = !isset($config['syslog']['nologdefaultpass']) ? "log" : "";
$ipfrules .= <<<EOD
......
<?php
function core_fw_firewall($fw)
{
global $config;
$log_block = !isset($config['syslog']['nologdefaultblock']);
$log_pass = !isset($config['syslog']['nologdefaultpass']);
if (!isset($config['system']['ipv6allow'])) {
// block All IPv6 except loopback traffic
$fw->registerFilterRule(0,
array('type'=>'pass','log'=>$log_pass, 'interface' => 'loopback', 'ipprotocol'=>'inet6')
);
$fw->registerFilterRule(0,
array('type'=>'block','log'=>$log_block, 'ipprotocol'=>'inet6', 'label' => 'Block all IPv6')
);
}
}
......@@ -41,8 +41,12 @@ class FilterRule
private $procorder = array(
'disabled' => 'parseIsComment',
'type' => 'parseType',
'log' => 'parseBool,log',
'quick' => 'parseBool,quick',
'interface' => 'parseInterface',
'ipprotocol' => 'parsePlain',
'interface' => 'parseInterface'
'protocol' => 'parseReplaceSimple,tcp/udp:{tcp udp}',
'label' => 'parsePlain,label ","'
);
/**
......@@ -60,9 +64,26 @@ class FilterRule
* @param string $value field value
* @return string
*/
private function parsePlain($value)
private function parsePlain($value, $prefix="", $suffix="")
{
return empty($value) ? "" : $value . " ";
return empty($value) ? "" : $prefix . $value . $suffix . " ";
}
/**
* parse data, use replace map
* @param string $value field value
* @param string $map
* @return string
*/
private function parseReplaceSimple($value, $map)
{
foreach (explode('|', $map) as $item) {
$tmp = explode(':', $item);
if ($tmp[0] == $value) {
return $tmp[1] . " ";
}
}
return $value . " ";
}
/**
......@@ -89,10 +110,26 @@ class FilterRule
*/
private function parseInterface($value)
{
if (empty($this->interfaceMapping[$value]['if'])) {
return "##{$value}##";
if (empty($value)) {
return "";
} elseif (empty($this->interfaceMapping[$value]['if'])) {
return "on ##{$value}## ";
} else {
return "on ". $this->interfaceMapping[$value]['if']." ";
}
}
/**
* parse boolean, return text from $valueTrue / $valueFalse
* @param string $value field value
* @return string
*/
private function parseBool($value, $valueTrue, $valueFalse="")
{
if (!empty($value)) {
return !empty($valueTrue) ? $valueTrue . " " : "";
} else {
return $this->interfaceMapping[$value]['if']." ";
return !empty($valueFalse) ? $valueFalse . " " : "";
}
}
......@@ -117,10 +154,14 @@ class FilterRule
$tmp = $this->rule;
$tmp['interface'] = $interface;
$tmp['ipprotocol'] = $ipproto;
if (empty($this->interfaceMapping[$interface]['if'])) {
// disable rule when interface not found
// disable rule when interface not found
if (!empty($interface) && empty($this->interfaceMapping[$interface]['if'])) {
$tmp['disabled'] = true;
}
if (!isset($tmp['quick'])) {
// all rules are quick by default except floating
$tmp['quick'] = !isset($rule['floating']) ? true : false ;
}
$result[] = $tmp;
}
}
......@@ -147,7 +188,14 @@ class FilterRule
$ruleTxt = '';
foreach ($this->fetchActualRules() as $rule) {
foreach ($this->procorder as $tag => $handle) {
$ruleTxt .= $this->$handle(isset($rule[$tag]) ? $rule[$tag] : null);
$tmp = explode(',', $handle);
$method = $tmp[0];
$args = array(isset($rule[$tag]) ? $rule[$tag] : null);
if (count($tmp) > 1) {
array_shift($tmp);
$args = array_merge($args, $tmp);
}
$ruleTxt .= call_user_func_array(array($this,$method), $args);
}
$ruleTxt .= "\n";
}
......
......@@ -38,13 +38,16 @@ class Plugin
private $anchors = array();
private $filterRules = array();
private $interfaceMapping ;
private $interfaceStaticMapping;
/**
* init firewall plugin component
*/
public function __construct()
{
// set static mappings
$this->interfaceMapping = array();
$this->interfaceMapping['loopback'] = array('if' => 'lo0');
}
/**
......@@ -53,7 +56,7 @@ class Plugin
*/
public function setInterfaceMapping(&$mapping)
{
$this->interfaceMapping = $mapping;
$this->interfaceMapping = array_merge($this->interfaceMapping, $mapping);
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment