dstnat in conflict with gre over IPsec tunnel

Hi, I would ask you for advice and help. I already tried to search information/solution by myself, but I sucked.
Issue is this:
I have defined dstant for webserver - its port 80 and 443 forwarded from internet to server inside (for example 192.168.121.40/24), its fine and working.
I have establishd also site-to-site IPsec tunnel with another wan network on Mikrotik, its fine and working.

But, when I try to connect to any other server inside network on port 80 over IPsec tunnel its hijacked by dstnat rule and connection land on webserver.
I read its normal because of packet header over IPsec.
So I implement GRE interface over IPsec tunnel, but it doesn´t work out of box, I mean gre over IPses is working correctly but traffic to 80 and 443 port is still hijacked by dstnat rule.

What magic do I need to aply to fix this? Pls help me. I can provide /export, but I don´t think its needed, I need to understand general priciple of solution for this issue.

Thank you ,)

The action=dst-nat rule must match on additional criteria in order to distinguish the traffic coming in via the WAN from the internet from the traffic coming in via the GRE tunnel. If you make the rule match on in-interface=the-wan-interface-name, it won’t match on packets coming in via the GRE interface. Or you may omit the GRE tunnel and let the rule match on ipsec-policy=in,none - if you do so, the rule will not match on packets that came in via WAN but encapsulated in IPsec.

I undestand, your solution is doable, but than i will not be albe to acces webserver itself over IPsec.
What is good practice? I can not just acces webserver via lan IP because its nginix with virtual blocks, so I need to reach it via forwarded ports with ppublic IP.
You can say, that I should use public just for this server, but I can not to afford it because I have only one public IP and need it for several other purposes.
Is there any smart workaround?
I hoped you will answer my question, I read through forum and I realized you are a smart guy ,)

I can provide /export help, but I don´t think its needed wanted

Its high level answer I do not understand ,)

Buy for yourself a Palantír,
you don’t want us to use ours?


I can provide help, but I do not think it is wanted

Come on, I admit I did not use technical speak you are right magic will not help, but hopefully there is a some kind of proper solution,
Imagine this: one side of tunnel have ports 80,443 forwarded to local server and also another machines running services on these ports 80,443 (no problem if accesing localy or from interrnet). And you have antoher network connected over gre/IPsec and you want to acces webserver itself as wel as other machines, what is a proper solution for this?

I still don’t get what are your expectations and why the additional selectivity of the dstnat rule is not sufficient.

My understanding was that requests coming from the internet via WAN outside any VPN tunnel should be redirected to a particular web server A, whereas requests coming inside the VPN tunnel to the same ports should not be redirected anywhere, thus allowing to access the same TCP ports (80 and/or 443) on the IP addresses to which they have been sent. In this arrangement, you can access the web server A via the VPN exactly the same way like any of the other servers, by sending the request to the private IP of server A.

If you want to send requests to server A using its public IP even via the VPN tunnel, it is enough that the dst-nat rule matches on the public dst-address - if you send a request to any private address, the rule won’t match so the request will not be diverted. Requests to private addresses cannot come via WAN (they actually can if the ISP helps that, but you may still block them).

So as said, I must be missing some point.



/interface bridge
add arp=proxy-arp name=bridge1 protocol-mode=none
add arp=proxy-arp name=bridge2 protocol-mode=none
/interface gre
add allow-fast-path=no local-address=172.16.99.1 name=gre-tunnel1 \
    remote-address=172.16.99.2
/interface ethernet switch port
set 0 default-vlan-id=0
set 1 default-vlan-id=0
set 2 default-vlan-id=0
set 3 default-vlan-id=0
set 4 default-vlan-id=0
set 5 default-vlan-id=0
set 6 default-vlan-id=0
set 7 default-vlan-id=0
set 8 default-vlan-id=0
set 9 default-vlan-id=0
set 10 default-vlan-id=0
set 11 default-vlan-id=0
/interface list
add name=WAN
add name=LAN
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
add authentication-types=wpa2-psk eap-methods="" mode=dynamic-keys name=\
    WPA2_DOGE supplicant-identity=""
add authentication-types=wpa2-psk eap-methods="" mode=dynamic-keys name=\
    WPA2_ELEPHANT supplicant-identity=""
/interface wireless
set [ find default-name=wlan1 ] band=5ghz-onlyac country="czech republic" \
    mode=ap-bridge security-profile=WPA2_DOGE ssid=doge wireless-protocol=\
    802.11
set [ find default-name=wlan2 ] band=2ghz-onlyn country="czech republic" \
    disabled=no mode=ap-bridge security-profile=WPA2_DOGE ssid=doge \
    wireless-protocol=802.11 wps-mode=disabled
