Firewall rules for blocking all trafic from DMZ to LAN

Hello to all,

I’ve tried some research on the forum and tried to find responses but with no succes. So I came here to gather the help of you guys experts.

On my router I’ve setup a port with a physical connection to a NIC of my server dedicated to VMs that are exposed to the internet (DMZ). All the VMs are on a separated network and can access the internet. The VM that is actualy in the DMZ is my webserver.

So I’ve added the port forwarding and masquerade in the NAT rules to be able to access my webserver from the internet and from my network, that work fine.

I’ve also added firewall rules based on this thread ( Buying - RB1100AHx4 Dude Edition - Questions about Firewall ) to have a basic security.

The thing that I want to do now is to block the access from this DMZ to my LAN (I’ve been able to open a ssh access on one of my servers on the LAN side from the webserver in the DMZ) but still been able to do so from the LAN to the DMZ.

I’ve tried to log all the rules in the firewall and NAT but can’t see any trace of my ssh connection between my 2 servers. Here are the export of the rules I have :

/ip firewall filter
add action=accept chain=input comment="accept connexion from 69 for winbox" dst-port=8291 protocol=tcp src-address=192.168.69.0/24
add action=accept chain=input connection-state=established,related,untracked log=yes log-prefix=Main_
add action=drop chain=input connection-state=invalid
add action=accept chain=input in-interface-list=LAN log=yes log-prefix=ICMP_ protocol=icmp
add action=accept chain=input dst-address=127.0.0.1 log=yes log-prefix=Loop_
add action=drop chain=input in-interface-list=!LAN
add action=accept chain=forward comment="in IPsec" ipsec-policy=in,ipsec
add action=accept chain=forward comment="out IPsec" ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward connection-state=established,related hw-offload=yes log=yes log-prefix=Fasttrack_
add action=accept chain=forward connection-state=established,related,untracked log=yes log-prefix=Main_
add action=drop chain=forward connection-state=invalid
add action=drop chain=forward connection-nat-state=!dstnat connection-state=new in-interface-list=WAN

And the NAT rules

/ip firewall nat
add action=accept chain=srcnat dst-address=192.168.69.0/24 src-address=192.168.70.0/24
add action=dst-nat chain=dstnat dst-address-list=WAN-IP dst-port=80,443 protocol=tcp to-addresses=192.168.71.31
add action=masquerade chain=srcnat dst-address=192.168.71.0/24 src-address=192.168.69.0/24
add action=masquerade chain=srcnat dst-address=192.168.71.0/24 log=yes log-prefix=NAT_ src-address=192.168.70.0/24
add action=masquerade chain=srcnat ipsec-policy=out,none out-interface-list=WAN

Any idea where the connection passes through ?

Thx a lot for your help
Have a nice day
Clair

Well, you will need to describe your network specifying which port of your Mikrotik device is connected to what, the IP addresses of the various involved computers/servers and your FULL configuration, see here:

Thx for the fast response.

As requested here is a full export of my router config :

# 2026-01-05 14:54:17 by RouterOS 7.20.6
# software id = SL5X-B8U3
#
# model = CRS305-1G-4S+
# serial number = HJW0AWKAY79
/interface bridge
add name=bridge1

/interface ethernet
set [ find default-name=ether1 ] name="ether1 - WAN"
set [ find default-name=sfp-sfpplus1 ] disabled=yes
set [ find default-name=sfp-sfpplus3 ] disabled=yes
set [ find default-name=sfp-sfpplus2 ] name="sfp2 - DMZ"
set [ find default-name=sfp-sfpplus4 ] name="sfp4 - LAN"

/interface pppoe-client
add add-default-route=yes disabled=no interface="ether1 - WAN" name=\
    pppoe-out1 user=...

/interface list
add name=LAN
add name=WAN
add name=DMZ

/ip ipsec profile
add dh-group=modp2048 enc-algorithm=aes-256 hash-algorithm=sha256 name=\
    "profile - toMaison" nat-traversal=no

/ip ipsec peer
add address=82.197.183.59/32 exchange-mode=ike2 name=toMaison profile=\
    "profile - toMaison"

/ip ipsec proposal
add auth-algorithms=sha256 enc-algorithms=aes-256-cbc name=IKEv2 pfs-group=\
    modp2048

/ip pool
add name=dhcp_pool0 ranges=192.168.70.100-192.168.70.200

/ip dhcp-server
add address-pool=dhcp_pool0 interface=bridge1 lease-time=1d name=dhcp1

