Внезапно бывает надо запилить SSL сертификаты для некоторого веб-сайта у которого есть несколько доменных имён, например www.domain.com и domain.com. Конечно, можно создать по отдельному сертификату для каждого доменного имени, но так как мы все тут ленивые задницы, то лучше создать один SSL сертификат для всех доменных имён сайта и подсовывать в конигурацию Apache именно его. Ниже все описанные операции, опять же из-за лени, производятся от рута, не делайте так!
- Редактирование дефолтной конфигурации OpenSSL
Итак, предположим, у нас есть пустой RHEL/CentOS 5/6/7 без ничего в минимальной конфигурации. Начнём с установки или обновления пакета openssl, если ещё не:
[root@rhel7 ~]# yum install openssl openssl-libs
Далее нам надо изменить файл /etc/pki/tls/openssl.cnf с дефолтной кофигурацией OpenSSL. Если изменять этот файл, все настройки останутся и будут применены для дальнейших операций с OpenSSL. Поэтому мы будем изменять копию этого файла и использовать её для создания нашего сертификата:
[root@rhel7 ~]# mkdir multi-cn-cert && cd multi-cn-cert
[root@rhel7 multi-cn-cert]# cp /etc/pki/tls/openssl.cnf ./
Отредактируем наш временный кофигурационный файл OpenSSL и активируем опцию альтернативных доменных имён в секции [ req ]. Это секция, которая говорит OpenSSL как создавать запросы на подпись сертификата (Certificate Signing Request, CSR). В этой секции должна быть строка начинающаяся с req_extensions, изменим её так:
[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req # The extensions to add to a certificate request
Эта настройка говорит OpenSSL добавить секцию v3_req в запрос на подпись сертификата (CSR). Теперь редактируем секцию [ req_distinguished_name ], разумеется, вы должный указать свои значения countryName, stateOrProvinceName и так далее в этой секции:
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = RU
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Some Region
localityName = Locality Name (eg, city)
localityName_default = Somecity
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Domain Control Validated
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Web Operations
commonName = Common Name (eg, your name or your server\'s hostname)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
Далее редактируем секцию [ v3_req ] и добавим секцию [ alt_names ], чтобы они выглядели так, как показано ниже:
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = www.domain.com
DNS.2 = kb.domain.com
DNS.3 = domain.com
IP.1 = 192.168.1.1
IP.2 = 10.0.1.1
Заметьте, что всё, что мы написали в секции [ alt_names ] теперь появится во всех запросах на подпись сертификата (CSR-ах) созданных с помощью этого конфигурационного файла OpenSSL, если нужно будет создать запрос на подпись (CSR) с другими именами, нужно будет отредактировать этот файл и поменять строки DNS.x и IP.x.
- Создание секретного ключа
Создадим секретный 2048-битный ключ для домена www.domain.com. Имя файла ключа может быть любое, использование имени домена просто облегчает дальнейшие действия:
[root@rhel7 multi-cn-cert]# openssl genrsa -out www.domain.com.key 2048
Generating RSA private key, 2048 bit long modulus
.............................+++
.......+++
e is 65537 (0x10001)
- Создание запроса на подпись сертификата (CSR)
Создадим запрос на подпись сертификата (CSR), заполняя информацию о вашей организации. Внимание, на запрос о Common Name ответьте первым доменным именем, для которого создаётся сертификат, то есть, именем указанным в DNS.1. Так же будет запрошена парольная фраза, она повышает устойчивость сертификата ко взлому, но эту фразу придётся ручками вводить (или делать специальные настройки) каждый раз, как стартует сервис (в данном случае - Apache), использующий этот сертификат. Для уменьшения головной боли оставим парольную фразу пустой:
[root@rhel7 multi-cn-cert]# openssl req -new -out www.domain.com.csr -key www.domain.com.key -config openssl.cnf
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [RU]:
State or Province Name (full name) [Some Region]:
Locality Name (eg, city) [Somecity]:
Organization Name (eg, company) [Domain Control Validated]:
Organizational Unit Name (eg, section) [Web Operations]:
Common Name (eg, your name or your server's hostname) []:www.domain.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Проверим, что созданный запрос на подпись сертификата (CSR) содержит то, что нам нужно:
[root@rhel7 multi-cn-cert]# openssl req -text -noout -in www.domain.com.csr
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=RU, ST=Some Region, L=Somecity, O=Domain Control Validated, OU=Web Operations, CN=www.domain.com
...
Requested Extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Subject Alternative Name:
DNS:www.domain.com, DNS:kb.domain.com, DNS:domain.com, IP Address:192.168.1.1, IP Address:10.0.1.1
- Подпись и создание сертификата
Теперь у нас есть валидный запрос на подпись сертификата (CSR), по-правильному теперь надо отослать его в подписывающий центр сертификации (CA), чтобы ваш сертификат был доверяемым. Есть несколько центров, бесплатно подписывающих SSL сертификаты,
StartSSL или там
Let’s Encrypt какой, но для скорости мы пойдём неправильным путём и сделаем само-подписанный сертификат на 10 лет (обратите внимание на опцию -days), который будет недоверяемым и браузеры будут на него ругаться. Обратите также внимание на опцию -extfile, именно она говорит использовать наш локальный конфигурационный файл openssl.cnf и позволяет создать сертификат с расширением X509v3 стандарта X509:
[root@rhel7 multi-cn-cert]# openssl x509 -req -days 3650 -in www.domain.com.csr -signkey www.domain.com.key -out www.domain.com.crt -extensions v3_req -extfile openssl.cnf
Signature ok
subject=/C=RU/ST=Some Region/L=Somecity/O=Domain Control Validated/OU=Web Operations/CN=www.domain.com
Getting Private key
- Упаковка ключа и сертификата в файл PKCS12
Некоторые сервисы (например, веб-сервер IIS) требуют секретный ключ и сертификат в одном файле в формате PKCS12. Хотя здесь не будет описана настройка таких сервисов, но экспортировать секретный ключ и сертификат с пустым паролем в файл PKCS12 можно так:
[root@rhel7 multi-cn-cert]# openssl pkcs12 -export -in www.domain.com.crt -inkey www.domain.com.key -out www.domain.com.p12
Enter Export Password:
Verifying - Enter Export Password:
- Некоторые финальные замечания
Итак, после всех операций у нас есть следующие файлы:
[root@rhel7 multi-cn-cert]# ls -1
openssl.cnf # конфигурация OpenSSL для создания сертификата для нескольких доменных имён
www.domain.com.crt # SSL сертификат
www.domain.com.csr # запрос на подпись сертификата
www.domain.com.key # секретный ключ для само-подписывания
www.domain.com.p12 # секретный ключ и сертификат в формате PKCS12
Также, если вам не нужен сертификат с несколькими доменными именами, а только с одним, всё это можно упростить запуская интерактивный скрипт genkey из пакета crypto-utils (ещё требует пакет mod_ssl):
[root@rhel7 ~]# yum install crypto-utils mod_ssl
[root@rhel7 ~]# genkey --days 3650 www.domain.com
- Конфигурация SSL и использование созданного SSL сертификата в Apache
По этой теме (Apache и SSL) в этих ваших интернетах материалов чуть менее миллиона разной степени детализации, поэтому тут вкратце. Сначала установим собственно Apache и SSL модуль для него:
[root@rhel7 ~]# yum install httpd mod_ssl
Возится с несколькими виртуальными хостами вы будете сами, для простейшей SSL конфигурации надо отредактировать файл /etc/httpd/conf.d/ssl.conf:
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/www.domain.com.crt
SSLCertificateKeyFile /etc/pki/tls/private/www.domain.com.key
И скопировать файл сертификата www.domain.com.crt и секретный ключ www.domain.com.key куда настроено:
[root@rhel7 multi-cn-cert]# cp www.domain.com.crt /etc/pki/tls/certs/
[root@rhel7 multi-cn-cert]# cp www.domain.com.key /etc/pki/tls/private/
Теперь запускаем Apache с помощью вашей системы инициализации:
[root@rhel7 ~]# service httpd start
Redirecting to /bin/systemctl start httpd.service
И смотрим браузером на стартовую страницу по HTTPS. Браузер естественно ругнётся на само-подписанный SSL сертификат, но в его свойствах можно проверить что он выписан именно на несколько доменных имён и IP адресов:
Такие дела.
Пыщь!
Оригинал поста размещен в блоге
Ад, ненависть и локалхост. Комментить?
Набигай. Подкат?
ОИНЧ.