部分本地服务器无法连接Azure SQL Server报错64问题咨询
在本地SQL Server实例BadMachine1上创建指向Azure SQL Server的链接服务器,使用的创建脚本如下:
EXEC sp_addlinkedserver D365BI_Testing, '', 'SQLNCLI11', @datasrc='blabla.database.windows.net', @catalog = 'DbName' EXEC sp_addlinkedsrvlogin D365BI_Testing, 'false', null, 'blabla_Admin', 'thepassword'
创建流程无报错,但测试连接时SSMS返回如下错误:
TCP Provider: 指定的网络名不再可用。
登录前握手阶段出现错误,客户端无法建立连接。常见原因包括:客户端尝试连接不支持的SQL Server版本、服务器负载过高无法接收新连接、服务器存在内存/最大连接数等资源限制。
链接服务器"D365BI_Test2"的OLE DB访问接口"SQLNCLI11"返回消息"预登录失败导致客户端无法建立连接"。
链接服务器"D365BI_Test2"的OLE DB访问接口"SQLNCLI11"返回消息"客户端无法建立连接"。(Microsoft SQL Server, 错误: 64)
同数据中心另外两台本地服务器GoodMachine1、GoodMachine2执行完全相同的链接服务器配置,测试连接正常,可正常查询Azure SQL数据。
后续登录三台服务器,直接用SSMS直连目标Azure SQL数据库做验证:GoodMachine1、GoodMachine2直连正常,BadMachine1直连失败,报错如下:
无法连接到blabla.database.windows.net。
已成功与服务器建立连接,但是在预登录握手过程中发生错误。(provider: TCP Provider, error: 0 - 指定的网络名不再可用。)(Microsoft SQL Server, 错误: 64)
指定的网络名不再可用
目前已确认Azure侧防火墙规则配置正常,三台服务器的环境配置差异如下:
- BadMachine1:安装ODBC Driver 11、2014版旧版"Microsoft AS OLE DB Provider for SQL Server",运行SQL Server 2014
- GoodMachine1:安装ODBC Driver 11、13、17,无额外OLE驱动,运行SQL Server 2016
- GoodMachine2:安装ODBC Driver 13、最新版OLE驱动,运行SQL Server 2016
老旧驱动对TLS 1.2的兼容性缺失是最高概率的故障原因,和现有现象完全匹配:
创建链接服务器时使用的SQLNCLI11是随SQL Server 2014发布的SQL Server Native Client 11.0驱动,未打对应补丁的版本不支持TLS 1.2协议。而Azure SQL早已全面禁用TLS 1.0/1.1,强制要求客户端使用TLS 1.2及以上版本建立连接,握手阶段协议不匹配就会触发你看到的「TCP连接建立成功但预登录失败、提示网络名不可用」报错。
另外两台正常的服务器要么安装了13/17版本的高版本ODBC驱动,要么运行的SQL Server 2016原生默认支持TLS 1.2,因此不会触发该问题。
- 补全BadMachine1的官方补丁
先给SQL Server 2014安装SP3及后续累积更新,确保数据库引擎本身支持TLS 1.2;如果服务器操作系统是Windows Server 2012 R2及更早版本,同步安装系统层TLS 1.2支持补丁,否则系统层面发不出TLS 1.2的连接请求。 - 更换链接服务器使用的老旧驱动
不要继续用SQLNCLI11,先卸载服务器上老旧的SQL Server Native Client组件,安装最新版Microsoft OLE DB Driver for SQL Server(即MSOLEDBSQL),之后删除原有异常链接服务器,用新驱动重建,参考脚本:
-- 删除旧的异常链接服务器 EXEC sp_dropserver 'D365BI_Testing', 'droplogins' -- 用新驱动创建链接服务器 EXEC sp_addlinkedserver @server='D365BI_Testing', @srvproduct='', @provider='MSOLEDBSQL', @datasrc='blabla.database.windows.net', @catalog='DbName' -- 配置登录映射 EXEC sp_addlinkedsrvlogin @rmtsrvname='D365BI_Testing', @useself='FALSE', @locallogin=NULL, @rmtuser='blabla_Admin', @rmtpassword='thepassword' -- 配置基础连接参数 EXEC sp_serveroption 'D365BI_Testing', 'Collation Compatible', 'true' EXEC sp_serveroption 'D365BI_Testing', 'Connect Timeout', 30 EXEC sp_serveroption 'D365BI_Testing', 'Encrypt', 'true'
- 检查系统层TLS配置
打开注册表编辑器,定位到路径HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols:- 确认TLS 1.2项下的Client子项中,
Enabled值为1,DisabledByDefault值为0 - 确认TLS 1.0、TLS 1.1项下的Client子项中,
Enabled值为0
修改完成后重启服务器生效。
- 确认TLS 1.2项下的Client子项中,
- 网络层连通性兜底排查
在BadMachine1上用PowerShell命令Test-NetConnection blabla.database.windows.net -Port 1433测试端口连通性,排除本地Windows防火墙、出口网关/防火墙拦截1433端口流量的可能;如果出口部署了SSL流量检测、代理类设备,临时将Azure SQL域名加入检测白名单,这类设备篡改预登录阶段的SSL握手包也会触发同类报错。
内容的提问来源于stack exchange,提问作者bbb0777

