您在思考信息如何在TCP / IP协议堆栈的各层之间(尤其是在DNS和应用程序层协议之间)流动的过程中陷入了混乱。
您有一个公用IP地址。您的DNS肯定能同时解决mail.example.com
,并example.com
以相同的公网IP地址。
通常,包含对公共IP地址的请求的IP数据报将由防火墙的外部接口接收,不包含远程客户端尝试访问的主机的名称。您的防火墙无法神奇地“知道”远程客户端解析的主机名,因为两个主机名都解析为相同的IP地址。IP层不知道在应用程序层使用的主机名。
TCP和UDP协议使用端口号区分主机提供的特定服务。以您的示例为例,在发送入站TCP端口的同时,可以使用NAT防火墙的端口转发(也称为端口地址转换或PAT)功能将传入TCP端口80(HTTP)的请求发送到Web服务器25(SMTP)发送到您的电子邮件服务器。
但是,如果您计划在两台计算机上托管相同的服务,则此策略会出现问题。假设您要同时在Web服务器上托管一个安全网站(用于访问客户)和在电子邮件服务器上托管一个安全网站(用于Webmail)。到达NAT防火墙的公共IP地址到TCP端口443(HTTPS)的请求只能路由到一台服务器或另一台服务器。
针对这种情况的通用解决方案是拥有更多的公共IP地址。由于IPv4地址越来越稀缺,因此也可能会出现问题。
我们最终在应用程序层的某些协议中解决了公共IP地址的短缺问题。例如,HTTP / 1.1 Host:
专门添加了标头,以允许Web服务器在同一公共IP地址上托管多个网站。TLS添加了服务器名称指示(SNI)扩展名,以允许根据远程客户端输入的主机名选择适当的证书。
在应用程序层中执行这种解决方法意味着每个应用程序层协议都将需要其自己的“修补程序”(然后所有服务器和客户端软件都必须实现该“修补程序”)。这是一个很高的要求。
代替修改应用程序层协议,某些协议易于使用可以“路由”请求的软件在多个主机之间“多路复用”。这可能超出了简单NAT防火墙的能力,因为需要在应用程序层检查数据包。对于HTTP协议,使用像nginx这样的反向代理是这种“复用”(或Microsoft环境中Forefront TMG或ISA Server上的Web发布规则)的一个很好的例子。从理论上讲,任何协议都可以通过反向代理进行多路复用,但是协议越深奥,您谈论编写自定义代码的可能性就越大。
当您需要在一个公共IP地址上从两个不同的主机提供相同的服务时,您始终可以选择将其中一个主机移至非标准端口。但是,这将要求客户端知道非标准端口。对于HTTP(S),这将导致URL带有http://example.com:XXX
符号(其中XXX
是非标准端口号)。这只有在您自己决定的情况下才是问题所在。(我的经验表明,几乎没有最终用户能够处理:XXX
他们必须手动输入的任何URL中的端口符号。)