How to realise NAT redirect to LAN client from VPN?

Hello I use RouterOS 6.43 and I have this problem:

My router is connected to 3 networks:

  • WAN - public dynamic IP
  • LAN 192.168.3.0/24
  • VPN (OpenVPN), router IP is 10.1.1.31

I need access to one LAN client with IP 192.168.3.25 via public IP of my VPN network (PUBLIC_VPN_IP) - PUBLIC_VPN_IP:PORT. So I have created iptables DNAT rule on my VPN server:

iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 3641 -j DNAT --to-destination 10.1.1.31

And on my Mikrotik router I created these rules:
table MANGLE:

add action=mark-connection chain=prerouting disabled=no dst-address=10.1.1.31 dst-port=3641 new-connection-mark=int_to_3641 passthrough=no protocol=tcp

table NAT:

add action=dst-nat chain=dstnat disabled=no dst-address=10.1.1.31 dst-port=3641 protocol=tcp to-addresses=192.168.3.25 to-ports=80
add action=masquerade chain=srcnat disabled=no out-interface=ether1
add action=masquerade chain=srcnat connection-mark=int_to_3641 disabled=no

But it does not work. Could you help me please?
Thank you.

You have the masquerade for incoming connections in wrong place, it’s useless on VPN client, it needs to be on VPN server. The problem is when client is e.g. 1.2.3.4, router won’t send replies back via VPN, because as it sees it, route to 1.2.3.4 leads via default route. If you masquerade connections on VPN server, they will all look as from 10.1.1.x and that’s reachable over tunnel.

Problem with the above is that you lose source addresses. If you need your server to see them, you need to skip masquerade completely. Mark new connections coming from tunnel, add another default route in different routing table, and finally mark routing for replies to use the new routing table.

@Sob, many thanks for reply. So
I created masquerade on VPN server.
I changed new-connection-mark=int_to_3641 on mark routing in mangle table.
And I added this ip route:

/ip route add dst-address=0.0.0.0/0 gateway=10.1.1.1 routing-mark=int_to_3641

But it still not work.
Could you help me please what change/add yet?
Thanks.

What @Sob tried to tell you was that the Mikrotik (openvpn client) must “note down” through which interface (WAN or VPN) the request to the dst-nated application server has arrived, and must use that information to assign the routing-mark to the responses of the server. So a mangle rule in chain prerouting must assign a connection-mark to packets towards the server address coming from the VPN interface; as connections are tracked, any further packet belonging to the same connection, regardless the direction, has the connection-mark as a matchable attribute. So another mangle rule in chain prerouting rule then translates the connection-mark into a routing-mark for the response packets sent by the server. Beware - it either must not assign it to further packets from client to server, or you must undo the assignment using /ip route rule, because routing-mark has priority even over connected routes. More details and an example here.

You need only one, masquerade OR routing. And if you choose routing, check PCC example. It’s primarily about load balancing, so ignore that and only focus on the connection and route marking part. I really have to find some better example, but all I keep remembering is this one. And I’m too lazy to write same config again and again. :wink:

That’s why I keep links to my posts on ever recurring themes in my browser’s bookmarks and/or in bookmarks of my forum profile.

Thanks a lot. I am sorry, but I am only beginner with Mikrotik. So my config is:

nat:

chain=dstnat action=dst-nat to-addresses=192.168.3.25 to-ports=80 protocol=tcp dst-address=10.1.1.31 in-interface=ovpn-out1 dst-port=3641 log=yes log-prefix="X1"

mangle:

chain=prerouting action=mark-connection new-connection-mark=int_to_3641 passthrough=no protocol=tcp dst-address=10.1.1.31 in-interface=ovpn-out1 dst-port=3641 log=no log-prefix=""
chain=output action=mark-routing new-routing-mark=to_VPN1 connection-mark=int_to_3641

iproute:

/ip route add dst-address=0.0.0.0/0 gateway=10.1.1.1 routing-mark=to_VPN1 check-gateway=ping

But it still does not work. Where is mistake please?

Almost there, you want prerouting instead of output:

