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 14, 2017
1 parent dfb9ed1 commit 0b38eff
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 @@ -364,4 +364,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

5 comments on commit 0b38eff

@mimugmail
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I stumbled upon this one regarding my problem with Multi WAN and this post:
https://forum.opnsense.org/index.php?topic=5743.msg23575#msg23575

@fichtner Is this already in 17.7.1. Does this really work for local generated traffic to enter gateway (group)? It's not working for me but probably a Layer 8 problem.

@fichtner
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the fix in 17.7.1 works exactly the other way, it puts back interface pinning, so it sucks ;)

@mimugmail
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that linux users are spoiled with multiple routing tables.
Everybody wants this simple feature:

2 WANs, Connect from INET to WAN1, reply packet goes out WAN1 with source WAN1 address. Connect from INET to WAN2, reply packet goes out WAN2 with source WAN2 address.

This should be an implicitness ...

@mimugmail
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea why, but now it works as expected. I disabled gate groups and all pf rules with route target.
Only gateway switching enabled. Now I can reach OPN via WAN1 and WAN2 IP.

oO

@AdSchellevis
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mimugmail 65a55bb makes the route-to auto generated rules optional. Different expectations from different users, this is likely the best we can do now.

Please sign in to comment.