Access internal webserver over site2site-VPN tunnel

Hi,

I am working for hours on this problem and dont find a solution. I hope anybody can help.

I have multible sites with dynamic IPs (mikrotik routers), all connected to a central VPN-Server with a static IP (mikrotik chr on vps l2tp and ipsec combined). This solution works.
Every site connects directly to the internet for internet access. Only vpn traffic for access private lans runs over the vpn-tunnel.

My webserver runs on a virtual machine on site A in a private subnet. Now I want to access my website on this server over the static IP on my central site (VPS).
Important ist to use the static ip of the VPS. The traffic should run through the vpn tunnel or outside via nat from central site to the dynamic ip of site a. Both ways are possible.

NAT the traffic from static ip to dynamic ip is not really possible, because I can only use a static ip as destination.

I tried dst-nat from static IP central site to destination ip, but this doesnt work, because of the default route for public ips is the direkt Link of SiteA zu the internet.
I tried dst-nat from static IP with masquerade to the IP address of siteA l2tp tunnel and than dst-nat from IP siteA l2tp to the internal IP of the webserver, but it doesnd work.

Any ideas for me. In the attachment you can see the structure. Thanks

Mario
infrastructure.JPG

It is true that you can forward connection-establishing packets from clients in the internet, which come the static public IP of the CHR, a) to the current public IP of the router in front of your web server (so outside the tunnel) or b) to the server’s private address (so inside the tunnel). But you also have to ensure that the responses to the clients will arrive from the public IP of the CHR, and this is impossible to achieve in case a).

The point is that the TCP session is identified by the quadruple of (client-side IP, client-side port, server-side IP, server-side port) and if the client receives the response from a different IP:port than to which it has sent the request, it will not recognize it as a response to the request and will drop it, and so will do any firewalls between the client and the internet. And in case a), the request from client will be redirected to the current public IP of the router in front of the server, but you cannot route the response through the CHR outside the tunnel without losing the actual address of the client (which is the destination address in the response packet, so once you rewrite it by CHR’s address to force the packet through the CHR, the CHR has no way to restore it). And as more data is likely to flow from the server to the client, there is no point in routing the client requests outside the tunnel.

So it only makes sense to deal with case b). Your existing routing on the CHR knows the route to server’s private address via the tunnel, so a dst-nat rule from CHR’s public IP to the server’s private one (and the firewall filter allowing the dst-nated packet to be forwarded) are all you need on the CHR.

On the server’s router, however, you need to make sure that responses to connection requests coming via the VPN tunnel will be routed through the tunnel although the default route is through the regular WAN. This can only be achieved using connection-based policy routing which is explained in this post; start reading it from the last paragraph which will explain the link to your case. If it is not clear from there, komm zurück :wink:

If you can afford to dedicate a local interface and a dedicated VPN tunnel for the access to the server from the internet, you can also replace the above approach by a VRF setup, where the dedicated VPN tunnel and the local interface dedicated for the server would share a common routing instance (a vrf-assigned routing-mark). In fact this approach may turn out equally complex as the above as soon as you start thinking about management access to the server, but the advantage of this approach is that you can use fasttracking on the server’s router, so if it’s throughput becomes the bottleneck, take this way.

EDIT: of course you can also simply src-nat the packets from the clients to the server at the CHR to force the responses back through the CHR, but this would mean that the server would see all client’s connections as coming from the CHR itself which most people want to avoid, so I neglected this approach.

Hi Sindy,

thank you very much for that detailed repley. I have to read it more than once to understand. :wink: unfortunately i did not get it working.

Maybe you can help me, here is the detailed config. (relevant parts)

Internal adress of the webserver on site-B site i want to reach: 192.168.180.24
Tunnel configuration: “IPSec in L2TP-Tunnel” (site-B has no static ip)
For forwarding the traffic from CHR to site-B I use the L2TP-Tunnel (unfortunately not through the ipsec tunnel, this is another problem with routing - i will change that later)
CHR L2TP-Tunnel IP: 192.168.171.1
site-B L2TP-Tunnel IP: 192.168.171.2

CHR-Router:

ip firewall filter
chain=forward action=accept protocol=tcp dst-address=192.168.180.24 in-interface=ether1-wan dst-port=443,80 log=no log-prefix=“”

ip firewall nat
chain=dstnat action=dst-nat to-addresses=192.168.180.24 to-ports=80 protocol=tcp dst-address=[public ip chr] dst-port=80 log=no log-prefix=“”
chain=dstnat action=dst-nat to-addresses=192.168.180.24 to-ports=443 protocol=tcp dst-address=[public ip chr] dst-port=443 log=no log-prefix=“”

ip route
distance=1 dst-address=192.168.180.0/24 gateway=192.168.171.2

site-B router:

ip firewall filter
chain=forward action=accept protocol=tcp dst-address=192.168.180.24 in-interface=L2TP-Client-to-CHR dst-port=80,443 log=no log-prefix=“”
chain=forward action=accept protocol=tcp src-address=192.168.180.24 out-interface=L2TP-Client-to-CHR src-port=80,443 log=no log-prefix=“”

ip firewall mangle
chain=prerouting action=mark-connection new-connection-mark=CHR2webserver passthrough=no protocol=tcp dst-address=192.168.180.24 dst-port=80 log=yes log-prefix=“ConnMark-CHR2webserver”
chain=prerouting action=mark-connection new-connection-mark=CHR2webserver passthrough=no protocol=tcp dst-address=192.168.180.24 dst-port=443 log=yes log-prefix=“ConnMark-CHR2webserver”

ip route
add comment=“PBR nach CHR” distance=1 gateway=192.168.171.1 routing-mark=CHR2webserver

I can see in the log of site-B the incomming traffic (log=yes log-prefix=“ConnMark-CHR2webserver” ).
I have several rules for loging firewall drops on both sites, with the rules above i cant see any drops.

Thank you very much for your help.

Kind regards
Mario

“relevant parts” of not working config are usually not where the problem is hidden. It’s the parts which you think are irrelevant what is important :slight_smile:


That’s the first part which sounds suspicious. When you say “IPSec in L2TP tunnel”, it sounds like “(payload in IPsec) in L2TP”, which has only disadvantages - namely, the fact that IPsec policy has to be used to redirect packets into the tunnel instead of the normal routing tables. The usual way is “L2TP tunnel encrypted using IPsec”, i.e. the encapsulation hierarchy is “(payload in L2TP) in IPsec”. In this case, you can use the L2TP interfaces in the regular routing and don’t need to bother with IPsec policies at all (except if you need to use individual IPsec settings to transport the L2TP packets and cannot use the IPsec setup auto-created by RouterOS for the L2TP).

Other than that, it seems you’ve replaced the public IP of the CHR in one rule but forgot to do it in the other one, so better edit the post.

In any case, show the complete configurations (anonymized as hinted in my automatic signature below), as I’m afraid chances are high that there are hidden issues in the “unrelated” part of the configuration.