Проверка параметров SSL/TLS-серверов в консоли FreeBSD

Проверка параметров SSL/TLS Если Вы захотите выяснить параметры SSL/TLS некоторого публичного HTTPS-сервера, Вам поможет не нуждающийся в представлении SSL Server Test от Qualys SSL Labs. А что делать, если потребуется проверить аналогичные параметры HTTPS-серверов, доступ к которым ограничен, или серверов FTP, IRC, IMAP, POP3, SMTP, XMPP и PostgreSQL, которые поддерживают SSL/TLS? Не думаю, что Вы сильно удивитесь, если я предложу воспользоваться популярными в мире Linux и Unix инструментами, к числу которых относятся OpenSSL, nmap и SSLScan.

Какие параметры мы будем проверять?

Эта заметка описывает относительно простые в использовании и доступные в большинстве операционных систем семейства Linux / Unix способы проверки таких параметров SSL/TLS-серверов, как свойства и отсутствие ошибок установки их собственных SSL-сертификатов (далее — сертификатов), свойства и корректность работы цепочек сертификатов, в состав которых входят серверные сертификаты, поддержка TLS-расширений Server Name Indication и OCSP stapling, поддержка SSL/TLS-протоколов (далее — протоколов), а также соответствующих им наборов шифров, и, наконец, наличие некоторых опасных уязвимостей. Невзирая на то, что для решения перечисленных задач хватит функциональности OpenSSL, я рекомендую Вам не игнорировать соответствующие возможности nmap и SSLScan, использование которых не требует специальной подготовки, а результаты работы предоставляются в более простой для восприятия форме.

Подготовка OpenSSL, nmap и SSLScan

Все действия, которые описаны в данной заметке, выполнялись на компьютере с операционной системой FreeBSD 9.3 RELEASE. Все упоминаемое программное обеспечение устанавливалось из обновленной коллекции портов. Обязательно учтите, что для корректного решения поставленной задачи требуется заменить устаревший пакет OpenSSL, входящий в состав FreeBSD, более свежим аналогом из коллекции портов. Для его установки необходимо выполнить команды:

cd /usr/ports/security/openssl
make WITH="ZLIB" install clean

Следует отметить, что выбор опции [X] ZLIB zlib compression support (добавление WITH="ZLIB" в команду make install) не является обязательным, но он будет полезен в том случае, если Вы планируете не только проверять параметры SSL/TLS-серверов, но и тестировать их на наличие уязвимостей.
После завершения установки OpenSSL нужно добавить в файл /etc/make.conf строку:

DEFAULT_VERSIONS+=ssl=openssl

Теперь устанавливаемые порты будут использовать обновленный OpenSSL (порты, установленные до обновления OpenSSL, придется пересобрать).
Для установки nmap и SSLScan необходимо выполнить команды:

cd /usr/ports/security/nmap
make WITH="SSL" install clean
cd ../sslscan
make install clean

В связи с тем, что браузеры и другие SSL/TLS-клиенты используют корневые сертификаты из своих собственных хранилищ доверенных корневых сертификатов, поставщики сертификатов не рекомендуют устанавливать корневые сертификаты на серверы. Для избавления от проблем, связанных с отсутствием тех или иных корневых сертификатов, входящих в состав цепочек сертификации, достаточно установить порт security/ca_root_nss командами:

cd /usr/ports/security/ca_root_nss
make WITH="ETCSYMLINK" install clean

После завершения установки / переустановки перечисленных портов можно приступать к проверке параметров TLS/SSL-серверов.

Общий случай использования команды openssl s_client

Команда openssl s_client предназначена для установки соединения с удаленным SSL/TLS-сервером, передачи ему команд, приема результатов их выполнения и отображения информации об используемых параметрах SSL/TLS. Если команда не содержит ключ -connect host:port, выполняется подключение к серверу localhost:4433. По умолчанию сведения о параметрах SSL/TLS имеют среднюю детальность (на мой взгляд, она устроит подавляющее большинство системных администраторов), если добавить ключ -brief — минимальную, ключи -debug и / или -tlsextdebug — повышенную. В общем случае для проверки параметров какого-либо SSL/TLS-сервера достаточно указать команду s_client и единственный ключ -connect host:port. Например, команда:

/usr/local/bin/openssl s_client -connect sergeysl.ru:443

