dstnat rule executed on egress traffic

Hello everyone,

At the last couple of weeks im working on wordpress site in my local lab, the site got to situation when i want to get others opinions so i had “port forward” any ingress traffic from WAN with dst-port 8080 using the following dstnat rule

 
 #masquerade  is shown for your information.
 0    ;;; defconf: masquerade 
      chain=srcnat action=masquerade out-interface-list=WAN log=no log-prefix="mesqu" ipsec-policy=out,none
 1    ;;; enable remote access to wordpress
      chain=dstnat action=dst-nat to-addresses=192.168.88.35 to-ports=8080 protocol=tcp dst-port=8080 log-prefix=""

Later that day i’ve found that my IPTV stops work when trying to zapping channels, i’ve started to debug the communication of my streamer and found that the my streamer (ip 88.10) start session with IPTV server on port 80 then 8080 and then for some reason trying to communicate with wordpress server (ip 88.35) on port 8080 which on same subnet.

      1 0.000000       192.168.88.10         212.150.225.64        TCP      74     54538 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=4204672 TSecr=0 WS=64
      2 0.043196       192.168.88.10         224.0.0.251           MDNS     443    Modified by pacmen
      3 0.212710       192.168.88.10         194.90.120.134        TCP      74     39330 → 8080 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=4204736 TSecr=0 WS=64
      4 0.213260       192.168.88.35         192.168.88.10         TCP      74     8080 → 39330 [SYN, ACK] Seq=0 Ack=1 Win=65160 Len=0 MSS=1460 SACK_PERM=1 TSval=2344763495 TSecr=4204736 WS=128
      5 0.216328       192.168.88.10         192.168.88.35         TCP      56     39330 → 8080 [RST] Seq=1 Win=0 Len=0
      6 1.895825       192.168.88.10         212.150.225.64        TCP      74     54542 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=4205240 TSecr=0 WS=64
      7 2.906893       192.168.88.10         212.150.225.64        TCP      74     [TCP Retransmission] 54542 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=4205544 TSecr=0 WS=64
      8 4.266561       192.168.88.10         194.90.120.134        TCP      74     [TCP Retransmission] 39330 → 8080 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=4205952 TSecr=0 WS=64
      9 4.267134       192.168.88.35         192.168.88.10         TCP      74     [TCP Previous segment not captured] [TCP Port numbers reused] 8080 → 39330 [SYN, ACK] Seq=63343454 Ack=1 Win=65160 Len=0 MSS=1460 SACK_PERM=1 TSval=2344767549 TSecr=4205952 WS=128
     10 4.269848       192.168.88.10         192.168.88.35         TCP      56     39330 → 8080 [RST] Seq=1 Win=0 Len=0
     11 5.120036       192.168.88.10         212.150.225.64        TCP      74     [TCP Retransmission] 54542 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=4206208 TSecr=0 WS=64
     12 5.586699       192.168.88.10         104.199.64.255        SSL      77     Continuation Data

So I’ve figured it as something to do with my new nat rule but I didn’t understard why, i disable the dstnat rule and recorded working session initialization.