/interface bridge port
add bridge=bridge1 interface="sfp4 - LAN"

/interface ethernet switch
set 0 l3-hw-offloading=yes

/interface list member
add interface=bridge1 list=LAN
add interface=pppoe-out1 list=WAN
add interface="sfp2 - DMZ" list=DMZ

/ip address
add address=192.168.70.1/24 interface=bridge1 network=192.168.70.0
add address=192.168.71.1/24 interface="sfp2 - DMZ" network=192.168.71.0

/ip dhcp-server network
add address=192.168.70.0/24 dns-server=192.168.70.35 gateway=192.168.70.1

/ip dns
set servers=77.109.128.2,213.144.129.20

/ip firewall address-list
add address=cilab.ch list=WAN-IP
add address=192.168.70.0/24 list=LAN
add address=192.168.69.0/24 disabled=yes list=LAN

/ip firewall filter
add action=drop chain=forward dst-address=192.168.70.40 dst-address-list=LAN \
    in-interface="sfp2 - DMZ" log=yes log-prefix=DMZ_
add action=drop chain=input dst-address=192.168.70.40 in-interface=\
    "sfp2 - DMZ" log=yes log-prefix=DMZ_
add action=accept chain=input comment="accept connexion from 69 for winbox" \
    disabled=yes dst-port=8291 protocol=tcp src-address=192.168.69.0/24
add action=accept chain=input log=yes log-prefix=Main src-address=\
    !192.168.70.197
add action=accept chain=input connection-state=established,related,untracked \
    log=yes log-prefix=Main_
add action=drop chain=input connection-state=invalid
add action=accept chain=input in-interface-list=LAN log=yes log-prefix=ICMP_ \
    protocol=icmp
add action=accept chain=input dst-address=127.0.0.1 log=yes log-prefix=Loop_
add action=drop chain=input in-interface-list=!LAN
add action=accept chain=forward comment="in IPsec" ipsec-policy=in,ipsec
add action=accept chain=forward comment="out IPsec" ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward connection-state=\
    established,related hw-offload=yes log=yes log-prefix=Fasttrack_
add action=accept chain=forward connection-state=\
    established,related,untracked log=yes log-prefix=Main_
add action=drop chain=forward connection-state=invalid
add action=drop chain=forward connection-nat-state=!dstnat connection-state=\
    new in-interface-list=WAN

/ip firewall nat
add action=accept chain=srcnat dst-address=192.168.69.0/24 src-address=\
    192.168.70.0/24
add action=dst-nat chain=dstnat dst-address-list=WAN-IP dst-port=80,443 \
    protocol=tcp to-addresses=192.168.71.31
add action=masquerade chain=srcnat dst-address=192.168.71.0/24 src-address=\
    192.168.69.0/24
add action=masquerade chain=srcnat dst-address=192.168.71.0/24 log=yes \
    log-prefix=Hairpin_ src-address=192.168.70.0/24
add action=masquerade chain=srcnat ipsec-policy=out,none out-interface-list=\
    WAN

/ip ipsec identity
add peer=toMaison

/ip ipsec policy
add dst-address=192.168.69.0/24 peer=toMaison proposal=IKEv2 src-address=\
    192.168.70.0/24 tunnel=yes

/ip service
set ftp disabled=yes
set ssh disabled=yes
set telnet disabled=yes
set www disabled=yes
set winbox address=192.168.70.0/24,192.168.69.0/24
set api disabled=yes
set api-ssl disabled=yes

/system clock
set time-zone-name=Europe/Zurich

/system ntp client
set enabled=yes

/system ntp client servers
add address=ntp11.metas.ch
add address=ntp12.metas.ch

/system scheduler
add interval=10m name=noipUpdate_IPSEC on-event="..." policy=read,test start-date=2026-01-01 start-time=15:54:27
add interval=10m name=IPsec_ipUpdate on-event="..." policy=read,write,test start-date=2026-01-01 start-time=16:13:23
add interval=10m name=noipUpdate_Webserv on-event="..." policy=read,test start-date=2026-01-01 start-time=16:26:56

/system script
add dont-require-permissions=yes name=noipUpdate_IPSEC owner=clair policy=\
    read,test source="..."
add dont-require-permissions=no name=IPsec_ipUpdate owner=clair policy=\
    read,write source="..."
add dont-require-permissions=no name=noipUpdate_Webserv owner=clair policy=\
    read,test source="..."

/tool mac-server
set allowed-interface-list=LAN

Thx a lot for the help
Have a nice day
Clair

