First time setup firewall

Hey guys,

I’m new to Mikrotik routers and need some advice for my first firewall configuration.

I’m using the Mikrotik RouterBOARD RB2011UIAS-2HND-IN behind a Fritzbox 7490 (for VDSL) as “Exposed Host” to avoid Fritzbox’ NAT / Firewall. On the Mikrotik I’ve created a lan (192.168.0.0/24).

That’s the configuration I’ve made with the aid of the mikrotik manual:

/ip firewall filter
add chain=input connection-state=established
add chain=input connection-state=related
add chain=input in-interface=br-lan
add action=log chain=input
add action=drop chain=input
add chain=forward connection-state=established
add chain=forward connection-state=related
add chain=forward dst-address=!192.168.0.0/24 dst-port=80,443 in-interface=br-lan protocol=tcp
add chain=forward dst-address=!192.168.0.0/24 in-interface=br-lan protocol=icmp
add action=drop chain=forward

Well, I just wanna accept only established, related and local clients from the “br-lan” interface which is actually a bridge interface. Is there anything else I’ve to consider? I mean, invalid packets should drop as there’s no rule to accept those packets.

Forward chain: the same thing - I first wanna drop anything but established, related and particular rules like “browse or ping” should work.

These are my first steps, so don’t be too rough please ;D

In order to refine the configuration I thought it would be helpful to provide a basis.

Thank you very much so far!

Kind regards,

sls

Ok,

I’m not sure if no answere means everything on this configuration is okay :smiley:

I’m just trying out some things after read tons of topics here and there.

/ip firewall filter
add action=drop chain=input connection-state=invalid
add chain=input connection-state=established
add chain=input connection-state=related
add chain=input in-interface=lan src-address=192.168.10.0/24
add action=log chain=input
add action=drop chain=input

add action=drop chain=forward connection-state=invalid
add chain=forward connection-state=established
add chain=forward connection-state=related
add chain=forward in-interface=lan protocol=tcp src-address=192.168.10.0/24
add action=log chain=forward
add action=drop chain=forward

Would this be a “good” set up? Or should I think about to delete the “drop rule” and “tcp forward” rule instead as unsolicited traffic will be dropped by the “drop invalid packets” rule?

It looks like a good start. Keep the catch-all drop rule at the end, because dropping invalid at the beginning won’t protect you. From router’s perspective, there’s nothing wrong with unsolicited incoming connections from internet, they are just new, not invalid.

Few tips:

  • established & related can be in one rule
  • established & related will be most common, so it’s good idea to make it first rule
  • you probably don’t need to specifically limit accepted input/forward to 192.168.10.0/24, just incoming interface should be enough
  • if you want your users to be able to fully enjoy internet, you don’t want to limit them to tcp only

Hey,

Thanks a lot!

In order to allow my users to surf the web I would set both tcp and udp rules like this:

add chain=forward comment="Browse" in-interface=lan protocol=tcp



add chain=forward comment="Browse" in-interface=lan protocol=udp

Or just make a jump rule where I could make a custom tcp rule set if that’s more recommended as well as deny some tcp ports in it.

Btw: I thought it was enough to drop invalid packets and only allow related and established packets so i don’t need to define any special tcp/udp rules… :confused:

Thanks so far!

Kind regards,

sls

Usually nothing special is needed. My starting config goes like this:

For forward, allow established & related, drop invalid, allow anything from LAN (unless there’s reason to block something; if there is, match all outgoing connections only once and jump to dedicated chain to do detailed filtering - exactly as you wrote), allow forwarded ports (connection-nat-state=dstnat), reject the rest.

For input, allow established & related, drop invalid, allow anything from LAN (unless there’s reason to not allow some hosts to access router), allow selected external addresses (for remote administration, if needed; use src-address-list), allow icmp (I hate some people’s idea that blocking icmp, by which they mean ping, will make router “invisible” and more secure - it won’t and it sucks when debugging problems), reject the rest (not drop, if client is not allowed to access given port, just say it directly and spare it useless trying).

If there’s need for port forwarding, especially if it’s many ports to different internals hosts, match the address only once and jump to dedicated chain (you’ll appreciate it when public address changes and it will be enough to change it only in one place and not for each port forward rule). Add universal hairpin NAT rule for all ports, so any public service, which in fact runs on some of your internal hosts, will just work.

