Получить сертификат SSL / TLS сервера, используя «openssl s_client»

17

Я пытаюсь получить сертификат SSL / TLS для одного из наших балансировщиков нагрузки (Netscaler), используя:

openssl s_client -showcerts -connect lb.example.com:443

Но это не покажет мне сертификат:

CONNECTED(00000003)
write:errno=54

Использование -servername lb.example.comне помогает, и наш системный администратор сказал мне, что наши балансировщики нагрузки все равно не используют SNI.

Изменить : сервер находится в нашей внутренней сети и не принимает подключения из общедоступного Интернета. Это вывод openssl с -debug:

CONNECTED(00000003)
write to 0x7fec7af0abf0 [0x7fec7b803a00] (130 bytes => 130 (0x82))
0000 - 80 80 01 03 01 00 57 00-00 00 20 00 00 39 00 00   ......W... ..9..
0010 - 38 00 00 35 00 00 16 00-00 13 00 00 0a 07 00 c0   8..5............
0020 - 00 00 33 00 00 32 00 00-2f 00 00 9a 00 00 99 00   ..3..2../.......
0030 - 00 96 03 00 80 00 00 05-00 00 04 01 00 80 00 00   ................
0040 - 15 00 00 12 00 00 09 06-00 40 00 00 14 00 00 11   .........@......
0050 - 00 00 08 00 00 06 04 00-80 00 00 03 02 00 80 00   ................
0060 - 00 ff a6 f7 27 1a a7 18-85 cf b2 03 22 fc 48 3d   ....'.......".H=
0070 - dd a9 2c b7 76 67 62 80-df 85 ed 48 35 c7 d4 87   ..,.vgb....H5...
0080 - 8d d3                                             ..
read from 0x7fec7af0abf0 [0x7fec7b809000] (7 bytes => -1 (0xFFFFFFFFFFFFFFFF))
write:errno=54

И это соответствующий вывод из curl -v https://lb.example.com/:

$ curl -vI https://lb.exmple.com/
*   Trying 1.2.3.4...
* Connected to lb.exmple.com (10.1.2.3) port 443 (#0)
* TLS 1.2 connection using TLS_RSA_WITH_AES_256_CBC_SHA
* Server certificate: lb.example.com
* Server certificate: RapidSSL SHA256 CA - G2
* Server certificate: GeoTrust Primary Certification Authority - G3
> HEAD / HTTP/1.1
> Host: lb.exmple.com
> User-Agent: curl/7.43.0
> Accept: */*
>

Любые предложения относительно того, как я могу получить сертификат, используя openssl s_client?

Даниэль Серодио
источник
2
Вы делаете это правильно. Но на основании текущей информации невозможно сказать, что идет не так: это может быть брандмауэр, блокирующий рукопожатие TLS, проблема протокола TLS .... Это может помочь, если вы предоставите (общедоступный) URL, который вы пытаетесь использовать в качестве цели, или добавите полный отладочный вывод (опция -debug) к своему вопросу.
Штеффен Ульрих
Как сказал @SteffenUllrich, это может быть TLS. Смотрите openssl ту же ошибку - возможное решение здесь .
Зина

Ответы:

21

Через некоторое время я понял это: этот конкретный балансировщик нагрузки был настроен на использование только TLSv1.2, чего не понимает версия openssl, включенная в OS X (0.9.8). Я установил более новую версию openssl (> = 1.0.1), используя homebrew, так что это работает:

/usr/local/opt/openssl/bin/openssl s_client -showcerts -connect lb.example.com:443
Даниэль Серодио
источник
3

Я пытаюсь получить сертификат SSL / TLS для одного из наших балансировщиков нагрузки (Netscaler), используя:

 openssl s_client -showcerts -connect lb.example.com:443

Если это современная конфигурация (некоторые отказываются от того, что это значит), используйте:

openssl s_client -connect lb.example.com:443 -tls1 -servername lb.example.com | \
openssl x509 -text -noout

CONNECTED(00000003)
write to 0x7fec7af0abf0 [0x7fec7b803a00] (130 bytes => 130 (0x82))
0000 - 80 80 01 03 01 00 57 00-00 00 20 00 00 39 00 00
...

Похоже, что в байтах 0 и 1 есть дополнительная преамбула. В байте 2 должен быть тип записи. В байтах 3 и 4 должен быть номер версии. Байты 5 и 6 должны быть длиной 16 битов полезной нагрузки.

Вот рабочий пример:

$ openssl s_client -connect www.googl.com:443 -tls1 -servername www.googl.com -debug
CONNECTED(00000005)
write to 0x7f7fe1c1fa30 [0x7f7fe2022000] (132 bytes => 132 (0x84))
0000 - 16 03 01 00 7f 01 00 00-7b 03 01 71 c0 12 35 98
...

Сверху тип записи находится в позиции 0, а ее значение равно 0x16. 0x16 - это тип рукопожатия. Версия слоя записи - это следующие два байта в позициях 2 и 3. Их значения 0x03 0x01. Длина полезной нагрузки составляет 0x007f.

Также см. RFC 5246, Версия 1.2 протокола безопасности транспортного уровня (TLS) , стр. 18:

6.2.1.  Fragmentation

   The record layer fragments information blocks into TLSPlaintext
   records carrying data in chunks of 2^14 bytes or less.  Client
   message boundaries are not preserved in the record layer (i.e.,
   multiple client messages of the same ContentType MAY be coalesced
   into a single TLSPlaintext record, or a single message MAY be
   fragmented across several records).

      struct {
          uint8 major;
          uint8 minor;
      } ProtocolVersion;

      enum {
          change_cipher_spec(20), alert(21), handshake(22),
          application_data(23), (255)
      } ContentType;

      struct {
          ContentType type;
          ProtocolVersion version;
          uint16 length;
          opaque fragment[TLSPlaintext.length];
      } TLSPlaintext;

Возможно, ваша проблема связана со старым типом записи, совместимым с SSLv2. Или это может быть версия OpenSSL более низкого уровня, скажем, 0.9.5 или 0.9.8. Трудно сказать, и нам, вероятно, нужно больше информации.

Более подробная информация будет включать в себя ОС; Версия OpenSSL; если вы попытались заменить версию платформы OpenSSL своей собственной версией OpenSSL; если запущен брандмауэр или окно "веб-проверки" или другое промежуточное ПО; и что получает сервер.


Использование -servername lb.example.comне помогает, и наш системный администратор сказал мне, что наши балансировщики нагрузки все равно не используют SNI.

Это звучит немного необычно. Но это расширение TLS, поэтому его игнорируют, если оно не используется (и не приведет к фатальному предупреждению).

Основное правило в 2016 году: всегда используйте TLS 1.0 или выше и всегда используйте SNI.

jww
источник