пятница, 27 июля 2012 г.

Workflow: SSL сертификаты

Одна из рутинных операций, с которыми приходится сталкиваться системному администратору - управление SSL сертификатами. Я постараюсь собрать на одной странице справочное руководство, которое поможет управлять жизненным циклом сертификата. Для наглядности процесса я буду описывать процедуру в контексте WEB сервера (в остальных случаях многое совпадает, хотя есть и различия).

Для себя я выделяю несколько этапов в жизненном цикле SSL сертификата:
  • создание SSL сертификата
  • установка SSL сертификата
  • мониторинг валидности и срока окончания SSL сертификата

Создание SSL сертификата


Сертификат может быть подписан удостоверяющим центром (Certificate Authority, CA), чей сертификат не входит в список сертификатов корневых удостоверяющих центров (Root CA) включенных в поставку ОС или браузера, в этом случае он называется само-подписанным (self-signed).

 Генерация запроса на подписывание сертификата (Certificate Sign Request, CSR)


Создаем приватный ключ для сертификата (в целях безопасности создавется ключ с длиной 2048 бит)

$ openssl genrsa -out www.example.com.key 2048
Generating RSA private key, 2048 bit long modulus
............+++
.....................+++
e is 65537 (0x10001)

Далее генерируем запрос на подпись сертификата

$ openssl req -new -key www.example.com.key -out www.example.com.csr -subj '/CN=www.example.com/emailAddress=postmaster@example.com/'

Созданный запрос находится в файле www.example.com.csr. Дальнейшие действия зависят от CA и я их описывать не буду.

Генерация self-signed сертификата


Если нужно быстро создать self-signed сертификат, то это делается так

$ openssl req -new -nodes -x509 -out test.pem -newkey rsa:2048 -keyout test.pem -days 3650

в этом случае будет создан сертификат в формате PEM, действительный 10 лет с приватной частью без пароля и длиной ключа 2048 бит.

Если вы хотите использовать SAN (Subject Alternate Names), то сначала нужно выполнить шаги, описанные в разделе "Генерация запроса на подписывание сертификата", после чего у вас будет два файла: www.example.com.key и www.example.com.csr - они пригодятся для генерации сертификата.

$ cat > www.example.com.cnf << EOF
subjectAltName=DNS:example.com
EOF

$ openssl x509 -req -days 365 -in www.example.com.csr -signkey www.example.com.key -text -extfile www.example.com.cnf -out www.example.com.crt
Signature ok
subject=/CN=www.example.com/emailAddress=postmaster@example.com
Getting Private key

Установка SSL сертификата


В этом разделе я рассмотрю установку сертификата для наиболее часто встречающихся web-серверов Apache2 и Nginx. Для других процедура схожая и подробна описана в документации.

Если у вас сертификат self-signed, то вам нужны два файла: www.example.com.key - приватный ключ и www.example.com.crt - сертификат для домена www.example.com. Если же сертификат был куплен у CA, то зачастую к нему прилагается еще и сертификат CA, например gd_bundle.crt (у GoDaddy)

Установка сертификата для Apache2


Чтобы ограничить доступ к использованию сертификата, его приватный ключ доступен только пользователю root.

$ ls -l /etc/ssl/{certs,private}/www.example.com.*
-rw-r--r-- 1 root root 3951 Июл 27 12:57 /etc/ssl/certs/www.example.com.crt
-rw------- 1 root root 1675 Июл 27 12:42 /etc/ssl/private/www.example.com.key

Добавьте в файл конфигурации сайта блок

<IfModule mod_ssl.c>
    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/www.example.com.crt
    SSLCertificateKeyFile /etc/ssl/private/www.example.com.key
    # Uncomment line below if you have intermediate CA certificate
    #SSLCertificateChainFile /etc/ssl/certs/your_CA_intermediate.crt
</IfModule>

После этого можно перезагрузить конфигурацию Apache

# service httpd configtest && service httpd reload

Установка сертификата для Nginx


Добавьте в конфигурацию сайта блок

ssl_engine on;
ssl_certificate /etc/ssl/certs/www.example.com.crt;
ssl_certificate_key /etc/ssl/private/www.example.com.key;

Если у вас есть сертификат для intermediate CA, то его нужно объединить с сертификатом домена

# cat /etc/ssl/certs/www.example.com.crt /etc/ssl/certs/your_CA_intermediate.crt > /etc/ssl/certs/www.example.com_nginx.crt

И далее использовать для Nginx /etc/ssl/certs/www.example.com_nginx.crt вместо /etc/ssl/certs/www.example.com.crt. После этого можно перезагрузить конфигурацию Nginx

# nginx -t && service nginx reload

Мониторинг валидности SSL сертификата


Проверить срок окончания действия сертификата можно при помощи плагина Nagios. Для этого в файл /etc/nagios/commands.cfg нужно добавить:

define command{
    command_name check_ssl_cert
    command_line $USER1$/check_http -H $HOSTADDRESS$ -I $HOSTADDRESS$ -S -C $ARG1$
}

После этого нужно добавить новый сервис в хосты, где нужна проверка SSL сертификатов.

define service{
    use                 generic-service
    host_name           example.com
    service_description certificate expiration
    contact_groups      admins
    check_command       check_ssl_cert!30
}

Получение информации о SSL сертификате


Чтобы получить информацию о сертификате www.example.com.crt нужно выполнить:

$ openssl x509 -in www.example.com.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            cb:c6:3f:6f:36:40:9a:a7
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN=example.com/emailAddress=postmaster@example.com
        Validity
            Not Before: Jul 27 09:57:09 2012 GMT
            Not After : Jul 27 09:57:09 2013 GMT
        Subject: CN=example.com/emailAddress=postmaster@example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:ab:26:02:ea:14:6d:36:d0:61:9e:d6:45:d5:fe:
                    6b:a5:f6:ac:de:2c:93:41:91:56:e0:0c:e8:25:43:
                    d2:6e:25:2a:5b:81:fd:bf:1f:72:ec:94:84:32:35:
                    6f:d9:ec:8f:87:c1:94:d4:58:7a:ab:bc:9e:5b:4d:
                    e1:d9:9f:97:08:db:6a:9d:1d:dd:c4:af:c2:f7:79:
                    80:e0:15:f5:43:01:1f:09:c4:78:60:7a:34:d0:20:
                    db:67:47:12:33:1b:0e:d1:8a:db:e7:25:df:7b:66:
                    1d:fa:09:c5:61:50:05:51:bd:9d:06:59:79:a0:77:
                    eb:fb:f8:f1:40:a8:8c:6f:fe:99:54:74:40:61:a5:
                    35:18:99:88:e2:34:66:05:0e:94:8a:c7:65:60:d4:
                    1a:b6:69:d4:63:a4:e4:fe:28:53:a9:1e:f2:b1:c5:
                    98:4b:6a:59:92:32:59:10:12:38:57:c4:56:41:ba:
                    ac:01:24:ee:eb:3d:eb:a3:a6:91:11:18:9f:0f:04:
                    a6:f9:d4:a0:4f:fb:6e:bd:83:9f:d0:eb:68:26:dc:
                    f9:f0:f0:44:4d:6a:50:48:a5:df:39:6f:ef:99:b7:
                    d3:00:ff:41:cd:44:54:fe:aa:10:73:0f:b7:e6:7e:
                    18:28:95:b9:2d:8d:cc:83:19:31:2e:fd:16:4c:78:
                    f3:2b
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                DNS:www.example.com
    Signature Algorithm: sha1WithRSAEncryption
        0a:bb:ec:fe:b9:a3:de:63:9c:42:42:8f:aa:5c:a5:6e:f0:aa:
        d6:b1:5b:ee:03:c3:89:af:61:98:e5:84:fb:03:1b:80:d7:a7:
        bb:c0:f7:3d:59:1e:51:76:43:83:f2:17:08:2a:7f:03:f0:7d:
        b8:08:df:87:c4:40:5d:dd:26:8c:27:01:18:9c:6b:e4:4d:f9:
        bd:58:d5:85:2b:dc:e2:11:ff:b1:98:ea:8e:72:b2:24:22:ab:
        d5:f1:ea:3e:56:79:db:32:38:57:43:6f:42:2b:9d:ef:5b:37:
        b0:6f:d5:fe:80:04:67:4f:88:ce:84:20:6a:13:f0:8a:b4:75:
        6f:70:6f:f8:f2:b6:4b:74:50:6d:81:24:4a:1c:b3:6a:1c:12:
        a2:c4:8f:12:53:cd:a1:a5:93:2e:7a:ac:21:fb:0d:34:52:cc:
        e3:40:8c:5a:e5:06:8a:41:9e:9a:8f:6a:3b:45:e0:68:e8:dd:
        c8:e1:75:da:48:a2:d6:a4:8f:71:a1:11:08:f6:65:55:b4:26:
        f8:71:02:80:e6:90:fe:1f:5b:94:9c:0e:7d:1f:6b:49:8b:a8:
        3d:27:c3:0f:69:fc:ee:31:3b:62:b4:c4:03:3c:6b:b2:b4:0e:
        fd:da:64:53:a3:e3:54:67:90:6a:b6:c6:cb:c8:0f:97:5a:c3:
        a1:a9:71:bf

Чтобы получить информацию о запросе на подпись сертификата www.example.com.csr нужно выполнить:

$ openssl req -in www.example.com.csr -text -noout
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: CN=example.com/emailAddress=postmaster@example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:ab:26:02:ea:14:6d:36:d0:61:9e:d6:45:d5:fe:
                    6b:a5:f6:ac:de:2c:93:41:91:56:e0:0c:e8:25:43:
                    d2:6e:25:2a:5b:81:fd:bf:1f:72:ec:94:84:32:35:
                    6f:d9:ec:8f:87:c1:94:d4:58:7a:ab:bc:9e:5b:4d:
                    e1:d9:9f:97:08:db:6a:9d:1d:dd:c4:af:c2:f7:79:
                    80:e0:15:f5:43:01:1f:09:c4:78:60:7a:34:d0:20:
                    db:67:47:12:33:1b:0e:d1:8a:db:e7:25:df:7b:66:
                    1d:fa:09:c5:61:50:05:51:bd:9d:06:59:79:a0:77:
                    eb:fb:f8:f1:40:a8:8c:6f:fe:99:54:74:40:61:a5:
                    35:18:99:88:e2:34:66:05:0e:94:8a:c7:65:60:d4:
                    1a:b6:69:d4:63:a4:e4:fe:28:53:a9:1e:f2:b1:c5:
                    98:4b:6a:59:92:32:59:10:12:38:57:c4:56:41:ba:
                    ac:01:24:ee:eb:3d:eb:a3:a6:91:11:18:9f:0f:04:
                    a6:f9:d4:a0:4f:fb:6e:bd:83:9f:d0:eb:68:26:dc:
                    f9:f0:f0:44:4d:6a:50:48:a5:df:39:6f:ef:99:b7:
                    d3:00:ff:41:cd:44:54:fe:aa:10:73:0f:b7:e6:7e:
                    18:28:95:b9:2d:8d:cc:83:19:31:2e:fd:16:4c:78:
                    f3:2b
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha1WithRSAEncryption
        67:ee:0d:d9:c1:71:95:21:4f:b1:2a:7b:c2:db:76:1d:28:5c:
        a3:25:8e:ff:73:6f:cf:39:bd:64:3a:f8:14:de:c9:3c:9a:83:
        68:f1:be:0f:f1:46:4f:4d:e0:70:1b:a4:f6:21:f3:31:2e:42:
        cc:90:07:f3:d9:79:26:67:91:c6:89:56:40:bd:a1:06:92:c0:
        b2:e8:fe:79:e3:74:44:6c:29:95:32:af:f5:4c:0d:0f:fc:8a:
        51:41:86:92:fd:a5:6e:c3:a6:5e:29:4a:57:ea:21:b6:36:b7:
        c6:91:aa:70:ea:0e:b9:da:e7:80:5d:f4:38:ab:94:48:f9:4b:
        da:bc:29:36:25:7c:ac:cd:74:34:4c:87:bc:78:0a:18:81:a0:
        8f:02:e2:24:20:d4:7f:ce:46:bc:01:fb:1f:2a:1e:80:dd:98:
        a7:68:c3:3c:8e:b0:85:45:b2:1b:5e:7e:9b:d7:c6:89:59:41:
        30:e4:1e:ca:8e:2a:c0:88:85:78:33:83:10:9b:d8:fc:0c:40:
        89:cb:c6:6d:a3:54:9f:ea:50:1f:8f:cd:59:85:54:c9:0a:23:
        70:49:06:05:00:62:ce:9d:4e:e4:5a:4e:e5:36:19:96:ac:a2:
        90:07:42:42:74:07:96:3d:6a:36:dc:77:9e:ad:9f:01:e2:16:
        ce:e6:7b:da

Чтобы проверить, что сертификат www.example.com.crt соответствует секретному ключу www.example.com.key, нужно выполнить:

$ openssl s_server -key www.example.com.key -cert www.example.com.crt
Using default temp DH parameters
Using default temp ECDH parameters
ACCEPT

