Azure 应用服务中的 SSL

Azure 应用服务(Azure App Service)是一个多租户基础设施。 在 Azure 应用服务上创建网络应用时,我们提供了一个默认主机名,即 sitename.chinacloudsites.cn。 客户端可以通过 HTTP 或 HTTPS 向这些主机发送请求。 针对站点的默认主机名使用 HTTPS 时,主题名为 *.chinacloudsites.cn 的证书将返回给客户端以建立 SSL 连接。

客户使用自定义域名配置应用服务时,系统默认允许您选择 SNI-SSL 绑定类型或 IP-SSL 绑定类型。

SNI-SSL 绑定是免费的。 对于要使用的 SNI 绑定,向此主机发出请求的客户端需要在 TLS 初始握手消息中包含 SNI 报头。 从规范的角度来看,TLS 1.0 支持 SNI 报头扩展,当下所有浏览器默认都包含 SNI 报头。

相比之下,浏览器客户端或程序库可能存在旧版本。 要让自定义域为这些客户端正常工作,必须将该站点配置 IPSSL 绑定。

什么是 SNI 和 IP-SSL,为什么很重要?

初始 SSL 握手请求到达 Web 服务器时,强制性参数(如正在协商的 SSL 版本)和客户端支持的加密算法包含在 CLIENT HELLO 明文消息中。 从服务器的角度来看,基于上述信息,服务器需要选择适合该请求的证书。 对于有单个站点/主机名的 Web 服务器,问题变得简单,您可以在一个端口上仅使用一个绑定/证书来配置服务器即可。

但是在托管多个站点或主机名的 Web 服务器中,仅基于版本 + 加密算法,服务器无法选择正确的证书。 因此这要求服务器必须针对每个主机名的不同 IP 来配置绑定。

SNI 如何提供帮助?

为了使 SSL 服务器端可以在一个 IP 地址上支持多个主机名,2003 年在 RFC 3546 [https://tools.ietf.org/html/rfc3546]中引入了 SNI 扩展的概念。

根据此规范,客户端可以在发出 CLIENT HELLO 明文消息时将目标主机名称包含在额外服务器名扩展内。 然后根据这个信息,服务器可以选择合适的证书进行握手连接,从而解决了需要唯一 IP 地址的问题。

为什么 Azure 应用服务同时支持 SNI-SSL 和 IP-SSL 绑定?

虽然早在 2003 年就发布了 SNI 的 RFC,所有主流浏览器也在此后不久添加了支持,但仍有一些传统 HTTPS 客户端没有在 CLIENT HELLO 消息中包含 SNI 报头扩展。 如果希望支持这类客户端使用 Azure 应用服务网站,则建议添加 IP-SSL 绑定使此站点拥有专用 IP 地址,这样我们才能基于主机名选则正确的证书。

在 TLS 1.2 合规行动中,什么变更会影响您的服务?

我们现在对没有 SNI 报头的客户强制实施 TLS 1.2。 请注意,这些通常是不支持 SNI 的旧版浏览器客户端,或者是编写年代久远且一直未更新来支持 SNI 报头的程序代码。

1. 对于没有配置自定义域名的网站:

这些主机名始终是 SNI-SSL。

对于这些网站,主机名默认使用 sitename.chinacloudsites.cn。您可以将该网站所需的最低 TLS 版本配置为 1.0 及以上版本,系统会认可您的配置。

但是,如果请求到达时 CLIENT HELLO 消息没有附带 SNI 扩展,我们就无法确定该请求所需访问的确切站点,因此基于合规考虑我们要求该请求至少使用 TLS 1.2。

2. 对于配置了自定义域的站点:

  • SNI -SSL:

对于这些站点,您同样可以设置最低要求的 TLS 版本,并且会被系统认可。 但是,如果请求到达时 CLIENT HELLO 消息没有附带 SNI 扩展,我们就无法确定该请求所需访问的确切站点,因此和使用默认主机名的场景一样,基于合规考虑我们要求该请求至少使用 TLS 1.2。

  • IP-SSL:不会发生涉及影响您的服务的变更。

对于 IP-SSL 绑定,由于主机名有专用 IP,我们的系统可以根据传入的 IP 地址正确确定目标站点,因此对没有 SNI 报头的请求不需要 SNI 报头或最低 TLS 版本要求。 Web 应用程序的最低配置 TLS 版本将生效。

我目前正在使用 SNI-SSL 绑定:如果我受到影响该如何处理?

对于浏览器客户端,将浏览器客户端升级到主流浏览器最新版。出于安全最佳实践,强烈建议您使用最新浏览器来保护网站和用户。

对于编程场景,更新应用程序代码使用 TLS 1.2,或者如果仍需使用 TLS 1.0,请在 CLIENT HELLO 消息中明确包含主机名。

要使用 HttpWebRequest 或 HttpClient 更新 .NET 应用程序中的 TLS 版本,请更新 ServicePointManager 中的 SecurityProtocol,如下所示。

// To update the TLS version in a .NET C# app using HttpClient/HttpWebRequest,

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

请注意,使用 HttpWebRequest / HttpClient 类发出 SSL 请求时,会自动添加 SNI 报头。

如果上述选项均不适用,那么最后、最不推荐的选项就是使用 IP-SSL 绑定。

1. 如果您使用的是默认主机名,则需要使用 IP-SSL 添加自定义域名。

2. 如果您已使用自定义域名,则需要将绑定更改为 IP-SSL。

/* Sample code */

using System;

using System.Net;

namespace SNIClient

{

    class Program

    {

        static void Main(string[] args)

        {

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://mysite.chinacloudsites.cn/");

            try

            {

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                response.Close();

            }

            catch (WebException ex)

            {

                Console.WriteLine(ex.Message);

            }

        }

    }

}

如您有更多问题