No but I'll make one fast

Is that enough info ?

That is a switch with some routing capabilities, which speed is your internet connection?

Do I get right that the CRS305 is the device "Work" in the diagram? (and that the device "Home" is something else out of the scope of the DMZ problem?)

thx for all your answers.

First of all I've build a permanent IPsec tunnel between the 2 router for communication so yes there is a VPN between the 2 sites

For the other questions: yes the CRS305 is on my "work" site and it's internet connexion is 200Mb / 100Mb so it is enough. on the "home" site there is a CRS309 witch has more compute power (I've found out after buying these 2 routers that they were more switches and I must go for that at the moment). It doesn't change any thing to the functionalities only the performances.

Concerning the "home" network, I don't think there anything that needs to be done. I only need to have my DMZ concerne be resolved.

Have a nice day
Clair

Did you try adding a drop rule to the forward chain, at the bottom of the table:

/ip firewall filter
add action=drop chain=forward src-address=192.168.71.0/24 dst-address=192.168.70.0/24

?

If you also want to block access to 192.168.69.0/24, add both 192.168.69.0/24 and 192.168.70.0/24 to address list RESTRICTED and use the drop rule:

/ip firewall filter
add action=drop chain=forward src-address=192.168.71.0/24 dst-address-list=RESTRICTED

thx I'll try and comeback to you with feedback

Nope doesn't change anything :face_exhaling:

These rules looks like my first 2 in my config export but instead of source address I used In interface and I specified a LAN IP for log purposes.

Any idea ? (rising the thread a little)

Do you mean these lines:

That appears that you are trying to block traffic within the same subnet/LAN. That traffic won't be routed, it will be switched, and the ip firewall will have no chance to block anything.

What you did to verify and what you changed may be very obvious to you, but not to us.

The DEFACTO DEFAULT FIREWALL Setup corrected link, removed sid from end, it should work now.

Is worth at least a skim to see if you can find anything useful.

Your diagram is better than nothing, but doesn't include enough information (what interfaces are being used, what the devices are, etc.)

So no one is going to spend an hour trying to figure out what your problem is.

That's the way it works on a forum where the answers are coming from non-paid volunteers.

The post with enough info get the attention, and the ones that are too vauge or open ended just get skipped.

I could post other threads with info about how to ask questions, but you probably don't want to hear that.

If you just want guesses, you can ask chatgpt. But don't expect good results without good specifications, and even with good specification, you will get answers that don't apply to MikroTik.

Not really, the two rules at the top of your firewall only blocks access to a single host 192.168.70.40, not to the whole subnet, for that you'll need to specify dst-address=192.168.70.0/24 OR dst-address-list=LAN but WITHOUT dst-address=192.168.70.40.

Furthermore, the placement of the rule is important. If you read my post above, I specifically wrote:

Because if you want to achieve what you wrote: LAN -> DMZ possible but DMZ -> LAN not possible, then the drop rule has to be placed below these rules:

If you place the drop rule above them, then you won't be able to have the communication LAN -> DMZ because all response packets will be blocked too.

Thx for your response.

@Buckeye: From what I understand the 2 lines (1 for forward et 1 for input) should block traffic from the in-interface DMZ to the dst-address LAN (here a specific IP so I can track in the log)

About your concerne for lack of details and information, I understand. My though is that I try to bring enough information to the question in the smallest amount so people don't have to to spend 1/2 hour reading and digesting a lot of details that may or may not be very important to the root subject. This is so they have the easiest way to understand what the question is about. If someone need more details, I gladly give more information globally or on a more specific level.

Having not a great experience in firewall/routers configuration sharing, I totally admit that my initial post was not fully complet.

PS: The link you've included sound interesting but doesn't work.

@CGGXANNX: I know that in this state the rule should block traffic only to the specific IP 192.168.70.40 which is in the LAN. I did that on purpose to log the traffic more specificly. As for the position I know the order has a great importance. I've put the block rule all the way on top because my primary goal for the moment is to block traffic and like I've read, once a connection meet a rule requirements it stops testing there and doesn't go further down the list of rules. like you rightly explain the final rule will have to be placed in the right position and with the correct IP range.

auto-edit:
As I'm writing these lines, I've rechecked and without having done any changes to the router configuration now the connection between DMZ and LAN is blocked as wanted. I've changed the block rules to Dst-address List = LAN and removed the Dst-address specific and It work flawlessly. As for the position of the rule it is still at the top but doesn't avoid me to access the DMZ from the LAN as it blocks connection only in In. Interface -> Dst. Address List not the opposite way.