отобразит примерно такие сведения о HTTPS-сервере, на котором размещается мой персональный сайт (для сокращения размера данной заметки значительная часть содержимого сертификата сервера (Server certificate) и мандата сессии TLS (TLS session ticket) заменена точками):

CONNECTED(00000003)
depth=2 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN = StartCom Certification Authority
verify return:1
depth=1 C = IL, O = StartCom Ltd., OU = StartCom Certification Authority, CN = StartCom Class 1 DV Server CA
verify return:1
depth=0 C = RU, CN = sergeysl.ru
verify return:1
---
Certificate chain
 0 s:/C=RU/CN=sergeysl.ru
   i:/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class 1 DV Server CA
 1 s:/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class 1 DV Server CA
   i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIF6jCCBNKgAwIBAgIQVIe8Ciouz5R26m58bbO00DANBgkqhkiG9w0BAQsFADB4
................................................................
RO9fEYR80dy/SIvyqZEJS2XyONjfUDUjsM2r3nBm
-----END CERTIFICATE-----
subject=/C=RU/CN=sergeysl.ru
issuer=/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class 1 DV Server CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3709 bytes and written 434 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 3D9D9BA7E798D4F7DA5565C099F81FD9834CB7890AE4172B120BFDAFB402E24A
    Session-ID-ctx:
    Master-Key: 54EBCC204BE2EA99E8F4A5900C3BBAAF9B8942F818074BD1BF426E1E1F567E2E654F9D15C5C745045FCD094E6B32C52D
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 600 (seconds)
    TLS session ticket:
    0000 - 67 99 2a b8 f1 1f 3c 36-58 62 8f d5 08 9a 60 f2   g.*...<6Xb....`.
    .... - .. .. .. .. .. .. .. ..-.. .. .. .. .. .. .. ..   ................
    00a0 - 92 91 4e 8a e9 30 59 04-7f 2b 4c 35 29 e7 5f 4e   ..N..0Y..+L5)._N

    Start Time: 1469379229
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

Представленное сообщение содержит следующую информацию (для повышения удобства восприятия соответствующие группы строк выделены):
 Строка 1 подтверждает факт установки соединения (CONNECTED);
 Строки 2-8 содержат результат проверки цепочки сертификатов, использованной при установке соединения. Для каждого сертификата отображается глубина в цепочке сертификатов (depth), страна (C), организация (O), подразделение (OU), имя (CN) субъекта сертификации и результат проверки (verify return). Отсутствие части перечисленных сведений для бесплатного сертификата сервера связано с тем, что он не подтверждает принадлежность домена какой-либо организации;
 Строки 9-14 отображают содержимое цепочки сертификатов, установленной на сервер (Certificate chain). Для каждого сертификата отображается назначение (s), содержащее, такие сведения, как страна (C), организация (O), подразделение (OU), имя (CN) субъекта сертификации и аналогичная информация об издателе (i). По описанной в предыдущем пункте причине для сертификата сервера отображаются только страна и имя субъекта сертификации;
 Строки 15-23 содержат текст сертификата сервера в формате PEM, его назначение (subject) и информацию об издателе (issuer);
 Строки 24-55 отображают подробную информацию как о параметрах сервера, так и о параметрах текущего соединения. В них можно увидеть, что используется современный (New) протокол TLSv1.2 и набор шифров (Cipher) ECDHE-RSA-AES256-GCM-SHA384 (такая аббревиатура обозначает, что для генерации сеансового ключа используется алгоритм Диффи-Хеллмана на эллиптических кривых, для аутентификации сервера — алгоритм RSA, для шифрования трафика — алгоритм AES с длиной ключа 256 бит в режиме GCM, для контроля целостности (MAC) — алгоритм SHA384), публичный ключ сервера (Server public key) имеет длину 2048 бит, сервер поддерживает возобновление TLS-сессии (Secure Renegotiation), не поддерживает сжатие (Compression) и т.д. и т.п.
В связи с тем, что даже минимальный вариант команды openssl s_client предоставляет внушительные объемы информации о параметрах SSL/TLS-серверов, имеет смысл внимательнее разобраться в том, какие сведения нам понадобятся, и как использовать их для решения наших задач.

Проверка сертификата сервера и цепочки сертификатов с помощью openssl s_client

Для проверки параметров и отсутствия ошибок установки сертификата сервера, а также корректности работы цепочки сертификатов, частью которой он является, подойдет все та же команда openssl s_client. В рассмотренном выше примере показан результат ее работы для случая, когда сертификат сервера установлен корректно, и цепочка сертификатов не содержит ошибок. Например, при подключении к SSL/TLS-серверу с просроченным самоподписным сертификатом будут отображены примерно такие сведения (сообщения об ошибках выделены, «лишние» данные заменены точками):

CONNECTED(00000003)
depth=0 C = RU, ST = ..., L = ..., O = ..., OU = ..., CN = ..., emailAddress = ...
verify error:num=18:self signed certificate
verify return:1
depth=0 C = RU, ST = ..., L = ..., O = ..., OU = ..., CN = ..., emailAddress = ...
verify error:num=10:certificate has expired
notAfter=Aug 22 11:02:28 2015 GMT
verify return:1
depth=0 C = RU, ST = ..., L = ..., O = ..., OU = ..., CN = ..., emailAddress = ...
notAfter=Aug 22 11:02:28 2015 GMT
verify return:1
---
...
    Verify return code: 10 (certificate has expired)
---

 Для указания глубины верификации (или максимальной длины) цепочки сертификатов и включения проверки сертификата сервера необходимо добавить ключ -verify depth (depth — глубина проверки). В настоящее время проверка продолжается при появлении сообщений об ошибках, что позволяет диагностировать все проблемы в цепочке сертификатов. При этом возникает побочный эффект, который заключается в том, что соединение не обрывается, даже если сертификат сервера признается некорректным.
 Для прекращения проверки цепочки сертификатов при наличии критических ошибок следует указать ключ -verify_return_error. Например, его применение при проверке SSL/TLS-сервера с просроченным самоподписным сертификатом заметно сократит результат проверки цепочки сертификатов:

CONNECTED(00000003)
depth=1 C = ..., ST = ..., L = ..., O = ..., OU = ..., CN = ..., emailAddress = ...
verify error:num=19:self signed certificate in certificate chain
---
...
    Verify return code: 19 (self signed certificate in certificate chain)
---

 Для просмотра содержимого всех сертификатов цепочки сертификатов, а не только сертификата сервера нужно добавить ключ -showcerts.
 Для проверки цепочки сертификатов, корневой сертификат которой отсутствует в хранилище доверенных корневых сертификатов, необходимо применить один из ключей -CApath или -CAfile. Первый ключ позволяет указать путь к папке, имеющей формат hash, с корневым сертификатом, второй — имя файла в формате PEM с корневым сертификатом. Описание формата hash и список ключей, позволяющих выполнять дополнительные проверки параметров сертификата сервера, можно найти в документе verify.

Проверка поддержки технологии Server Name Indication с помощью openssl s_client

Для проверки того, что SSL/TLS-сервер поддерживает технологию SNI (Server Name Indication) придется немного усложнить команду openssl s_client путем добавления ключей -servername (он включает TLS-расширение SNI путем изменения соответствующих полей сообщения ClientHello), а также -tlsextdebug (он включает отображение дампа TLS-расширений, полученных с сервера). В связи с тем, что из весьма внушительного объема предоставляемых данных нам будет нужна единственная строка с текстом server name, имеет смысл найти ее с помощью grep(1) и отправить все «лишние» сведения, отображаемые через stderr, в /dev/null (учтите, что перенаправлении данных в /dev/null может привести к перегреву центрального процессора 😆 ). С учетом сказанного для проверки поддержки SNI, например, на HTTPS-сервере google.com следует выполнить команду:

/usr/local/bin/openssl s_client -connect google.com:443 -servername google.com -tlsextdebug 2>/dev/null | grep "server name"

Если HTTPS-сервер поддерживает технологию SNI (google.com ее поддерживает), будет отображено примерно такое сообщение:

TLS server extension "server name" (id=0), len=0

Если SNI не поддерживается, Вы не увидите никаких сообщений.

Проверка поддержки технологии OCSP stapling с помощью openssl s_client

Для проверки того, что SSL/TLS-сервер поддерживает технологию OCSP stapling, придется добавить в команду openssl s_client ключ -status (он включает отправку запроса состояния OCSP stapling и отображение полученного ответа). В связи с тем, что интересующие нас данные начинаются со строки, содержащей текст OCSP response: и занимают 17 строк, последняя из которых в случае поддержки OCSP stapling включает текст Next Update:, можно найти и обрезать нужные сведения с помощью двух вызовов grep(1), а заодно отправить «лишнюю» информацию, отображаемую через stderr, в /dev/null. Из-за того, что необходимые нам данные отправляются сервером после закрытия соединения, следует сразу передать ему команду QUIT. С учетом сказанного для проверки поддержки OCSP stapling, например, на HTTPS-сервере yandex.ru придется выполнить команду:

echo QUIT | /usr/local/bin/openssl s_client -connect yandex.ru:443 -status 2>/dev/null | grep -A 17 'OCSP response:' | grep -B 17 'Next Update:'

Если HTTPS-сервер поддерживает технологию OCSP stapling (yandex.ru ее поддерживает), будет отображено примерно такое сообщение:

OCSP response:
======================================
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = PL, O = Unizeto Technologies S.A., CN = Certum Validation Service
    Produced At: Aug 13 18:36:03 2016 GMT
    Responses:
    Certificate ID:
      Hash Algorithm: sha1
      Issuer Name Hash: AD9E23067DA87259458311E48B5056CD47D24B02
      Issuer Key Hash: 375CE319E0B28EA1A84ED2CFABD0DCE30B5C354D
      Serial Number: 25DF9C4886B7B8CC8815AD6A69C47E30
    Cert Status: good
    This Update: Aug 13 18:36:03 2016 GMT
    Next Update: Aug 20 18:36:03 2016 GMT

Если OCSP stapling не поддерживается, Вы не увидите никаких сообщений.
Остается добавить, что я не рекомендую Вам запоминать рассмотренную в этом разделе команду, по крайней мере, до знакомства с SSLScan, который позволяет выполнять аналогичные действия более простым способом.

Проверка поддержки протоколов и наборов шифров с помощью openssl s_client

Поддержка тех или иных протоколов и наборов шифров определяет безопасность сервера и список клиентов, которые могут его использовать. Для получения хотя бы примерного представления о данном вопросе, имеет смысл познакомиться с документом ciphers и почитать качественные статьи соответствующей тематики, такие как Выбор ciphersuites для TLS и уязвимость Logjam. Опыт Яндекса. После этого можно начинать проверку поддержки протоколов и наборов шифров.
По умолчанию команда openssl s_client использует максимальную версию протокола, одновременно поддерживаемую клиентом и сервером.
 Для проверки того, что SSL/TLS-сервер поддерживает протокол SSLv2, SSLv3, TLSv1, TLSv1.1 или TLSv1.2, нужно указать один из ключей -ssl2, -ssl3, -tls1, -tls1_1 или -tls1_2, соответственно. Например, для проверки поддержки протокола SSLv2 на HTTPS-сервере этого сайта необходимо выполнить команду:

/usr/local/bin/openssl s_client -connect sergeysl.ru:443 -ssl2

Она должна закрыть соединение с HTTPS-сервером примерно с таким сообщением об ошибке:

CONNECTED(00000003)
write:errno=54
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 39 bytes
---
New, (NONE), Cipher is (NONE)
...
SSL-Session:
    Protocol  : SSLv2
    Cipher    : 0000
...
    Verify return code: 0 (ok)
---

При аналогичной проверке поддержки протокола SSLv3 сообщения об ошибке изменится:

CONNECTED(00000003)
34381169544:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:1472:SSL alert number 40
34381169544:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:656:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
...
SSL-Session:
    Protocol  : SSLv3
    Cipher    : 0000
...
    Verify return code: 0 (ok)
---

Если интересующий Вас протокол поддерживается, Вы не только увидите упомянутые в двух предыдущих разделах параметрах сервера и текущего соединения, но и сможете обмениваться командами и результатами их выполнения с сервером (соединение будет оставаться открытым, пока Вы его не закроете).
 Для того чтобы отказаться от использования протокола SSLv2, SSLv3, TLSv1, TLSv1.1 и TLSv1.2 (или любой комбинации данных протоколов), следует добавить ключ (или любую комбинацию ключей) -no_ssl2, -no_ssl3, -no_tls1, -no_tls1_1 и -no_tls1_2, соответственно.
 Для получения списка наборов шифров, которые поддерживает OpenSSL, нужно выполнить команду:

/usr/local/bin/openssl ciphers

 Для того чтобы сведения о наборах шифров стали более подробными, необходимо указать ключ -v
 Для отображения наборов шифров, соответствующих протоколам SSLv3-TLSv1.2, следует добавить ключ -ssl3 (или -tls1), протоколу SSLv2 -ключ -ssl2.
 Для гибкого ограничения списка используемого набора шифров нужно дополнить команду необязательной строкой cipherlist, позволяющей задать один или несколько наборов шифров, разделенных двоеточиями (запятые и пробелы допустимы, но почти не используются). Например, строка 'RC4-SHA' определяет один набор шифров, строка 'SHA1' — наборы шифров, включающие алгоритм SHA1, строка 'SSLv3' — наборы шифров, которые связаны с протоколом SSLv3. Строки могут объединяться с помощью символа +, обозначающего логическую операцию AND. Например, строка 'SHA1+DES' задает наборы шифров, имеющие в составе алгоритмы SHA1 и DES. Каждая из строк может предваряться символами !, - или +, при этом ! обеспечивает удаление наборов шифров, определенных в следующей за ним строке (удаление происходит даже в случае последующего явного включения соответствующие наборов шифров), - удаляет соответствующие наборы шифров, но позволяет включить их в дальнейшем, + не добавляет дополнительные наборы шифров, а перемещает существующие в конец списка. Когда строка не начинается с перечисленных символов, она интерпретируется как определение набора шифров, которое необходимо добавить в существующий список наборов шифров. Если строка включает уже добавленные наборы шифров, она будет проигнорирована — соответствующие наборы шифров не будут помещены в конец списка. Строка, определяющая набор шифров, может быть дополнена суффиксом @STRENGTH, который обеспечивает сортировку списка наборов шифров по убыванию длины ключей (стойкости). Еще один полезный суффикс @SECLEVEL=n, позволяет указать security level, равный n. Подробное описание других возможностей строки cipherlist имеется в документе ciphers, а для первого знакомства, будет достаточно того, что здесь написано. Для улучшения понимания полученных сведений имеет смысл рассмотреть несколько примеров cipherlist из документации OpenSSL:
 'ALL:eNULL' задает все наборы шифров, кроме не обеспечивающих шифрование (они же eNULL), отсортированные по убыванию стойкости;
 'ALL:!ADH:@STRENGTH' включает все наборы шифров, кроме анонимных DH и выключенных по умолчанию eNULL, отсортированные аналогично;
 'ALL:!aNULL' задает все наборы шифров, кроме не обеспечивающих аутентификацию (они же aNULL) и выключенных по умолчанию eNULL;
 '3DES:+RSA' включает все наборы шифров, содержащие алгоритм 3DES, при этом наборы шифров с алгоритмом RSA перемещаются в конец списка;
 'RC4:!COMPLEMENTOFDEFAULT' задает все наборы шифров, включающие алгоритм RC4, кроме наборов шифров без аутентификации (COMPLEMENTOFDEFAULT обозначает все, что включено в ALL, но выключено по умолчанию. В настоящее время это все наборы шифров, содержащие алгоритм RC4, и анонимные наборы шифров. Учтите, что если Вы захотите включить eNULL, не входящий в состав ALL, придется заменить COMPLEMENTOFDEFAULT на COMPLEMENTOFALL);
 'RSA:!COMPLEMENTOFALL' включает все наборы шифров, содержащие алгоритм RSA, кроме описанных выше COMPLEMENTOFALL;
 'ALL:@SECLEVEL=2' задает все наборы шифров, соответствующие security level, равному 2.
 После получения элементарного представления о наборах шифров можно вернуться к команде openssl s_client, позволяющей проверять их поддержку на SSL/TLS-серверах. Для выполнения такой проверки необходимо указать ключ -cipher, дополненный рассмотренной выше строкой cipherlist. Признаки того, что набор шифров поддерживается или не поддерживается, аналогичны рассмотренным при описании проверки поддержки протоколов. Следует отметить, что как и в случае с протоколами, при указании нескольких наборов шифров используется самый стойкий, одновременно поддерживаемый клиентом и сервером. В связи с этим для выявления поддержки всех наборов шифров на некотором SSL/TLS-сервере нужно выполнить приличное количество команд openssl s_client, либо автоматизировать эту процедуру с помощью примерно таких скриптов. На мой взгляд, указанные способы выявления списка поддерживаемых наборов шифров хороши для хакеров специалистов по безопасности, но слишком сложны для применения в повседневной жизни, поэтому (как и в случае с проверкой поддержки OCSP stapling) я не рекомендую Вам использовать их до знакомства с соответствующими возможностями nmap и SSLScan.

Проверка параметров SSL/TLS-серверов с помощью nmap

Одна из многочисленных возможностей nmap заключается в поддержке скриптов, написанных на языке Lua. Сегодня в комплект поставки nmap входит более 500 таких скриптов. Вы можете познакомиться с ними на NSEDoc Reference Portal или изучить содержимое папки /usr/local/share/nmap/scripts. В нашем случае понадобятся скрипты с именами ssl-....nse, предназначенные для проверки таких параметров SSL/TLS-серверов, как свойства их сертификатов, списки поддерживаемые протоколов и наборов шифров, а также наличие некоторых уязвимостей. Для запуска одного (или нескольких) скриптов необходимо указать его имя (или несколько имен, разделенных запятыми) в качестве аргумента ключа -script. В связи с тем, что по умолчанию nmap проверяет все порты, имеет смысл ограничить их количество с помощью ключа -p, аргументом которого должен быть номер нужного порта (или номера нескольких портов, разделенные запятыми).
На этом можно закончить «вступительную часть» и перейти к рассмотрению примеров проверки параметров SSL/TLS-серверов с помощью nmap.
 Для получения информации о сертификате HTTPS-сервера данного сайта с необходимо выполнить команду:

nmap -script ssl-cert -p 443 sergeysl.ru

В отличие от команды openssl s_client, она отобразит параметры сертификата сервера в достаточно лаконичном виде:

...
PORT    STATE SERVICE
443/tcp open  https
| ssl-cert: Subject: commonName=sergeysl.ru/countryName=RU
| Issuer: commonName=StartCom Class 1 DV Server CA/organizationName=StartCom Ltd./countryName=IL
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2016-06-10T08:25:47
| Not valid after:  2017-06-10T08:25:47
| MD5:   de90 c9d7 fe4b 9ad9 72fe 15fc 1e7f 8f25
|_SHA-1: 759d 764d 6ab4 a895 8b32 87ff 5d73 e0d2 1e29 d397
...

 Для выявления списка протоколов и наборов шифров, поддерживаемых на HTTPS-сервере этого сайта, следует выполнить команду:

nmap -script ssl-enum-ciphers -p 443 sergeysl.ru

В отличие от команды openssl s_client, она предоставит сведения обо всех поддерживаемых протоколах и наборах шифров:

...
PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.1:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|_  least strength: C
...

Представленное сообщение содержит следующую информацию о том, что HTTPS-сервер:
 поддерживает протоколы TLSv1, TLSv1.1 и TLSv1.2;
 поддерживает перечисленные наборы шифров, сгруппированные по протоколам, при этом большинство наборов шифров имеет стойкость A, и только шифры, включающие алгоритм 3DES, отвечают уровню C (менее стойкие наборы шифров включены для обеспечения поддержки браузера Microsoft Internet Explorer 8.0 для Microsoft Windows XP). Стойкость наборов шифров обозначается буквами от A (максимальная) до F (минимальная), при этом оценка зависит от используемых алгоритмов обмена ключами и шифрования трафика, но не зависит от алгоритма контроля целостности. Для получения дополнительных сведений о методологии ранжирования конфигураций SSL/TLS-серверов стоит познакомиться с документом SSL Server Rating Guide;
 не поддерживает сжатие ни для одного из протоколов;
 самостоятельно задает предпочтительный набор шифров;
 поддерживает наборы шифров со стойкостью не ниже уровня C.
Для сравнения рассмотрим результат проверки «заброшенного» SMTPS-сервера:

PORT    STATE SERVICE
465/tcp open  smtps
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - F
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - F
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - F
|       TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - F
|       TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - F
|       TLS_DH_anon_WITH_3DES_EDE_CBC_SHA - F
|       TLS_DH_anon_WITH_AES_128_CBC_SHA - F
|       TLS_DH_anon_WITH_AES_256_CBC_SHA - F
|       TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA - F
|       TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA - F
|       TLS_DH_anon_WITH_RC4_128_MD5 - F
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA - F
|       TLS_RSA_WITH_AES_128_CBC_SHA - F
|       TLS_RSA_WITH_AES_256_CBC_SHA - F
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - F
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - F
|       TLS_RSA_WITH_RC4_128_MD5 - F
|       TLS_RSA_WITH_RC4_128_SHA - F
|     compressors:
|       NULL
|     cipher preference: client
|     warnings:
|       Broken cipher RC4 is deprecated by RFC 7465
|       Ciphersuite uses MD5 for message integrity
|       Insecure certificate signature: MD5
|_  least strength: F

В отличие от предыдущего примера, в этот раз можно увидеть, что SMTPS-сервер:
 поддерживает единственный протокол TLSv1;
 поддерживает наборы шифров с минимальной стойкость F;
 не предлагает клиентам предпочтительный набор шифров;
Кроме перечисленных сведений, сообщение содержит три предупреждения (они выделены) о том, что:
 используются наборы шифров, содержащие алгоритм RC4, запрещенный в документе RFC 7465;
 используются наборы шифров, включающие алгоритм контроля целостности MD5;
 сертификат сервера подписан с помощью небезопасного алгоритма MD5.
Как видите, разница между относительно нормальной и плохой конфигурациями заметна даже невооруженным взглядом.
 Для проверки HTTPS-сервера данного сайта на наличие уязвимостей Heartbleed (CVE-2014-0160), MITM CCS injection (CVE-2014-0224), а также Logjam (CVE 2015-4000) (в связи с тем, что протоколы SSLv2 и SSLv3 выключены, не имеет смысла искать связанные с ними уязвимости) нужно выполнить команду:

nmap -script ssl-heartbleed,ssl-ccs-injection,ssl-dh-params -p 443 sergeysl.ru

Если соответствующие уязвимости отсутствуют, она не отобразит никаких сведений, кроме номера порта, протокола, состояния и типа службы:

...
PORT    STATE SERVICE
443/tcp open  https

...

Это все, что я хотел рассказать о соответствующей функциональности nmap. Остается добавить, что Вы должны рассматривать упомянутые и «забытые» скрипты для nmap как удобные дополнительные инструменты, но ни в коем случае не как самодостаточный комплекс для выявления уязвимостей SSL/TLS-серверов.

Проверка параметров SSL/TLS-серверов с помощью SSLScan

SSLScan позиционируется автором как простой и быстрый инструмент проверки параметров SSL/TLS-серверов. Собственно, таковым он и является. Как и оба уже рассмотренных инструмента, SSLScan позволяет проверять параметры сертификатов SSL/TLS-серверов, получать списки поддерживаемых протоколов и наборов шифров, а также выявлять наличие уязвимости Heartbleed (CVE-2014-0160). Кроме этого, SSLScan позволяет проверять поддержку технологии OCSP.
Особенность SSLScan заключается в отображении разноцветных сообщений, при этом соответствующие цвета сигнализируют о нормальных, посредственных или нуждающихся в исправлении значениях параметров:
 Красный цвет фона, сильнее всего привлекающий внимание, выделяет наборы шифров, не обеспечивающие шифрование;
 Красный цвет текста — устаревшие наборы шифров (≤40 бит), устаревшие протоколы SSLv2 / SSLv3 и устаревший алгоритм подписи сертификатов MD5;
 Желтый цвет текста — слабые наборов шифров (≤56 бит), наборы шифров, содержащие алгоритм RC4, и слабый алгоритм подписи сертификатов SHA1;
 Розовый цвет текста — наборы шифров, содержащие анонимные DH-алгоритмы ADH или AECDH;
 Зеленый цвет текста — стойкие наборы шифров и алгоритмы подписи сертификатов.
В общем случае при запуске SSLScan достаточно указать в командной строке только имя хоста и номер порта (если номер порта не задан, используется значение 443), разделенные двоеточием. Например, для проверки параметров HTTPS-сервера этого сайта необходимо выполнить команду:

sslscan sergeysl.ru

Она отобразит примерно такие сведения о параметрах HTTPS-сервера и его сертификата, а также о поддерживаемых протоколах и наборах шифров:

Относительно нормальный результат проверки параметров HTTPS-сервера с помощью SSLScan

В связи с тем, что информация, представленная в сообщении, прокомментирована выше, я не буду повторяться. Обратите внимание на значительное количество зеленого, небольшое желтого, и, наконец, полное отсутствие розового и красного цветов. Такая «цветовая гамма» является признаком относительно приемлемой конфигурации HTTPS-сервера. Для сравнения следует рассмотреть результат проверки уже упоминавшегося «заброшенного» SMTPS-сервера:

Плохой результат проверки параметров SMTPS-сервера с помощью SSLScan

В отличие от предыдущего примера, в этот раз можно увидеть присутствие красного цвета, привлекающего внимание к устаревшему алгоритму подписи, слабому ключу, недоверенному издателю, а также истекшему сроку действия сертификата (все перечисленное совершенно естественно для самоподписного сертификата, сгенерированного более 10 лет назад). Кроме красного, можно заметить приличное количество розового и желтого цветов. Такая «цветовая гамма» говорит о том, что конфигурация SMTPS-сервера давно требует напильника обновления (жаль, что не все владельцы подобных серверов способны это услышать).
 Для отключения некоторых проверок SSLScan и соответствующего уменьшения объема отображаемых сведений следует воспользоваться ключом (или любой комбинацией ключей) --no-check-certificate, --no-ciphersuites, --no-renegotiation, --no-compression, --no-heartbleed. Первый из них отключает выявление устаревших алгоритмов подписи сертификатов MD5 или SHA-1 и коротких (<2048 бит) ключей, второй — проверку поддерживаемых наборов шифров, третий и четвертый — проверку поддержки возобновления TLS-сессии и сжатия, пятый — выявление уязвимости Heartbleed (CVE-2014-0160).
 Для проверки только тех наборов шифров, которые связаны с протоколом SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2 или всеми протоколами TLS версии от 1.0 до 1.2, следует указать ключ --ssl2, --ssl3, --tls10, --tls11, --tls12 или --tlsall, соответственно.
 Для сокрытия имен эллиптических кривых и длин ключей EDH/RSA необходимо добавить ключ --no-cipher-details (он работает только с OpenSSL ≥1.0.2).
 Для превращения цветных сообщений в монохромные (не представляю, зачем это может понадобиться) следует указать ключ --no-colour.
 Для добавления в отображаемое сообщение подробной информации о параметрах сертификата сервера нужно добавить ключ --show-certificate.
 Для проверки поддержки технологии OCSP необходимо указать ключ --ocsp (вспомните соответствующий вариант команды openssl s_client 😉 ).
На этом можно закончить краткий рассказ про SSLScan. Я не могу сказать, что SSLScan способен заменить рассмотренные выше инструменты, однако он имеет полное право стать их дополнением. Невзирая на «заброшенное» состояние, в настоящее время SSLScan корректно выполняет свои функции. Будем надеяться, что его форк rbsec/sslscan продолжит развиваться и рано или поздно заменит своего родителя.

Проверка параметров SSL/TLS-серверов с поддержкой STARTTLS

Остается добавить, что команда openssl s_client и SSLScan позволяют проверять параметры SSL/TLS-серверов с поддержкой технологии STARTTLS.
 Для проверки параметров FTP-, IMAP-, POP3 и SMTP-серверов, поддерживающих STARTTLS, с помощью команды openssl s_client следует указывать ключ -starttls с аргументом ftp, imap pop3 или smtp, соответственно.
 Для проверки параметров FTP-, IRC-, IMAP-, POP3-, SMTP-, PostgreSQL- и XMPP-серверов, поддерживающих STARTTLS, с помощью SSLScan нужно добавлять один из ключей --starttls-ftp, --starttls-irc, --starttls-imap, --starttls-pop3, --starttls-smtp (в случае зависания соединения с SMTP-сервером из-за использования протокола SSLv3 поверх соединения STARTTLS необходимо указать описанный в предыдущем разделе ключ --tlsall), --starttls-psql и --starttls-xmpp, соответственно. Если добавление ключа --starttls-xmpp не помогает, можно попробовать заменить его на --xmpp-server (данный ключ предназначен для инициирования XMPP-соединения сервер-сервер).

Заключение

Я надеюсь, что собранные здесь рекомендации помогут Вам начать проверку параметров обслуживаемых SSL/TLS-серверов, а затем плавно перейти к внесению изменений в их конфигурации. Ни в коем случае не торопитесь, старательно изучайте соответствующую документацию, и через некоторое время Ваши серверы будут иметь практически идеальные параметры SSL/TLS. При появлении свободного времени я постараюсь помогать Вам в этом, а пока предлагаю поучаствовать в обсуждении (конструктивная критика приветствуется) и благодарю за внимание!

Понравилась статья?

 Подписывайтесь на RSS или почтовую рассылку;

 Присоединяйтесь в Twitter, Facebook, Google+, VK;

 Делитесь ссылкой в социальных сетях или блогах:

Оставить комментарий