add disabled=no keepalive-frames=disabled mac-address=0A:55:31:A7:DF:50 \
    master-interface=wlan2 multicast-buffering=disabled name=wlan3 \
    security-profile=WPA2_ELEPHANT ssid=elephant wds-cost-range=0 \
    wds-default-cost=0 wps-mode=disabled
/ip ipsec profile
add dh-group=modp2048 dpd-interval=1m enc-algorithm=aes-128 name=\
    profile_envi-pur
add dh-group=modp2048 dpd-interval=1m enc-algorithm=aes-128 name=profile_sa
add dh-group=modp2048 name=test
/ip ipsec peer
add address=193.85.247.170/32 name=test profile=test
add address=193.85.247.170/32 disabled=yes name=envi-pur profile=\
    profile_envi-pur
add address=185.52.173.182/32 name=sa profile=profile_sa \
    send-initial-contact=no
/ip ipsec proposal
add enc-algorithms="aes-256-cbc,aes-256-ctr,aes-192-cbc,aes-192-ctr,aes-128-cb\
    c,aes-128-ctr,3des" name=proposal_envi-pur pfs-group=modp1536
add enc-algorithms="aes-256-cbc,aes-256-ctr,aes-192-cbc,aes-192-ctr,aes-128-cb\
    c,aes-128-ctr,3des" name=proposal_sa pfs-group=modp1536
add enc-algorithms=aes-256-cbc,aes-192-cbc name=test
/ip pool
add name=dhcp ranges=192.168.121.2-192.168.121.90
add name=hoste-pool ranges=192.168.131.2-192.168.131.29
add name=ovpn-pool ranges=10.121.0.2-10.121.0.50
/ip dhcp-server
add add-arp=yes address-pool=dhcp disabled=no interface=bridge1 lease-time=1d \
    name=server1
add add-arp=yes address-pool=hoste-pool disabled=no interface=bridge2 \
    lease-time=1d name=server2
/ppp profile
add dns-server=192.168.121.1 local-address=10.121.0.1 name=ovpn_fanix \
    remote-address=ovpn-pool wins-server=192.168.121.50
/queue simple
add disabled=yes max-limit=64k/64k name=queue1 target=192.168.121.6/32
add disabled=yes max-limit=64k/64k name=queue2 target=192.168.121.11/32
add max-limit=512k/512k name=queue3 target=192.168.131.0/24
/user group
set read policy="local,telnet,ssh,reboot,read,test,winbox,api,romon,tikapp,!ft\
    p,!write,!policy,!password,!web,!sniff,!sensitive,!dude"
/interface bridge port
add bridge=bridge1 interface=ether2
add bridge=bridge1 interface=ether3
add bridge=bridge1 interface=ether4
add bridge=bridge2 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
add bridge=bridge1 interface=wlan1
add bridge=bridge1 interface=wlan2
add bridge=bridge2 interface=wlan3
/ip settings
set rp-filter=strict
/interface l2tp-server server
set use-ipsec=yes
/interface list member
add interface=ether1 list=WAN
add interface=bridge1 list=LAN
/interface ovpn-server server
set auth=sha1 certificate=ovpn-srv-fanix cipher=aes256 default-profile=\
    ovpn_fanix enabled=yes require-client-certificate=yes
/ip address
add address=10.7.125.134/30 comment=WAN interface=ether1 network=10.7.125.132
add address=192.168.121.1/24 comment=LAN interface=bridge1 network=\
    192.168.121.0
add address=192.168.131.1/24 comment=hoste interface=bridge2 network=\
    192.168.131.0
add address=172.16.99.1/30 interface=gre-tunnel1 network=172.16.99.0
/ip dhcp-server network
add address=192.168.121.0/24 dns-server=192.168.121.71 gateway=192.168.121.1 \
    ntp-server=192.168.121.1 wins-server=192.168.121.50
add address=192.168.131.0/24 dns-server=8.8.8.8 gateway=192.168.131.1 \
    ntp-server=89.221.218.101
/ip dns
set allow-remote-requests=yes servers=192.168.121.71,1.1.1.1,8.8.8.8
/ip firewall address-list
add address=cz.pool.ntp.org list=NTP
add address=pool.ntp.org list=NTP
add address=192.168.1.0/24 comment="envi-pur LAN" list=LAN
add address=192.168.121.0/24 comment="home LAN" list=LAN
add address=192.168.251.0/24 comment="envi-pur server LAN" list=LAN
add address=192.168.10.0/24 comment="sa LAN" list=LAN
add address=cloud.mikrotik.com list=ALLOWED_IP
add address=wtfismyip.com list=ALLOWED_IP
add address=cloud2.mikrotik.com list=ALLOWED_IP
add address=upgrade.mikrotik.com list=ALLOWED_IP
/ip firewall filter
add action=accept chain=input comment=ovpn dst-port=1194 protocol=tcp
add action=drop chain=input dst-port=53 in-interface=ether1 protocol=udp
add action=drop chain=input dst-port=53 in-interface=ether1 protocol=tcp
add action=drop chain=input comment=Shumkov_BL in-interface=ether1 \
    log-prefix=Shumkov_BL src-address-list=blacklist
add action=drop chain=input comment=\
    "Drop all traffic from addresses in My_BL" log=yes log-prefix=My_BL \
    src-address-list=My_BL
add action=accept chain=input comment=icmp protocol=icmp
add action=accept chain=input comment=IPsec dst-port=500,4500 protocol=udp
add action=accept chain=input comment=IPsec protocol=gre
add action=accept chain=input comment=IPsec protocol=ipsec-esp
add action=accept chain=input comment=NTP src-address-list=NTP
add action=accept chain=input comment=\
    "Allow access to the router from the LAN address list" src-address-list=\
    LAN
add action=accept chain=input comment=\
    "Allow access to the router from the ALLOWED_IP address list" \
    src-address-list=ALLOWED_IP
add action=accept chain=input comment=\
    "Allow established and related connections to the router" \
    connection-state=established,related
add action=accept chain=input comment=Winbox dst-port=8290 protocol=tcp
add action=accept chain=input comment="Webfig - https" dst-port=8080 \
    protocol=tcp
add action=drop chain=input comment="Drop all other traffic to the router" \
    disabled=yes log-prefix=DISABLED_INPUT
add action=drop chain=forward comment="block z87-a" disabled=yes src-address=\
    192.168.121.6
add action=drop chain=forward comment="J\E1chym mobil (wlan)" disabled=yes \
    src-address=192.168.121.11
add action=drop chain=forward comment="Drop invalid connections" \
    connection-state=invalid log-prefix=INVALID_TRAFFIC
add action=drop chain=forward comment=Shumkov_BL log=yes log-prefix=\
    Shumkov_BL src-address-list=blacklist
add action=drop chain=forward comment=Shumkov_BL dst-address-list=blacklist \
    log=yes log-prefix=Shumkov_BL
add action=drop chain=forward comment="guest lan separation" dst-address=\
    192.168.121.0/24 log-prefix=GUEST_LAN src-address=192.168.131.0/24
add action=drop chain=forward comment=My_BL log=yes log-prefix=My_BL \
    src-address-list=My_BL
add action=drop chain=forward comment=My_BL dst-address-list=My_BL log=yes \
    log-prefix=My_BL
add action=fasttrack-connection chain=forward connection-mark=!ipsec \
    connection-state=established,related disabled=yes
add action=accept chain=forward comment=\
    "Allow established and related connections" connection-state=\
    established,related
add action=accept chain=forward comment="Allow new connections from the LAN" \
    connection-state=new src-address-list=LAN
add action=accept chain=forward comment=\
    "Allow new connections from the all ppp" connection-state=new \
    in-interface=all-ppp
add action=accept chain=forward comment=\
    "Allow new connections from the guest LAN" connection-state=new \
    src-address=192.168.131.0/24
add action=accept chain=forward comment=webserver dst-port=80,443 protocol=\
    tcp
add action=accept chain=forward comment=Minecraft dst-port=25565,25566 \
    protocol=tcp
add action=accept chain=forward comment=qBittorrent dst-port=6881 protocol=\
    tcp
add action=accept chain=forward comment=qBittorrent dst-port=6881 protocol=\
    udp
add action=drop chain=forward comment=\
    "Drop all other traffic through the router" disabled=yes log-prefix=\
    DISABLED_FORWARD
/ip firewall mangle
add action=mark-connection chain=forward comment=\
    "mark out ipsec connections to exclude them from fasttrack" ipsec-policy=\
    out,ipsec new-connection-mark=ipsec passthrough=yes
add action=mark-connection chain=forward comment=\
    "mark in ipsec connections to exclude them from fasttrack" ipsec-policy=\
    in,ipsec new-connection-mark=ipsec passthrough=yes
/ip firewall nat
add action=dst-nat chain=dstnat disabled=yes in-interface=gre-tunnel1 \
    to-addresses=192.168.121.0/24