Чтобы проверить, что на хосте www.example.com:443 работает SSL, нужно

$ openssl s_client -connect www.example.com:443
CONNECTED(00000003)
depth=0 /CN=www.example.com/emailAddress=postmaster@example.com
verify error:num=18:self signed certificate
verify return:1
depth=0 /CN=www.example.com/emailAddress=postmaster@example.com
verify return:1
---
Certificate chain
 0 s:/CN=www.example.com/emailAddress=postmaster@example.com
   i:/CN=www.example.com/emailAddress=postmaster@example.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDHzCCAgegAwIBAgIJAPDuTyLDfjC6MA0GCSqGSIb3DQEBBQUAMEExGDAWBgNV
BAMTD3d3dy5leGFtcGxlLmNvbTElMCMGCSqGSIb3DQEJARYWcG9zdG1hc3RlckBl
eGFtcGxlLmNvbTAeFw0xMjA3MjcxMjIxMjdaFw0xMzA3MjcxMjIxMjdaMEExGDAW
BgNVBAMTD3d3dy5leGFtcGxlLmNvbTElMCMGCSqGSIb3DQEJARYWcG9zdG1hc3Rl
ckBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAML2
5wYHIL3abm4KO8tsapBZ7AEVVnnDhetEDU1TvgMs7Xr183sDp7sNP7Hg/3vDe6la
cXV8WOSOXo7CGtTDr6r4XY9PnYK+dWU6uB0k+y4c++5SWefM8a8ASyzn/INIcySr
x5jZ/gib7nWYNxqJzZUgjfxNtcXMSv6qqQJpZFvS+i0hAqZlbHzkC4vSZPqq9UDn
jpU2wvX9tqEU/O6u6XeRAbsZly967PpOwsBevh201geH/8FZ7gUdl8/dn7l4ZoTF
tnXoLWTbarYxMQh+ML4IU8KmchoaHhCloDS4YYeG/TVAFg2WzUdbJWnUjZaLz9Xs
x3MZfX1M7TdvAFHgHf0CAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w
DQYJKoZIhvcNAQEFBQADggEBAFdDhY7cNBypP/F3+kcFXL/9Du/TVihTB6lD6Ljx
jPxr/W/yF8wDTCfi1SEWElRfEArCkhjHqneoRzM0EZj54tPay1f6DF9VK9yLN7vv
jKXP01rt1MArqHvk0YujwUA8VT16IQwaa3mJBUyC/RLazkrn/Pa526yVb7fe1gB/
Q4vJOuTFPV6g7FF57zQxsC50gBbDCSrAGvdEdZtlmFXwBtvYcxJCjNbbc8yWs2xz
2SHKNzxqwiEhQ+SoBKMzGN9aGKVTRCLgaA+ZlHaWRlCz8kkq/di7jDS6ohs0Xyts
qhT86owpdcy81Sp1ohUYsYbjbgYrF6Z7sTkrtHZ+qdHohtw=
-----END CERTIFICATE-----
subject=/CN=www.example.com/emailAddress=postmaster@example.com
issuer=/CN=www.example.com/emailAddress=postmaster@example.com
---
No client certificate CA names sent
---
SSL handshake has read 1374 bytes and written 255 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 2ED787CC1ABD979D19002CF241C9A897ECE0A9FFAA539AED30D05AFCC52A4342
    Session-ID-ctx: 
    Master-Key: F5AD4DFDDFC9D5E35BC509918D797A3F2CDAB26629B69E5B304870978C2576231F081FCE9E224A3FB369D7A7AF8F4A80
    Key-Arg   : None
    Start Time: 1343392406
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---

Еще один из способов оценить работу SSL - использовать online checker, например этот.

4 комментария:

  1. В дополнение ко всему, полезный ресурс для проверки созданного CSR запроса на правильность - http://www.emaro-ssl.ru/tools/check_csr.php

    ОтветитьУдалить
  2. А как сделать несколько Subject Alternative Name ?

    ОтветитьУдалить
    Ответы
    1. Примерно так:

      subjectAltName=DNS:example.com, DNS:example.net, DNS:example.org

      Удалить
  3. Спасибо за статью. Правда, еще можно немного добавить команд по генерации csr,key и crt в разных ситуациях (на лету без вопросом, с готовым ключом, с ключом без пароля, и тп.), как пишут здесь - http://sysadm.pp.ua/internet/pound-apache-nginx-ssl-setup.html

    ОтветитьУдалить