简体   繁体   English

如何从服务器检查协商的TLS握手?

[英]How do you check the Negotiated TLS Handshake from the Server?

If I have a dozen endpoints, and my WebAPI Service is configured for TLS 1.1 and TLS 1.2 , how do I check each incoming endpoint request to see which version was negotiated? 如果我有十几个端点,并且我的WebAPI服务是针对TLS 1.1TLS 1.2配置的,那么如何检查每个传入端点请求以查看协商的版本?

So if a consumer of my endpoints currently only supports TLS 1.0 and TLS 1.1 , they'll (obviously?) negotiate a TLS 1.1 handshake. 因此,如果我的端点的消费者目前仅支持TLS 1.0TLS 1.1 ,他们(显然?)会协商TLS 1.1握手。 But if a different consumer supports TLS 1.2 and TLS 1.3 , they'll (obviously?) negotiate a TLS 1.2 handshake. 但是,如果不同的消费者支持TLS 1.2TLS 1.3 ,他们(很明显?)会协商TLS 1.2握手。

I want to track all of my consumers to see what handshakes are being negotiated. 我想跟踪我的所有消费者,看看正在谈判什么样的握手。 How do I do that per-request? 我如何按要求执行此操作?

If you are using IIS it looks like you can add some extended logging to your IIS logs. 如果您使用的是IIS,则可以在IIS日志中添加一些扩展日志记录。

https://cloudblogs.microsoft.com/microsoftsecure/2017/09/07/new-iis-functionality-to-help-identify-weak-tls-usage/ https://cloudblogs.microsoft.com/microsoftsecure/2017/09/07/new-iis-functionality-to-help-identify-weak-tls-usage/

plagiarizing ... er ... quoting for posterity: 抄袭......呃...为后人引用:

To enable this new functionality, these four server variables need to be configured as the sources of the custom fields in IIS applicationHost.config. 要启用此新功能,需要将这四个服务器变量配置为IIS applicationHost.config中自定义字段的源。 The custom logging can be configured on either server level or site level. 可以在服务器级别或站点级别配置自定义日志记录。 Here is a sample site-level configuration: 以下是站点级配置示例:

<site name="Default Web Site" id="1" serverAutoStart="true">
 <application path="/">
 <virtualDirectory path="/" physicalPath="C:\inetpub\wwwroot" />
 </application>
 <bindings>
 <binding protocol="https" bindingInformation="*:443:" />
 </bindings>
 <logFile>
 <customFields>
 <clear />
<add logFieldName="crypt-protocol" sourceName="CRYPT_PROTOCOL" sourceType="ServerVariable" />
<add logFieldName="crypt-cipher" sourceName="CRYPT_CIPHER_ALG_ID" sourceType="ServerVariable" />
<add logFieldName="crypt-hash" sourceName="CRYPT_HASH_ALG_ID" sourceType="ServerVariable" />
<add logFieldName="crypt-keyexchange" sourceName="CRYPT_KEYEXCHANGE_ALG_ID" sourceType="ServerVariable" />
 </customFields>
 </logFile>
 </site>

Each SSL info field is a hexadecimal number that maps to either a secure protocol version or cipher suite algorithm. 每个SSL信息字段都是十六进制数字,映射到安全协议版本或密码套件算法。 For an HTTP plain-text request, all four fields will be logged as '-'. 对于HTTP纯文本请求,所有四个字段都将记录为“ - ”。

Me again: 又是我:

It looks like CRYPT_PROTOCOL can be 400 for TLS1.2, 40 for TLS 1.0, 10 for SSLv3 in the IIS Text logs. 看起来CRYPT_PROTOCOL对于CRYPT_PROTOCOL可以是400 ,对于TLS 1.0可以是40 ,对于IIS文本日志中的SSLv3可以是10

From the examples, it looks like there might be ServerVariable values on each Request if you want to try to include in custom logs that are a bit easier to customize than the IIS log itself. 从示例中可以看出,如果您希望尝试包含自定义日志,而不是IIS日志本身,则可能会在每个请求上包含ServerVariable值。

Great Question! 好问题! and I may have a chance to use this answer m'self. 我可能有机会自己使用这个答案。


So ... it looks like you CAN get the ServerVariables from WebAPI but only in an unexpected way. 所以...看起来你可以从WebAPI获得ServerVariables,但只是以一种意想不到的方式。 See the snippet below. 请参阅下面的代码段。 It seems if you enumerate the collection or call the Keys property all you get is some subset of variables. 看起来如果你枚举集合或调用Keys属性,你得到的只是变量的一些子集。 But if you explicitly request the CRYPT_* variables before any of those actions then you can indeed get them from your controller. 但是如果您在任何这些操作之前明确请求CRYPT_ *变量,那么您can indeed可以从控制器获取它们。 I tried this on WebAPI 5.2.6 targeting .net 4.6.2 running under IIS as an Azure Classic Cloud Service. 我尝试在WebAPI 5.2.6上将.net 4.6.2作为Azure Classic Cloud Service在IIS下运行。 I suggest trying this and seeing if it works for you. 我建议尝试这个,看看它是否适合你。 If you have a more recent reference for Server Variables, please edit this answer and replace https://docs.microsoft.com/en-us/iis/web-dev-reference/server-variables with your link. 如果您有更新的服务器变量参考,请编辑此答案并将https://docs.microsoft.com/en-us/iis/web-dev-reference/server-variables替换为您的链接。

Below worked for me on date of writing for environment listed. 下面列出的环境写作日期对我有用。 It may change in the future. 它可能在将来发生变化。 For production I would definitely move this into a helper method. 对于制作我肯定会把它变成一个辅助方法。

if (Request.Properties.TryGetValue("MS_HttpContext", out object context))
 {
 if (context is HttpContextWrapper wrapper)
  {
  var v = wrapper.Request?.ServerVariables;
  if (v != null)
   {
   var headers = response.Headers;
   const string CRYPT_PROTOCOL = nameof(CRYPT_PROTOCOL);
   try
    {
    headers.Add($"SV_{CRYPT_PROTOCOL}", $"[{v[CRYPT_PROTOCOL].Replace("\r", "0x0D").Replace("\n", "0x0A")}]");
    }
    catch (Exception ex)
    {
       headers.Add($"SV_{CRYPT_PROTOCOL}", ex.Message);
    }
    foreach (string key in v.AllKeys)
      {
      headers.Add($"SV_{key}", v[key].Replace("\r", "0x0D").Replace("\n", "0x0A"));
      }
     headers.Add($"SV_DONE", "All Server Variables Replaced");
     }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM