用URL重写曲线解决二级域名带端口的解析问题

现状

服务器A,公网IP,运行IIS,和一个80端口的web服务(网站A),该网站必须使用https,且在网站上配置了URL重写,自动将http转换为https。

服务器B,无公网IP,在80端口运行web服务(网站B),该网站无需https。

二级域名a.xx.cn已经指向网站A。

需求

希望增加二级域名b.xx.cn,不带有任何端口后缀,直接解析到网站B,同时不影响原来网站A的运行。

这里主要有两个困难:

1、服务器B无法从公网直接访问。

2、域名解析只可能到IP,不可能指定端口。

方案

1、服务器A与服务器B通过Zerotier加入同一个虚拟内网。

2、服务器A通过自带的netsh interface portproxy命令,将8080端口映射至服务器B的80端口。

3、如果IIS没有URL重写模块,到此处下载安装:https://www.iis.net/downloads/microsoft/url-rewrite

4、服务器A上的IIS中,安装“应用请求路由”组件。安装程序下载网址:https://www.iis.net/downloads/microsoft/application-request-routing

5、服务器A中,在IIS的服务器层启用“应用请求路由”的“服务器代理”,并在服务器层(注意不是网站层)添加URL重写,将包含“b.xx.cn”的请求,重写至a.xx.cn:8080。

模式匹配:^(.*)$
条件设置:对条件{HTTP_HOST},匹配:^(https?:\/\/)?(www\.)?b\.xx\.cn([\/\w\.-]*)*\/?$
重写URL:http://a.xx.cn:8080/{R:1}

其中,{R:1}确保了网址的后半部分不被遗漏。

此时,由于服务器层的URL重写比网站层的URL重写更为前置,所以http://b.xx.cn的请求首先被重写至http://a.xx.cn:8080。不匹配b.xx.cn的其他请求,则仍然被服务器A的网站A处理,并自动转换为https请求。

这样做的一大好处是,本质上用户访问的是a.xx.cn:8080,但网址上始终显示的是b.xx.cn,非常圆满且高大上。

由于b.xx.cn支持任意后缀直接访问,该方案显著优于域名解析服务提供的显式或隐式url转发。后者只是一个网站首页的敲门砖,用途非常有限,随便点个链接就暴露端口,非常不环保。

强迫症患者自此得到了极大的满足。