/ip firewall mangle
chain=prerouting in-interface=<server LAN> action=mark-routing new-routing-mark=to_VPN1 connection-mark=int_to_3641

@Sob many thanks, but now I have interesting error on side of web browser (PUBLIC_IP_VPN:3641):

The connection has been reset. (ERR_CONNECTION_RESET).

In Mikrotik log I see that firewall rules are using.

Maťo, do you really need to dstnat twice? I mean, can’t you add a route to 192.168.3.25 already at the openvpn server, and dstnat to that address already there?

@sindy VPN server is outside LAN where is 192.168.3.25 and on this client is not possible directly connection to my VPN. Only Mikrotik router is directly connected to my VPN network. So it seems internet → VPN server → Mikrotik router → client. Btw How do you know my name with accents? :slight_smile:

He’s psychic, he knows everything! (Or maybe it could have something to do with your writing, the order of words, … :slight_smile:)

But back to main topic, rules seem to be ok, so find out what exactly happens. You can add some logging rules, e.g:

/ip firewall mangle
add chain=prerouting protocol=tcp dst-address=10.1.1.31 in-interface=ovpn-out1 dst-port=3641 action=log log-prefix="0"
add chain=prerouting connection-mark=int_to_3641 action=log log-prefix="1"
add chain=forward connection-mark=int_to_3641 action=log log-prefix="2"
add chain=postrouting connection-mark=int_to_3641 action=log log-prefix="3"

Move them to the top and you should see incoming SYN, then SYN,ACK going back, etc.

@Sob thanks, log:
@sindy Are you from Central/Eastern Europe? :slight_smile:

11:09:48 firewall,info 2 forward: in:ovpn-out1 out:bridge, proto TCP (SYN), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:3641->192.
168.3.25:80), len 52 
11:09:48 firewall,info 3 postrouting: in:(unknown 0) out:bridge, proto TCP (SYN), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:3641
->192.168.3.25:80), len 52 
11:09:48 firewall,info 1 prerouting: in:bridge out:(unknown 0), src-mac MAC, proto TCP (SYN,ACK), 192.168.3.25:80->PUBLIC_IP:2659, NAT (192.
168.3.25:80->10.1.1.31:3641)->PUBLIC_IP:2659, len 52 
11:09:48 firewall,info 2 forward: in:bridge out:ovpn-out1, src-mac MAC, proto TCP (SYN,ACK), 192.168.3.25:80->PUBLIC_IP:2659, NAT (192.168.3
.25:80->10.1.1.31:3641)->PUBLIC_IP:2659, len 52 
11:09:48 firewall,info 3 postrouting: in:(unknown 0) out:ovpn-out1, src-mac MAC, proto TCP (SYN,ACK), 192.168.3.25:80->PUBLIC_IP:2659, NAT (
192.168.3.25:80->10.1.1.31:3641)->PUBLIC_IP:2659, len 52 
11:09:48 firewall,info 2 forward: in:ovpn-out1 out:bridge, proto TCP (ACK), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:3641->192.
168.3.25:80), len 40 
11:09:48 firewall,info 3 postrouting: in:(unknown 0) out:bridge, proto TCP (ACK), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:3641
->192.168.3.25:80), len 40 
11:09:48 firewall,info 2 forward: in:ovpn-out1 out:bridge, proto TCP (ACK,PSH), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:3641->
192.168.3.25:80), len 489 
11:09:48 firewall,info 3 postrouting: in:(unknown 0) out:bridge, proto TCP (ACK,PSH), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:
3641->192.168.3.25:80), len 489 
11:09:48 firewall,info 1 prerouting: in:bridge out:(unknown 0), src-mac MAC, proto TCP (ACK), 192.168.3.25:80->PUBLIC_IP:2659, NAT (192.168.
3.25:80->10.1.1.31:3641)->PUBLIC_IP:2659, len 40 
11:09:48 firewall,info 2 forward: in:bridge out:ovpn-out1, src-mac MAC, proto TCP (ACK), 192.168.3.25:80->PUBLIC_IP:2659, NAT (192.168.3.25:
80->10.1.1.31:3641)->PUBLIC_IP:2659, len 40 
11:09:48 firewall,info 3 postrouting: in:(unknown 0) out:ovpn-out1, src-mac MAC, proto TCP (ACK), 192.168.3.25:80->PUBLIC_IP:2659, NAT (192.
168.3.25:80->10.1.1.31:3641)->PUBLIC_IP:2659, len 40 
11:09:48 firewall,info 2 forward: in:ovpn-out1 out:bridge, proto TCP (RST), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:3641->192.
168.3.25:80), len 40 
11:09:48 firewall,info 3 postrouting: in:(unknown 0) out:bridge, proto TCP (RST), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:3641
->192.168.3.25:80), len 40 
11:09:48 firewall,info 2 forward: in:ovpn-out1 out:bridge, proto TCP (ACK,PSH), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:3641->
192.168.3.25:80), len 489 
11:09:48 firewall,info 3 postrouting: in:(unknown 0) out:bridge, proto TCP (ACK,PSH), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:
3641->192.168.3.25:80), len 489 
11:09:48 firewall,info 1 prerouting: in:bridge out:(unknown 0), src-mac MAC, proto TCP (RST), 192.168.3.25:80->PUBLIC_IP:2659, NAT (192.168.
3.25:80->10.1.1.31:3641)->PUBLIC_IP:2659, len 40 
11:09:48 firewall,info 2 forward: in:bridge out:ovpn-out1, src-mac MAC, proto TCP (RST), 192.168.3.25:80->PUBLIC_IP:2659, NAT (192.168.3.25:
80->10.1.1.31:3641)->PUBLIC_IP:2659, len 40 
11:09:48 firewall,info 3 postrouting: in:(unknown 0) out:ovpn-out1, src-mac MAC, proto TCP (RST), 192.168.3.25:80->PUBLIC_IP:2659, NAT (192.
168.3.25:80->10.1.1.31:3641)->PUBLIC_IP:2659, len 40