add action=masquerade chain=srcnat comment="hairpin NAT" disabled=yes \
    dst-address=192.168.121.0/24 src-address=192.168.121.0/24
add action=netmap chain=srcnat comment="hairpin NAT with NETMAP" disabled=yes \
    dst-address=192.168.121.0/24 src-address=192.168.121.0/24 to-addresses=\
    10.168.188.0/24
add action=accept chain=srcnat comment="envi-pur LAN" dst-address=\
    192.168.1.0/24 src-address=192.168.121.0/24
add action=accept chain=srcnat comment="envi-pur server LAN" dst-address=\
    192.168.251.0/24 src-address=192.168.121.0/24
add action=accept chain=srcnat comment="envi-pur kamery LAN" dst-address=\
    192.168.84.0/24 src-address=192.168.121.0/24
add action=accept chain=srcnat comment="sa LAN" dst-address=192.168.10.0/24 \
    src-address=192.168.121.0/24
add action=src-nat chain=srcnat comment="srcnat LAN" src-address=\
    192.168.121.0/24 to-addresses=10.7.125.134
add action=src-nat chain=srcnat comment="srcnat guest LAN" src-address=\
    192.168.131.0/24 to-addresses=10.7.125.134
add action=dst-nat chain=dstnat comment="Minecraft mc.fanix.cz" dst-port=\
    25565 in-interface=ether1 protocol=tcp to-addresses=192.168.121.50 \
    to-ports=25565
add action=dst-nat chain=dstnat comment="Minecraft z87-a" dst-port=25566 \
    in-interface=ether1 protocol=tcp to-addresses=192.168.121.6 to-ports=\
    25566
add action=dst-nat chain=dstnat comment="Minecraft Dynmap" disabled=yes \
    dst-port=8123 in-interface=ether1 protocol=tcp to-addresses=\
    192.168.121.50 to-ports=8123
add action=dst-nat chain=dstnat comment=webserver dst-port=80 in-interface=\
    ether1 log=yes protocol=tcp to-addresses=192.168.121.40 to-ports=80
add action=dst-nat chain=dstnat comment="webserver - https" dst-port=443 \
    in-interface=ether1 log=yes protocol=tcp to-addresses=192.168.121.40 \
    to-ports=443
add action=dst-nat chain=dstnat comment=qBittorrent dst-port=6881 \
    in-interface=ether1 protocol=tcp to-addresses=192.168.121.1 to-ports=6881
add action=dst-nat chain=dstnat comment=qBittorrent dst-port=6881 \
    in-interface=ether1 protocol=udp to-addresses=192.168.121.1 to-ports=6881
/ip firewall service-port
set ftp disabled=yes
set tftp disabled=yes
set irc disabled=yes
set h323 disabled=yes
set sip disabled=yes
set pptp disabled=yes
set udplite disabled=yes
set dccp disabled=yes
set sctp disabled=yes
/ip ipsec identity
add peer=envi-pur
add peer=sa
add peer=test
/ip ipsec policy
add comment="home LAN to envi-pur LAN" disabled=yes dst-address=\
    192.168.1.0/24 peer=envi-pur proposal=proposal_envi-pur src-address=\
    192.168.121.0/24 tunnel=yes
add comment="home LAN to envi-pur kamery LAN" disabled=yes dst-address=\
    192.168.84.0/24 peer=envi-pur proposal=proposal_envi-pur src-address=\
    192.168.121.0/24 tunnel=yes
add comment="home LAN to envi-pur server LAN" disabled=yes dst-address=\
    192.168.251.0/24 peer=envi-pur proposal=proposal_envi-pur src-address=\
    192.168.121.0/24 tunnel=yes
add comment="ovpn to envi-pur LAN" disabled=yes dst-address=192.168.1.0/24 \
    peer=envi-pur proposal=proposal_envi-pur src-address=10.121.0.0/24 \
    tunnel=yes
add comment="ovpn to envi-pur kamery LAN" disabled=yes dst-address=\
    192.168.84.0/24 peer=envi-pur proposal=proposal_envi-pur src-address=\
    10.121.0.0/24 tunnel=yes
add comment="ovpn to envi-pur server LAN" disabled=yes dst-address=\
    192.168.251.0/24 peer=envi-pur proposal=proposal_envi-pur src-address=\
    10.121.0.0/24 tunnel=yes
add comment="home LAN to sa" dst-address=192.168.10.0/24 peer=sa proposal=\
    proposal_sa src-address=192.168.121.0/24 tunnel=yes
add comment="ovpn to sa" dst-address=192.168.10.0/24 peer=sa proposal=\
    proposal_sa src-address=10.121.0.0/24 tunnel=yes
