FreeTDS не удается подключиться к SQL Server после последних исправлений Windows и tls1 отключен

у меня странная проблема с FreeTDS (MacOS 10.11.5) не подключается к SQL Server 2014, работающему на Windows Server 2012 r2, к которому я смог подключиться ранее (около недели назад). Сервер на прошлой неделе проходил закалку безопасности (самые последние исправления 2012 r2, плюс другие вещи*, которые я предполагаю, являются виновником, но моя локальная машина dev (и на самом деле только 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

не очень полезно - я сделал нормальное устранение неполадок, в том числе пробовал различные версии 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()

когда я подключаюсь к другим серверам и смотрю на freetds.log I can прочитайте пакеты (вроде), например:

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.' 

в отличие от DB01, где пакеты являются линиями и линиями }.???G?? .?T???٠

вот настройки времени компиляции freetds - мне нужны GnuTLS = yes?:

$ 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

вот мои 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

некоторые другие точки данных быстрого устранения неполадок:

  • используя TCPVew на сервере, я вижу, что мои соединения принимаются (но журнал подтверждает это как ну)

  • у нас есть сервер Windows, который служит PHP-страницы (подключение к DB01 через ODBC) , и у нас не было проблем с этим сервером, подключающимся к DB01

  • я могу использовать jTDS (через IntelliJ и Pycharm) для подключения к db01 хорошо, это был бы конец расследования, если бы я мог. провод jTDS в приложении django.

  • Майкрософт с JDBC не будет подключение к db01 (это также new), этот драйвер дает эту ошибку:
    [08S01] The driver could not establish a secure connection to SQL Server 
    

    С помощью шифрования Secure Sockets Layer (SSL). Ошибка: "сервер выбрал SSLv3, но эта версия протокола не включена или не поддерживается клиентом." ... Ява.ленг.К RuntimeException: класса javax.чистая.протокол SSL.SSLHandshakeException: Сервер выбрал SSLv3, но эта версия протокола не включена или не поддерживается клиентом.

кто-нибудь еще видел это? Есть ли способ указать TLS 1.2 и т. д. при подключении к freetds? (Я не смог найти документы по этому вопросу)

обновление:

Я думал посмотреть в Windows event viewer для любых ошибок, и это то, что там:

    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]]

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)

после Большого устранения неполадок мы откатили KB3172605 на сервере MS Windows Server 2008 R2, на котором работает наша БД MS SQL Server ... проблема. (КБ 3172605 заменяет КБ 3161639. )


TLDR; мне нужно было переустановить freetds с поддержкой gnutls вместо openssl.

после многих (нет, действительно много) проб и ошибок я, наконец, понял решение freetds на mac не подключается.

мне все еще нужно подключить остальные, поэтому pyodbc работает и т. д. но вот основное исправление:

brew edit freetds

замените формулу freetds следующим https://gist.github.com/hanleybrand/dfb7b9004aae250fabd01cd2466251c4

короче говоря, он добавляет опцию --with-gnutls к brew установите и убедитесь, что если он существует, это происходит до --with-openssl. Я не рассматривал это серьезно, но я подозреваю, что openssl/gnutls-это либо/или, и не и/или.

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

после этого tsql работал нормально - как я уже упоминал выше, мне все еще нужно настроить остальные (unixodbc, pyodbc), но я уверен, что если tsql работает, что остальные тоже будут, хотя я не могу быть полностью уверен.

это может быть связано с наборами шифров в двух пакетах (OpenSSL agains gnutls), как указывает @FlipperPA


Я сделал кучу тестирования с этим, и нашим решением было откатить этот патч:

https://support.microsoft.com/en-us/kb/3161639

по-видимому, набор шифров влияет больше, чем Edge и IE. :) Я открыл дело с Microsoft, и они знают о проблемах, которые это вызвало. Из лошадиной пасти:--1-->

поскольку проблема больше не возникает после удаления этого КБ обновление решило проблему, я сделал быстрый поиск в этом обновлении KB для до тех случаях. На данный момент имеется 21 дело по вопросам это обновление с прошлого месяца. Если вы не знаете и основываетесь на моем исследование, KB 3161639 добавляет дополнительные ключи шифрования, которые используют TLS 1.2 протокол, введенный в обновление KB 3161608. Следующие шифры, скорее всего, являются теми, которые вызывают проблему:

TLS_DHE_RSA_WITH_AES_128_CBC_SHA

TLS_DHE_RSA_WITH_AES_256_CBC_SHA

Я подозреваю, что либо ваш сервер Unix / Linux и / или FreeTDS ODBC не поддерживает эти наборы шифров или не настроен для него.
С учетом сказанного, у вас есть несколько вариантов:

  1. используйте обходной путь отсутствия установленного обновления KB 3161639
  2. переустановите обновление KB 3161639. Настроил порядок шифров, чтобы убедиться, что новые наборы шифров не выбраны.

мы пошли с опцией 1, и развернул его по всей нашей сети, и не видел никаких негативных последствий. Надеюсь, это поможет.


Я видел такое же поведение под FreeTDS (версия 0.91) после недавних исправлений Microsoft.

