Skip to content

Commit

Permalink
firewall: only add gateway rules when the protocol is assigned to the…
Browse files Browse the repository at this point in the history
… interface

PR: #1681

(cherry picked from commit 5739487)
(cherry picked from commit 3676fb4)
(cherry picked from commit afcca42)
(cherry picked from commit 9dc19a1)
  • Loading branch information
AdSchellevis authored and fichtner committed Aug 21, 2017
1 parent 6472f6b commit e0cad8c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 7 deletions.
28 changes: 28 additions & 0 deletions src/etc/inc/filter.lib.inc
Original file line number Diff line number Diff line change
Expand Up @@ -376,4 +376,32 @@ function filter_core_rules_system($fw, $defaults)
);
}

// out from this Firewall, using the selected gateway.
foreach ($fw->getInterfaceMapping() as $ifdescr => $ifcfg) {
if (!isset($ifcfg['virtual']) && $ifcfg['if'] != 'lo0') {
$intf_has_v4 = false;
$intf_has_v6 = false;
foreach (legacy_getall_interface_addresses($ifcfg['if']) as $addr) {
$intf_has_v4 = $intf_has_v4 || is_subnetv4($addr);
$intf_has_v6 = $intf_has_v6 || is_subnetv6($addr);
}
foreach ($fw->getInterfaceGateways($ifcfg['if']) as $gwname) {
$gwproto = $fw->getGateway($gwname)['proto'];
// only try to add gateway rules for traffic leaving this interface when the correct protocol is
// assigned to the interface (e.g. no ipv4 gateway when :network doesn't resolve to an ipv4 network)
if (($gwproto == 'inet' && $intf_has_v4) || ($gwproto == 'inet6' && $intf_has_v6)) {
$fw->registerFilterRule(100000,
array('from' => $ifcfg['if'], 'direction' => 'out', 'gateway' => $gwname,
'destination' => array('network'=> $ifdescr, "not" => true),
'statetype' => 'keep',
'allowopts' => true,
'quick' => false,
'label' => "let out anything from firewall host itself"),
$defaults['pass']
);
}
}
}
}

}
24 changes: 17 additions & 7 deletions src/opnsense/mvc/app/library/OPNsense/Firewall/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public function setGateways($gateways)
$this->gatewayMapping[$key] = array("logic" => "route-to ( {$gw['interface']} {$gw['gateway']} )",
"interface" => $gw['interface'],
"gateway" => $gw['gateway'],
"proto" => strstr($gw['gateway'], ':') ? "inet6" : "inet",
"type" => "gateway");
}
}
Expand All @@ -94,9 +95,13 @@ public function setGatewayGroups($groups)
if (is_array($groups)) {
foreach ($groups as $key => $gwgr) {
$routeto = array();
$proto = 'inet';
foreach ($gwgr as $gw) {
if (Util::isIpAddress($gw['gwip']) && !empty($gw['int'])) {
$routeto[] = str_repeat("( {$gw['int']} {$gw['gwip']} )", $gw['weight']);
if (strstr($gw['gwip'], ':')) {
$proto = 'inet6';
}
}
}
if (count($routeto) > 0) {
Expand All @@ -108,6 +113,7 @@ public function setGatewayGroups($groups)
$routetologic .= " sticky-address ";
}
$this->gatewayMapping[$key] = array("logic" => $routetologic,
"proto" => $proto,
"type" => "group");
}
}
Expand All @@ -124,20 +130,24 @@ public function getInterfaceGateways($intf)
$protos_found = array();
foreach ($this->gatewayMapping as $key => $gw) {
if ($gw['type'] == 'gateway' && $gw['interface'] == $intf) {
if (strstr($gw['gateway'], ':')) {
$proto = 'v6';
} else {
$proto = 'v4';
}
if (!in_array($proto, $protos_found)) {
if (!in_array($gw['proto'], $protos_found)) {
$result[] = $key;
$protos_found[] = $proto;
$protos_found[] = $gw['proto'];
}
}
}
return $result;
}

/**
* Fetch gateway
* @param string $gw gateway name
*/
public function getGateway($gw)
{
return $this->gatewayMapping[$gw];
}

/**
* @return array
*/
Expand Down

0 comments on commit e0cad8c

Please sign in to comment.