我有一个已运行多年的 AWS Lambda 函数 (REST Api),它仅查询远程 SQL Server 上的存储过程。我想对其进行一些更改,并借此机会更新了代码,因为它的目标框架是.NET Core 2.1。
因此,我创建了一个针对 .NET 8.0 的新 C# 项目,并使用“Lambda ASP.NET Core Web Minimal API”模板。顺便说一句,我很难让它工作,但我终于做到了,感谢这篇文章:使用 AWS Lambda 构建无服务器 .NET Minimal API(使用控制器)。
但是现在当我尝试连接到我的 SQL Server 时遇到此异常:
与服务器成功建立连接,但在预登录握手过程中出现错误。 (提供商:SSL 提供商,错误:31 - 加密(ssl/tls)握手失败)
有了这个内在的例外:
System.IO.IOException:从传输流接收到意外的 EOF 或 0 字节。
在我所做的研究中,几乎所有地方都说此异常与使用 TLS 1.2 连接到 SQL Server 有关。我尝试了很多解决方案但没有成功。
这是 SQL Server 环境(托管在本地云服务器提供商上):
这是我正在使用的连接字符串:
$"Data Source={serverUrl};Initial Catalog={database};User ID={username};Password={pwd};"
到目前为止我尝试过的事情:
11.0.7507
)。TrustServerCertificate=True
、Encrypt=False
和 MultiSubnetFailover=True
。System.Data.SqlClient
(版本 4.8.6)更改为 Microsoft.Data.SqlClient
(版本 5.2.0)。--编辑1--
在评论部分与用户AlwaysLearning和Charlieface交换一些信息后,我尝试在服务器上使用WireShark捕获更多信息,所以我将发布一些屏幕截图。我使用
tcp port 1433
作为捕获过滤器,然后使用 ssl
作为显示过滤器。
当我执行旧的 AWS Lambda 函数(在 .NET Core 2.1 上运行)时,它已经使用 TLS v1.2 与服务器进行通信,并且可以正常工作:
但是当我执行新的 AWS Lambda 函数(在 .NET 8.0 上运行)时,它也使用 TLS v1.2 进行通信,但有点不同,一开始它说它是 TLSv1,但在消息内部它说它是 TLS v1。 2 还:
还有一些扩展(以黄色标记)在其工作的通话中未使用:
我想其中一些是问题所在,也许
psk_key_exchange_modes
和key_share
?--编辑2--
查看执行旧函数时客户端和服务器之间交换的
Server Hello
消息,似乎TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
是握手协议中使用的密码套件:
这些是执行旧函数时
Client Hello
消息中列出的密码套件:
执行新函数时,此密码套件 (
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
) 不会在 Client Hello
消息中列出:
经过一番研究,我发现在 TLS 握手过程中,服务器从客户端收到
Client Hello
消息,然后突然用 [FIN, ACK]
消息而不是 Server Hello
响应结束“对话”,这是很不寻常的。或显示解析 Client Hello
消息时可能出现的任何问题的警报消息。
然后我在某处读到,这种异常行为可能是由密码套件的某些问题或与证书相关的某些问题引起的。我的服务器上没有证书,所以我开始想知道这是否是问题所在。因此,我搜索了一种使用免费 TLS 证书生成器 Let's Encrypt 与 SQL Server 的方法,并找到了这篇文章:
使用 Let’s Encrypt 证书加密 SQL Server 连接
另外一篇文章也提供了一些关于如何在 SQL Server 中配置 TLS 证书的好建议:
在 SQL Server 上启用 TLS
在服务器上安装 TLS 证书并将其与 SQL Server 关联后,新的 AWS Lambda 函数中与 SQL Server 的连接开始工作!