The log shows that the first RST came from client side:

11:09:48 firewall,info 2 forward: in:ovpn-out1 out:bridge, proto TCP (RST), PUBLIC_IP:2659->192.168.3.25:80, NAT PUBLIC_IP:2659->(10.1.1.31:3641->192.168.3.25:80), len 40

Other than that, there is nothing in the log which would give a clue what has made the client side reset the connection. Be aware that it may not be an activity of the client itself, it can as well be some firewall on the path between the client and the Tik, so the first place I’d sniff next would be the OpenVPN server (tcpdump on both the internet-facing interface and the OpenVPN TAP).

And yes, you’re right about the reason why I could guess the native spelling of your nickname. Sme obaja, ty i ja, made in… (well, sure in my case, not sure in yours :slight_smile: )

@sindy thanks, so I have pcap files, what way is better for share with you?
@sindy in Slovakia :slight_smile: Poznáme sa? :slight_smile:

There is little point in sharing the files, you should be able to see on your own from them whether first RST came from the client side or whether it was the OpenVPN server’s firewall which disliked the connection and sent the RST actively to both sides. If you don’t have Wireshark, tcpdump itself can be used to filter the files:
tcpdump -r file-name.pcap tcp port 3641
should show you something like
18:03:45.219750 IP 192.168.32.26.57013 > 10.155.3.76.5900: Flags [P.], …
You are interested in the source IP address on the very first line where R can be found in the list following the Flags keyword.
The further analysis steps, as always, are to identify the box which has sent the RST (so the next capture point is the client PC), and once you identify it, to find out why it disliked the connection.
A useful hint: Wireshark (tcpdump) always tells you what has happened. Much more rarely it tells you why it has happened. This is a question which only application logs can answer (but yes, sometimes there are none). My personal guess is that some anti-virus software on your PC doesn’t like a TCP connection to a weird port number, but it is nothing more than a guess.

You seem not to know the same song. So I’m a tiny bit further to the west. And none of the three Matos I know is Z.

@sindy Thanks. Of course I have Wireshark. So during sniffing on VPN server tun0 interface:

