Настройка авторизации на веб-сервере Apache по сертификату пользователя.
Posted on Декабрь 10th, 2009 in FreeBSD, Linux, Безопасность вебсайтов | 8 Comments »
Исходные данные:
OC – FreeBSD или Linux, в наличии должен быть openssl
Веб-сервер – Apache 2.2 + mod_ssl (http://test.lan)
Необходимо:
Настроить SSL – издать сертификаты, настроить веб-сервер
При доступе к определенной директории веб-сервер должен запрашивать авторизацию по сертификату клиента.
Исходим из того что веб-сервер корректно установлен, у хоста есть полное FQDN и он корректно резолвится и доступен извне по портам 80/tcp и 443/tcp.
В первую очередь необходимо будет:
1) Настроить свой CA (Certificate Authority) для издания сертификатов веб-сервера и клиентов.
2) Сгенерировать ключ и сертификат веб-сервера
3) Сгенерировать и импортировать ключи и сертификаты веб-клиентов.
Приступим:
Создадим директорию доступную только суперпользователю:
mkdir /CA
chmod 700 /CA
cd /CA
Сгенерируем закрытый ключ CA:
openssl genrsa -des3 -out ca.key 2048
Сгенерируем сертификат CA:
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
openssl x509 -in ca.crt -text -noout
Сгенерируем закрытый ключ вебсервера:
openssl genrsa -des3 -out webserver.key 1024
Сгенерируем запрос на сертификат вебсервера:
openssl req -new -key webserver.key -out webserver.csr
Сгенерируем сертификат вебсервера:
openssl x509 -req -in webserver.csr -out webserver.crt -sha1 -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650
openssl x509 -in webserver.crt -text -noout
Защитим ключи от прочтения посторонними:
chmod 0400 *.key
Конфигурацию ssl я вынес из файла httpd.conf в файл httpd-ssl.conf,
и указал в конфигурации httpd.conf:
Include etc/apache22/extra/httpd-ssl.conf
В файле httpd-ssl.conf внес следующие изменения:
#httpd-ssl.conf
Listen 443
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
SSLPassPhraseDialog builtin
SSLSessionCache "shmcb:/var/run/ssl_scache(512000)"
SSLSessionCacheTimeout 300
SSLMutex "file:/var/run/ssl_mutex"
<VirtualHost _default_:443>
DocumentRoot "/usr/local/www/apache22/data"
ServerName test.lan:443 #имя указаное в Common Name сертификата веб-сервера
ServerAdmin you@example.com
ErrorLog "/var/log/httpd-error-ssl.log"
TransferLog "/var/log/httpd-access-ssl.log"
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile "/CA/webserver.crt"
SSLCertificateKeyFile "/CA/webserver.key"
SSLCertificateChainFile "/CA/ca.crt"
SSLCACertificateFile "/CA/ca.crt"
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory "/usr/local/www/apache22/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
BrowserMatch ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog "/var/log/httpd-ssl_request.log" \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
Запускаем вебсервер, проверяем работает ли, заходим по https, смотрим. Если все работает идем далее:
Издадим сертификат пользователя, настроим доступ к определенной веб-папке по сертификату.
Внесем изменения в httpd-ssl.conf, добавим строки:
<Directory /usr/local/www/apache22/data/ssl> #путь к веб-корню у меня /usr/local/www/apache22/data/
SSLVerifyClient require
SSLVerifyDepth 1
</Directory>
Издадим сертификат пользователя:
cd /CA
openssl genrsa -des3 -out fox.key 1024
openssl req -new -key fox.key -out fox.csr
openssl x509 -req -in fox.csr -out fox.crt -sha1 -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650
openssl pkcs12 -export -in fox.crt -inkey fox.key -name "fox cert" -out fox.p12
В процессе создания и импорта закрытого ключа, запрашивается пароль – необходимо внести. Затем переносим файл.p12 на ту систему где планируется его использование, переносим его либо в личное хранилище сертификатов, если ОС клиента – Windows, либо импортируем в хранилище Firefox`a, либо заливаем в аппаратный ключ или смарткарту.
Проверям. Пользуемся.
P.S. Немного сумбурно описал, но это в первую очередь для себя =)
P.P.S: Есть такой момент – при перезапуске вебсервера будет требоваться ввести пароль закрытого ключа вебсервера в консоли. Это определяется параметром
SSLPassPhraseDialog builtin
Решается следующим образом: в каталоге доступном только пользователю root создаем скрипт.
У меня, например, /root/webpass.sh
#!/bin/sh
echo "somepassword"
И в конфиге прописал:
SSLPassPhraseDialog exec:/root/webpass.sh
8 Responses
Только на вечер наметил подобные работы, как по каналам RSS пришла эта замечательная заметка. Спасибо
Круто, но я не понял веркэраунда с пассфразой. Не проще было ключ без нее сделать серверный? Один фиг в открытом виде передается.
Смысл в том, что файл с парольной фразой должен быть доступен только суперпользователю (root).
а если просто сделать доступ к директории по паролю(ну или средствами веб-формы) и всё это будет по https.
Пользователь же докажет свою подлинность по средством пароля, что ещё нужно?
Риторический вопрос: что проще украсть (подобрать) – пароль или сертификат, закрытый ключ которого дополнительно защищен паролем или находится на аппаратном ключе типа eToken ?
Отсюда и ответ зачем это надо.
А если закрыты ключ харнится на etkoen, что и где нужно прописать в apache, что бы тот за ключем обращался к токену???
В тексте про это явно сказано. Ищите строчку в тексте – SSLPassPhraseDialog builtin
Единственное что я нашел, этот явный путь к закрытому ключу сервера SSLCertificateKeyFile \”/CA/webserver.key\”
Если это webserver.key у меня в токен зашит, что я укажу в SSLCertificateKeyFile
?