|Time     | 192.168.88.10                         |
|         |                   | 194.90.120.134    |                   
|0.000000 |         39616 → 8080 [SYN] S          |TCP: 39616 → 8080 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=4391776 TSecr=0 WS=64
|         |(39616)  ------------------>  (8080)   |
|0.005902 |         8080 → 39616 [SYN, A          |TCP: 8080 → 39616 [SYN, ACK] Seq=0 Ack=1 Win=4380 Len=0 MSS=1460 TSval=2599415847 TSecr=4391776 SACK_PERM=1
|         |(39616)  <------------------  (8080)   |
|0.008820 |         39616 → 8080 [ACK] S          |TCP: 39616 → 8080 [ACK] Seq=1 Ack=1 Win=65535 Len=0 TSval=4391778 TSecr=2599415847
|         |(39616)  ------------------>  (8080)   |
|0.012245 |         GET /ngx/out/u/12_pr          |HTTP: GET /ngx/path/to/index.m3u8?smil_profile=androidtv_4k&token=sometokenandotherinfo HTTP/1.1 
|         |(39616)  ------------------>  (8080)   |
|0.018035 |         8080 → 39616 [ACK] S          |TCP: 8080 → 39616 [ACK] Seq=1 Ack=260 Win=4639 Len=0 TSval=2599415859 TSecr=4391779
|         |(39616)  <------------------  (8080)   |
|0.068688 |         HTTP/1.1 302 Found            |HTTP: HTTP/1.1 302 Found 
|         |(39616)  <------------------  (8080)   |
|0.072245 |         39616 → 8080 [ACK] S          |TCP: 39616 → 8080 [ACK] Seq=260 Ack=336 Win=65535 Len=0 TSval=4391797 TSecr=2599415910
|         |(39616)  ------------------>  (8080)   |
|0.073067 |         39616 → 8080 [FIN, A          |TCP: 39616 → 8080 [FIN, ACK] Seq=260 Ack=336 Win=65535 Len=0 TSval=4391797 TSecr=2599415910
|         |(39616)  ------------------>  (8080)   |
|0.078760 |         8080 → 39616 [ACK] S          |TCP: 8080 → 39616 [ACK] Seq=336 Ack=261 Win=4639 Len=0 TSval=2599415920 TSecr=4391797
|         |(39616)  <------------------  (8080)   |
|0.079257 |         8080 → 39616 [FIN, A          |TCP: 8080 → 39616 [FIN, ACK] Seq=336 Ack=261 Win=4639 Len=0 TSval=2599415920 TSecr=4391797
|         |(39616)  <------------------  (8080)   |
|0.080738 |         39616 → 8080 [ACK] S          |TCP: 39616 → 8080 [ACK] Seq=261 Ack=337 Win=21729 Len=0 TSval=4391800 TSecr=2599415920
|         |(39616)  ------------------>  (8080)   |

If you confused as i do i still kept the best.
I enabled the wordpress dstnat rule again and also log activity when this rule is executed (hited) and got the following when zapping again.

17:38:10 firewall,info dstnat: in:bridge out:(unknown 0), src-mac e0:b6:55:ea:32:e6, proto TCP (SYN), 192.168.88.10:36788->194.90.120.134:8080, len 60

Which to my eyes looks like that the rule is also executed when a egress traffic tries to get out of the nat thats what redirect my streamer to my wordpress server, although this rule is dstnat chain which from my understanding applies to traffic originated from the WAN towards the LAN wordpress server so it shouldn’t be executed.

I managed to solve this issue by applying ‘in-interface=wan’ which makes my confusion grow.

 1    ;;; enable remote access to wordpress
      chain=dstnat action=dst-nat to-addresses=192.168.88.35 to-ports=8080 protocol=tcp in-interface=Port 1 - Wan dst-port=8080 log=yes log-prefix=""

I’ve post this issue as i’ve looked at the firewall wiki and according to what i’ve read there, i got confused as following results.
Would appreciate if you could put some sense
model: 2011iL
firmware-type: ar9344
factory-firmware: 3.10
current-firmware: 6.46.5
upgrade-firmware: 6.46.5

Post your complete config as snippets never reveal the true picture…
/export hide-sensitive file=anynameyouwish

also is your WANIP static or dynamic??

The dst-nat rule you created is too greedy. Here’s translation of the rule to english: take any packet passing router in any direction whose dst-port equals 8080 and pass it to IP address 192.168.88.35 to port 8080.
I guess you want it in plain words like this: take any packet arriving at any of WAN interfaces whose dst-port equals 8080 and pass it to IP address 192.168.88.35 to port 8080.

In ROSish the missing part of dst-nat rule is “in-interface-list=WAN” …

My ip is dynamic.



According to what you saying here you completely right and i understand it.
According to the wiki, i get little bit confuse, https://wiki.mikrotik.com/wiki/Manual:IP/Firewall/NAT

destination NAT or dstnat. This type of NAT is performed on packets that are destined to the natted network. It is most comonly used to make hosts on a private network to be acceesible from the Internet. A NAT router performing dstnat replaces the destination IP address of an IP packet as it travel through the router towards a private network.

Which the wiki basically make a clear separation between ‘‘dstnat chain’’ to ‘‘srcnat chain’’ to my understanding, it means.
srcnat - (Egress packets) - packet originated on LAN towards the WAN (LAN → WAN) of course i don’t forget the address translation process.
dstnat - (Ingress packet) - packet coming from the WAN towards the LAN (WAN → LAN).
so if the dstnat chain is packet originating from WAN (ingress) i doesn’t have to specify from which interface the packet would come from since its clear that it come from the WAN.

Anyway thanks for taking your time on me!

Your understanding is wrong. src-nat is mangling the src-address and src-port … while dst-nat is mangling dst-address and dst-port.

NAT has no notion of LAN or WAN. Remember, ROS is highly versatile, capable of running many networks and conceptually none of them are LAN or WAN. Sure, in default config there are interface lists named LAN and WAN and you can use them in NAT rules as part of connection matching criteria … but it doesn’t affect the way src-nat and dst-nat are operating. Actually the term “NATed network” from wiki only gets defined by matching criteria of NAT rule itself.

By that you mean ROS looking on the src part of the packet when using src-nat, and on the dst address when using dst-nat?

Exactly.


Which by itself makes rule half-baked. Luckily default setup makes firewall statefull (by enabling connection tracking) and the rest of work is done by an extremely useful pair of filter rules:


add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
add action=accept chain=forward comment="defconf: accept established,related, untracked" connection-state=established,related,untracked

(actually there’s a third one matching the second one in the above pair, but with action=fasttrack-connection which doesn’t change to basic concept of firewall, it only improves performance).
The above quoted rules take care of any packets which belong to connections with state of established, related or untracked. And this rule, in addition to “forward” packets, takes care of packets, belonging to the same connection, but with src- and dst- fields reversed. If there weren’t these rules, it would be extremely hard to create meaningful and yet safe filter rules to deal with reverse packets.