在最近的Windows补丁和TLS1被禁用后,FreeTDS无法连接到SQL Server

Pet*_*ley 7 sql-server ssl freetds

我遇到了一个奇怪的问题,FreeTDS(MacOS 10.11.5)没有连接到运行在Windows Server 2012 r2上的SQL Server 2014,而我之前已经能够连接到这个(大约一周左右).上周的服务器一直在进行安全加固(最近的2012 r2补丁,加上其他东西*我假设是罪魁祸首,但我的本地开发机器(实际上只有我机器上的FreeTDS)似乎是补丁后唯一的问题.

我怀疑导致问题的原因在于RC4密码和SSL 2.0&TLS 1.0被禁用,但我不知道如何修复它.

要清楚,不像其他类似的问题 - 我不能通过任何方式连接freetds到DB01,但我可以连接其他驱动程序到DB01(但我正在开发一个python应用程序,在这个实例中需要freetds)和其他机器可以连接到DB01 .

基本错误是:

$ tsql -S DB01 -U db_user
Password: ****************
locale is "en_US.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
Error 20002 (severity 9):
    Adaptive Server connection failed
There was a problem connecting to the server
Run Code Online (Sandbox Code Playgroud)

没有超级帮助 - 我已经完成了正常的故障排除,包括尝试各种TDS版本,在命令行上使用不同的开关等.

该日志还指出存在SSL问题的可能性 - 例如,tls.c日志记录"handshake failed",包含字符串"SSL_Self_Signed_Fallback"的数据包(否则数据包不可读):

net.c:216:Connecting to 000.000.000.000 port 1433 (TDS version 7.4)
net.c:242:tds_open_socket: connect(2) returned "Operation now in progress"
net.c:343:tds_open_socket() succeeded
packet.c:741:Sending packet
[blah blah]
login.c:1185:detected flag 0
tls.c:116:in tds_push_func_login
tls.c:86:in tds_pull_func_login
packet.c:741:Sending packet
[blah blah]
packet.c:639:Received packet
[blah blah... what?
xxx |..0.S.S. L._.S.e.|
xxx |l.f._.S. i.g.n.e.|
xxx |d._.F.a. l.l.b.a.|
xxx |c.k0...1 blahblah|
tls.c:116:in tds_push_func_login
packet.c:741:Sending packet
0000 12 01 00 0f 00 00 00 00-15 03 00 00 02 02 28    |........ ......(|
tls.c:923:handshake failed
login.c:530:login packet rejected
query.c:3796:tds_disconnect() 
util.c:165:Changed query state from IDLE to DEAD
util.c:322:tdserror(0x7fef2b403aa0, 0x7fef2b403ba0, 20002, 0)
util.c:352:tdserror: client library returned TDS_INT_CANCEL(2)
util.c:375:tdserror: returning TDS_INT_CANCEL(2)
mem.c:644:tds_free_all_results()
Run Code Online (Sandbox Code Playgroud)

当我连接到其他服务器并查看freetds.log时,我可以读取数据包(有点),例如:

xxx |.C.h.a.n .g.e.d. |
xxx |.d.a.t.a .b.a.s.e|
xxx |. .c.o.n .t.e.x.t|
xxx |. .t.o.  .'.m.a.s|
xxx |.t.e.r.' 
Run Code Online (Sandbox Code Playgroud)

与DB01不同的是,数据包是行和行 }.???G?? .?T????

这是freetds编译时设置 - 我需要GnuTLS =是吗?:

$ tsql -C
Compile-time settings (established with the "configure" script)
                            Version: freetds v1.00.9
             freetds.conf directory: /usr/local/Cellar/freetds/1.00.9/etc
     MS db-lib source compatibility: no
        Sybase binary compatibility: no
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 7.3
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: no
                            OpenSSL: yes
                             GnuTLS: no
                               MARS: no
Run Code Online (Sandbox Code Playgroud)

这是我的freetds.conf文件:

[global]
    # TDS protocol version
    tds version = auto
    dump file = /tmp/freetds.log
    debug flags = 4FFF
    text size = 64512
[DB01]
    host = db01.mydomain.tld
    port = 1433
    tds version = 7.4
    database = DB_NAME
    # I added this in case it was a cert issue, see below
    check certificate hostname = no
Run Code Online (Sandbox Code Playgroud)

其他一些快速故障排除数据点:

  • 在服务器上使用TCPVew我可以看到我的连接被接受(但日志也证实了这一点)

  • 我们有一个服务于PHP页面的Windows服务器(通过ODBC连接到DB01)我们对连接到DB01的服务器没有任何问题

  • 我可以使用jTDS(通过IntelliJ和Pycharm)连接到db01罚款,如果我可以在django应用程序中连接jTDS,这将是调查的结束.

  • Microsoft的JDBC驱动程序不会连接到db01(这也是新的),该驱动程序会出现此错误:

    [08S01] The driver could not establish a secure connection to SQL Server 
    
    Run Code Online (Sandbox Code Playgroud)

    通过使用安全套接字层(SSL)加密.错误:"服务器选择了SSLv3,但客户端未启用或不支持该协议版本." ... java.lang.RuntimeException:javax.net.ssl.SSLHandshakeException:服务器选择了SSLv3,但客户端未启用或不支持该协议版本.

有没有人见过这个?有没有办法在与freetds连接时指定TLS 1.2等?(我无法找到关于此的文档)

更新:

我想在Windows事件查看器中查找任何错误,这就是那里的内容:

    DB01    17836   Error   MSSQLSERVER Application 7/20/2016 2:52:18 PM
    The login packet used to open the connection is structurally invalid;
 the connection has been closed. Please contact the vendor of the client
 library. [CLIENT: [my ip address]]

    [and also]

    Length specified in network packet payload did not match number of 
bytes read; the connection has been closed. Please contact the vendor 
of the client library. [CLIENT: [my ip address]]
Run Code Online (Sandbox Code Playgroud)

Pet*_*ley 6

TLDR; 我需要重新安装支持gnutls而不是openssl的freetds。

经过大量(没有,真的很多)反复试验,我终于找到了解决Mac上freetds无法连接的解决方案。

我仍然需要整理其余部分,以便pyodbc可以工作,等等。但这是基本的解决方法:

brew edit freetds

用此https://gist.github.com/hanleybrand/dfb7b9004aae250fabd01cd2466251c4替换freetds公式

简而言之,它会将选项添加--with-gnutls到brew安装中,并确保该选项存在之前--with-openssl。我没有仔细研究过,但是我怀疑openssl / nutls是或/而不是和/或。

brew rm freetds && brew install freetds --with-gnutls --with-unixodbc

之后,tsql可以正常工作-正如我上面提到的,我仍然必须设置其余的(unixodbc,pyodbc),但是我非常有信心,如果tsql可以工作,其余的也可以,尽管我不能完全确定。

@FlipperPA指出,这可能与两个软件包中的密码集有关(openssl agains gnutls)


小智 5

应用Linux和MS补丁后,我们间歇性地出现此错误.我们仍然可以从Linux连接到MSSQL服务器,但随机连接将以EOF错误终止...即使在查询中.我打开了freetds日志,看到加密握手失败,如下所示:

    net.c:1366:handshake failed: A TLS packet with unexpected length was received.          
    login.c:466:login packet rejected
    util.c:331:tdserror(0x1e752b0, 0x2c27f40, 20002, 0)
Run Code Online (Sandbox Code Playgroud)

经过多次故障排除后,我们在运行MS SQL Server DB的MS Windows Server 2008 R2服务器上回滚了KB3172605 ...它解决了这个问题.(KB 3172605取代KB 3161639.)