короче говоря, обновление FreeTDS до ночного снимка, доступного из http://www.freetds.org/ (1.00.24 по состоянию на этот пост) исправили проблему для меня. Я скомпилировал источник и обновил строку драйвера FreeTDS в odbcinst.ini файл конфигурации для указания на новый файл общего объекта (<path>/libtdsodbc.so), например:

[TDS]
Description = FreeTDS Driver
Driver = /usr/local/lib/libtdsodbc.so

были некоторые OpenSSL связанные совершает FreeTDS в начале сентября., 2016 в том числе этот коммит, который ссылается на несовместимость патч Microsoft:

обновить список шифров OpenSSL

это повышает безопасность, а также исправить недавнюю несовместимость между OpenSSL и SChannel (варианты SChannel исправлены в пара месяцев.)

основываясь на других комментариях здесь, которые указывают на проблему совместимости набора шифров, это может быть фиксация, что исправить положение. Тем не менее, на данный момент еще не была официально выпущена версия FreeTDS, которая включает эту фиксацию (последний официальный релиз был версией 1.0 в мае 2016).

ссылки на исправления Microsoft, упомянутые в других комментариях:

  • KB3161639 С июня 2016 патч свертки.

    в этой статье описывается обновление, в котором добавляются новые наборы шифров TLS и набор Шифров по умолчанию приоритеты изменяются в Windows RT 8.1, Windows 8.1, Windows Server 2012 R2, Windows 7 или Windows Server 2008 R2. Эти новые наборы шифров улучшают совместимость с серверами, которые поддерживают ограниченный набор наборов шифров.

  • KB3172605 С июля 2016 патч rollups (и переиздан в сентябре. 2016). Описание этого патча от история обновлений Windows Server 2008 R2 SP1 статьи:

    21 июля , 2016-KB3172605 Это обновление включает улучшения качества. Никаких новых функций операционной системы не вводится и никаких новых обновлений безопасности не включены. Ключевые изменения включают:

    • улучшена поддержка в Microsoft Cryptographic Application Programming Interface (CryptoAPI), чтобы помочь идентифицировать веб-сайты, которые используют безопасный алгоритм хэша 1 (SHA-1).
    • Устранена проблема в Microsoft Secure Channel (SChannel), которая иногда вызывает безопасность транспортного уровня (TLS) 1.2 сбой подключения в зависимости от того, настроен ли корневой сертификат как часть цепочки сертификатов для проверки подлинности сервера.

после проб и ошибок у меня был противоположный опыт от Питера Хэнли, который задокументирован в одном из вышеупомянутых сообщений, хотя, как указывает Питер, ошибка немного отличается. Я испытываю ошибку EOF, упомянутую Скоттом, которая коренится в коде ошибки TLS 20 (bad_record_MAC). На стороне MS это сообщается как ошибка SChannel.

поскольку я развертывался на нескольких серверах и хотел RPM, я редактировал freetds.spec-файл для удаления --with-gnutls и заменил его --with-openssl=yes, а затем перестроил RPMs с rpmbuild, проверив, что rpmbuild фактически использовал директиву, которую я добавил, и не содержал --with-gnutls.

для тестирования я написал небольшую утилиту Perl, которая быстро подключается к базе данных / отключается.

Я несколько раз проверял, что при использовании --with-gnutls ошибка TLS / SChannel / EOF встречается между 0,5% и 1% времени.

когда только директива --with-openssl=yes используется и без --with-gnutls присутствует, я не получаю никаких ошибок. Эти тесты выполнялись с интервалом в несколько минут и включали 5000 попыток соединения в быстрой последовательности (около 10 соединений открывались и закрывались в секунду). Никакие другие параметры конфигурации freetds не были изменены. Единственное различие между двумя тестами-это директивы, перечисленные выше. Сборка и установка файлов конфигурации RPM, freetds и т. д. все было автоматизировано и не менялось между испытание.

когда возникает ошибка, она сообщается на стороне клиента как:

DBI connect ('MYDBNAME', 'mydomain\myusername',...) ошибка:
[unixODBC][FreeTDS][SQL Server] не удается подключиться к источнику данных (SQL-08001) [состояние было 08001 теперь 01000]
[unixODBC] [FreeTDS] [SQL Server]адаптивное подключение сервера не удалось (SQL-01000)
[unixODBC][FreeTDS][SQL Server]неожиданный EOF с сервера (SQL-01000) at ./dbconnectiontestlots.pl строка 18

в этом тесте используется freetds-1.00.24-1.x86_64, загруженный непосредственно из freetds.org, построенный на компилятора RHEL6. Следующие RPMs были установлены из папки/root/rpmbuild/ RPMS / для этого теста после запуска rpmbuild каждый раз:

386996 Jan 5 14: 28 freetds-1.00.24-1.архитектуру x86_64.об / мин
187560 Jan 5 14: 28 freetds-unixodbc-1.00.24-1.архитектуру x86_64.об / мин

unixODBC x86_64 2.2.14-14.el6 также был установлен напрямую через yum.

Update: в то время как это решение работает на 32-разрядных и 64-разрядных системах RHEL6 он не работает на 32-битных системах RHEL5