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 报头的程序代码。
这些主机名始终是 SNI-SSL。
对于这些网站,主机名默认使用 sitename.chinacloudsites.cn。您可以将该网站所需的最低 TLS 版本配置为 1.0 及以上版本,系统会认可您的配置。
但是,如果请求到达时 CLIENT HELLO 消息没有附带 SNI 扩展,我们就无法确定该请求所需访问的确切站点,因此基于合规考虑我们要求该请求至少使用 TLS 1.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 绑定。
如果您使用的是默认主机名,则需要使用 IP-SSL 添加自定义域名。
如果您已使用自定义域名,则需要将绑定更改为 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);
}
}
}
}
如您有更多问题
请访问 App Service论坛 或 Stack Overflow论坛
在线 创建工单
https://www.azure.cn/zh-cn/blog/2018/06/20/Breaking-change-for-SNI-SSL-hostnames-on-Azure-App-Service