【问题标题】:Mono HTTPS Error - "Error Writing Headers"Mono HTTPS 错误 - “写入标头错误”
【发布时间】:2016-05-04 13:27:17
【问题描述】:

范围:

我正在尝试与外部集中式 Logging service 提供程序集成,使用 HTTPS 请求将日志发布到它。

我们在Mono 之上运行C#,使用Ubuntu 14.04 LTS 作为操作系统。

我们已经使用 mono 多年了,所以我们对它的行为和潜在的缺陷/问题非常熟悉。

以前的设置

当你在谷歌上搜索这个问题时,你会发现基本上有两种解决方案,对于这种情况,它们都没有对我有用。这是我到目前为止所做的事情

Basic Mono-Complete Setup + ca-certificates-mono(这可能会解决 HTTPS 相关问题)。

除此之外,我知道 Mono 默认不信任任何证书,它拥有自己的证书链,我们必须将它们导入其中。为此,我运行了mozroots --import --sync --ask-remove,它打印出“已下载并安装了 140 个证书”。

此外,我们使用这个讨厌的单行代码覆盖了 CertificateValidationCallback:

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { return true; };

以上都没有解决我们的问题。

错误、错误和更多错误:

Note that all of the codes below do work on Windows.

到目前为止,我们已经尝试过:

  • 使用本机 .NET WebClient 异步调用 (PostAsync)。

因此,我们得到了诸如Cant find file system.net.http.dll 之类的错误,一旦我们将它从我们的Windows 系统复制到它,我们就会得到另一个错误Task Exception(不记得那里的确切消息)。

显然,在 Xamarin 程序上使用此客户端往往可以解决人们遇到的问题,但我们仍然会遇到上面列出的相同错误,使用来自 .NET 的标准 HttpClient

  • 编写我们自己的 WebRequests Wrapper

这是我们得到的最接近实际解决方案的解决方案,在 Mono 上运行时会导致 Error Writing Headers

小代码示例:

using (WebRequests webClient = new WebRequests ())
{
                // Client Configuration
                webClient.BufferSize       = 32 * 1024;
                webClient.Accept           = "application/json";
                webClient.ContentType      = "application/json; charset=" + Encoding.UTF8.HeaderName;
                webClient.Timeout          = 60000;
                webClient.ReadWriteTimeout = 60000;
                webClient.Encoding         = Encoding.UTF8.WebName;

                // Dummy Logz Payload - One Json Per Line
                string LogzPayload = "{id:'1', value='1'}\n{id:'2', value='2'}";

                // Request to Logz
                webClient.Post ("https://listener-4.logz.io:8071/?token=OUR_TOKEN&type=json", LogzPayload);
}

更新 1:

刚刚尝试运行以下命令并立即出现异常:

certmgr --ssl https://listener-4.logz.io:8071/?token=OUR_TOKEN&type=json --machine

例外:

Unhandled Exception:
System.IO.IOException: The authentication or decryption has failed. --->     System.IO.IOException: The authentication or decryption has failed. --->  Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
  at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord  (IAsyncResult asyncResult) <0x4192e470 + 0x00132> in <filename unknown>:0
  at Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord  (IAsyncResult ar, Boolean ignoreEmpty) <0x4192e3a0 + 0x00031> in <filename  unknown>:0
  at Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (IAsyncResult result) <0x4192abb0 + 0x00225> in <filename unknown>:0
  --- End of inner exception stack trace ---

【问题讨论】:

  • 你用的是什么版本的 Mono?

标签: c# .net linux ssl mono


【解决方案1】:

我对 Mono 不是很熟悉,但我知道他们使用自己的 TLS 堆栈,而 .NET 使用来自操作系统的 TLS 堆栈。如果我是正确的,CipherSuiteFactory.cs 中定义了可用的密码套件,这表明没有可用的 ECDHE 和 DHE 密码。但据我所知,服务器仅支持 ECDHE 和 DHE 密码,因此不会有共享密码,TLS 握手将失败。服务器支持的密码有:

ECDHE-RSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-SHA384
ECDHE-RSA-AES256-SHA
DHE-RSA-AES256-SHA256
DHE-RSA-AES256-SHA

其中大部分是需要 TLS 1.2 的密码,Mono 根本不支持(请参阅State of TLS in Mono)。但即使是其余的也只是 Mono 似乎不支持的 DHE 或 ECDHE。他们正在积极处理new TLS stack,但看起来还没有完成。

如果您有权访问服务器,您可能会尝试配置密码 AES256-SHA,这可能是 Mono 目前支持的最佳密码。

【讨论】:

  • 哇。这是一个地狱般的答案! :) 所以你的意思是,除非 Mono 发布它是新的 TLS Stack,或者 Logz 添加对其他芯片的支持,否则我们无法让它工作,对吧?此外,您是如何检查服务器支持的密码的?
  • @MarcelloGrechiLins:是的,这就是我要说的。我已经用my own Perl tool 检查了密码,但你也可以使用the Python tool sslyze
  • 你测试过 logz.io 还是 API one ?
  • @MarcelloGrechiLins:我已经测试了 API,即 listener-4.logz.io:8071。主页 logz.io 本身有不同的密码,包括一些应该与 Mono 一起使用的密码(如 AES256-SHA)。但是https://logz.io 的名称不匹配(改为 cloudfront.net),所以我猜它不打算与 https 一起使用(仅限主页,浏览器也会抱怨)。
  • 我刚刚与 Logz 的支持团队打了个电话,他们证实了我的意思。这些是他们实施的密码。至于单声道,你也是正确的,它们不支持那些密码,所以我要做的就是回退到 HTTP 请求而不是 HTTPS 请求。
【解决方案2】:

我建议您切换到 Ubuntu 16.04,因为这会带来一个默认同步证书的 Mono 软件包版本,因此您不需要运行 mozroots,而且您更可能不会在这方面遇到问题。

【讨论】:

  • Ubuntu 不是问题。正如@SteffenUllrich 指出的那样,Mono 有自己的 TLS 堆栈,该堆栈有问题并且错过了某些密码的实现,导致 HTTPS 握手不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-05
  • 2012-08-17
  • 2014-08-27
  • 2016-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多