Switching to new router and wanted to cleanup the firewall mess

Hi.

So, I’m switching from RB2011UiAS to CCR2004-16G-2S+ and, since my RB2011 firewall config is a mess I wanted to “rewrite it” and came up with this (only input chain):

/ip firewall filter
add action=drop chain=input in-interface-list=WAN comment="permanently DENIED ips" src-address-list=uninvited-perm log-prefix=input_perm_deny log=yes
add chain=input action=accept comment="ALLOW established, related" connection-state=established,related
add chain=input action=accept comment="ALLOW OpenVPN roadwarriors" connection-state=new dst-port=11978 protocol=tcp log-prefix=input_openvpn_connect log=yes
add chain=input action=add-dst-to-address-list comment="ADD unknown IPSEC endpoints to reject list" address-list=ipsec-uninvited-endpoits address-list-timeout=2w connection-state=new dst-port=500 in-interface-list=WAN protocol=udp src-address-list=!ipsec-allowed-endpoints
add chain=input action=accept comment="ALLOW IPSEC tunnels from known endpoints" connection-state=new dst-port=500,4500,1701 in-interface-list=WAN protocol=udp src-address-list=ipsec-allowed-endpoints log-prefix=input_ipsec_connect log=yes
add chain=input action=drop comment="DENY IPSEC connections from reject list" dst-port=500 in-interface-list=WAN protocol=udp src-address-list=ipsec-uninvited-endpoints log-prefix=input_ipsec_uninvited log=yes
add chain=input action=add-src-to-address-list address-list="port-scanners" address-list-timeout=2w comment="ADD Port scanners to list" protocol=tcp psd=21,3s,3,1
add chain=input action=add-src-to-address-list address-list="port-scanners" address-list-timeout=2w comment="ADD NMAP FIN Stealth scan" protocol=tcp tcp-flags=fin,!syn,!rst,!psh,!ack,!urg
add chain=input action=add-src-to-address-list address-list="port-scanners" address-list-timeout=2w comment="ADD SYN/FIN scan" protocol=tcp tcp-flags=fin,syn
add chain=input action=add-src-to-address-list address-list="port-scanners" address-list-timeout=2w comment="ADD SYN/RST scan" protocol=tcp tcp-flags=syn,rst
add chain=input action=add-src-to-address-list address-list="port-scanners" address-list-timeout=2w comment="ADD FIN/PSH/URG scan" protocol=tcp tcp-flags=fin,psh,urg,!syn,!rst,!ack
add chain=input action=add-src-to-address-list address-list="port-scanners" address-list-timeout=2w comment="ADD ALL/ALL scan" protocol=tcp tcp-flags=fin,syn,rst,psh,ack,urg
add chain=input action=add-src-to-address-list address-list="port-scanners" address-list-timeout=2w comment="ADD NMAP NULL scan" protocol=tcp tcp-flags=!fin,!syn,!rst,!psh,!ack,!urg
add chain=input action=drop comment="DENY port scanners" src-address-list="port-scanners"
add chain=input action=drop comment="DENY invalid" connection-state=invalid
add chain=input action=drop comment="DENY DNS queries from WAN" dst-port=53 in-interface-list=WAN protocol=tcp
add chain=input action=drop comment="DENY DNS queries from WAN" dst-port=53 in-interface-list=WAN protocol=udp
add chain=input action=drop comment="DENY non admins from accessing configuration ports" dst-port=1978,1922 protocol=tcp src-address-list=!informatycy log-prefix=input_non_admins log=yes
add chain=input action=drop comment="DENY all packets which are not destined to routes IP address" dst-address-type=!local
add chain=input action=drop comment="DENY all packets which does not have unicast source IP address" src-address-type=!unicast
add chain=input action=drop comment="DENY all packets from public internet which should not exist in public network" in-interface-list=WAN src-address-list=not_public
add chain=input action=drop comment="DENY everything not from LAN" in-interface-list=!LAN
add chain=input action=drop comment="DENY verything else"

I have two IPSEC tunnels with external offices and OpenVPN server for roadwarriors. Is it to much? Not enough?

From a deny-everything-allow-something, you can remove all drop rules (in the end) except for the last rule (drop everything). This will give the same result, just will have a higher kiss-rate.

With that, you can remove all port-scanners rules as well, as they are no longer used.

That would bring it back to:

/ip firewall filter
add action=drop chain=input in-interface-list=WAN comment="permanently DENIED ips" src-address-list=uninvited-perm log-prefix=input_perm_deny log=yes
add chain=input action=accept comment="ALLOW established, related" connection-state=established,related
add chain=input action=accept comment="ALLOW OpenVPN roadwarriors" connection-state=new dst-port=11978 protocol=tcp log-prefix=input_openvpn_connect log=yes
add chain=input action=add-dst-to-address-list comment="ADD unknown IPSEC endpoints to reject list" address-list=ipsec-uninvited-endpoits address-list-timeout=2w connection-state=new dst-port=500 in-interface-list=WAN protocol=udp src-address-list=!ipsec-allowed-endpoints
add chain=input action=accept comment="ALLOW IPSEC tunnels from known endpoints" connection-state=new dst-port=500,4500,1701 in-interface-list=WAN protocol=udp src-address-list=ipsec-allowed-endpoints log-prefix=input_ipsec_connect log=yes
add chain=input action=drop comment="DENY verything else"

In theory, an IPsec vpn will be enough.
It will be more correct this way and let’s not forget about the Forward section :slight_smile:

/ip firewall address-list
add address=192.168.88.0/24 list=Admin
{Input Chain}
/ip firewall filter
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 chain=input action=accept comment="ALLOW OpenVPN roadwarriors" connection-state=new dst-port=11978 protocol=tcp log-prefix=input_openvpn_connect log=yes
add action=accept chain=input src-address-list=Admin comment="Config Access"
add action=accept chain=input comment=L2TP dst-port=500,1701,4500 \
    in-interface-list=WAN protocol=udp
add action=accept chain=input comment="IKE IPSec" in-interface-list=WAN \
    protocol=ipsec-esp
add action=accept chain=input comment="Allow LAN DNS queries-UDP" \ 
dst-port=53 in-interface-list=LAN protocol=udp
add action=accept chain=input comment="Allow LAN DNS queries - TCP" \
dst-port=53 in-interface-list=LAN protocol=tcp
add action=drop chain=input comment="drop all else"

+1 johnson’

Only change I would make is add the internal loopback, the router uses for various functionalities behind the scenes.
add action=accept chain=input comment=defcon: accept to local loopback" dst-address=127.0.0.1 after the ICMP rule.

(only very minor quibble would be to change wording from ‘allow’ to ‘negotiate handshake’, as the rule does not allow access by road warriors to input chain )

add chain=input action=accept comment=“negotiate handshake OpenVPN roadwarriors” connection-state=new dst-port=11978 protocol=tcp log-prefix=input_openvpn_connect log=yes

oops, you’re right
I don’t know, but usually this rule is used when CapsMan is configured on the network. Isn’t that so?
“accept to local loopback”

Yes, but my understanding is that it may be used in the background for other things, but not clearly stated anywhere.

Took me a while, as I was busy with other matters. Anyway, taking into consideration what you have said, I came with this final (?) sollution:

