mirror of
https://github.com/opnsense/plugins.git
synced 2026-10-12 02:20:37 +00:00
net/frr: fix and complete automatic firewall rules (#5736)
* net/frr: fix and complete automatic firewall rules Generate rules directly for every enabled routing protocol and remove the dependency on configured OSPF networks or interfaces. * Tighten the OSPF rules a bit more * Also guard creation of rules if frr is not enabled
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2026 Deciso B.V.
|
||||
* Copyright (C) 2018 Franco Fichtner <[email protected]>
|
||||
* Copyright (C) 2017 Fabian Franz
|
||||
* All rights reserved.
|
||||
@@ -30,14 +31,13 @@
|
||||
function frr_enabled()
|
||||
{
|
||||
$model = new \OPNsense\Quagga\General();
|
||||
return (string)$model->enabled == '1';
|
||||
return !$model->enabled->isEmpty();
|
||||
}
|
||||
|
||||
function frr_carp_enabled()
|
||||
{
|
||||
$model = new \OPNsense\Quagga\General();
|
||||
return (string)$model->enabled == '1' &&
|
||||
(string)$model->enablecarp == '1';
|
||||
return !$model->enabled->isEmpty() && !$model->enablecarp->isEmpty();
|
||||
}
|
||||
|
||||
function frr_configure()
|
||||
@@ -59,153 +59,360 @@ function frr_configure_do($verbose = false)
|
||||
function frr_firewall($fw)
|
||||
{
|
||||
global $config;
|
||||
if (empty((string)(new \OPNsense\Quagga\General())->fwrules)) {
|
||||
$model = new \OPNsense\Quagga\General();
|
||||
if ($model->enabled->isEmpty() || $model->fwrules->isEmpty()) {
|
||||
// automatic rules disabled
|
||||
return;
|
||||
}
|
||||
$ospf = new \OPNsense\Quagga\OSPF();
|
||||
|
||||
if ((string)$ospf->enabled == '1') {
|
||||
$ospf_default = [
|
||||
'ipprotocol' => 'inet',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
];
|
||||
foreach ($ospf->networks->network->iterateItems() as $network) {
|
||||
if ((string)$network->enabled == '1') {
|
||||
$fw->registerFilterRule(
|
||||
1, /* priority */
|
||||
[
|
||||
'descr' => 'Pass OSPF (autogenerated)',
|
||||
'from' => $network->ipaddr . '/' . $network->netmask,
|
||||
'to' => '224.0.0.0/24',
|
||||
'direction' => 'in'
|
||||
],
|
||||
$ospf_default
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'descr' => 'Pass OSPF UNICAST (autogenerated)',
|
||||
'from' => $network->ipaddr . '/' . $network->netmask,
|
||||
'to' => '(self)',
|
||||
'direction' => 'in'
|
||||
],
|
||||
$ospf_default
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'descr' => 'Pass OSPF (autogenerated)',
|
||||
'from' => '(self)',
|
||||
'to' => '224.0.0.0/24',
|
||||
'direction' => 'out'
|
||||
],
|
||||
$ospf_default
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'descr' => 'Pass OSPF UNICAST (autogenerated)',
|
||||
'from' => '(self)',
|
||||
'to' => $network->ipaddr . '/' . $network->netmask,
|
||||
'direction' => 'out',
|
||||
],
|
||||
$ospf_default
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!(new \OPNsense\Quagga\OSPF())->enabled->isEmpty()) {
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF MULTICAST',
|
||||
'to' => '224.0.0.5/32',
|
||||
'direction' => 'in',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF MULTICAST DR',
|
||||
'to' => '224.0.0.6/32',
|
||||
'direction' => 'in',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF UNICAST',
|
||||
'to' => '(self)',
|
||||
'direction' => 'in',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF MULTICAST',
|
||||
'from' => '(self)',
|
||||
'to' => '224.0.0.5/32',
|
||||
'direction' => 'out',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF MULTICAST DR',
|
||||
'from' => '(self)',
|
||||
'to' => '224.0.0.6/32',
|
||||
'direction' => 'out',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF UNICAST',
|
||||
'from' => '(self)',
|
||||
'direction' => 'out',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$ospf6 = new \OPNsense\Quagga\OSPF6();
|
||||
if (!(new \OPNsense\Quagga\OSPF6())->enabled->isEmpty()) {
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet6',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF6 MULTICAST',
|
||||
'from' => 'fe80::0/10',
|
||||
'to' => 'ff02::5/128',
|
||||
'direction' => 'in',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet6',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF6 MULTICAST DR',
|
||||
'from' => 'fe80::0/10',
|
||||
'to' => 'ff02::6/128',
|
||||
'direction' => 'in',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet6',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF6 UNICAST',
|
||||
'from' => 'fe80::0/10',
|
||||
'to' => '(self)',
|
||||
'direction' => 'in',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet6',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF6 MULTICAST',
|
||||
'from' => '(self)',
|
||||
'to' => 'ff02::5/128',
|
||||
'direction' => 'out',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet6',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF6 MULTICAST DR',
|
||||
'from' => '(self)',
|
||||
'to' => 'ff02::6/128',
|
||||
'direction' => 'out',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet6',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass OSPF6 UNICAST',
|
||||
'from' => '(self)',
|
||||
'to' => 'fe80::0/10',
|
||||
'direction' => 'out',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
if ((string)$ospf6->enabled == '1') {
|
||||
$ospf6_default = [
|
||||
'ipprotocol' => 'inet6',
|
||||
'protocol' => 'ospf',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
];
|
||||
if (!(new \OPNsense\Quagga\BGP())->enabled->isEmpty()) {
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet46',
|
||||
'protocol' => 'tcp',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass BGP',
|
||||
'to' => '(self)',
|
||||
'to_port' => 179,
|
||||
'direction' => 'in',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet46',
|
||||
'protocol' => 'tcp',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass BGP',
|
||||
'from' => '(self)',
|
||||
'to_port' => 179,
|
||||
'direction' => 'out',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($ospf6->interfaces->interface->iterateItems() as $interface) {
|
||||
if ((string)$interface->enabled == '1') {
|
||||
$fw->registerFilterRule(
|
||||
1, /* priority */
|
||||
[
|
||||
'interface' => (string)$interface->interfacename,
|
||||
'descr' => 'Pass OSPF6 MULTICAST (autogenerated)',
|
||||
'from' => 'fe80::0/10',
|
||||
'to' => 'ff02::5/128',
|
||||
'direction' => 'in'
|
||||
],
|
||||
$ospf6_default
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1, /* priority */
|
||||
[
|
||||
'interface' => (string)$interface->interfacename,
|
||||
'descr' => 'Pass OSPF6 MULTICAST DR (autogenerated)',
|
||||
'from' => 'fe80::0/10',
|
||||
'to' => 'ff02::6/128',
|
||||
'direction' => 'in'
|
||||
],
|
||||
$ospf6_default
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'interface' => (string)$interface->interfacename,
|
||||
'descr' => 'Pass OSPF6 UNICAST (autogenerated)',
|
||||
'from' => 'fe80::0/10',
|
||||
'to' => '(self)',
|
||||
'direction' => 'in'
|
||||
],
|
||||
$ospf6_default
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'interface' => (string)$interface->interfacename,
|
||||
'descr' => 'Pass OSPF6 MULTICAST (autogenerated)',
|
||||
'from' => '(self)',
|
||||
'to' => 'ff02::5/128',
|
||||
'direction' => 'out'
|
||||
],
|
||||
$ospf6_default
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'interface' => (string)$interface->interfacename,
|
||||
'descr' => 'Pass OSPF6 MULTICAST DR (autogenerated)',
|
||||
'from' => '(self)',
|
||||
'to' => 'ff02::6/128',
|
||||
'direction' => 'out'
|
||||
],
|
||||
$ospf6_default
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'interface' => (string)$interface->interfacename,
|
||||
'descr' => 'Pass OSPF6 UNICAST (autogenerated)',
|
||||
'from' => '(self)',
|
||||
'to' => 'fe80::0/10',
|
||||
'direction' => 'out'
|
||||
],
|
||||
$ospf6_default
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!(new \OPNsense\Quagga\BFD())->enabled->isEmpty()) {
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet46',
|
||||
'protocol' => 'udp',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass BFD',
|
||||
'to' => '(self)',
|
||||
'to_port' => 3784,
|
||||
'direction' => 'in',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet46',
|
||||
'protocol' => 'udp',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass BFD',
|
||||
'from' => '(self)',
|
||||
'to_port' => 3784,
|
||||
'direction' => 'out',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet46',
|
||||
'protocol' => 'udp',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass BFD MULTIHOP',
|
||||
'to' => '(self)',
|
||||
'to_port' => 4784,
|
||||
'direction' => 'in',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet46',
|
||||
'protocol' => 'udp',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass BFD MULTIHOP',
|
||||
'from' => '(self)',
|
||||
'to_port' => 4784,
|
||||
'direction' => 'out',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
if (!(new \OPNsense\Quagga\RIP())->enabled->isEmpty()) {
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet',
|
||||
'protocol' => 'udp',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass RIP',
|
||||
'to' => '(self),224.0.0.9,255.255.255.255',
|
||||
'to_port' => 520,
|
||||
'direction' => 'in',
|
||||
]
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'ipprotocol' => 'inet',
|
||||
'protocol' => 'udp',
|
||||
'statetype' => 'keep',
|
||||
'type' => 'pass',
|
||||
'disablereplyto' => 1,
|
||||
'quick' => true,
|
||||
'log' => !isset($config['syslog']['nologdefaultpass']),
|
||||
'#ref' => 'ui/quagga/general/index',
|
||||
'descr' => 'Pass RIP',
|
||||
'from' => '(self)',
|
||||
'to_port' => 520,
|
||||
'direction' => 'out',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user