[v6] dstnat not applying anymore? [solved with hairpin NAT]

SOLVED: September 5, 2023
https://forum.mikrotik.com/viewtopic.php?t=198838#p1023608 discovery
https://forum.mikrotik.com/viewtopic.php?t=179343 solution


This is probably not an issue if you actually, deeply understand how networking works. For the rest of us, here is the setup, the problem, and the solution:

If the below post applies to you, try using a different network, outside of your LAN, to reach the service you’re trying to port-forward. If you can reach the service using your external IP from a network other than your LAN – but you cannot see it using the same IP from within the same LAN as where the server is located, the solution is to apply a hairpin NAT.

The problem: internal traffic takes a different path than external traffic to reach any services you’re exposing through NAT or port-forwarding. As such, LAN traffic hitting the server looks different to the server than expected.

There are many solutions described in places such as https://help.mikrotik.com/docs/display/ROS/NAT#NAT-HairpinNAT and http://forum.mikrotik.com/t/hairpin-nat-the-easy-way/146718/1 – I followed a simpler set of steps as described in https://www.youtube.com/watch?v=_kw_bQyX-3U (as I don’t need dynamic WAN support).

Thanks to everybody that guided me here!



Original post below:
Hey there! Hope everybody’s doing well.

I’m new to the MikroTik ecosystem – I purchased my first device less than 8 or so months ago, and I’ve had no issues with it so far that I couldn’t find help for within a few Google searches. However, I am experiencing some issues recently with port forwarding that I haven’t encountered before.

A quick rundown of my network chain:

  1. Motorola/Arris SB8200
  2. MikroTik hEX S
  3. Netgear RAX54

LAG is enabled on the SB8200, and the MikroTik is paired with a bonded connection (ether1, ether2) to the modem. The RAX54 is in AP-only mode and is connected to the hEX S on ether4. The hEX S is running the latest LTS RouterOS v6.49.8.

In the past I configured the firewall NAT rules (on RouterOS) to publicly expose certain services from one of my LAN devices. The LAN device was connected via ether3 and a static IP to the hEX S. Recently, I’ve had to use a wireless connection for my device instead, which needed some massaging to fix the static IP briefly – but eventually the device fetched the right IP from the router using WiFi as well. However, I can’t seem to get port forwarding to work again. Previously, I had forwarded ports 3000 (some test server) and maybe 25565 (for Minecraft) – but right now, I’m trying to expose just 80 for an HTTP service.

I’m trying to expose 192.168.88.253:80 as <external_ip>:80, and here are the very basic filter and NAT rules that I’ve stripped down to while troubleshooting this issue:

[admin@RouterOS] > /ip firewall filter print
Flags: X - disabled, I - invalid, D - dynamic 
 0  D ;;; special dummy rule to show fasttrack counters
      chain=forward action=passthrough 

 1    ;;; fasttrack: established,related
      chain=forward action=fasttrack-connection connection-state=established,related log=no log-prefix="" 

 2    ;;; accept: established,related
      chain=input action=accept connection-state=established,related log=no log-prefix="" 

 3    ;;; accept: established,related
      chain=forward action=accept connection-state=established,related log=no log-prefix="" 

 4    ;;; drop invalid
      chain=input action=drop connection-state=invalid log=no log-prefix="" 

 5    ;;; drop invalid
      chain=forward action=drop connection-state=invalid log=no log-prefix="" 

 6    ;;; Accept ICMP
      chain=input action=accept protocol=icmp in-interface-list=WAN log=no log-prefix="" 
[admin@RouterOS] > /ip firewall nat print
Flags: X - disabled, I - invalid, D - dynamic 
 0    ;;; defconf: masquerade
      chain=srcnat action=masquerade out-interface-list=WAN ipsec-policy=out,none 

 1    ;;; web server (80)
      chain=dstnat action=dst-nat to-addresses=192.168.88.253 protocol=tcp dst-address=<external_ip> in-interface-list=WAN dst-port=80 log=yes log-prefix="web_server"



I get a filter log hit whenever I use this open port check tool to check port 80 on my external IP like so:

web_server dstnat: in:bonding1 out:(unknown 0), src-mac 00:01:5c:68:68:46, proto TCP (SYN), 198.199.98.246:41692-><external_ip>:80, len 60

