Pull to refresh

Создание инфраструктуры PKI для клиентской SSL авторизации в Apache 2.

Не связывался бы с этим и дальше, но пришлось по работе связывать самодельную систему с терминалами оплаты Элекснет. Написать программную часть на PHP не составило труда, тем более что от их системы идут простые POST запросы. Гораздо сложнее оказалось первый раз в жизни настраивать SSL, о чем я сейчас и расскажу.

Для работы нам понадобится Linux с установленными пакетами apache2 и openssl

Суть работы системы такова. Когда клиент вводит на терминале оплаты свои реквизиты, сервер элекснета подключается к нашему серверу по https, и отправляет два POST запроса, один для проверки возможности платежа, и если на первый мы ответим положительно, то терминал принимает деньги и отправляет нам второй запрос с суммой денег.

Для обеспечения безопасности используется SSL и инфраструктура PKI.

Кратко, PKI позволяет проверить, подписан ли сертификат доверенным центром сертификации. По идее, чтобы получить хороший доверенный сертификат, нужно заплатить центру сертификации, но для личных нужд сойдет и самодельный сертификат.

Процесс настройки выглядит так.

Элекснет мы
1. Генерация сертификата CA
2. Генерация запроса на подпись (certificate signing request, csr)
3. подписывание csr при помощи сертификата CA и передача обратно
4. получение подписанного сертификата
5. генерация серверного сертификата для Apache
6. настройка Apache


Теперь по пунктам

1. Генерация сертификата CA.


Сертификат CA — обычный самоподписанный сертификат, его можно сгенерировать командой
openssl req -new -x509 -days 3650 -keyout cakey.pem -out cacert.pem

Ответьте на вопросы по своему усмотрению. Ключевая фраза понадобится для подписывания чего-то этим сертификатом.

Если ничего не менять, получится 1024 битный RSA ключ, что нас вполне устроит. Срок годности этого сертификата — 10 лет (3650 дней). Через это время сам сертификат и все ключи которые им подписаны протухнут, и их придется пересоздать.

На этом шаге получаем два файла. Это сертификат cacert.pem и секретный ключ от него cakey.pem. Второй нужен для подписывания, а первый для проверки подписей. Соответственно первый можно раздавать всем и каждому, а второй надо держать в надежном месте.

2. Запрос на подпись



Вообще-то его генерируем не мы, но для тестирования это действие все равно нужно будет проделать.

openssl req -new -out request.csr -keyout request.pem

В файле request.csr мы получили запрос на подпись сертификата, в request.pem секретную часть будущего сертификата. Правила хранения те же самые что и у CA сертификата. Файл request.csr на втором шаге нам пришлют по электронной почте, icq или другому небезопасному транспорту. Ничего секретного в нем нету, все осталось в request.pem :)

3. Подписывание запроса.



На этом этапе используется полученный файл request.csr, и созданные нами cacert.pem и cakey.pem. Также нас спросят ключевую фразу из пункта 1.
openssl x509 -req -in request.csr -CA cacert.pem -CAkey cakey.pem -CAcreateserial -out client_cert.crt -days 365

createserial служит для создания серийного номера нового сертификата. Нужно только первый раз, затем используется -CAserial cacert.srl для увеличения этого номера.

На выходе получится client_cert.crt. Его надо отдать обратно. Опять же, ничего секретного в нем нету, без секретного ключа request.pem он бесполезен.

4. Сертификат сервера.



Для Apache можно использовать сертификат CA, но удобнее и безопаснее использовать отдельный сертификат. Не обязательно использовать тот же самый CA, можно сгенерировать и другой. Для геренации сертификата, подписанного нашим основным CA, нужно проделать действия, описанные в шагах 2 и 3. Самоподписанный сертификат можно сделать при помощи команды из шага 1. Можно объединить оба эти подхода, выполнив шаги 1, 2 и 3. Одна особенность: Common Name нового сертификата должен совпадать с доменным именем сервера (как в ServerName). На выходе мы получим сертификат и ключ к нему. С ключа нужно снять ключевую фразу, чтобы Apache мог запускаться без ввода пароля :). Делается это при помощи команды
openssl rsa -in request.key -out request.nokey, request.key это ключевой файл сгенерированный только что.

Полученные на данном шаге файлы (подписанный сертификат и ключ к нему без пароля) нужно положить в место, доступное для apache. Также нужно скопировать сертификат cacert.pem (тот, которым подписывали запрос)

5. Настройка apache.



Для простоты настройки я создал дополнительный VirtualHost на 1433 порту.

<VirtualHost *:1443>
ServerName server #Доменное имя сервера, оно же CN сертификата
SSLEngine on #Разрешить SSL
SSLCertificateFile /etc/apache2/ssl/server.pem #сгенерированный на шаге 4 сертификат
SSLCertificateKeyFile /etc/apache2/ssl/server.key # и ключ к нему
DocumentRoot /opt/eleksnet/ # специально убрал из /var/www/ чтобы нельзя было получить доступ из других виртуалхостов.
SSLProtocol all #Разрешить все версии SSL
<Directory /opt/eleksnet/>
SSLCACertificateFile /etc/apache2/ssl/CA/ca.crt # Сертификат CA, которым подписывали запрос!
SSLVerifyClient require #Требовать!
SSLVerifyDepth 5 #В принципе не требуется, у нас глубина всего 1.





Если после перезапуска apache не работает, нужно проверить его error.log. Скорее всего вы перепутали какие-то файлы сертификатов или не правильно выставили права на них.

6. Проверка работоспособности.



Если закомментировать все в Directory, мы должны мочь зайти по адресу server:1433/. Это свидетельствует о корректной настройке SSL на апаче. Чтобы не возникало предупреждение в браузере, по-хорошему надо импортировать сертификать CA, который подписал сертификат сервера Делается это просто. Нужно взять cacert.pem и импортировать его. в firefox это делается так:
импорт сертификата CA

Для теста аутентификации нужно создать и импортировать сертификат, подписанный нашим CA. Для этого нужно снова проделать шаги 2 и 3. :) Если сертификат для apache подписывался этим же CA, можно использовать и его.

Маленькая тонкость: браузеры обычно требуют сертификаты в формате pkcs12. Для преобразования сертификата в этот формат служит еще один режим работы openssl: openssl pkcs12
openssl pkcs12 -export -in <сертификат клиента> -inkey <ключ от сертификата клиента> -out cert.p12

Теперь файл cert.p12 можно успешно импортировать на вкладку «Ваши сертификаты».

импорт сертификата клиента

Можно проверить, что зайти в защищенный раздел можно только с нашего браузера :).

Итог



Я научился создавать и подписывать сертификаты для аутентификации клиента на apache. Это требуется для подключения платежной системы, но может пригодиться и для создания админки :). В процессе написания поста сюда, я сделал шпаргалку, так как через год часть этой процедуры (а именно шаги 2 и 3 :) ) придется повторить.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.