Firewall – Exposing multiple servers behind NAT using a single public IP address

domain-name-systemfirewallnat;networking

This is a Canonical Question about NAT and DNS

I'm currently trying to set up a network with a DMZ containing a web server and an e-mail server separated from the Internet by a network address translating (NAT) firewall.

I have installed the NAT firewall with the following interfaces:

WAN - x.x.x.x (redacted public IP address)
DMZ - 192.168.124.5/24
LAN - 192.168.123.5/24

On my DMZ I have my two hosts:

Web server - 192.168.124.30
E-mail server - 192.168.124.32

I know that I will need to configure the DNS for the example.com domain to resolve both example.com and mail.example.com to my public IP address.

I would like my NAT firewall to forward all incoming requests to example.com to the web server at 192.168.124.30, and all incoming requests to mail.example.com to the e-mail server at 192.168.124.32. I see a "port forwarding" feature in my NAT firewall's configuration but can't seem to achieve what I'm looking for.

Best Answer

You're getting muddled in your thinking about how information flows between the layers of the TCP/IP protocol stack-- between DNS and application layer protocols, specifically.

You have one public IP address. Your DNS can certainly resolve both mail.example.com and example.com to the same public IP address.

In general, the IP datagrams containing requests to your public IP address, which will be received by the external interface of your firewall, don't contain the name of the host the remote client is attempting to access. Your firewall can't magically "know" which hostname the remote client resolved, since both hostnames resolve to the same IP address. The IP layer isn't aware of the hostname used at the application layer.

The TCP and UDP protocols differentiate specific services offered by a host using port numbers. In the case of your example it may be possible to use the port forwarding (also called port address translation, or PAT) feature of your NAT firewall to send incoming requests to TCP port 80 (HTTP) to the web server while sending inbound TCP port 25 (SMTP) to your email server.

If, however, you plan to host the same service on both machines then this strategy becomes problematic. Suppose you are going to host both a secure web site on your web server (for Customer access) and a secure web site on your email server (for webmail). Requests coming to your NAT firewall's public IP address to TCP port 443 (HTTPS) can only be routed to one server or the other.

The generalized solution to this situation is to have more public IP addresses. Because IPv4 addresses are becoming scarce that can also be problematic.

We end up working around the scarcity of public IP addresses in some protocols at the application layer. For example, HTTP/1.1 added the Host: header specifically to allow a web server to host multiple websites on the same public IP address. TLS adds the Server Name Indication (SNI) extension to allow selection of the appropriate certificate based on the hostname entered by the remote client.

Doing this kind of workaround in the application layer means that every application layer protocol would need its own "fix" (and then all the server and client software would have to implement that "fix"). That's a tall order.

In lieu of modifying the application layer protocol some protocols are easily amenable to being "multiplexed" between multiple hosts using software that can "route" requests. This likely goes beyond what a simple NAT firewall is capable of because the packets need to be inspected at the application layer. Using a reverse-proxy like nginx is a good example of this kind of "multiplexing" (or Web publishing rules on Forefront TMG or ISA Server in a Microsoft environment) for the HTTP protocol. In theory any protocol could be multiplexed via a reverse proxy but the more esoteric the protocol the more likely you'd be talking about having custom code written.

When you need to offer the same service from two different hosts on a single public IP address you always have the option to move one of the hosts to a non-standard port. This will require that clients be aware of the non-standard port, however. In the case of HTTP(S) this results in URLs with the http://example.com:XXX notation (where XXX is the non-standard port number). Whether this would be problematic in your situation is something that only you can decide. (My experience has shown that virtually no end users are capable of handling :XXX port notation in any URL they have to hand-enter.)