but never when I use the browser, and by following some advice in another post here and running

/tool sniffer quick ip-address=<external_ip> port=80

I do see activity whenever I visit my external IP with my browser, so I don’t believe it is my ISP blocking port 80.



Any ideas, tips, or suggestions would be amazing. Thanks for an otherwise wonderful experience!

Why is that relevant or helpful to your question? (Not being snarky; serious question.)

What would be relevant and helpful is if you told us you’d put the modem into bridge mode, without which your modem’s NAT layer is going to prevent RouterOS’s dstnat from doing anything useful at all short of a double-NAT port-forwarding dance.


I’m trying to expose just 80 for an HTTP service.

Have you disabled WebFig? (“/ip/service/disable www”) Without that, one of the two will interfere with the other.

Same goes for the Let’s Encrypt feature that’s useful for getting www-ssl service working. Even though the final service is on another port, the ACME negotiation must occur on port 80 since it must be able to succeed when TLS is not yet working.


[admin@RouterOS] > /ip firewall filter print

>

Much better than posting the output of assorted "print" commands is to show the configuration that yields them [per item B here](https://forum.mikrotik.com/viewtopic.php?p=970629).

If it isn’t, then it’s my inexperience compelling me to provide a “complete enough picture” – from my inexperienced point-of-view.


The SB8200 (the modem I have) isn’t a router, doesn’t offer WiFi, and doesn’t perform any NAT (as far as I know). There is no bridge-mode for my modem.


The only services IP services left enabled at the moment are winbox and api-ssl – everything else is disabled (including www and www-ssl)


Thanks!

# aug/24/2023 21:05:56 by RouterOS 6.49.8
# software id = 45F5-4C1D
#
# model = RB760iGS
# serial number = <removed>
/interface bridge
add admin-mac=<removed> auto-mac=no comment=defconf name=local
/interface bonding
add mode=802.3ad name=bonding1 slaves=ether1,ether2
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/ip pool
add name=dhcp ranges=192.168.88.10-192.168.88.254
/ip dhcp-server
add address-pool=dhcp disabled=no interface=local name=defconf
/interface bridge port
add bridge=local comment=defconf interface=ether3
add bridge=local comment="defconf // Netgear AP" interface=ether4
add bridge=local comment=defconf interface=ether5
add bridge=local comment=defconf interface=sfp1
/ip neighbor discovery-settings
set discover-interface-list=LAN
/interface detect-internet
set detect-interface-list=all
/interface list member
add comment=defconf interface=local list=LAN
add interface=bonding1 list=WAN
/ip address
add address=192.168.88.1/24 comment=defconf interface=local network=\
    192.168.88.0
/ip dhcp-client
add comment=defconf disabled=no interface=bonding1 use-peer-dns=no
/ip dhcp-server lease
add address=192.168.88.254 client-id=1:<removed> comment=NETGEAR \
    mac-address=<removed> server=defconf
add address=192.168.88.251 client-id=1:<removed> mac-address=\
    <removed> server=defconf
add address=192.168.88.250 client-id=1:<removed> mac-address=\
    <removed> server=defconf
add address=192.168.88.253 client-id=1:<removed> mac-address=\
    <removed> server=defconf
/ip dhcp-server network
add address=192.168.88.0/24 comment=defconf gateway=192.168.88.1
/ip dns
set allow-remote-requests=yes servers=1.1.1.1,1.0.0.1,8.8.8.8
/ip firewall filter
add action=fasttrack-connection chain=forward comment=\
    "fasttrack: established,related" connection-state=established,related
add action=accept chain=input comment="accept: established,related" \
    connection-state=established,related
add action=accept chain=forward comment="accept: established,related" \
    connection-state=established,related
add action=drop chain=input comment="drop invalid" connection-state=invalid
add action=drop chain=forward comment="drop invalid" connection-state=invalid
add action=accept chain=input comment="Accept ICMP" in-interface-list=WAN \
    protocol=icmp
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN
add action=dst-nat chain=dstnat comment="web server (80)" dst-address=\
    <removed> dst-port=80 in-interface-list=WAN log=yes log-prefix=\
    web_server protocol=tcp to-addresses=192.168.88.253
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh disabled=yes
set api disabled=yes
/ip upnp
set enabled=yes
/system clock
set time-zone-name=America/Los_Angeles
/system identity
set name=RouterOS
/tool mac-server
set allowed-interface-list=LAN
/tool mac-server mac-winbox
set allowed-interface-list=LAN

I hope this paints a clearer picture of what might be going on.

It looks like a sane configuration to me. You may be right that link aggregation has something to do with why it doesn’t work as expected.

Try naming the bond’s interfaces explicitly in the interface list: “add interface=ether1 list=WAN ; add interface=ether2 list=WAN”.

Alternately, you could try formulating the DSTNAT rule as:


/ip firewall nat
add action=dst-nat chain=dstnat comment="web server (80)" dst-port=80 in-interface=bonding1 protocol=tcp to-addresses=192.168.88.253

Note that you don’t need dst-address to make this work. The in-interface plus the dst-port suffices to avoid false triggers.

If this still doesn’t work, I’d try remapping the port like so:


/ip firewall nat
add action=dst-nat chain=dstnat comment="web server (80)" dst-port=8080 in-interface=bonding1 protocol=tcp to-addresses=192.168.88.253 to-port=80

If connecting to TCP port 8080 now works from the outside, your ISP is likely blocking inbound port 80 connections.

Another item on list of things to blindly try: set /interface detect-internet set detect-interface-list=none

I lost internet connectivity when I did that. Neither direct IP nor google.com worked (same with YouTube and a couple other). Does that seem normal? These were the interface list members at that moment:


/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/interface list member
add comment=defconf interface=local list=LAN
add interface=ether1 list=WAN
add interface=ether2 list=WAN



I’ve removed the dst-address field just to type less, and switched to port 8080 for further testing (and switched the server port to 8080 as well, accessible at 192.168.88.253:8080). Still the same results – regardless of whether I’m using in-interface=bonding1 or in-interface-list=WAN. For example, this doesn’t work:


/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" ipsec-policy=out,none out-interface-list=WAN
add action=dst-nat chain=dstnat comment="web server (80)" dst-port=8080 in-interface=bonding1 log=yes log-prefix=web_server protocol=tcp to-addresses=192.168.88.253



Thanks for chiming in! Still no difference as far as I’m aware :frowning:

Sorry to bump, but I’ve been dealing with this issue since my last post with no change.

Today I reset my router configuration (twice; first without resetting user configurations – once that didn’t fix my port forwarding issue, then again with user configurations reset included). I also tried to disable my input port bonding and using just “ether1” as my WAN interface (not forgetting to include “ether2” as part of the bridge again).

None of the above solutions have worked for me so far, and this is the minimally-edited configuration I have ended up with now (with port bonding re-enabled):


# sep/05/2023 07:50:22 by RouterOS 6.49.8
# software id = 45F5-4C1D
#
# model = RB760iGS
# serial number = <REDACTED>
/interface bridge
add admin-mac=48:A9:8A:18:B7:3F auto-mac=no comment=defconf name=bridge
/interface bonding
add name=bonding1 slaves=ether1,ether2
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/ip hotspot profile
set [ find default=yes ] html-directory=hotspot
/ip pool
add name=default-dhcp ranges=192.168.88.10-192.168.88.254
/ip dhcp-server
add address-pool=default-dhcp disabled=no interface=bridge name=defconf
/interface bridge port
add bridge=bridge comment=defconf disabled=yes interface=ether2
add bridge=bridge comment=defconf interface=ether3
add bridge=bridge comment=defconf interface=ether4
add bridge=bridge comment=defconf interface=ether5
add bridge=bridge comment=defconf interface=sfp1
/ip neighbor discovery-settings
set discover-interface-list=LAN
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=bonding1 list=WAN
/ip address
add address=192.168.88.1/24 comment=defconf interface=bridge network=\
    192.168.88.0
/ip dhcp-client
add comment=defconf disabled=no interface=bonding1 use-peer-dns=no
/ip dhcp-server network
add address=192.168.88.0/24 comment=defconf dns-server=192.168.88.1 gateway=\
    192.168.88.1
/ip dns
set allow-remote-requests=yes servers=1.1.1.1,1.0.0.1,8.8.8.8
/ip dns static
add address=192.168.88.1 comment=defconf name=router.lan
/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 action=accept chain=input comment=\
    "defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" \
    in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" \
    ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
    ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-state=established,related
add action=accept chain=forward comment=\
    "defconf: accept established,related, untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=drop chain=forward comment=\
    "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
    connection-state=new in-interface-list=WAN
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN
add action=dst-nat chain=dstnat dst-port=8080 in-interface-list=WAN protocol=\
    tcp to-addresses=192.168.88.253 to-ports=8080
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh disabled=yes
set api disabled=yes
set winbox address=192.168.88.0/24
/system clock
set time-zone-name=America/Los_Angeles
/tool mac-server
set allowed-interface-list=LAN
/tool mac-server mac-winbox
set allowed-interface-list=LAN

Still trying to access “192.168.88.253:8080” (or 80, for that matter) from my public IP address to no avail.

Unfortunately, my networking knowledge isn’t advanced enough to be able to trace the path any packets are actually taking – but I don’t think my ISP is blocking either port 80 or 8080 as “/tool sniffer quick ip-address=<external_ip> port=” shows some activity whenever I visit sniffed relevant port. Here’s what that output looks like:


ether4                                                                                            5.205     21 <-  A4:B1:C1:34:D2:53 48:A9:8A:18:B7:3F        192.168.88.253:53116                <remote_ip>:8080 (http-alt)      ip:tcp       66   1 no 
bridge                                                                                            5.205     22 <-  A4:B1:C1:34:D2:53 48:A9:8A:18:B7:3F        192.168.88.253:53116                <remote_ip>:8080 (http-alt)      ip:tcp       66   1 no 
bridge                                                                                            5.205     23 ->  48:A9:8A:18:B7:3F A4:B1:C1:34:D2:53        <remote_ip>:8080 (http-alt)      192.168.88.253:53116                ip:tcp       54   1 no 
ether4                                                                                            5.205     24 ->  48:A9:8A:18:B7:3F A4:B1:C1:34:D2:53        <remote_ip>:8080 (http-alt)      192.168.88.253:53116                ip:tcp       54   1 no 
ether4                                                                                            5.488     25 <-  A4:B1:C1:34:D2:53 48:A9:8A:18:B7:3F        192.168.88.253:53115                <remote_ip>:8080 (http-alt)      ip:tcp       66   2 no 
bridge                                                                                            5.488     26 <-  A4:B1:C1:34:D2:53 48:A9:8A:18:B7:3F        192.168.88.253:53115                <remote_ip>:8080 (http-alt)      ip:tcp       66   2 no 
bridge                                                                                            5.488     27 ->  48:A9:8A:18:B7:3F A4:B1:C1:34:D2:53        <remote_ip>:8080 (http-alt)      192.168.88.253:53115                ip:tcp       54   2 no 
ether4                                                                                            5.488     28 ->  48:A9:8A:18:B7:3F A4:B1:C1:34:D2:53        <remote_ip>:8080 (http-alt)      192.168.88.253:53115                ip:tcp       54   2 no 
ether4                                                                                            5.714     29 <-  A4:B1:C1:34:D2:53 48:A9:8A:18:B7:3F        192.168.88.253:53116                <remote_ip>:8080 (http-alt)      ip:tcp       66   1 no 
bridge                                                                                            5.714     30 <-  A4:B1:C1:34:D2:53 48:A9:8A:18:B7:3F        192.168.88.253:53116                <remote_ip>:8080 (http-alt)      ip:tcp       66   1 no 
bridge                                                                                            5.714     31 ->  48:A9:8A:18:B7:3F A4:B1:C1:34:D2:53        <remote_ip>:8080 (http-alt)      192.168.88.253:53116                ip:tcp       54   1 no 
ether4                                                                                            5.714     32 ->  48:A9:8A:18:B7:3F A4:B1:C1:34:D2:53        <remote_ip>:8080 (http-alt)      192.168.88.253:53116                ip:tcp       54   1 no 
ether4                                                                                            5.992     33 <-  A4:B1:C1:34:D2:53 48:A9:8A:18:B7:3F        192.168.88.253:53115                <remote_ip>:8080 (http-alt)      ip:tcp       66   2 no 
bridge                                                                                            5.992     34 <-  A4:B1:C1:34:D2:53 48:A9:8A:18:B7:3F        192.168.88.253:53115                <remote_ip>:8080 (http-alt)      ip:tcp       66   2 no 
bridge                                                                                            5.993     35 ->  48:A9:8A:18:B7:3F A4:B1:C1:34:D2:53        <remote_ip>:8080 (http-alt)      192.168.88.253:53115                ip:tcp       54   2 no 
ether4                                                                                            5.993     36 ->  48:A9:8A:18:B7:3F A4:B1:C1:34:D2:53        <remote_ip>:8080 (http-alt)      192.168.88.253:53115                ip:tcp       54   2 no 
ether4                                                                                            6.226     37 <-  A4:B1:C1:34:D2:53 48:A9:8A:18:B7:3F        192.168.88.253:53116                <remote_ip>:8080 (http-alt)      ip:tcp       66   1 no 
bridge                                                                                            6.226     38 <-  A4:B1:C1:34:D2:53 48:A9:8A:18:B7:3F        192.168.88.253:53116                <remote_ip>:8080 (http-alt)      ip:tcp       66   1 no 
bridge                                                                                            6.226     39 ->  48:A9:8A:18:B7:3F A4:B1:C1:34:D2:53        <remote_ip>:8080 (http-alt)      192.168.88.253:53116                ip:tcp       54   1 no 
ether4                                                                                            6.226     40 ->  48:A9:8A:18:B7:3F A4:B1:C1:34:D2:53        <remote_ip>:8080 (http-alt)      192.168.88.253:53116                ip:tcp       54   1 no

I see that weird “http-alt” identifier and I don’t know what that means, but asides from that I guess it’s fine? I’ve ensured a number of times now that my server is setup to accept non-local connections, and that my AP is indeed in AP mode.

Since I’m able to access the port locally just fine (at “192.168.88.253:8080”), I assume that there are no issues in LAN. Wireshark detects packets sent via LAN but nothing shows up from WAN. Is it safe to assume that the issue is somewhere between the modem → router → access-point? With the access-point and modem performing no NAT, I assume the router is the only thing monitoring and blocking traffic. However, I don’t really know what the AP could be doing after the router, and I don’t know if that’s part of the reason why port forwarding isn’t working for me.

I haven’t been able to take some of this hardware offline, but I will have an opportunity to do so next week – then I can test just the router and modem (without the wireless AP) to see if that resolves the issue. What are my options if that doesn’t fix my issue? What about if it does?

Do you see that rule’s counter increasing in WinBox?

Is the machine at IP 192.168.88.253 in fact listening on TCP 8080, or do you need to say “to-port=80” or similar here?

To my surprise, yes! BUT! Not through the browser – ONLY if I run some type of port checking tool (like https://canyouseeme.org or https://yougetsignal.com/tools/open-ports), I see the rule counter properly increment by 1! These services also detect whether my server is running or not (reporting “open” while running and “closed” otherwise).



I specifically moved from port 80 to 8080 just to test whether this was an issue caused by my ISP. The NAT rule is set to target port 8080 and the service itself is also listening on port 8080 (configured as 0.0.0.0:8080 with a machine IP 192.168.88.253, so “192.168.88.253:8080” is the LAN address).


So, somehow – I can ping my server from an open port checking tool, but I can’t reach it through the browser. I don’t think my server itself would be blocking connections specifically (in fact, it shows successful connections and disconnections from those port checking tools). I know that there’s a difference between listening on the host “127.0.0.1” or “localhost” versus “0.0.0.0” – from what I understand, I have to use “0.0.0.0” in order keep my service publicly accessible, and that’s what I’ve done.

Are you trying to hit your public IP address from within your LAN then?
It sounds like it, but you’ve not exactly been explicit about that.
If so, it’s just a simple “Hairpin NAT” solution that’s required.
Have you tried it from somewhere off the LAN?

Phrases like “when I use the browser” and “through the browser” are not helpful. Tell people where you are connecting FROM.

Son of a *****.

Yes, I’ve been trying to connect to my external IP from within my LAN this whole time. I did NOT know it mattered whether I was connecting from within LAN or not (in this case) – that has never been something I’ve had to contend with while port-forwarding in the past, which I guess is because it was abstracted away from me on other platforms/devices. In hindsight, of course that totally explains why I can see my service from other websites but not from a browser on a device connected to the same LAN.

I just tested the external IP and open port from another internet connection, and yes, it resolves to the correct service as expected. I’m truly sorry that I wasn’t explicit about which network service requests from originating from! That’s just not something I would have even considered otherwise.

After some googling, and reading https://help.mikrotik.com/docs/display/ROS/NAT#NAT-HairpinNAT, http://forum.mikrotik.com/t/hairpin-nat-the-easy-way/146718/1 and watching https://youtu.be/_kw_bQyX-3U?si=1pRgSGSC0UcI-ylO, I setup a very basic NAT rule to allow local connections to use my external IP address. Which worked! Then I added a couple others to test, and they work as well! Here are my working settings:


# sep/05/2023 12:48:07 by RouterOS 6.49.8
# software id = 45F5-4C1D
#
# model = RB760iGS
# serial number = <REDACTED>
/interface bridge
add admin-mac=48:A9:8A:18:B7:3F auto-mac=no comment=defconf name=bridge
/interface bonding
add name=bonding1 slaves=ether1,ether2
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/ip pool
add name=default-dhcp ranges=192.168.88.10-192.168.88.254
/ip dhcp-server
add address-pool=default-dhcp disabled=no interface=bridge name=defconf
/interface bridge port
add bridge=bridge comment=defconf disabled=yes interface=ether2
add bridge=bridge comment=defconf interface=ether3
add bridge=bridge comment=defconf interface=ether4
add bridge=bridge comment=defconf interface=ether5
add bridge=bridge comment=defconf interface=sfp1
/ip neighbor discovery-settings
set discover-interface-list=LAN
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=bonding1 list=WAN
/ip address
add address=192.168.88.1/24 comment=defconf interface=bridge network=\
    192.168.88.0
/ip dhcp-client
add comment=defconf disabled=no interface=bonding1 use-peer-dns=no
/ip dhcp-server network
add address=192.168.88.0/24 comment=defconf dns-server=192.168.88.1 gateway=\
    192.168.88.1
/ip dns
set allow-remote-requests=yes servers=1.1.1.1,1.0.0.1,8.8.8.8
/ip dns static
add address=192.168.88.1 comment=defconf name=router.lan
/ip firewall address-list
add address=<REDACTED> list=WAN_IP
add address=192.168.88.253 list=SERVER
/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 action=accept chain=input comment=\
    "defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" \
    in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" \
    ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
    ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-state=established,related
add action=accept chain=forward comment=\
    "defconf: accept established,related, untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=drop chain=forward comment=\
    "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
    connection-state=new in-interface-list=WAN
/ip firewall nat
add action=masquerade chain=srcnat comment=HairpinNAT dst-address-list=SERVER \
    out-interface-list=LAN protocol=tcp src-address=192.168.88.0/24
add action=masquerade chain=srcnat comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN
add action=dst-nat chain=dstnat comment=Dev.HTTP dst-address-list=WAN_IP \
    dst-port=8080 protocol=tcp to-addresses=192.168.88.253
add action=dst-nat chain=dstnat comment=HTTP dst-address-list=WAN_IP \
    dst-port=80 protocol=tcp to-addresses=192.168.88.253
add action=dst-nat chain=dstnat comment=HTTPS dst-address-list=WAN_IP \
    dst-port=443 protocol=tcp to-addresses=192.168.88.253
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh disabled=yes
set api disabled=yes
set winbox address=192.168.88.0/24
/system clock
set time-zone-name=America/Los_Angeles
/tool mac-server
set allowed-interface-list=LAN
/tool mac-server mac-winbox
set allowed-interface-list=LAN

Thank you very much for your help! I’ll make some edits to the OP containing what I learned and how to solve this – partially for my reference, and partially in-case anybody else stumbles here. Otherwise, feel free to lock this thread or do whatever it is you guys generally do.

I noticed there was some debate on the proper way and the various methods to accomplish this. If there’s a simpler or more complete method than I’ve chosen that might be more useful in my case, please let me know.

Thanks again!

https://forum.mikrotik.com/viewtopic.php?t=179343