Sql-server – TLS 1.2 breaks SQL Server linked servers

linked-serversql servertls-1.2

As part of a recent security blitz we set up TLS 1.2 on all of our servers. Last night I flipped the "Force Encryption" flag on all of our SQL Servers and since then I've had a weird issue with linked servers.

I have two servers;

  • Server A running SQL Server 2016 SP2 CU3

  • Server B running SQL Server 2012 SP4

Both have the correct encryption certificates on them, both have have the necessary registry edits to disable SSL and TLS 1.0 & 1.1, leaving just TLS 1.2 enabled. Both have the certificate set in SQL Server Config Mgr and "Force Encryption" set.

The linked server from Server A to B (2016 to 2012) works fine.
The linked server from Server B to A (2012 to 2016) shows the server and lists the databases, but any attempt to query the tables over that linked server generates the error:

TCP Provider: The specified network name is no longer available. (Microsoft SQL Server, Error: 64)

I can however start a SQL Server Management Studio session on Server B and connect to Server A just fine. So its only the linked server that is having the problem.

I checked the extended events on Server A and I can see the trace event for the SSL handshake coming from Server B using TLS 1.2, so the connection request is clearly coming in with the correct encryption set.

Googling the error seems to indicate a name resolution issue, so I tried setting up other linked servers using both the FQDN and the IP address, but neither resolved the issue.

Any help at this point would save what remaining hair I have left.

To eliminate network issues, I went to one of my 2016 servers that has a 2012 instance on it for backward compatibility. The same issue. the 2016 instance can query a linked server to the 2012 instance. The 2012 instance cannot query a linked server to the 2016 instance. A second test between two 2016 instances had the same issue too.

The SQL Server Client Version is 11.4.7462.6.

Registry Settings:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

Best Answer

Are you familiar with using any tools such as netmon, wireshark, or netsh? You might want to do a capture as you replicate this issue. Something that sticks out in my mind is Server B might be trying to hit something external to the mix (i.e. Certificate Revocation List CRL check) and that call is failing. A CRL check takes place on the client side of the equation - in this case Server B is the client. If you are able to run a trace you probably want to filter for tcp resets where the client (Server B) is involved. In wireshark a filter for this would look like tcp.flags.reset == 1 and ip.addr == 10.X.X.X where 10.X.X.X would be the ip address of Server B.