Протокол SSL позволяет организовать доступ к сайту (или его части) путем авторизации по клиентским сертификатам. При попытке входа на защищенный ресурс, сервер запрашивает у клиента сертификат. Если проверка сертификата проходить успешно, клиент получает доступ к защищенным ресурсам.
Весьма удобно.
Реализовать этот механизм можно с помощью Apache и его модуля mod_ssl. Для этого понадобится:
- создать доверенный сертификат (Certificate Authority) для подписи и проверки клиентских сертификатов;
- сконфигурировать сервер для запроса и проверки клиентских сертификатов для запроса и проверки клиентских сертификатов;
- создать клиентские сертификаты и передать их клиентам.
Конфигурация сервера для запроса и проверки клиентских сертификатов
Настроим один из серверов, рассмотренных в предыдущей статье, для авторизации по клиентским сертификатам. К примеру citename.ru. CA для него уже создан. По этому начнем с настройки виртуального хоста. В файл настроек нужно добавить следующее:
SSLCACertificateFile | Абсолютный путь к файлу доверенного сертификата (CA) |
SSLVerifyClient require | Требование предоставить сертификат для авторизации. Если сертификат не будет предоставлен - доступ будет запрещен. |
Секция VirtualHost для citename.ru должна выглядеть так:
/etc/apache2/vhosts.d/citename_ssl_vhost.conf |
<VirtualHost 11.222.33.4:443> DocumentRoot "/var/www/localhost/htdocs" ErrorLog /var/log/apache2/ssl_citename_error_log <IfModule log_config_module> SSLEngine on SSLCertificateFile /etc/apache2/ssl/citename-CA.crt |
Теперь можно сказать Apache перечитать конфигурацию
# /etc/init.d/apache2 reload
Создание клиентского сертификата
Подготовим структуру каталогов и файлов для хранилища сертификатов.
# mkdir /etc/ssl/citename.ru
# cd /etc/ssl/citename.ru
# mkdir db
# mkdir db/certs
# mkdir db/newcerts
# touch db/index.txt
# echo "01" > db/serial
# chmod 700 ./
В каталоге db/certs
будем хранить выданные сертификаты. В файле db/index.txt
будут храниться данные о выданных сертификатах. А в файле db/serial - серийный номер для нового сертификата.
Создаем конфигурационный файл для подписи сертификатов.
/etc/ssl/citename.ru/citename-CA.conf |
[ ca ] [ CA_CITENAME ] database = $dir/index.txt # Файл базы сертификатов # Файл доверенного сертификата default_days = 365 # Срок действия нового сертификата (дни) policy = policy_citename # Политика секции [ policy_citename ] |
Создаем запрос на клиентский сертификат.
# openssl req -new -newkey rsa:1024 -nodes -keyout user01.key -days 365 \
-subj "/C=RU/ST=Arkh/L=Arkh/O=OAO/OU=Sales/CN=user01/emailAddress=userЭтот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра." \
-out user01.csr
Аргументы команды:
req | Генерация нового сертификата |
-new | Запрос на подпись сертификата |
-newkey rsa:1024 | Новый закрытый RSA ключ длиной 1024 бита |
-nodes | Не шифровать закрытый ключ |
-keyout user01.key | Закрытый ключ сохранить в user01.key |
-days 365 | Срок действия сертификата |
-subj | Информация о владельце сертификата. |
C - Двухсимвольное обозначение страны |
|
-out user01.csr | Запрос на сертификат сохранить в user01.csr |
Результатом команды будут два файла: закрытый ключ user01.key
и запрос на сертификат user01.csr
. Проверим что у нас получилось.
# openssl req -noout -text -in user01.csr
Certificate Request: Data: Version: 0 (0x0) Subject: C=RU, ST=Arkh, L=Arkh, O=OAO, OU=Sales, CN=user01/emailAddress=Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:d9:18:df:76:81:90:3b:f1:2f:05:bd:e1:bc:a1: a8:0f:6d:ad:92:8c:ae:86:28:79:16:db:6a:7f:1a: d7:38:98:78:e3:52:70:26:9a:b2:9c:1f:80:f7:d6: 99:82:f7:55:7d:a2:57:78:63:28:cd:70:93:96:a6: d3:40:55:20:d0:45:f2:7d:8f:d1:83:0d:50:2b:d3: ed:71:c6:2d:af:0a:8b:92:55:2b:25:17:22:3d:71: db:ee:ef:95:e7:52:d6:aa:46:31:e2:ee:c5:09:78: d4:78:a7:f0:f0:0b:4f:bb:38:2b:3b:2d:46:99:49: 6b:aa:42:e0:67:7c:1c:4c:5b Exponent: 65537 (0x10001) Attributes: a0:00 Signature Algorithm: sha1WithRSAEncryption 14:81:32:d3:32:ef:a8:fd:03:7a:91:0c:7c:73:b7:9c:a8:59: 3a:18:27:30:48:6a:0c:9a:47:1f:91:12:2e:5a:8e:fd:15:37: 05:c4:6f:04:16:51:f0:7b:b6:50:ce:08:b1:ce:5f:e6:4a:a1: f2:df:c5:e6:fb:cd:29:2d:32:fc:6b:cc:52:52:f6:ba:4b:88: d3:cd:97:14:7c:49:f5:03:82:ca:14:74:d0:6f:20:07:bc:8e: 42:41:3c:61:17:a5:36:32:e8:08:95:18:c7:f8:63:5f:18:82: 76:70:65:b1:c9:fe:d9:5d:e3:cf:f8:c4:08:54:dd:ca:af:f5: 77:96 |
# openssl rsa -noout -text -in user01.key
Private-Key: (1024 bit) modulus: 00:d9:18:df:76:81:90:3b:f1:2f:05:bd:e1:bc:a1: a8:0f:6d:ad:92:8c:ae:86:28:79:16:db:6a:7f:1a: d7:38:98:78:e3:52:70:26:9a:b2:9c:1f:80:f7:d6: 99:82:f7:55:7d:a2:57:78:63:28:cd:70:93:96:a6: d3:40:55:20:d0:45:f2:7d:8f:d1:83:0d:50:2b:d3: ed:71:c6:2d:af:0a:8b:92:55:2b:25:17:22:3d:71: db:ee:ef:95:e7:52:d6:aa:46:31:e2:ee:c5:09:78: d4:78:a7:f0:f0:0b:4f:bb:38:2b:3b:2d:46:99:49: 6b:aa:42:e0:67:7c:1c:4c:5b publicExponent: 65537 (0x10001) privateExponent: 5a:c5:85:99:bd:2e:9b:81:8a:91:b2:05:12:a3:dc: eb:26:86:ae:81:d7:ef:0c:39:25:0f:75:05:d4:29: 2c:e6:c3:94:f8:c1:1f:c3:0a:ef:30:54:f2:4b:6e: 40:4e:3e:16:9b:ac:4b:0f:da:dd:9b:36:7a:85:22: 4b:01:cd:07:c3:32:26:31:d8:b1:fd:fa:d0:64:8b: 3d:48:ba:be:f0:3a:82:3a:08:b8:da:18:7c:41:2f: 05:7f:bc:09:25:21:a2:17:ec:b0:dd:36:e8:79:f4: 4a:70:14:f1:d0:22:ad:8a:0b:d8:30:2e:ee:50:f3: 77:c2:6d:48:c1:a5:dc:41 prime1: 00:ed:13:50:fb:cd:03:83:1d:d3:48:02:3b:bd:12: b8:9a:bd:4d:4a:6e:b3:53:16:b6:67:f0:74:53:89: 1f:2c:45:46:16:36:ee:88:aa:7c:b5:2a:f0:c0:c0: b3:ee:24:2f:b3:7c:19:9a:c8:8a:09:18:79:a4:a8: 25:38:12:28:2b prime2: 00:ea:6d:4b:d1:b4:d3:ee:c0:24:1f:83:61:a5:67: 33:18:da:1c:90:cf:23:bb:06:c7:3e:21:c0:77:00: 9c:1e:52:18:38:23:61:93:27:a1:d0:61:1f:ad:0c: 14:ad:d2:ae:eb:4e:7d:c8:03:89:f4:8a:a3:c1:2b: 51:64:48:a4:91 exponent1: 00:95:ca:5e:a0:ba:28:3d:ef:da:4e:e5:1a:59:9c: 3a:87:8a:94:0b:33:66:9a:58:ff:67:2c:c6:53:01: 90:70:a8:54:60:34:d5:02:04:b6:46:c1:9a:dc:2e: e5:80:d1:dc:51:cb:57:62:34:d3:02:6c:34:6f:94: cd:ef:5f:89:81 exponent2: 26:19:4b:38:32:b6:3a:d8:19:46:d1:d8:5d:c4:4e: e6:9c:14:06:68:d3:ba:c2:98:40:fd:c5:44:d1:e1: 8d:7f:f4:15:b3:92:59:13:18:d6:3f:e2:a1:02:14: 9e:47:5e:4c:39:be:71:72:39:ca:77:79:b3:9c:31: a7:25:b3:31 coefficient: 19:e7:3a:5b:2d:75:4f:26:ab:f1:4b:8a:9e:c1:32: 40:9e:6e:a8:bb:8a:5f:36:8a:f1:30:39:37:01:59: 6c:7e:67:35:3f:bd:fc:3e:eb:fb:b9:a6:af:7c:9d: 7f:c3:83:d1:6e:11:d6:0d:56:05:9b:07:fd:27:32: 22:8c:cf:61 |
Подпишем сертификат ключом сервера.
openssl ca -config citename-CA.conf -in user01.csr -out user01.crt -batch
Результатом команды будет вывод на экран что-то вроде этого:
Using configuration from citename-CA.conf Write out database with 1 new entries |
И файл подписанного сертификата user01.crt
.
Аргументы команды:
ca | Подпись запроса на сертификат доверенным сертификатом |
-config citename-CA.conf | Использовать конфигурационный файл citename-CA.conf |
-in user01.csr | Файл запроса на сертификат находится в user01.csr |
-out user01.crt | Подписанный сертификат сохранить в user01.crt |
-batch | Не задавать вопросов и автоматически сертифицировать |
Проверим что получилось.
# openssl x509 -noout -text -in user01.crt
Certificate: Data: Version: 1 (0x0) Serial Number: 2 (0x2) Signature Algorithm: md5WithRSAEncryption Issuer: C=RU, ST=Arkh, L=Arkh, O=OAO, OU=Sales, CN=citename.ru/emailAddress=Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. Validity Not Before: Jan 30 18:58:53 2018 GMT Not After : Jan 30 18:58:53 2016 GMT Subject: C=RU, ST=Arkh, L=Arkh, O=OAO, OU=Sales, CN=user01/emailAddress=Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:d9:18:df:76:81:90:3b:f1:2f:05:bd:e1:bc:a1: a8:0f:6d:ad:92:8c:ae:86:28:79:16:db:6a:7f:1a: d7:38:98:78:e3:52:70:26:9a:b2:9c:1f:80:f7:d6: 99:82:f7:55:7d:a2:57:78:63:28:cd:70:93:96:a6: d3:40:55:20:d0:45:f2:7d:8f:d1:83:0d:50:2b:d3: ed:71:c6:2d:af:0a:8b:92:55:2b:25:17:22:3d:71: db:ee:ef:95:e7:52:d6:aa:46:31:e2:ee:c5:09:78: d4:78:a7:f0:f0:0b:4f:bb:38:2b:3b:2d:46:99:49: 6b:aa:42:e0:67:7c:1c:4c:5b Exponent: 65537 (0x10001) Signature Algorithm: md5WithRSAEncryption 72:e5:e6:7d:e2:c1:fd:63:d1:55:72:96:2c:92:e2:1b:7f:b8: fc:d7:0e:ce:72:dc:24:3d:f4:db:27:79:26:c8:17:15:7f:fe: c4:36:6e:32:9e:40:20:c5:b6:30:ae:ee:3c:12:36:3a:45:1b: cc:d5:92:f6:72:d7:9d:84:b8:71:16:03:26:a9:2b:43:2a:68: 06:91:ff:76:5b:46:98:07:18:d5:2f:2c:81:97:5c:80:f7:1d: 55:d5:13:2e:25:10:82:ea:33:13:3c:a5:1d:c2:18:dd:e5:7c: f0:05:1e:ae:2a:80:01:3f:69:f4:c5:7f:da:18:b8:e9:29:90: 67:0c |
Подготовим сертификат для передачи пользователю.
# openssl pkcs12 -export -in user01.crt -inkey user01.key -out user01.p12 \
-certfile /etc/apache2/ssl/citename-CA.crt -passout pass:passwordkey
Аргументы команды:
pkcs12 | Работать с файлом в формате PKCS#12. |
-export | Экспортировать сертификат в файл |
-in user01.crt | Клиентский сертификат |
-inkey user01.key | Закрытый ключ клиентского сертификата |
-certfile | Доверенный сертификат |
-out user01.p12 | Сертификат в формате PKCS#12 для передачи пользователю |
-passout pass:passwordkey | Закрыть файл паролем passwordkey |
Клиентский сертификат готов. Хранится он в файле user01.p12
. Теперь его можно передать пользователю для установки в браузер.
Переместим все созданные файлы в каталог db/certs
на хранение.
# mv ./user01.* db/certs/
Скрипт для создания клиентских сертификатов
Если сертификаты нужно создавать на регулярной основе - можно воспользоваться скриптом
mk-user-certs |
#!/bin/bash ### ================================================================================= ### usage () { # У getopts есть неприятная фича/баг. Если у опции с аргументом не введен аргумент, if [[ $OPTARG =~ ^-[n/p/e/c/t/l/o/u]$ ]] if [ $# -eq "$NO_ARGS" ] # Сценарий вызван без аргументов? while getopts "rsn:p:e:c:t:l:o:u:" Option exit $E_OPTERROR;; # ПО-УМОЛЧАНИЮ # Проверка обязательных опций SUBJ="$C$ST$L$O$OU$CN$E" # Проверим указан ли пароль # Создаем запрос на сертификат if ! [ -z $SH_RES ] # Если указана опция -r # Подписываем сертификат if ! [ -z $SH_RES ] # Если указана опция -r openssl x509 -noout -text -in "$BASE_DIR/$C_NAME.crt" # Упаковать сертификат в файл PKCS#12 if [ $SEND_EMAIL -eq 1 ] # Если указана опция -s mv $BASE_DIR/$C_NAME.* "$CERTS" exit 0 |
Для корректной работы скрипта требуется наличие установленных программ: mail-client/mailx (mail - консольный клиент для отправки почтовых сообщений, app-arch/rar (архиватор), app-arch/sharutils (перекодировщик двоичных файлов в текстовый вид для почтовых вложений).
Добавить комментарий