Port forwarding and firewall rules

Hi there!

After reading through various guides and tutorials I’ve come to the conclusion that I need some help in order to properly configure port forwarding on my router.

For context: the router was initially configured by my ISP

The forwarding/NAT rule itself is probably the smaller problem, altough I do have some questions about that as well, so let’s get into that first:
(I’m primarily using the web interface so forgive the formatting)

To implement forwarding from public IP (port 80) → server on internal network at port 80 (in this case 192.168.1.18:80) I’d create the following entry:

Chain=dstnat
Protocol=6 (tcp)
Dst. Port=80
In. Interface=sfp-sfpplus1 {not entirely sure here, but since that’s the “top level” entry point of the internet it would make sense?}
Action=dst-nat
To Adresses=192.168.1.18
To Ports=80

The mikrotik example (https://help.mikrotik.com/docs/display/RKB/Port+forwarding) shows “WAN” in the In. Interface List, but it’s only: all, dynamic, none or static for me


To give a bit more context, and to continue with my next question, here’s the exported config (censored some stuff with “xxx”):

# oct/05/2023 04:01:37 by RouterOS 7.6
# software id = ZLAH-2LRX
#
# model = RB4011iGS+

/interface bridge
add name=bridge1 protocol-mode=none
/interface pppoe-client
add add-default-route=yes disabled=no interface=sfp-sfpplus1 name=pppoe-out1 \
    use-peer-dns=yes user= xxx
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/ip pool
add name=dhcp_pool0 ranges=192.168.1.20-192.168.1.253
/ip dhcp-server
add address-pool=dhcp_pool0 interface=bridge1 lease-time=3d10m name=dhcp1
/port
set 0 name=serial0
set 1 name=serial1
/interface bridge port
add bridge=bridge1 interface=ether1
add bridge=bridge1 interface=ether2
add bridge=bridge1 interface=ether3
add bridge=bridge1 interface=ether4
add bridge=bridge1 interface=ether5
add bridge=bridge1 interface=ether6
add bridge=bridge1 interface=ether7
add bridge=bridge1 interface=ether8
add bridge=bridge1 interface=ether9
add bridge=bridge1 interface=ether10
/ip address
add address=192.168.1.254/24 interface=bridge1 network=192.168.1.0
/ip dhcp-server network
add address=192.168.1.0/24 dns-server=xxx,xxx,8.8.8.8 \
    gateway=192.168.1.254
/ip firewall address-list

#(bunch of ISP addresses and names)

/ip firewall filter
add action=accept chain=input comment="Allow Established connections" \
    connection-state=established,related
add action=drop chain=input comment="Drop Invalid connections" \
    connection-state=invalid
add action=accept chain=forward comment="Established, Related" \
    connection-state=established,related
add action=drop chain=forward comment="Drop invalid" connection-state=invalid \
    log-prefix=invalid
add action=accept chain=input comment="Allow Established connections" \
    connection-state=established,related
add action=drop chain=input comment="Drop Invalid connections" \
    connection-state=invalid
add chain=input comment="Allow PPtP 1723" dst-port=1723 in-interface=\
    pppoe-out1 log-prefix=_allow1723 protocol=tcp
add chain=input comment="Allow PPtP GRE 47" in-interface=pppoe-out1 \
    log-prefix=_allowGRE47 protocol=gre
add chain=input comment="allow L2TP VPN (ipsec-esp)" dst-port=500 \
    in-interface=pppoe-out1 log-prefix=_allow1723 protocol=udp
add chain=input comment="allow L2TP VPN (ipsec-esp)" dst-port=4500 \
    in-interface=pppoe-out1 log-prefix=_allow1723 protocol=udp
add chain=input comment="allow L2TP VPN (ipsec-esp)" dst-port=10000 \
    in-interface=pppoe-out1 log-prefix=_allow1723 protocol=udp
add chain=input comment="allow L2TP VPN (ipsec-esp)" dst-port=1701 \
    in-interface=pppoe-out1 log-prefix=_allow1723 protocol=udp
add chain=input comment="allow L2TP VPN (ipsec-esp)" in-interface=pppoe-out1 \
    log-prefix=AllowL2TP protocol=ipsec-esp
add action=accept chain=input comment="allow IP from WAN" in-interface=\
    pppoe-out1 log-prefix=_allowWAN src-address-list=AllowWAN
add action=drop chain=input comment="drop all from WAN" in-interface=\
    pppoe-out1 log-prefix=_dropWAN
add action=accept chain=forward comment="Established, Related" \
    connection-state=established,related
add action=drop chain=forward comment="Drop invalid" connection-state=invalid \
    log-prefix=invalid
add action=drop chain=forward comment=\
    "Drop incoming packets that are not NATted" connection-nat-state=!dstnat \
    connection-state=new in-interface=pppoe-out1 log-prefix=!NAT
/ip firewall nat
add action=masquerade chain=srcnat out-interface=pppoe-out1 src-address=\
    192.168.1.0/24
/ip service
set telnet disabled=yes
set ftp disabled=yes
set ssh disabled=yes
set api disabled=yes
set api-ssl disabled=yes
/system clock
set time-zone-name=Europe/Vienna
/system identity
set name="xxx"
/system ntp client
set enabled=yes
/system routerboard settings
set enter-setup-on=delete-key

With that in mind, I just want to implement the rule/filter:

Chain=forward
Dst. Address=192.168.1.18
Protocol=6 (tcp)
Dst. Port=80
Action=accept

Would that be all I require in order to achive my goal, and how/where do I implement it without “interferring” with any ISP set rules?

Thanks in advance!

Then you need to be careful else you’ll lose WebFig access from inside the LAN.


In. Interface=sfp-sfpplus1 {not entirely sure here, but since that’s the “top level” entry point of the internet it would make sense?}

This is what saves you. It distinguishes connections to port 80 from the Internet as needing to be handled differently than those from the LAN.


how/where do I implement it without “interferring” with any ISP set rules?

I doubt it matters. As you can see in the fourth packet flow diagram here, the dstnat chain is ahead of everything else. Rules are evaluated in the order given, but within the chains they occur in. You could probably put this rule in last and it’d still end up running first since there are no other dstnat rules defined.

Config, firewall in particular, uses in-interface=pppoe-out1. So it’s probably the best to use it in your DST NAT rule as well.

First things first.
I am not happy to see this rule in the input chain.
add action=accept chain=input comment=“allow IP from WAN” in-interface=
pppoe-out1 log-prefix=_allowWAN src-address-list=AllowWAN

I understand the need to be able to config the router remotely but this method is a security recipe for trouble.
You already have multiple VPN rules, so enter the router through an existing tunnel and configure the router via VPN
and get rid of this rule…

Secondly, probably my ass for MKX, the dst-nat rule needs to have the correct determinant, matching of the appropriate interface, and yes absolutely
in-interface being the name of the pppoe interface is bang on. If that same interface was identified as part of the WAN interface list, one could use that alternatively.
If, however, one wanted local users also to use the Public IP or affiliated domain name, then we are getting into hairpin nat territory and different strategies would be required including modifying the default forward chain rule and creating different dst-nat rule structures.

Aside, not normally required to insert the source address of lans subnet(s) in masquerade rule (it can be unnecessarily limiting) … were you expecting incoming VPN users to use your internet??