前言

公司 IIS7 服务器之前使用的是泛域名解析,购买了通配证书,解析出一些分站和图片服务器、移动端等。显然通配证书太贵,之后就只针对主域名 www.xxx.com 购买免费的 DVSSL 证书(原赛门铁克)。之前发现了 https 网站加载 http 资源在 Chrome 浏览器下会自动转化为加载 https 资源,因 https 资源不存在而加载失败的情况。详见:图片资源加载失败,报错:net::ERR_CERT_COMMON_NAME_INVALID 问题解决。因为使用单独的图片域名访问图片资源,而图片域名未添加 SSL 证书,所以在 Chrome 下资源全部加载失败。唯一的办法就是配置图片域名的 SSL 证书。

通过 IIS 左侧最高一级菜单下找到服务器证书,并成功导入了从阿里云下载的 pfx 证书后,选择图片服务站进行绑定 https 时,弹出了警告的对话框:“至少一个其他网站正在使用 HTTPS,而此绑定用另一个证书配置。确定要重用此 HTTPS 绑定并将其他网站重新指定为使用新证书吗”。意思是当前的 IIS 服务器只能用一个 HTTPS 绑定,使用一个证书配置。如果点击确定了,那么主站也会用这个图片服务器的证书,而这个证书不通配,显然会造成主站无法访问的结果。

探索

网上找到两种解决方案,一种是 Windows 2012 IIS 8.5 部署多个 SSL 证书绑定 https,一种是 iis7 绑定多个域名证书

第一个方案是针对 IIS 8.5 的,高版本对这个问题有了解决方法。在绑定 https 弹框中,主机名可以修改,并且多了一个“需要服务器名称指示(N)” 的勾选框。在需要绑定多个 https 时,填写主机名,第一个不需要勾选“需要服务器名称指示(N)”,从第二个绑定HTTPS的开始勾选即可解决。

第二个方案比较对应,同属于 IIS7。主要是通过修改 C:/Windows/system32/inetsrv/config/applicationHost.config 虚拟主机配置文件来解决 443 主机名不可修改的问题。大体就是找到第一个 https 域名绑定所在位置:

...
<bindings>
    <binding protocol="http" bindingInformation="*:80:web1.web.com" />
    <binding protocol="https" bindingInformation="*:443:" />
</bindings>
...

他举的例子是 web1.web.com, 在第一条 443 端口后面加上绑定的主机名:

...
<bindings>
    <binding protocol="http" bindingInformation="*:80:web1.web.com" />
    <binding protocol="https" bindingInformation="*:443:web1.web.com" />
</bindings>
...

cmd 命令行先 iisreset /stop 关闭 IIS7 服务后,保存上面修改的配置,然后再在命令行中输入 iisreset /start 开启 IIS7 服务。测试发现第一个 https 域名绑定列表上确实显示出了主机名(之前是不可编辑的):

IIS 网站绑定
IIS 网站绑定

之后是导入第二个 https 域名证书。默认导入的证书显示别称是 alias,这需要修改一下,以便第二个证书绑定时可以填写主机名(也可以方便列表查找)。

Win + r 打开运行窗口,输入 mmc 打开控制台根节点,想要操作的证书项需要通过 文件 -> 添加/删除管理单元 -> 选择弹框左侧证书项添加 -> 确认后选择计算机账户然后一直到完成,这时才会出现在控制台更节点下。点开 个人 -> 证书 可以看到服务器上添加的所有证书列表,这些与 IIS 服务器上服务器证书列表一致,只是这里可以修改友好别称。选中证书,右键属性,弹出菜单中修改友好别称项,将之修改为 *.xx.xx。比如第二个 https 需要绑定的主机名是 loveu.seasidecrab.com,则修改为 *.seasidecrab.com。这里其实说明了一个可以修改绑定 https 主机名的方法,那就是将证书的友好别称改成 *.xx.xx此时添加 https 绑定时,选择 *.xx.xx 别称的证书,主机名就可以修改了。

但即便是这样,填写了第二个的主机名,点击确定时依然弹出了那个确认警告:“至少一个其他网站正在使用 HTTPS...”。

尝试过直接修改配置文件,将两个 https 绑定项 443 后分别加上主机名,然后启动 IIS7 服务。两个 https 站点的 https 绑定列表中,主机名一栏显示已修改成功,但第二个 https 默认绑定的是第一个 https 的证书。再去修改绑定证书,依然会提示那个警告。

所以方案二也不可行,至少使用同一一级域名的子域名不可行。

最后看到一个阿里云的教程:在服务器的同一IP地址和端口中绑定多站点但证书不匹配。标题比较拗口,但意思就是绑定多域名(主机名)SSL 证书不匹配。文章中给了 4 条针对 IIS 服务器的解决方案:

  • 绑定到多端口
  • 绑定到多IP地址
  • 通配证书
  • 升级 IIS

多端口的方案早就被废弃了,测试或后台可以这么搞,对外提供服务访问不适合加端口。多 IP 对于使用阿里云服务器也不太现实(公司暂时没有扩充服务器的计划)。通配证书是之前采用的,现在被废弃的,显然短时间内也不会再去启用。那么只有最后一项升级 IIS 服务器了。

将 IIS 版本升级到 IIS8,IIS8 中支持 SNI(Server Name Indication)功能,服务器可以从请求中提取出相应的主机头从而获取相应的证书。关于 SNI 的开启方式请参见 SSL Scalability。

好嘛,绕了一圈,又绕到了方案一。高版本 IIS 自己解决了这个问题,但我是不敢升级 IIS7 的(非专业运维,没必要吃力不讨好),那么就搁着吧!

PS:小小的思考了一下,升级 IIS8 方案里说是通过从请求中提取相应的主机头从而获取相应的证书,但我采用方案二修改主机配置的方法,将两个主机名都手动修改了,为什么没有自动获取相应的证书呢?还是说 IIS8 的时候才支持这样的功能?