0

In short: Is it possible to access the device/server (without the GW address set in the Network configuration of this device) from outside the device's LAN?

Current setup:

  1. I'm renting an ESXi server with ESXi ports exposed to the internet - the host has its public IP (x.x.x.x). The default GW on ESXi is set to the public IP of the service provider's gateway (i.e., x.x.x.1).
  2. I've additionally set up the ESXi's Management Network to be accessible from the ESXi LAN switch - it's possible to access ESXi from any LAN VM (LAN - 192.168.0.0/24, ESXi LAN-IP 192.168.0.2).
  3. I have pfSense FW installed as the VM (with its public IP on WAN (y.y.y.y), and LAN-IP 192.168.0.1)), so other VMs can access the internet.

Problem: It's not possible to access the ESXi on LAN IP through pfSense (both using port forwarding with NAT or from the OpenVPN network set up on pfSense). I understand that ESXi doesn't have a way to add additional routes to use pfSense FW as the gateway to access specified LAN subnets and ESXi doesn't know how to reply to the address outside ESXi's LAN.

Question: Is there a way to set up the connectivity through pfSense FW (or any other FW/GW as the example) from outside the ESXi-LAN and the host inside the ESXi-LAN without the gateway being set up on the ESXi host's Network setup?

2
  • Yes, it's possible, but the recipient device needs to see only LAN addresses (since it only has route to LAN). So, you have to do double NAT, i.e. translate both source and destination addresses at once. I explained how to do this with Linux several times; sorry, I don't know if it's possible with pfSense. Commented Sep 24, 2023 at 16:04
  • Thanks, @NikitaKipriyanov. I just tried to understand the double NAT, but still can't find appropriate examples and explanations. Is it possible, for you to share a link to the thread you've mentioned? Commented Sep 24, 2023 at 16:23

1 Answer 1

0

(I actually mentioned double NAT several times, but didn't explained in detail. The following is for Linux and will work the same way on Mikrotik RouterOS; I am not sure how to implement this concept on other systems and even if that's possible at all.)

NAT is usually classified as either SNAT or DNAT.

It is called SNAT, "source NAT" is when the source address of the first packet of the flow gets translated (changed) into something else. (Often the source port gets changed too.) Usually this is used to allow all computers in the LAN that uses private (RFC1918) addresses to access public Internet; for that, their addresses are changed to the public address of the NAT box when it routes then away. In addition, it remembers the changes made, that allows to distinguish reply packets and apply the reverse address (and port) replacement for them. But for those internal systems to send packets through our NAT box they need a route trough it in the first place. (They might even not know it performs NAT.)

For example, in Linux:

iptables -t nat -A POSTROUTING -o wan_iface -j MASQUERADE

(MASQUERADE is a SNAT-type rule, just spelled other way and having special logic "translate to whatever address the outgoing interface has".)

DNAT, "destination NAT" is when the system takes the packet and changes its destination address. Usually this is done to "forward" packets to some "internal" system behind the NAT box; for example, one may set up router to forward whatever comes to ports 80 and 443 and was originally destined to the router's IP to change destination IP and forward it further into some web server. The NAT box will detect replies and replace addresses and ports back in them. But, that system will see the original source IP address so it needs a route to that source address of the packet through the NAT box to reply properly.

For example,

iptables -t nat -A PREROUTING -i wan_iface -p tcp --dport 443 -j DNAT --to-destination internal_ip

In both cases, usually the NAT box is set up as a "default gateway", so all systems route packets through it when the remote address is not in the LAN.

But, actually it's not one or another, you may apply both concepts simultaneously. For that, you need to add both rules rules and craft them so they both will match the same packet. Since DNAT rules are processed first, the SNAT rule will see the packet half-translated (destination address and port already changed); this needs to be considered when building a second rule match. An example:

iptables -t nat -A PREROUTING -i wan_iface -p tcp --dport 443 -j DNAT --to-destination internal_ip
iptables -t nat -A POSTROUTING -o lan_iface -p tcp --dport 443 -d internal_ip -j MASQUERADE

Notice that second match checks for the destination address set by the first rule. Also worth mentioning that DNAT rules are typically used with ingress interface and "original" destination IP address filter, and SNAT rules often are used with egress interface and "original" source IP address filter (but not in this example; you probably should add one, read the caveat in the end).

What will happen is that the packet will first get translated according to the first rule and gets its destination address changed to some internal IP. Then, packet gets routed (decided to be forwarded), routed again now the egress interface gets selected, and second rule fires, which changes the source of the IP to the LAN-side address of the router. So now, the system that has the internal IP will receive packet "from the router" and "to itself". So, since the source address now is "in the LAN", it doesn't need a gateway to send reply. Any replies will be properly translated and forwarded back, of course.

The big downside of this is that the internal system has no way to know who really originated the connection; that information is hidden by the gateway. So, the gateway has to tightly filter whose packets it will mangle and pass this way to not allow any malice. There is no way around this if the target system has no set gateway.

Another enhancement could be to assign additional address to the LAN interface of the gateway, precisely to use it in the SNAT rule (-j SNAT --to-source additional_LAN_address instead of -j MASQUERADE). That way, if there are only a few external systems that need to communicate that way, you may assign an "internal" address to each and translate each system into "its" internal address. These addresses will be seen by the target gatewayless system so it will be able to tell whose this packet is.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .