范围:
我正在尝试与外部集中式Logging service提供程序集成,使用HTTPS
请求将日志发布到该提供程序。
我们在C#
之上运行Mono
,使用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.
到目前为止,我们已经尝试过:
PostAsync
)。结果,我们收到诸如Cant find file system.net.http.dll
之类的错误,一旦我们实际将这个错误从我们的Windows系统复制到它,我们就会收到另一个错误Task Exception
(不记得那里的确切消息)。
显然,在Xamarin程序上使用此客户端倾向于解决人们遇到的问题,但我们仍然使用HttpClient
中的标准.NET
类来获得上面列出的相同错误
这是我们与实际解决方案最接近的,在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 ---
答案 0 :(得分: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)。但即使是剩下的只有DHE或ECDHE,Mono似乎并不支持。他们正在积极研究new TLS stack,但看起来还没有完成。
如果您有权访问服务器,则可能尝试配置密码AES256-SHA,这可能是Mono当前支持的最佳密码。
答案 1 :(得分:0)
我建议您切换到Ubuntu 16.04,因为它带来了默认情况下同步证书的Mono软件包版本,因此您不需要运行mozroots,并且您更有可能没有问题在这个区域附近。