/ip firewall filter
# input
add chain=input action=accept comment="ALLOW established, related" connection-state=established,related log-prefix=input_a_estrel
add chain=input action=drop comment="DENY invalid connection states" connection-state=invalid log-prefix=input_d_invaid
add chain=input action=accept comment="ALLOW OpenVPN roadwarriors handshake" connection-state=new dst-port=11978 protocol=tcp log-prefix=input_a_ovpn_handshake
add chain=input action=add-dst-to-address-list comment="ADD unknown IPSEC endpoints to reject list" address-list=ipsec-uninvited-endpoits address-list-timeout=2w connection-state=new dst-port=500 in-interface-list=WAN protocol=tcp src-address-list=!ipsec-allowed-endpoints
add chain=input action=accept comment="ALLOW IPSEC tunnels from known endpoints" dst-port=500,4500,1701 in-interface-list=WAN protocol=tcp src-address-list=ipsec-allowed-endpoints log-prefix=input_a_ipsec_l2tp
add chain=input action=accept comment="ALLOW IPSEC tunnels from known endpoints" in-interface-list=WAN protocol=ipsec-esp src-address-list=ipsec-allowed-endpoints log-prefix=input_a_ipsec_ike
add chain=input action=drop comment="DENY IPSEC connections from reject list" dst-port=500 in-interface-list=WAN protocol=udp src-address-list=ipsec-uninvited-endpoints log-prefix=input_d_ipsec_uninvited
add chain=input action=accept comment="ALLOW DNS queries from LAN" dst-port=53 in-interface-list=LAN protocol=tcp log-prefix=input_a_dns_tcp
add chain=input action=accept comment="ALLOW DNS queries from LAN" dst-port=53 in-interface-list=LAN protocol=udp log-prefix=input_a_dns_udp
add chain=input action=accept comment="ALLOW admins to access configuration ports" dst-port=1978,1922 protocol=tcp src-address-list=informatycy log-prefix=input_a_admins
add chain=input action=accept comment="ALLOW ping from LAN" protocol=icmp in-interface-list=LAN log-prefix=input_a_ping
add chain=input action=accept comment="defcon: accept to local loopback" dst-address=127.0.0.1
add chain=input action=drop comment="DENY everything else" log-prefix=input_d_all
# forward
add chain=forward action=accept comment="Allow IPSEC packets in" ipsec-policy=in,ipsec log-prefix=forward_a_ipsec_in
add chain=forward action=accept comment="Allow IPSEC packets out" ipsec-policy=out,ipsec log-prefix=forward_a_ipsec_out
add chain=forward action=accept comment="Accept established and related packets" connection-state=established,related log-prefix=forward_a_estrel
add chain=forward action=drop comment="DENY invalid connection states" connection-state=invalid log-prefix=forward_d_invalid
add chain=forward action=drop comment="ALLOW OpenVPN SOLEMIS user to some ips only" dst-address-list="!openvpn-solemis-allow-lan-ip" in-interface=ovpn-solemis
add chain=forward action=drop comment="ALLOW OpenVPN SOLEMIS user to some ips only" out-interface=ovpn-solemis src-address-list="!openvpn-solemis-allow-lan-ip"
add chain=forward action=accept comment="Allow OpenVPN users to LAN" dst-address=10.0.0.0/24 src-address=10.11.11.0/24
add chain=forward action=accept comment="Allow OpenVPN users from LAN" dst-address=10.11.11.0/24 src-address=10.0.0.0/24
add chain=forward action=accept comment="defconf:  drop all from WAN not DSTNATed" connection-nat-state=!dstnat connection-state=new in-interface-list=WAN
add chain=forward action=drop comment="defconf: drop bad forward IPs" src-address-list=no_forward_ipv4
add chain=forward action=drop comment="defconf: drop bad forward IPs" dst-address-list=no_forward_ipv4
add chain=forward action=drop comment="DENY Internet access to some IPs" out-interface-list=WAN src-address-list=no-internet-clients log-prefix=forward_d_internet
add chain=forward action=drop comment="DENY WLAN Guests from LAN" in-interface=bridgeGuests out-interface-list=!WAN

Going from the top:

input

allow established, related
deny invalid
allow connections to openvpn server
add to deny list if a unknown IP tries to create a tunnel
allow known IPs to create tunnels
deny creating tunnels for all deny list IPs
allow DNS from LAN
allow DNS from LAN
allow admin (via winbox/ssh) connections from admin IPs
allow ping from LAN
deny everything else
#forward
allow ipsec in
allow ipsec out
allow established, related
deny invalid
allow solemis openvpn user access to only some IPs (solemis to selected ips)
allow solemis openvpn user access to only some IPs (selected ips to solemis)
allow all other openvpn users to LAN (openvpn to LAN)
allow all other openvpn users to LAN (LAN to openvpn)
defconf: drop not DSTNATed connections from WAN
defconf: addressess that cannot be forwarded
defconf: addressess that cannot be forwarded
deny internet for some IPs
deny LAN for guests (wi-fi)


I am wandering about three things as for forward chain:

  1. since there is accept for established, related do I need the second rule for solemis openvpn user? this user initiates a connection with allowed IPs, so their "answer" will be established,related, so do I really need to specifically allow traffic from those IPs to solemis user?
  2. same thing for all other OpenVPN users (their second rule).
  3. what would happen if the last rule had been drop everything else?

You didnt quite grasp the concept of drop all else…( all other rules save invalid traffic need only be accept ).
You forgot to use drop all in forward chain???

Also you dont need to create firewall rules for reply traffic, it is already permitted.
AKA open vpn user to LAN is good enough, ( it would be nonsensical in most situations for the LAN to contact a road warrior device )

