我想要使用 IIS 和 SSL 托管一个可以监听子域名(例如 sub.domain.com)的网站以及位于二级域名(例如 domain2.com、domain3.com)下的多个网站。
对于具有子域名的网站,我有一个通配符证书(* .domain.com),并且我还有专门针对其他网站(domain2.com 和 domain3.com)的证书。
这样的设置可以托管在同一个 IIS 上吗(如果重要的话,在 Azure 云服务 Web 角色中)?
问题正是这里解释:理论上,为此我们需要使用 SNI 进行绑定,为 domain2/3.com 指定主机,然后为 *.domain.com 设置一个带有 * 主机的万能网站。但实际上,无论绑定如何设置,如果万能网站已启用,它也会接收对 domain2/3.com 的所有请求(尽管据说它只是作为最后的手段进行匹配)。
任何帮助,将不胜感激。
仍未解决
不幸的是,我无法解决这个问题:似乎只有通过极其复杂的方法才能解决,比如创建一个位于 IIS 和互联网之间的软件(基本上就是防火墙),并修改传入请求(在 SSL 握手发生之前!)以允许这种情况。我确信无论如何,这在 IIS 上都是不可能的,即使是从本机模块也不行。
我必须澄清一下:我们使用 Azure 云服务,因此我们还有一个限制,即不能使用多个 IP 地址(请参阅:http://feedback.azure.com/forums/169386-cloud-services-web-and-worker-role/suggestions/1259311-multiple-ssl-and-domains-to-one-app)。如果您可以将多个 IP 指向您的服务器,那么您就不会遇到此问题,因为您也可以为 IP 创建绑定,并且这些绑定将一起工作通配符绑定。更具体地说,您需要一个用于通配符站点的 IP(但由于您现在有一个单独的 IP,因此您不必配置通配符主机名绑定)和另一个用于所有其他非通配符站点的 IP。
实际上,我们的解决方法是使用非标准 SSL 端口 8443。因此,SNI 绑定实际上绑定到此端口,因此它可以与其他绑定一起使用。虽然不太好,但对我们来说是一种可以接受的解决方法,直到您可以为 Web 角色使用多个 IP。
现在无效的绑定
第一个 https 绑定是带有简单证书的 SNI,第二个不是 SNI,而是带有通配符证书。
http 站点和 SNI https 站点都可以运行,但是使用通配符绑定的站点会出现“HTTP 错误 503。服务不可用。”(没有任何进一步的信息,没有失败请求跟踪或事件日志条目)。
最终让它基本正常工作
按照 Tobias 的描述启用 ETW 跟踪日志后发现根本错误如下:
请求(请求 ID 0xF500000080000008)由于以下原因被拒绝:UrlGroupLookupFailed。
据我了解,这意味着 http.sys 无法将请求路由到任何可用的端点。
检查已注册的端点后netsh http show urlacl
发现,端口 443 上确实注册了某些内容:
Reserved URL : https://IP:443/
User: NT AUTHORITY\NETWORK SERVICE
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;NS)
删除它并netsh http delete urlacl url=https://IP:443/
最终启用我的 SSL 绑定。
答案1
Baris 是对的!在 IP:PORT 绑定上配置的 SSL 证书(例如:100.74.156.187:443)在 http.sys 中始终优先!因此解决方案如下:
不要为您的 wildcard-fallback-certificate 配置 IP:443 绑定,但为其配置 *:443 绑定(* 表示“全部未分配”)。
如果您已经在 Azure 云服务 SSL 端点上配置了通配符证书(就像我一样),则必须将 Azure 云服务运行时 (IISconfigurator.exe) 创建的 SSL 绑定从 IP:PORT 更改为 *:PORT。我在以下方法中调用启动时我的网络角色:
public static void UnbindDefaultSslBindingFromIp()
{
Trace.TraceInformation(">> IISTenantManager: Unbind default SSL binding from IP");
using (var serverManager = new Microsoft.Web.Administration.ServerManager())
{
try
{
var websiteName = string.Format("{0}_Web", Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CurrentRoleInstance.Id);
var site = serverManager.Sites[websiteName];
var defaultSslBinding = site.Bindings.Single(b => b.IsIPPortHostBinding && b.Protocol == "https");
defaultSslBinding.BindingInformation = string.Format("*:{0}:", defaultSslBinding.EndPoint.Port);
serverManager.CommitChanges();
}
catch (Exception ex)
{
Trace.TraceError(ex.ToString());
}
}
}
以下屏幕截图显示了我们的云服务的工作配置。请不要对非标准端口感到困惑。屏幕截图来自模拟的云服务。
还有一件事要提一下:不要改变全部绑定到 *,因为 HTTP(端口 80)绑定仅适用于已部署云服务中的 IP:PORT 绑定。其他内容绑定到 IP:80,因此 *:80 不起作用,因为 * 代表“全部未分配”,而 IP 已在 http.sys 中的其他地方分配。
答案2
确保您的 catch-all 绑定不是 IP:Port 类型。当 HTTPS 绑定存在 IP:Port 绑定而不需要 SNI 时,该绑定将始终优先。对于 catch-all 情况,请使用 *:Port 绑定(* 表示全部未分配)。
答案3
IIS 确实支持 SNI,即使在 Azure 云服务 Web 角色中也是如此,尽管您无法通过门户获取配置,并且如果您在部署后在框上执行此操作,它将在下一次部署时被清除。解决方案是自动化配置。请在此处查看详细信息: