NAT reflection for DMZ



  • Hey guys,

    I am running pfSense in a configuration with three interfaces (LAN, DMZ, WAN). After having set up several servers in the DMZ and configuring port forwarding from the WAN, I used NAT reflection in order to be able to access them from the LAN the same way as I do from the WAN by only using the domain pointing to the public ip address. Everything seemed fine until I discovered that a service on one server tried to contact another service on the same machine using the domain referring to the WAN's IP. (I don't know why it hasn't been implemented using the loopback address but I have no means to change this.) After spending some time in order to find out what went wrong I discovered that the NAT reflection did only work on the LAN interface.

    Do you know how to also enable NAT reflection on the DMZ?

    I know that NAT reflection is not that popular and sometimes considered to be a dirty hack by some but I can't see a way achieving my goal using a split DNS.

    Thanks in advance for any support provided!



  • @Inperpetuammemoriam:

    Everything seemed fine until I discovered that a service on one server tried to contact another service on the same machine using the domain referring to the WAN's IP.

    If I understand this part correctly, you're saying that the server has a service which is trying to connect to another service running on itself? But it's using the external (WAN) address because the server is set to use external DNS?

    Unless the server needs to access the external address for any other reason, why not add the loopback address to your hosts file on the server, making the loopback resolve to the server's own hostname? The hosts file is consulted before DNS, so this would override the external name resolution.



  • Thank you for your quick reply!

    If I understand this part correctly, you're saying that the server has a service which is trying to connect to another service running on itself?

    Yes, that's correct.

    But it's using the external (WAN) address because the server is set to use external DNS?

    It seems so.

    Unless the server needs to access the external address for any other reason, why not add the loopback address to your hosts file on the server, making the loopback resolve to the server's own hostname? The hosts file is consulted before DNS, so this would override the external name resolution.

    The loopback address is already in "/etc/hosts". I also added the last line to the hosts file and now the server is able to access the service:

    
    127.0.0.1  localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1        localhost localhost.localdomain localhost6 localhost6.localdomain6
    <lan ip="">host.example.org example.org</lan> 
    

    This seems like a quick fix to a misconfigured service. However, if I wanted to change the local IP of that server I would need to change the hosts file again. I would therefore prefer to manage to get it done over NAT reflection.



  • @Inperpetuammemoriam:

    I used NAT reflection in order to be able to access them from the LAN the same way as I do from the WAN by only using the domain pointing to the public ip address. Everything seemed fine until I discovered that a service on one server tried to contact another service on the same machine using the domain referring to the WAN's IP. (I don't know why it hasn't been implemented using the loopback address but I have no means to change this.)

    NAT reflection is not a DNS, so it is not able to translate addresses.

    @Inperpetuammemoriam:

    Do you know how to also enable NAT reflection on the DMZ?

    Have you tried "NAT reflection + Proxy"?



  • NAT reflection is not a DNS, so it is not able to translate addresses.

    That seems obvious. ;-)

    The point is that I want to access all the services hosted on different local machines through the exactly the same placeholder ("example.org"). Using port forwarding I can simply redirect requests to the corresponding machines. However, without NAT reflection I wouldn't be able access the ports on the WAN side if I was on the LAN or the DMZ.

    Have you tried "NAT reflection + Proxy"?

    I honestly do not know what "NAT reflection + Proxy" does compared to "Pure NAT". I would be glad if someone could tell me.



  • From the pfSense book (which no self-respecting pfSense user should be without)…

    Enable (NAT + Proxy) The NAT + proxy mode uses a helper program to send packets to the target of the
    port forward. It is useful in setups where the interface and/or gateway IP used for communication
    with the target cannot be accurately determined at the time the rules are loaded. Reflection rules
    are not created for ranges larger than 500 ports and will not be used for more than 1000 ports total
    between all port forwards. This mode does not work reliably with UDP, only with TCP. Because this
    is a proxy, the source address of the traffic, as seen by the server, is the firewall’s IP address closest
    to the server.

    Enable (Pure NAT) The pure NAT mode uses a set of NAT rules to direct packets to the target of the
    port forward. It has better scalability, but it must be possible to accurately determine the interface
    and gateway IP used for communication with the target at the time the rules are loaded. There are no
    inherent limits to the number of ports other than the limits of the protocols. All protocols available
    for port forwards are supported. If you choose this option, and your servers are on the same subnet
    as your clients, you will also need to check Enable automatic outbound NAT for Reflection a few
    options down the page from here.



  • @KOM:

    From the pfSense book (which no self-respecting pfSense user should be without)…

    Enable (NAT + Proxy) The NAT + proxy mode uses a helper program to send packets to the target of the
    port forward. It is useful in setups where the interface and/or gateway IP used for communication
    with the target cannot be accurately determined at the time the rules are loaded. Reflection rules
    are not created for ranges larger than 500 ports and will not be used for more than 1000 ports total
    between all port forwards. This mode does not work reliably with UDP, only with TCP. Because this
    is a proxy, the source address of the traffic, as seen by the server, is the firewall’s IP address closest
    to the server.

    Enable (Pure NAT) The pure NAT mode uses a set of NAT rules to direct packets to the target of the
    port forward. It has better scalability, but it must be possible to accurately determine the interface
    and gateway IP used for communication with the target at the time the rules are loaded. There are no
    inherent limits to the number of ports other than the limits of the protocols. All protocols available
    for port forwards are supported. If you choose this option, and your servers are on the same subnet
    as your clients, you will also need to check Enable automatic outbound NAT for Reflection a few
    options down the page from here.

    Thanks for pasting the definitions!

    After reading them I still can't see how using "NAT + Proxy" could solve my problem, especially when reading that only TCP works reliably… (I don't want to solve a problem by creating another one) From what I understand of it, shouldn't I be able to achieve reflection for the DMZ using "Pure NAT"?



  • I can't see a way achieving my goal using a split DNS.

    Why not?


  • LAYER 8 Global Moderator

    "(I don't know why it hasn't been implemented using the loopback address"

    Well if your using its fqdn to access itself, you don't have loopback using that address, so no it would never work anyway.  change your hostfile to resolve its own fqdn to loopback and that should fix that problem.

    Just as adding its fqdn for its lan IP works…  Other issue with the service maybe not listening on loopback?  Not all services do.  So even if you modify your loopback address in host file it might not work?

    I am with KOM why do you not just setup a host override to point whatever fqdn your trying to resolve to resolve to its lan IP vs its public IP..  This correct way to do it.. Nat reflection to just talk to yourself - how does that make sense?  Why send packets over the wire through the firewall just to come back??



  • Why not?

    I don't want to use FQDNs to access servers from the outside. I also prefer not have my DNS server listening on the WAN interface. (Maybe I'm a bit paranoid but isn't it better to reduce the number of open doors?)

    I know that this solution seems a bit strange since in fact the problem is caused by the server, not the firewall. The thing is that I would like to fix this using the firewall since there probably will be a fix for this in the service's upcoming releases and I don't want to touch the server's configuration files too much. As I don't want to use a split DNS, I also need the NAT reflection in order to have a harmonised URL for the LAN and the WAN.

    Following the log file on the server, the service is trying to connect to the domain (without a host specified) using the port assigned for HTTPS:

    
    Unable to connect to ssl://example.org:443.
    
    

  • LAYER 8 Global Moderator

    huh???  what do you think example.org is?  that is a fqdn, will should really be something.example.org but example.org works just setup an override in pfsense dns.  Does your client use for dns?  Does it not point to pfsense dns, or whatever you local dns is just create a record for example.org so resolve the internal IP for your internal clients.

    Not sure what any of that would have to do with running dns on pfsense on the wan?

    I think this a lack of understanding here..  so if I am outside and I use https://example.org I sure wouldn't need to use :443 on the end since that is the default ssl/tls port.  Also are you just using IPs on the outside to access stuff that you foward in or does a user on the public net just do http://1.2.3.4 ??

    A split dns just means that you resolve a fqdn (fully qualified domain name or something.example.org) to different IP then the rest of the planet or other people using a different name server, etc.

    So if your using names to access something there is no need to resolve that to your public when the actual device resides on your local network so just resolve it to the local IP.  There are no extra doors that are open here to the outside or information leakage even.



  • huh???  what do you think example.org is?  that is a fqdn […]

    There has been a misunderstanding. I thought that an FQDN also had to have the "host" part.

    Does your client use for dns?  Does it not point to pfsense dns, or whatever you local dns is just create a record for example.org so resolve the internal IP for your internal clients.

    The DNS Server is listening on LAN and DMZ. The problem is that there are multiple machines listening on "example.org" and, as far as I know, the DNS system doesn't care about ports. (I might assign "example.org" to one of them but what about the others?) How should an internal client find the right machine then?

    I think this a lack of understanding here..

    Probably. ;-)

    so if I am outside and I use https://example.org I sure wouldn't need to use :443 on the end since that is the default ssl/tls port.

    This is true but in either way I won't be able to connect the server, if the port is not open.

    Also are you just using IPs on the outside to access stuff that you foward in or does a user on the public net just do http://1.2.3.4 ??

    I'm not sure what you are trying to ask me. Both, users from outside and inside, should be able to access the same server when using "http://example.org" or "http://<wan_ip>".

    A split dns just means that you resolve a fqdn (fully qualified domain name or something.example.org) to different IP then the rest of the planet or other people using a different name server, etc.

    To avoid potential misunderstandings: A split DNS configuration just overwrites the public DNS, right?

    There are no extra doors that are open here to the outside or information leakage even.

    Good to know! ;-)</wan_ip>


  • LAYER 8 Global Moderator

    "A split DNS configuration just overwrites the public DNS, right?"

    A split dns does NOTHING to the public dns.. You just resolving something locally to its local IP vs asking the public name server for the public IP..  If you consider that overwriting then ok..

    "Both, users from outside and inside, should be able to access the same server when using "http://example.org" or "http://<wan_ip>"."

    Why would a user inside need to use the WAN IP??  When the server is local.. Why don't they just go to http://LAN_IP  but yes a user on the outside going to http://example.org resolves that to 1.2.3.4  it hits the wan of your router, your router forwards it to 192.168.1.100 for example..  With split dns a user on your network say 192.168.1.99 hits http://example.org it resolves to 192.168.1.100 vs 1.2.3.4

    "The problem is that there are multiple machines listening on "example.org""

    How would that be.. you mean you have example.org points to 1.2.3.4 but the user has to use http://example.org:81 and you forward 81 to the right server 192.168.1.101 vs .100???

    That is broken from the get go..  If you can not get multiple public IPs to match up to your private then you should use a reverse proxy to forward to specific private IP based on the name so hostA.example.org goes to .100 and hostB.example.org goes to .101

    This way user never has to use :portnumber anywhere..  and you have hostA and hostB all resolve to 1.2.3.4 on the public side, but internally resolve to 192.168.1.100 for hostA and 192.168.1.101 for hostB</wan_ip>



  • @Inperpetuammemoriam:

    This seems like a quick fix to a misconfigured service. However, if I wanted to change the local IP of that server I would need to change the hosts file again. I would therefore prefer to manage to get it done over NAT reflection.

    If you changed the local IP of the server you'd need to amend your NAT reflection settings anyway, so I'm not sure why this is a problem.

    You seem concerned about avoiding split DNS for some reason, though it's a little hard to see why. Split DNS simply resolves internal hosts for internal hosts using external domain names matched to internal IP addresses, but doesn't affect your external DNS at all as far as the outside world is concerned. If split DNS isn't your thing, then what about just a host override?

    There are quite a few perfectly valid options you're choosing to discard, almost all of them preferable to using NAT reflection.



  • Why would a user inside need to use the WAN IP??  When the server is local.. Why don't they just go to http://LAN_IP  but yes a user on the outside going to http://example.org resolves that to 1.2.3.4  it hits the wan of your router, your router forwards it to 192.168.1.100 for example..  With split dns a user on your network say 192.168.1.99 hits http://example.org it resolves to 192.168.1.100 vs 1.2.3.4

    Let me give you an example: I have a mobile device (laptop, smartphone, etc.) that connects to one server for a file hosting service and to another for VOIP. If I assign "example.org" inside the network I will have to use FQDNs (hostname+domainname) in order to be able to distinguish between the servers. The problem is that if I then go outside of the network, I will not be able to resolve the servers' locations using the same FQDN, except for web servers when using a reverse proxy. (See below)

    How would that be.. you mean you have example.org points to 1.2.3.4 but the user has to use http://example.org:81 and you forward 81 to the right server 192.168.1.101 vs .100???

    Exaclty. Port 80 may be forwarded to one server (192.168.1.100) whereas port 5060 may be forwarded to another (192.168.1.101). Having different machines for independent services makes maintenance much easier and safer.

    That is broken from the get go..  If you can not get multiple public IPs to match up to your private then you should use a reverse proxy to forward to specific private IP based on the name so hostA.example.org goes to .100 and hostB.example.org goes to .101

    This way user never has to use :portnumber anywhere..  and you have hostA and hostB all resolve to 1.2.3.4 on the public side, but internally resolve to 192.168.1.100 for hostA and 192.168.1.101 for hostB

    Don't only think about web servers. I agree with you that most users find it annoying to be forced to also enter the right port when browsing, but no one really cares about that when it comes to entering the ports to access your mail server, for example. I already tried a reverse proxy configuration once (Squid?) but I abandoned it because of decreased system stability and the poor outcome.



  • If you changed the local IP of the server you'd need to amend your NAT reflection settings anyway, so I'm not sure why this is a problem.

    There is one device less to configure since NAT will always need reconfiguration in this case. Not changing the server's configuration enables me with the possibility to just copy it and paste it to another preconfigured network. (Think of a testing network with different address configuration from where machines are copied and pasted to the live network)

    You seem concerned about avoiding split DNS for some reason, though it's a little hard to see why. Split DNS simply resolves internal hosts for internal hosts using external domain names matched to internal IP addresses, but doesn't affect your external DNS at all as far as the outside world is concerned. If split DNS isn't your thing, then what about just a host override?

    Split DNS doesn't work if the criterion is to use the same placeholder ("example.org") to access distinct servers in the DMZ from LAN and from WAN.

    There are quite a few perfectly valid options you're choosing to discard, almost all of them preferable to using NAT reflection.

    I agree that, concerning the traffic that stays in the DMZ, it is nothing more than a dirty fix but for the traffic from the other interfaces i don't see a major overhead.


  • LAYER 8 Global Moderator

    And again use of same fqdn to acess different servers is BROKE idea right out of the gate.  Good luck with such nonsense



  • @johnpoz:

    And again use of same fqdn to acess different servers is BROKE idea right out of the gate.  Good luck with such nonsense

    Please explain why it is. Up to now I can't see a technical reason confirming your point.

    Did I make clear for what reasons I can't use a reverse proxy? Do you see no advantage in having independent services running on independent machines?


  • LAYER 8 Global Moderator

    you don't see a problem with using the same name for multiple machines??  Really??

    If you can not run a reverse proxy, and your limited to 1 public IP then still use fqdn to point to the machine on the outside..

    So you have hosta.example.com point to 1.2.3.4 on outside, hostb.example.com point to 1.2.3.4 on outside

    If you want to run the same services on these that use the same port, with your limitation of 1 pubic IP then yes you can use different ports so

    hosta.example.com:portA  hostb.example.com:portB  on the outside those point to your 1.2.3.4 address

    On the inside
    hosta.example.com points to privateAdddressA and hostb points to pirvateaddressB, etc..  Problem solved users on outside can use the same url http://hosta.example.com:port as the users on the inside.  Just with split dns uses on outside resolve to your public and your forward forwards to correct private via teh port being used.  On the inside the uri points directly to the machine in use.  And does not have to reflect of anything.

    No matter what if your private side server changes IPs you would have to change the port forward anyway.

    Your trying to leverage a work around of only having 1 public IP by using different ports to get to your multiple private IPs…  When in a real setup you would have different public IPs for your multiple services you wanted to run on the outside that used the same port.


Log in to reply