I'm going to clean this list of rule to remove all the debugging specifics and have a more definitive config.

I thank all of you for the help and the time you've spend to educate me to firewall/router configs and forums

Have a nice day
Clair

When a PC in LAN make a connection to a server in DMZ, the firewall rules are applied to packets in both directions. For example, with a TCP connection the PC, let's say 192.168.70.15 will send a SYN packet to the server at 192.168.71.20. No rules on the forward chain of the filter table is blocking this packet, so it gets through and arrives at the server.

As part of the TCP handshake, the server at 192.168.71.20 will send a response in the form of a SYN/ACK packet with source address 192.168.71.20 and destination 192.168.70.15. What do you think will happen with this packet?

It will arrive at the router and will be processed by the firewall and will arrive at the box numbered 14 in this chart:

That's where the rules of the forward chain of the filter table will be consulted again, in the order that they appear in the table, from top to bottom.

If you have that rule as first among all the chain=forward rules:

/ip firewall filter
add action=drop chain=forward dst-address-list=LAN \
    in-interface="sfp2 - DMZ" log=yes log-prefix=DMZ_

then it will match with this SYN/ACK packet, because all conditions (dst-address-list and in-interface) are met. The action is drop and the packet will be discarded, and your PC will never receive this packet. It will wait a while, tries to resend the SYN packet a few more times, then gives up with a timeout error.

That's why in a normal firewall configuration you usually see that at the top or near the top of the chain=forward rules list, there is an action=accept rule that matches on connection-state=established,related,untracked. Here the keyword is established. That SYN/ACK packet I mentioned above will have connection-state=established and usually will be matched immediately by this rule and be accepted and let through. You want that rule (and the fasttrack rule matching on established too) to be at the very top to be able to let the packets, in both directions, of a connection for which you already let the first packet through (the SYN packet in this case) to be accepted as soon as possible. This saves processing and most importantly, in this case, allows the traffic in the return direction to not be affected by the DMZ -> LAN blocking.

Hence the rule that blocks traffic in the DMZ -> LAN direction should be placed BELOW those two rules with connection-state=established. That will allow connection attempts from the servers in DMZ to devices in LAN to be blocked, but still allows devices in LAN to makes connection to servers in DMZ and receives answers.

This bolded part is important. If you put the drop rule at the top, you'll make that part impossible.

I understand.

But then why I'm able to login with ssh on my server on the DMZ from my computer in LAN ? I should have a timeout no ?

It doesn't seem like you do.

Your mission, should you accept it, is to provide the output of:
/ip firewall filter export
every time you change something and it doesn't work as you expect, as this is the only way a willing helping member can - hopefully - spot where the issue is and give you proper suggestions to correct the behaviour.

Right now we have no idea of what you have in your firewall, or if you have implemented correctly the rules CGGXANNX suggested, or if there are other seemingly unrelated rules that actually affect your firewall behaviour, it is very easy to mistype something or - in the case of firewall rules - to misplace them.

A general advice is - since rules are used in strict "order of appearance" for each chain - to have all input chain rules grouped together, then all forward rules, etc., and this make it also easier to read them and check their order.

It doesn't seem like you do.

Man the thing I don't understand is why you've said that.

I've read the message and understood the back and forth relationship of a request and when a request passes in one way it will be rejected in the other by the rule forward been above the accept.

Like I've said in the previous message, I haven't changed the firewall configuration from the start of the thread (OK I've removed the parts specifically for logs) and my screen shot is not to give technical details, witch is on my second message where you can see my full export with the filter rules, but for proof of why I'm surprise to be able to connecte to my server with the knowledge given by CGGXANNX.

and as you've asked here is the filter export :

/ip firewall filter
add action=drop chain=forward dst-address-list=LAN in-interface="sfp2 - DMZ" log=yes log-prefix=DMZ_DROP_
add action=drop chain=input dst-address-list=LAN in-interface="sfp2 - DMZ" log=yes log-prefix=DMZ_DROP_
add action=accept chain=input comment="accept connexion from 69 for winbox" dst-port=8291 protocol=tcp src-address=192.168.69.0/24
add action=accept chain=input connection-state=established,related,untracked log-prefix=Main_
add action=drop chain=input connection-state=invalid
add action=accept chain=input in-interface-list=LAN log-prefix=ICMP_ protocol=icmp
add action=accept chain=input dst-address=127.0.0.1 log-prefix=Loop_
add action=drop chain=input in-interface-list=!LAN
add action=accept chain=forward comment="in IPsec" ipsec-policy=in,ipsec
add action=accept chain=forward comment="out IPsec" ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward connection-state=established,related hw-offload=yes log-prefix=Fasttrack_
add action=accept chain=forward connection-state=established,related,untracked log-prefix=Main_
add action=drop chain=forward connection-state=invalid
add action=drop chain=forward connection-nat-state=!dstnat connection-state=new in-interface-list=WAN

Like I've said, these rules are taken from a post (Buying - RB1100AHx4 Dude Edition - Questions about Firewall - #4 by rextended) and are in the grouped/ordered in the same way.

What I meant was that this is functionally EXACTLY the same as what you have just posted, only it is more readable:

/ip firewall filter

#let's start with input chain

#begin input chain
add action=drop chain=input dst-address-list=LAN in-interface="sfp2 - DMZ" log=yes log-prefix=DMZ_DROP_
add action=accept chain=input comment="accept connexion from 69 for winbox" dst-port=8291 protocol=tcp src-address=192.168.69.0/24
add action=accept chain=input connection-state=established,related,untracked log-prefix=Main_
add action=drop chain=input connection-state=invalid
add action=accept chain=input in-interface-list=LAN log-prefix=ICMP_ protocol=icmp
add action=accept chain=input dst-address=127.0.0.1 log-prefix=Loop_
add action=drop chain=input in-interface-list=!LAN
#end input chain

#begin forward chain
add action=drop chain=forward dst-address-list=LAN in-interface="sfp2 - DMZ" log=yes log-prefix=DMZ_DROP_
add action=accept chain=forward comment="in IPsec" ipsec-policy=in,ipsec
add action=accept chain=forward comment="out IPsec" ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward connection-state=established,related hw-offload=yes log-prefix=Fasttrack_
add action=accept chain=forward connection-state=established,related,untracked log-prefix=Main_
add action=drop chain=forward connection-state=invalid
add action=drop chain=forward connection-nat-state=!dstnat connection-state=new in-interface-list=WAN

Since the rule:

add action=drop chain=forward dst-address-list=LAN in-interface="sfp2 - DMZ" log=yes log-prefix=DMZ_DROP_

is the FIRST one in forward chain, it will be evaluated BEFORE any other rule in the same chain and thus drop the "return connections".

What you should have is instead:

/ip firewall filter
#let's start with input chain

#begin input chain
add action=drop chain=input dst-address-list=LAN in-interface="sfp2 - DMZ" log=yes log-prefix=DMZ_DROP_
add action=accept chain=input comment="accept connexion from 69 for winbox" dst-port=8291 protocol=tcp src-address=192.168.69.0/24
add action=accept chain=input connection-state=established,related,untracked log-prefix=Main_
add action=drop chain=input connection-state=invalid
add action=accept chain=input in-interface-list=LAN log-prefix=ICMP_ protocol=icmp
add action=accept chain=input dst-address=127.0.0.1 log-prefix=Loop_
add action=drop chain=input in-interface-list=!LAN
#end input chain

#begin forward chain
add action=accept chain=forward comment="in IPsec" ipsec-policy=in,ipsec
add action=accept chain=forward comment="out IPsec" ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward connection-state=established,related hw-offload=yes log-prefix=Fasttrack_
add action=accept chain=forward connection-state=established,related,untracked log-prefix=Main_
add action=drop chain=forward dst-address-list=LAN in-interface="sfp2 - DMZ" log=yes log-prefix=DMZ_DROP_
add action=drop chain=forward connection-state=invalid
add action=drop chain=forward connection-nat-state=!dstnat connection-state=new in-interface-list=WAN

Hope now it is more clear.

If I get it right, your SSH connection is from LAN to (server on ) DMZ, not DMZ to LAN, Or am I misunderstanding?

1 Like

Thx for your explanations and the details you've given. I already know that the position of the rule is "wrong" it was on purpose. I'll implement the way you and CGGXANNX explained when I can notice that I can't log on my server in DMZ from my computer in LAN. For the moment I try to understand why does it work as it shouldn't with the drop rule on top.

to simplify the behavior I have actually is what I want: Connection from LAN -> DMZ OK but connection from DMZ -> LAN KO. The thing that bother's me is that it should not work. Like you've all explained I should not be able to connecte to my server from the LAN with the rule in that order.

I've tested to access the server (since it is a webserver) from the browser and it was blocked by the rule on the top position but worked when I moved the rule to the bottom.