It’s not “one and only best config”, no such thing exists, different people have different needs. But I’d say it’s simple and sane one.

IMO dont need drop invalid packet rule because without that rule, in the end invalid packet will get drop by drop/reject the rest rule.

You don’t have to. But then router will try to match them against all following rules. And you already know they are invalid, so why not get rid of them right away.

Will it really try to match if it is dropped in the end?

If you have e.g.:

#1: accept established & related
#2: accept from interface ether1
#3: accept to 192.168.1.100
#4: drop

Then invalid packet from ether1 will be accepted by rule #2, invalid packet to 192.168.1.100 by rule #3 and only other invalid packets will get all the way to #4 and get dropped. It would not happen if #2 and #3 had connection-state=new, but that’s what I like about dropping invalid at the beginning, once you get rid of them (and accept established & related), all the rest is new and there’s no need to add state matcher to every rule.

Yeah.
This could be. I am also dropping the invalids at the beginning normally, but looking at the statistics the dropped invalid packets are approximatelly 0,05% of the finally dropped packets. Does it worth to employ additional rule that needs to be checked for all packets that will for 99,99% pass through it? From this point of view I see it not efficient, as it is uselessly employing the firewall.

On plus side, it must be very simple check. The whole connection tracking takes resources, but it’s done anyway, you can’t save anything here (unless you turn it off completely). The check itself can’t be nothing more than comparing two numbers, so the only noticeable difference will be some general overhead associated with rule processing.

It would be interesting to test it and see if there’s any measurable difference. I’ve been thinking about such testing for a long time (not specifically this, but various things like rule order, using different chains, etc.), but didn’t get to it yet.

So the Forward chain is like the input chain, established & related, allow anything from my LAN (which also means I don’t need to specify particular protocols as well as ports, right?) but what I can’t see is connection-nat-state=dstnat. I’m not sure what this rule does.

I’ve read about examples for the input chain to provide an OpenVPN server like this:

/ip firewall filter add chain=input dst-port=1194 protocol=tcp

Would this also goes with tcp port 443 (which is more usable for proxies) if there’re both webserver and OpenVPN server on LAN site which listens on Port 443?

I picked up a lot of useful tips here and doing my best to understand how RouterOS works, so thank you very much :]

Kind regards,

sls

Right. All conditions are extra limits. If you don’t add any, all packets will match. If you specify incoming interface, all packets from there will match.

It’s when you forward ports to internals hosts. E.g. your router has public address, but you want to run website on some internal server. So you do:

/ip firewall nat
add action=dst-nat chain=dstnat dst-address=<public ip> dst-port=80 protocol=tcp \
    to-addresses=192.168.0.10

and all packets to :80 get forwarded to 192.168.0.10:80. But they would get blocked in forward chain, because only connections originating from LAN are allowed. Accept rule with connection-nat-state=dstnat makes it easy to accept all forwarded connections. Otherwise you would have to add specific rules for each internals host and port.

If you only have one public address, you can’t share port 443 for both OpenVPN and webserver. Standard OpenVPN does have such option, but the one in RouterOS does not. You have to choose. Or set up standard OpenVPN server on internal host, forward port 443 to it and let it forward https traffic to webserver.

I also never configured firewall on my own before but recently I started to read about fasttrack so I feel that I should understand firewall first. This is my RB2011 config:

 0    chain=input action=accept connection-state=established,related 
 1    chain=input action=accept protocol=icmp 
 2    chain=input action=drop in-interface=ether1-gateway 
 3    chain=input action=accept protocol=udp port=53   <-- it's DNS right?
 4    chain=input action=accept src-address=192.168.1.0/24 
 5    chain=input action=reject reject-with=icmp-port-unreachable 
 6    chain=forward action=accept connection-state=established,related 
 7    chain=forward action=drop connection-state=invalid 
 8    chain=forward action=drop dst-address=192.168.0.0/24 
 9    chain=forward action=drop src-address=192.168.3.0/24 dst-address=192.168.0.0/16