MY_PUBLIC_IP send TCP SYN to -> 10.1.1.31 
10.1.1.31 -> MY_PUBLIC_IP  (SYN, ACK)
MY_PUBLIC_IP  -> 10.1.1.31 (ACK)
TCP connection is established.
MY_PUBLIC_IP  -> 10.1.1.31 (HTTP GET) still to port 3641
10.1.1.31 -> MY_PUBLIC_IP  (ACK)
And now
MY_PUBLIC_IP  -> 10.1.1.31 send RST. 
MY_PUBLIC_IP  -> 10.1.1.31 (TCP Spurious Retransmission).
10.1.1.31 -> MY_PUBLIC_IP  (RST).

During snffing on VPN server eth0
I see the same only with public IP of my VPN instead of 10.1.1.31. And I see more TCP PSH packets within a connection.
I disabled all security tools on my PC and my colleague tried it too from your PC with the same result. On VPN server is configured iptables, fail2ban and PSAD (both use only iptables rules) I can post here export of my iptables rules.
Any idea please?

I know this song, it occurred to me, but phrase “Sme obaja, ty i ja” is really specific only for Slovak language… So you are from Czech republic :slight_smile: But the song is true because I was born in last year existence of Czechoslovakia, you maybe too :slight_smile: Z is the first letter of my surname. I would send you my full name, but this forum does not support private messages…

From your sniffs and the log taken previously on your 'Tik, it comes out that the client sends its GET, receives an ACK for it (which it may or may not like, there’s still a chance that something is wrong with the contents of that ACK but that’s still what Wireshark should show you (it would be too much for tcpdump, it already needs protocol dissection only available in Wireshark) and then a reset arrives from the client side. But the browser at client PC gives a message which suggests that it has also received the reset, not sent it.

As the reset came from the client side quite fast, prior to any retransmission of the GET, it means that either the ACK has made it to the sender of the RST (whatever it is) or the RST was triggered already by the downstream GET itself. In any case, there is nothing to look for at the OpenVPN server. If you say that you’ve switched off all the security software on the client PC, what remains is some device on the path between the client PC and the OpenVPN’s public address. So as said before, the next capturing point should be the PC itself´to confirm this assumption.

If the “spurious retransmission” after the first RST is actually a retransmission of the GET (check raw packet data and/or the syn and ack values, Wireshark won’t dissect http in a retransmitted packet), it is almost sure that the RST has been sent by something else than the client itself.

PSH packet as such is nothing unusual, TCP is a stream protocol with buffering so PSH is used to tell the receiving side “stop buffering and push what you’ve accumulated in the buffer so far to the application right now”, i.e. in most cases to indicate an end of a PDU carrying a request which needs an immediate response.


The phrase only appears in the song in Slovak so writing it in Czech would not have been a reference to the song :slight_smile:


Private messages on this forum are disabled on purpose, because otherwise everyone would send PMs to Normis :slight_smile:

@sindy during sniffing with Wireshark on my PC and on PC of my colleague (he has other ISP) RST sometimes comes from my VPN server public IP. So it seems:

Successful TCP handshake 
HTTP GET from client
TCP SYN, ACK from VPN server
TCP ACK from client
HTTP GET /robots.txt from client
TCP retransmission from client 
TCP RST from VPN server

I can send you my pcap files.

Good move with this song. :slight_smile: It is a big pity with PMs.

We’re getting very far from Mikrotik. The RST you can see at the client side can be both the one forwarded from the server side as well as one generated by the firewall somewhere between, but the fact that it comes instead of the ACK for the GET, which you could still see at the internet-facing interface of the OpenVPN server, suggests that there is something between the client and the OpenVPN server which sends the reset towards the server in the name of the client and has dropped the ACK in the server->client direction.

You can post the pcap anywhere and place a link to it here, but it will be accessible to everyone, so if you don’t want to leak the public IP of the openvpn server, you’ll have to analyse the ACK packet yourself. It should not be a big deal, though. Just check that the seq and ack numbers properly match the state of the connection after the GET; if they do, the security equipment probably doesn’t like the GET itself, otherwise it may tear down the connection because there is a mistake in the ACK fields; in that case you would have to capture the same connection at all places (the two interfaces of the OpenVPN server, the Mikrotik, and the server) to find out which of those devices has messed the fields.