Packets flow through things in a pretty complicated way if you think of everything all at once (see the current packet flow diagram v6)…
http://wiki.mikrotik.com/wiki/Manual:Packet_Flow_v6
Anyhow, given this flow, you can see there are lots of different ways packets go through the mikrotik.
The main ones for basic use are filter forward and srcnat.
I have two main goals in my firewall chain designs (besides the desired effect):
1- minimum number of rules to check per packet.
2- rules are as simple and straightforward as possible.
2a. - use as few match criteria as possible. The more criteria, the more likely the rule won’t match / ignore packets in all situations.
Other things to keep in mind - checking 5 src IP addresses by using 5 rules with src-address is going to be much less efficient than using an address list. Those are designed for fast searches just like the routing table is.
Not all checks are created equal - a rule which looks at the protocol doesn’t have much to check - one binary number from the packet does or does not equal the binary number you specified. fast. regex search through the contents of the packet payload = slow.
The big concept for a lot of people: the input/output chains are for packets to/from the Mikrotik itself, regardless of address or interface. If you are on ether1 with 192.168.1.12, and you ping 192.168.2.1 which is the Mikrotik’s IP on ether2, the packet does NOT go through forward and then input - just directly to input.
Ok - for efficiency and the questions you asked about “which rule first?”
I put drop rules for src-address-list / dst-address-list = blacklist as the very first rule.
The very second rule is allow established,related connection states.
I decided that this is best because if I DO see a security threat taking place, and add the guilty IP to blacklist, then I don’t want him to get 5 more password guesses before sshd closes the socket. I want him gone now. If the blacklist comes after established, then existing links will stay functional. Ip address lookups are fast, even for a large list, so I decided to make this one extra check on every packet.
After these two rules, anything you specify is only going to get checked once per new connection. (a scan or syn flood would go nuts on these still, though, but that’s why there is a blacklist). Given that, you don’t need to put state=new in any rule. It’s impossible to get here w/o the state being new or invalid. If invalid bothers you, drop those before moving on.
I typically put interface-specific rules where possible - the policy is based on “things in this direction” regardless of the IP, it’s a quick check, and it keeps you from having to remember to go change everything from 192.168.88.x to 192.168.99.x when you decide to renumber for some reason or other.
Another thing to use interfaces to switch on is custom chains - if a packet comes in on interface GUEST, then jump to chain guest. one check if it’s not guest, X number of checks if it is. If you only have one GUEST rule, and you really value efficiency, then just keep the one rule in the main forward chain, but I find that in addition to being efficient, seperate chains are READABLE and EASIER TO TROUBLESHOOT.
So in short - if your rule chain is essentially: give the finger to bad guys, accept whatever you asked for, then check the rest for things you actually want to allow, throw away the rest - then this should be quite efficient.
Here is my entire firewall config for my home router:
/ip firewall address-list
add address=w.x.y.z list=Whitelist
add address=a.b.c.0/23 comment="Work" list=Whitelist
add address=d.e.f.0/23 comment="Customer" list=Whitelist
/ip firewall filter
add chain=input comment="Permit existing connections" connection-state=established,related
add chain=input comment="Allow all ICMP" protocol=icmp
add chain=input comment="Allow whitelisted sources" src-address-list=Whitelist
add action=drop chain=input comment="WAN - default deny" in-interface=ether6
/ip firewall nat
add action=src-nat chain=srcnat comment="Use correct src-ip when talking to DOCSIS modem." \
dst-address=192.168.100.0/24 out-interface=ether6 to-addresses=192.168.100.2
add action=masquerade chain=srcnat out-interface=ether6 to-addresses=0.0.0.0
I didn’t even bother with a blacklist for my home router - if I’m in it and see something going on, I’ll just block it with a rule - but if I wanted rules that can ‘detect’ port scans or something, then I would need a blacklist.
As you see, I allow ICMP - hiding from ping scans isn’t really going to help at all.
Well, that’s my firewall 101 speech. I hope it’s been helpful.