How to flush the default firewall

Hi,

I’m writing a script for my RB5009ug. The assumption is that the script gets applied on a freshly-reset device, on top of the default configuration.

One of the script’s objectives is to configure the firewall. My (naive?) plan was to first remove all default rules/chains and then recreate them from scratch.

This works for the input chain, e.g.:

/ip firewall filter remove [/ip firewall filter find chain=input];
/ip firewall filter {
    add chain=input connection-state=invalid action=drop comment="Drop invalid";
    # ...
    add chain=input action=drop comment="Drop";
}

However this doesn’t seem to work for the forward chain:

/ip firewall filter remove [/ip firewall filter find chain=forward];
failure: cannot remove builtin

What’s the recommended way of approaching this?

Incidentally, I wish the script could be applied on a blank device instead of on top of existing defaults. Working on a blank device would be more robust and cleaner as the final state of the device would be completely described by a single file (a purely declarative approach). Contrarily, working on top of existing defaults means that the script may first have to undo some of the defaults and then apply its changes. The result is no longer determined by a single file, rather by the interaction of the script plus the defaults. This makes things more brittle, for example should the defaults change over time. I might be wrong but I understand that the purely declarative approach is not possible?

Thanks, best wishes.

I would strongly recommend to start from default and only change when you fully understand what the impact is.

Some rules are built-in and can effectively not be removed.

I’use theses commands to bootstrap every rb5009 i deploy ; the goal is to remove everything and have a dedicated outofband eth for mgmt (and this one is securised after). And now, i lost a time with the fuc___g default password.
After that, i use the newly created outofband mgmt port and inject the main configuration generated for this dev, reboot it, and it’s ready to use.

#####################################
##### FROM ether2 192.168.88.1
#####################################
## remove defconf firewall filter
/ip firewall filter remove [find dynamic=no]
/ip firewall nat remove [find]
/ip firewall raw remove [find]
/ip firewall mangle remove [find]
/ip firewall address-list remove [find]
/ip firewall layer7-protocol remove [find]
/ip firewall connection remove [find]

/ipv6 firewall filter remove [find dynamic=no]
/ipv6 firewall nat remove [find]
/ipv6 firewall raw remove [find]
/ipv6 firewall mangle remove [find]
/ipv6 firewall address-list remove [find]
/ipv6 firewall connection remove [find]

## configure ether8 as out of band management
/interface bridge port remove [find interface="ether8"]
/ip address add address=192.168.99.1/24 interface=ether8 network=192.168.99.0
/ip firewall filter add action=accept chain=input comment="admin mikrotik out-of-band eth8" in-interface=ether8

## remove defconf interface list
/interface/list/remove LAN 
/interface/list/remove WAN
/interface/list/member/remove [find]

## remove defconf dhcp config
/ip/pool/remove default-dhcp
/ip/dhcp-server/remove defconf
/ip/dhcp-server/network/remove [find]
/ip/dhcp-client/remove ether1

## remove defconf misc config
/ip neighbor discovery-settings/set discover-interface-list=none
/ip/dns/static/remove [find]
/tool/mac-server/set allowed-interface-list=none 
/tool/mac-server/mac-winbox/set allowed-interface-list=none 




#####################################
##### FROM ether8 192.168.99.254
#####################################
## remove defconf lan bridge
# /interface/bridge/port/remove [find]
# /interface/bridge/remove bridge 
/ip/address/remove [find address="192.168.88.1/24"]

plan was to first remove all default rules/chains - that’s a bad idea!
Don’t write any long scripts, don’t complicate the whole configuration. Default rules are used for everything. If you don’t like the default config, then I can recommend another version - drop everything and allow only what is needed. This is good practice.
If, for example, it is necessary to open a port for Wiregurd, then we do it in “Input chain”. If there is a need to release a port through the router, then we do it in the “forward” chain. And we must use the address list. It should be remembered that in Mikrotik the firewall policy is executed from top to bottom. Sequence is also important.

INPUT CHAIN → To the Router or to Router Services. Directional flow is WAN to Router, and LAN to Router.
FORWARD CHAIN → Through the Router. Direction flow is LAN to LAN, LAN to WAN, WAN to LAN.
OUTPUT CHAIN → From the Router. Directional flow is Router to WAN.

/ip firewall filter
{Input Chain}
add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment="defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=accept chain=input in-interface-list=LAN
add action=drop chain=input comment="drop all else"
{forward chain}
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-state=established,related
add action=accept chain=forward comment="defconf: accept established,related, untracked" connection-state=established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=forward comment="allow internet traffic" in-interface-list=LAN out-interface-list=WAN
add action=accept chain=forward comment="allow port forwarding" connection-nat-state=dstnat
add action=drop chain=forward comment="drop all else"
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" out-interface-list=WAN

Ok, I understand. I think I’ll follow your advice. (I suppose it’s then a matter of adding new rules while specifying the correct position with ‘place-before’ then.)

Thanks for your help!

Hi, thanks so much! Your script has been very helpful, I’ve taken inspiration from various of its parts. In the end I may abandon the idea of nuking the default configuration to the ground, rather I think I’ll apply more targeted changes on top of defconf.

I’m still in the process of understanding the whole RouterOS workflow, I’d have hoped for a more declarative approach, but it is what it is.

Thank you, have a lovely day.

Thanks, this is useful. I may end up following your advice and being more selective in my changes instead of deleting the whole defconf.

Thanks, have a lovely day.