It was created from modified factory settings by my friend who in fact introduced me to MT hardware. At the beginning firewall was to me something “totally too difficult” to deal with it on my own as i was just learning basics of networking in high school with this router. But now I think it’s time to step forward. So i have few questions related to it:


I don’t have equivalent of:

 add chain=forward in-interface=lan protocol=tcp src-address=192.168.10.0/24



I also don’t have this rule despite using NAT. And i don’t have drop all at the end.

I’m using plenty of networks in home (192.168.4.0 private wifi, 192.168.3.0 is public wifi, 192.168.2.0 is DMZ web server, 192.168.1.0 private wired with NAS, 192.168.0.0 is network between faulty, vulnerable ISP router and RB2011) so I don’t really feel like adding every single src-address combination…

On the other hand i don’t really know what’s happening “below” firewall rules if there’s no drop all rule at the end so I’m not sure what to do now. Is it bad practice to not have drop all at the end? I’m mostly interested in this NAT rule. What’s difference between having this rule and drop all at the end versus not having drop all at the end? Does it affect connectivity of p2p traffic or stuff like Tor and i2p routers? If I have server set as DMZ (as in dst-nat forward all traffic not caught by earlier nat rules) is it even possible that something will actually be not caught by this rule?

EDIT:

By analogy to your posts I’ve changed to this:

 0    ;;; input
      chain=input action=accept connection-state=established,related
 1    chain=input action=drop connection-state=invalid
 2    chain=input action=accept protocol=icmp
 3    chain=input action=drop in-interface=ether1-gateway
 4    chain=input action=accept protocol=udp port=53
 5    chain=input action=accept src-address=192.168.1.0/24
 6    chain=input action=reject reject-with=icmp-port-unreachable

 7    ;;; forward
      chain=forward action=accept connection-state=established,related
 8    chain=forward action=drop connection-state=invalid
 9    chain=forward action=drop dst-address=192.168.0.0/24
10    chain=forward action=drop src-address=192.168.3.0/24 dst-address=192.168.0.0/16
11    chain=forward action=accept src-address=192.168.0.0/16
12    chain=forward action=accept connection-nat-state=dstnat in-interface=ether1-gateway
13    chain=forward action=drop

But I still don’t know what’s the difference comparing to my previous setup. Nothing is dropped by last rule even if I’m connecting to random ports from WAN.

You don’t have to add all combinations. If some subnets can go anywhere (.1, .2 and .4), you’d need three rules for them with just src-address. Then fourth rule with src-address=192.168.3.0/24 and dst-address=!192.168.0.0/16 and you’d be done.

If no rule matches the packet, default action is accept. So in your original config, .3 subnet was not allowed to access any other 192.168.x.x, which does make sense for public wifi. And then nothing could access .0 subnet, which does not make sense to me. Why prevent anyone from accessing “faulty, vulnerable ISP router”, but allow that router to access all internal networks? Shouldn’t it be the other way around, i.e. src-address=192.168.0.0/24? Everything else was allowed.

Unconditional drop at the end is whitelist approach, either you specifically allow something or it’s not allowed. It’s possible to go with blacklist, specifically block everything you don’t want and all the rest will be allowed by default. I like whitelist better, but you can’t say that one is always better than the other.

Accept rule with connection-nat-state=dstnat only allows forwarded ports. No drop rule at the end allows everything not blocked by earlier rules.

If you have some port forwarded to your p2p program, it will be accepted by this rule. Not that you can see any difference, because previously it was accepted by default.

Yes. If some bad guy managed to deliver packet with source address e.g. 192.168.1.10 and destination 192.168.2.10 to your WAN interface, your original config would accept it. But in practice, it’s extremely unlikely to happen.

If you’re connecting to random ports on your router from internet, it would normally go into input chain. If you forward all to DMZ, it’s accepted by rule #12.

Thanks for explanation :slight_smile:

I think i forgot to mention - .0.0/24 is connected to ether1-gateway. So it’s isolated by ether1 rules right? I mean it has the same level of privilleges as traffic incoming from WAN right? So there’s no really need to block such traffic. Or I forgot about something? This faulty router is actually my gateway to WAN… :confused:

About dst-address rules - well it’s because it’s this Thomson TWG870 router where entering http://192.168.0.1/Backup.bin allows everyone to download backup file with plain text admin login and password… Also entering http://192.168.0.1/xxxxxxx… (long url more than 512 chars) breaks router and resets to factory settings with open wifi and admin panel access through wifi… Technically you can put both of mentioned above addresses eg. on website as image src, which i could visit from eg. PC in .1.0/24 network and it’d be quite bad i think… Atm. this router is just set to DMZ everything to MT.

Actually I’ve already experienced resetting it to factory without my knowledge and whole internet gone down. So I decided that it’ll be better to block any incoming traffic. Unfortunately my ISP really doesn’t want replace this crap or even allow me to use plain coax->RJ45 converter. Yet still i don’t want to change ISP because this one gives me static public IP for free even with cheapest contract. Also it’s really reliable, I literally never had downtime in my life. So it’s quite unfortunate situation…

You have great router. :wink: With this knowledge, your rule does make sense. But your internal networks are still not protected from it.

No. You have no “ether1 rules”. Well, you have action=drop, in-interface=ether1-gateway, but that’s for input. So if evil hackers broke into your Thompson router, they would not be able to access your MikroTik router. But they could access anything in any internal network, because nothing blocks traffic from 192.168.0.1 to 192.168.x.x in forward chain. The drop rule #13 at the end would do it, but it never gets there, because such packets would be accepted by #11. Even #9 wouldn’t save you, because reply packets for connection initiated from 192.168.0.1 would be established and thus allowed by #7.

Okay, well, I tried to connect to the OpenVPN server on Mikrotik, and everything seems to be fine, but there’s just a problem. First, my RoadWarrior has the same public ip address even tough if the VPN connection was established. Second thing is, that I can’t access to the Mikrotik via VPN without that rule:

/ip firewall filter 
add action=accept chain=input comment="OpenVPN" disabled=no dst-port=1194 protocol=tcp

What I wanna try to do is to get my RoadWarrior inside one of my local networks in order to access to internal shares as well as surf “through” the internal lan. Therefore I set up a lot of little /30 IP pools as you can see at the docs https://openvpn.net/index.php/open-source/documentation/howto.html#policy,%20OpenVPN

In OpenVPN GUI (Client side) I route 192.168.17.0 255.255.255.0 (target subnet on Mikrotik) but, yeah, it doesn’t work.

Kind regards,

sls

If OpenVPN server runs on router, then yes, obviously you have to add accept rule for its port, if your other rules block all connections from WAN by default.

To access your internal LAN, you can:

  1. Set up whole LAN as bridge and add client as bridge port. That way it will be direct part of LAN.
  2. Keep client completely separate, no bridge and different subnet. It’s good if you want to do some easy traffic filtering between LAN and VPN client, because it’s standard routing between interfaces. But there might be problem with hosts’ default firewall, e.g. Windows allow access to shares only from same subnet.
  3. Keep the interfaces separated, but use smaller part of current subnet (e.g. your /30) for client, and enable Proxy ARP on LAN interface. This way, client’s address will look like part of LAN (although broadcasts won’t work), so no trouble with firewalls.

If you want to “surf through LAN”, i.e. make it look like you’re using internet from router’s address, your VPN client must have default route via VPN. Then you need forward rule allowing access from VPN client to WAN and some srcnat or masquerade rule for those connections. And it should work fine.

I won’t give you specific OpenVPN config stuff from the top of my head, because I don’t set it up very often. I would have to make a test network first and I don’t feel like doing it right now. :wink:

Hey Sob,

Thanks for your advices. That was very helpful!

So, I have 3 ports on a bridge, 2 ports were seperated with each different subnets as well as an own subnet for OpenVPN. Everything works great, but there’s just a last question right now. I’ve custom tcp and udp chains where any packets coming in / through the router were catched by a jump rule. I’m not sure if it’s more reasonable to create a “connection-state=new” rule after the custom tcp chains in order to use custom chains to only deny ports in it.

Ah, before i forget: I heard that all traffic between interfaces with different subnets will usually be routed, right? That’s what I’m trying to inhibit because there are some local shares not every subnet should be able to access. Maybe I’ll create some new firewall rules to avoid that.

Thanks so far - Mikrotik is just great :slight_smile:

Kind regards,

sls