/ip firewall filter
# input
add chain=input action=accept comment="ALLOW established, related,untracked" connection-state=established,related, untracked
add chain=input action=drop comment="DENY invalid connection states" connection-state=invalid
add chain=input action=accept comment="ALLOW OpenVPN roadwarriors handshake" connection-state=new dst-port=11978 protocol=tcp 
add chain=input action=accept comment="ALLOW IPSEC tunnels from known endpoints" dst-port=500,4500,1701 in-interface-list=WAN protocol=tcp src-address-list=ipsec-allowed-endpoints
add chain=input action=accept comment="ALLOW IPSEC tunnels from known endpoints" in-interface-list=WAN protocol=ipsec-esp src-address-list=ipsec-allowed-endpoints 
add chain=input action=accept comment="ALLOW DNS queries from LAN" dst-port=53 in-interface-list=LAN protocol=tcp 
add chain=input action=accept comment="ALLOW DNS queries from LAN" dst-port=53 in-interface-list=LAN protocol=udp 
add chain=input action=accept comment="ALLOW admins to access configuration ports" dst-port=1978,1922 protocol=tcp src-address-list=informatycy 
add chain=input action=accept comment="defcon: accept to local loopback" dst-address=127.0.0.1
add chain=input action=drop comment="DENY everything else"
# forward
add chain=forward action=accept comment="Allow IPSEC packets in" ipsec-policy=in,ipsec log-prefix=forward_a_ipsec_in
add chain=forward action=accept comment="Allow IPSEC packets out" ipsec-policy=out,ipsec log-prefix=forward_a_ipsec_out
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-state=established,related hw-offload=yes
add chain=forward action=accept comment="Accept established and related packets" connection-state=established,related 
add chain=forward action=drop comment="Deny invalid connection states" connection-state=invalid
add chain=forward action=accept comment="internet traffic"  in-interface-list=LAN  out-interface-list=WAN  src-address-list=!no-internet-clients
add chain=forward action=drop comment="Allow  some OpenVPN users to limited ips only"  src-address-list=OVPN-SOLEMIS dst-address-list=openvpn-solemis-allow-lan-ip
add chain=forward action=accept comment="Allow all other OpenVPN users to entire LAN" src-address-list=OVPN-OTHER  dst-address=10.0.0.0/2
add chain=forward action=accept comment="port forwarding" connection-nat-state=dstnat
add chain=forward action=drop comment="drop all else"

It was not clear if had two openvpn tunnels or one…
in-interface=openvpn-somolemis was used on one rule but not the second rule??
is there an
in-interfac=openvpn-plain ??
So I simply created two source address list, those limited and those not…

Yeah, well, I kind of did, kind of didn’t, it seems. I get the basic idea under all that: allow what’s needed, drop everything else. On Mikrotik’s help pages the drop all rule is always there for input chain, but as far as forward chain goes, in both basic and advanced, firewall examples they do not use drop everything else rule. Instead, they either end with drop not dst-natted, or some address-lists drops. Thus, my question about the drop all rule for forward chain.

As for the “input chain add to list and drop from that list with IPSEC tunnels” this way, I thought, I can drop that attempts a bit faster, even before they come to the last input rule (which is drop all).

That is what I thought, and yet in most examples found on blogs, youtube etc. they almost always block/allow in both directions.

There are three 24/7 IPSEC/IKE2 tunnels. As for OpenVPN it is used for classic road warriors scenario. Users connect to that server from their Windows machines when needed. Some of those users should not have access to specific IPs on LAN. For each “limited” openvpn user secret I created an “OVPN Server Binding” interface and so this rule

add chain=forward action=drop comment="ALLOW OpenVPN SOLEMIS user to some ips only" dst-address-list="!openvpn-solemis-allow-lan-ip" in-interface=ovpn-solemis

was meant to do just that. If it was correct I would create similar rules for other limited road warriors. The following rule

add chain=forward action=accept comment="Allow OpenVPN users to LAN" dst-address=10.0.0.0/24 src-address=10.11.11.0/24

allows all other road warriors to access whole LAN, since 10.11.11.0/24 is their subnet and 10.0.0.0/24 is LAN.

Now, without the drop all rule for forward chain, if something is not DENIED by any other rule, it is permitted by default by the firewall, right? That would mean there is no need for any allow rules for traffic between different subnets/interfaces. If, however the drop all rule is there at the end, all ALLOW scenarios must be covered. That is, why you put this rule in

add chain=forward action=accept comment="internet traffic"  in-interface-list=LAN  out-interface-list=WAN  src-address-list=!no-internet-clients

as without it nobody would have internet access. I get that. It also means, that I do not have to DROP the traffic between GUESTs (wifi) and LAN, as it is not allowed by any rule, so it is dropped by the last drop rule. If so, I need to allow my wifi subnet (no the GUEST’s one) to access internet and LAN. As for internet access, all I need to do is add the wifi bridge to LAN interface list. To let the wifi users (subnet 10.12.12.0/24) to access LAN I need a forward rule, something like this (has to be both ways, so that LAN ips can initiate connections to wifi users too):

add chain=forward action=accept comment="ALLOW wifi users to LAN"  src-address=10.12.12.0/24 dst-address=10.0.0.0/24
add chain=forward action=accept comment="ALLOW wifi users from LAN"  src-address=10.0.0.0/24 dst-address=10.12.12.0/24

Am I getting close?