Не связывался бы с этим и дальше, но пришлось по работе связывать самодельную систему с терминалами оплаты Элекснет. Написать программную часть на PHP не составило труда, тем более что от их системы идут простые POST запросы. Гораздо сложнее оказалось первый раз в жизни настраивать SSL, о чем я сейчас и расскажу.
Для работы нам понадобится Linux с установленными пакетами apache2 и openssl
Суть работы системы такова. Когда клиент вводит на терминале оплаты свои реквизиты, сервер элекснета подключается к нашему серверу по https, и отправляет два POST запроса, один для проверки возможности платежа, и если на первый мы ответим положительно, то терминал принимает деньги и отправляет нам второй запрос с суммой денег.
Для обеспечения безопасности используется SSL и инфраструктура PKI.
Кратко, PKI позволяет проверить, подписан ли сертификат доверенным центром сертификации. По идее, чтобы получить хороший доверенный сертификат, нужно заплатить центру сертификации, но для личных нужд сойдет и самодельный сертификат.
Процесс настройки выглядит так.
Теперь по пунктам
Сертификат CA — обычный самоподписанный сертификат, его можно сгенерировать командой
Ответьте на вопросы по своему усмотрению. Ключевая фраза понадобится для подписывания чего-то этим сертификатом.
Если ничего не менять, получится 1024 битный RSA ключ, что нас вполне устроит. Срок годности этого сертификата — 10 лет (3650 дней). Через это время сам сертификат и все ключи которые им подписаны протухнут, и их придется пересоздать.
На этом шаге получаем два файла. Это сертификат cacert.pem и секретный ключ от него cakey.pem. Второй нужен для подписывания, а первый для проверки подписей. Соответственно первый можно раздавать всем и каждому, а второй надо держать в надежном месте.
Вообще-то его генерируем не мы, но для тестирования это действие все равно нужно будет проделать.
В файле request.csr мы получили запрос на подпись сертификата, в request.pem секретную часть будущего сертификата. Правила хранения те же самые что и у CA сертификата. Файл request.csr на втором шаге нам пришлют по электронной почте, icq или другому небезопасному транспорту. Ничего секретного в нем нету, все осталось в request.pem :)
На этом этапе используется полученный файл request.csr, и созданные нами cacert.pem и cakey.pem. Также нас спросят ключевую фразу из пункта 1.
createserial служит для создания серийного номера нового сертификата. Нужно только первый раз, затем используется -CAserial cacert.srl для увеличения этого номера.
На выходе получится client_cert.crt. Его надо отдать обратно. Опять же, ничего секретного в нем нету, без секретного ключа request.pem он бесполезен.
Для Apache можно использовать сертификат CA, но удобнее и безопаснее использовать отдельный сертификат. Не обязательно использовать тот же самый CA, можно сгенерировать и другой. Для геренации сертификата, подписанного нашим основным CA, нужно проделать действия, описанные в шагах 2 и 3. Самоподписанный сертификат можно сделать при помощи команды из шага 1. Можно объединить оба эти подхода, выполнив шаги 1, 2 и 3. Одна особенность: Common Name нового сертификата должен совпадать с доменным именем сервера (как в ServerName). На выходе мы получим сертификат и ключ к нему. С ключа нужно снять ключевую фразу, чтобы Apache мог запускаться без ввода пароля :). Делается это при помощи команды
Полученные на данном шаге файлы (подписанный сертификат и ключ к нему без пароля) нужно положить в место, доступное для apache. Также нужно скопировать сертификат cacert.pem (тот, которым подписывали запрос)
Для простоты настройки я создал дополнительный VirtualHost на 1433 порту.
Если после перезапуска apache не работает, нужно проверить его error.log. Скорее всего вы перепутали какие-то файлы сертификатов или не правильно выставили права на них.
Если закомментировать все в Directory, мы должны мочь зайти по адресу server:1433/. Это свидетельствует о корректной настройке SSL на апаче. Чтобы не возникало предупреждение в браузере, по-хорошему надо импортировать сертификать CA, который подписал сертификат сервера Делается это просто. Нужно взять cacert.pem и импортировать его. в firefox это делается так:

Для теста аутентификации нужно создать и импортировать сертификат, подписанный нашим CA. Для этого нужно снова проделать шаги 2 и 3. :) Если сертификат для apache подписывался этим же CA, можно использовать и его.
Маленькая тонкость: браузеры обычно требуют сертификаты в формате pkcs12. Для преобразования сертификата в этот формат служит еще один режим работы openssl: openssl pkcs12
Теперь файл cert.p12 можно успешно импортировать на вкладку «Ваши сертификаты».

Можно проверить, что зайти в защищенный раздел можно только с нашего браузера :).
Я научился создавать и подписывать сертификаты для аутентификации клиента на apache. Это требуется для подключения платежной системы, но может пригодиться и для создания админки :). В процессе написания поста сюда, я сделал шпаргалку, так как через год часть этой процедуры (а именно шаги 2 и 3 :) ) придется повторить.
Для работы нам понадобится 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. Для этого нужно снова проделать шаги 2 и 3. :) Если сертификат для apache подписывался этим же CA, можно использовать и его.
Маленькая тонкость: браузеры обычно требуют сертификаты в формате pkcs12. Для преобразования сертификата в этот формат служит еще один режим работы openssl: openssl pkcs12
openssl pkcs12 -export -in <сертификат клиента> -inkey <ключ от сертификата клиента> -out cert.p12
Теперь файл cert.p12 можно успешно импортировать на вкладку «Ваши сертификаты».

Можно проверить, что зайти в защищенный раздел можно только с нашего браузера :).
Итог
Я научился создавать и подписывать сертификаты для аутентификации клиента на apache. Это требуется для подключения платежной системы, но может пригодиться и для создания админки :). В процессе написания поста сюда, я сделал шпаргалку, так как через год часть этой процедуры (а именно шаги 2 и 3 :) ) придется повторить.