Назад | Перейти на главную страницу

Почему git перестал работать после того, как сервер отключил SSLv3?

Как и большинству других, нашему серверу репозитория необходимо как можно скорее отключить SSLv3 (и v2).

Однако это, похоже, нарушает работу наших git-клиентов - по крайней мере, на RHEL5 (соединения с моего рабочего стола FreeBSD работают нормально). Даже самый последний git (2.1.2) дает сбой, и обновление библиотек OpenSSL до последней версии от поставщика не помогло.

тем не мение! Тот же git-client отлично работает с github.com - и на github.com уже отключен SSLv3. Методом проб и ошибок я установил SSL-конфигурацию нашего сервера (Apache) в соответствии с github:

SSLProtocol     ALL -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCipherSuite  "AES128-SHA AES256-SHA RC4-SHA"

Бегом sslscan против нашего сервера и github я получаю идентичный список принятых и отклоненных шифров. Но git продолжает терпеть неудачу:

    % git clone https://git.example.net/git/puppet-hiera
    Cloning into 'puppet-hiera'...
    * Couldn't find host git.example.net in the .netrc file, using defaults
    * About to connect() to git.example.net port 443
    *   Trying 10.89.8.27... * connected
    * Connected to git.example.net (10.89.8.27) port 443
    * successfully set certificate verify locations:
    *   CAfile: /etc/pki/tls/certs/ca-bundle.crt
      CApath: none
    * Unknown SSL protocol error in connection to git.example.net:443
    * Closing connection #0
    fatal: unable to access 'https://git.example.net/git/puppet-hiera/': Unknown SSL protocol error in connection to git.example.net:443

Теперь единственное заметное различие между SSL нашего сервера и GitHub заключается в том, что sslscan может выводить сведения о сертификате GitHub, но не может получить их с нашего сервера.

Когда я подключаюсь к нашему git-серверу со своего рабочего стола FreeBSD, то же самое git clone команда работает. Вместо ошибки после вывода CApath: none, Я вижу:

      CApath: none
    * SSL connection using AES128-SHA
    * Server certificate:
             subject: C=US; postalCode= ............

и клонирование успешно. Как мне настроить наш сервер так, чтобы git работал с ним даже из старых RHEL5-систем - как с GitHub-серверами?

Обновить: пытаясь получить доступ к нашему серверу просто curl, У меня аналогичная ошибка по SSL-совместимости. Однако я смог преодолеть это, вызвав curl с явным --tlsv1 вариант (также известный как -1). Итак, программное обеспечение в системах RHEL5 способный необходимых протоколов и шифров - как заставить его использовать их по умолчанию вместо того, чтобы пробовать старые и терпеть неудачу?

Хорошо, вот сделка. Отключение SSLv3 в сегодняшнем Apache означает, что сервер даже не скажет клиенту, что он хочет использовать TLS. Если клиент не начать разговор с TLS, клиент потерпит неудачу - даже если мог поговорим о TLS. Большое спасибо пользователю Крис С., который проанализировал проблему и даже предложил патч для Apache mod_ssl в ответе на связанный вопрос.

Посмотрев на патч Криса, разработчики Apache придумали более исчерпывающий, который может даже стать частью следующего выпуска Apache. Он представляет новую опцию для Apache SSLProtocols директива: ANY. Когда Apache встречает ANY, он сообщит подключающемуся клиенту (через SSLv2Hello), что он должен переключиться на TLS:

SSLProtocol ANY -SSLv2 -SSLv3

Я вставляю патч для тех, кто не может позволить себе ждать Apache 2.4.11.

Index: modules/ssl/ssl_private.h
===================================================================
--- modules/ssl/ssl_private.h    (revision 1635012)
+++ modules/ssl/ssl_private.h    (working copy)
@@ -295,8 +295,10 @@ typedef int ssl_opt_t;
 #define SSL_PROTOCOL_TLSV1_2 (1<<4)
 #define SSL_PROTOCOL_ALL   (SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1| \
                 SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2)
+#define SSL_PROTOCOL_ANY   (1<<5)
 #else
 #define SSL_PROTOCOL_ALL   (SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1)
+#define SSL_PROTOCOL_ANY   (1<<3)
 #endif
 typedef int ssl_proto_t;

Index: modules/ssl/ssl_engine_init.c
===================================================================
--- modules/ssl/ssl_engine_init.c    (revision 1635012)
+++ modules/ssl/ssl_engine_init.c    (working copy)
@@ -490,6 +490,7 @@ static apr_status_t ssl_init_ctx_protocol(server_r
     }

     cp = apr_pstrcat(p,
+                     (protocol & SSL_PROTOCOL_ANY ? "SSLv23, " : ""),
              (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
              (protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""),
 #ifdef HAVE_TLSV1_X
Index: modules/ssl/ssl_engine_config.c
===================================================================
--- modules/ssl/ssl_engine_config.c    (revision 1635012)
+++ modules/ssl/ssl_engine_config.c    (working copy)
@@ -1311,6 +1311,9 @@ static const char *ssl_cmd_protocol_parse(cmd_parm
     else if (strcEQ(w, "all")) {
         thisopt = SSL_PROTOCOL_ALL;
     }
+        else if (strcEQ(w, "any")) {
+            thisopt = SSL_PROTOCOL_ANY|SSL_PROTOCOL_ALL;
+        }
     else {
         return apr_pstrcat(parms->temp_pool,
                parms->cmd->name,
Index: modules/ssl/ssl_engine_io.c
===================================================================
--- modules/ssl/ssl_engine_io.c    (revision 1635012)
+++ modules/ssl/ssl_engine_io.c    (working copy)
@@ -1137,6 +1137,7 @@ static apr_status_t ssl_io_filter_handshake(ssl_fi
      * IPv4 and IPv6 addresses are not permitted".)
      */
     if (hostname_note &&
+            !(sc->proxy->protocol & SSL_PROTOCOL_ANY) &&
         sc->proxy->protocol != SSL_PROTOCOL_SSLV3 &&
         apr_ipsubnet_create(&ip, hostname_note, NULL,
                 c->pool) != APR_SUCCESS) {

Мне нравится объяснение, которое вы предоставили о том, как внести корректировки на стороне сервера, чтобы заставить работать клиентов git. Моя проблема заключалась в попытке подключиться к джазжубу, где у меня нет возможности изменить сервер. Я придумал это решение сегодня (и поздно вечером):

https://developer.ibm.com/answers/answers/164635/view.html

Если у вас есть отзывы об этом, я бы хотел их услышать.

-Майкл