diff --git a/src/etc/inc/filter.inc b/src/etc/inc/filter.inc index 133d06c0d..f791dd647 100644 --- a/src/etc/inc/filter.inc +++ b/src/etc/inc/filter.inc @@ -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 .= <<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') + ); + } +} diff --git a/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php b/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php index c841a9414..0ad78a9b1 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php +++ b/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php @@ -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 $this->interfaceMapping[$value]['if']." "; + 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 !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"; } diff --git a/src/opnsense/mvc/app/library/OPNsense/Firewall/Plugin.php b/src/opnsense/mvc/app/library/OPNsense/Firewall/Plugin.php index c130eb0c4..bb775a878 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Firewall/Plugin.php +++ b/src/opnsense/mvc/app/library/OPNsense/Firewall/Plugin.php @@ -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); } /**