add dst-address=172.16.99.2/32 peer=test proposal=test src-address=\
    172.16.99.1/32 tunnel=yes
add comment=test dst-address=192.168.1.0/24 peer=test proposal=test \
    src-address=192.168.121.0/24 tunnel=yes
/ip route
add distance=1 gateway=10.7.125.133
add distance=1 dst-address=192.168.1.0/24 gateway=bridge1
add distance=1 dst-address=192.168.1.0/24 gateway=172.16.99.2
add distance=1 dst-address=192.168.10.0/24 gateway=bridge1
add distance=1 dst-address=192.168.251.0/24 gateway=bridge1
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh disabled=yes
set www-ssl certificate=kavka disabled=no port=8080 tls-version=only-1.2
set api disabled=yes
set winbox port=8290
set api-ssl disabled=yes

Not you, aparently I am missing something and my explanations skilll are not good enough so I am posting configuration export.
Issue is this: from lan 192.168.1.0/24 (it is one site of the gre/IPsec tunnel) I am not able acces local machines in network 192.168.121.0/24 on port 80 (its at the other site of the gre/IPsec tunnel ).
When I disable that dstnat rule:

add action=dst-nat chain=dstnat comment=webserver dst-port=80 in-interface=\
    ether1 log=yes protocol=tcp to-addresses=192.168.121.40 to-ports=80

than I am able to acces othe machines on port 80, but not webserver itself via public DNS name (it has A record at DNS registrator for my public IP)

I I swear on my honor that what I am about to say is not a joke, nor sarcasm, nor a provocation,
but only what I actually think without double entenders, maybe misspelled because I am not a native English speaker.

Your configuration per-se is not complicated, but for follow all reasonong cause me a headache…

Try to add to this rule one missing fields: the Public IP (10.7.125.134 on example below)

# from
add action=dst-nat chain=dstnat dst-port=80 in-interface=ether1 protocol=tcp to-addresses=192.168.121.40 to-ports=80

# to
add action=dst-nat chain=dstnat dst-port=80 in-interface=ether1 protocol=tcp to-addresses=192.168.121.40 to-ports=80 dst-address=10.7.125.134

OK, I start getting it. When you mentioned

it didn’t come to my mind that you were talking about assigning the public IP directly to the web server rather than to the router.

So the solution is to add dst-address=the.public.ip.address to the dst-nat rule as I’ve already suggested above, and not to add any matching on in-interface(-list) or ipsec-policy to it. That way, requests arriving to the public IP will be redirected no matter which way they will get to the router, but requests arriving to the private IPs will not.

Something like this?

# removed in-interface=ether1 added dst-address=10.7.125.134
add action=dst-nat chain=dstnat dst-port=80 protocol=tcp to-addresses=192.168.121.40 to-ports=80 dst-address=10.7.125.134

Yes, both of us came to the same conclusion/solution, let's wait for the OP's reaction :slight_smile:

@sindy, not really, yours is better because I didn’t notice the detail on the in-interface…

@wolfram paste this on terminal (replace the 10.7.125.134 with the correct ether1 IP!!!) and let us know the results, please…

/ip firewall nat
set [find where comment~"webserver"] dst-address=10.7.125.134 !in-interface

Guys thank you very much! You both helped me, now its working :slight_smile:
Last one question because I am curious: will this dstnat configuration also work over raw IPsec (I mean wtihout gre interfaces)?

Yes and I actually used this fix:

# from
add action=dst-nat chain=dstnat dst-port=80 in-interface=ether1 protocol=tcp to-addresses=192.168.121.40 to-ports=80

# to
add action=dst-nat chain=dstnat dst-port=80 in-interface=ether1 protocol=tcp to-addresses=192.168.121.40 to-ports=80 dst-address=10.7.125.134

The right question is: why not?
You simply say with that rule “hijacks all traffic directed to any destination, to port 80 and 443, to another IP”…

directed to any destination = not specify dst-nation :laughing:

So than I do not see any advantages to use gre/IPsec isntead raw IPsec.

For VPN between mikrotik device usually I have 1 public IP on both side and I use EoIP with IPsec (GRE)
The traffic is already encrypted before entering the MikroTik RouterBOARD.

When I can not do directly a link, for example because I do not control the 2nd Router, I’m forced to use the VPN mode provided from that router,
but I do not accept any work where I’m forced to use pptp protocol…

@rextended,
when to use EoIP Ipsec (GRe) vs when to use wireguard??

Actually there are 3 posibilities EoIP tunnel, IP tunnel and GRE tunnel, I am using GRE is there any important differencies or recomendations which one to prefer?