Как стать автором
Обновить

Установка и настройка центра сертификации EJBCA в Debian 6 с поддержкой LunaSA HSM

Время на прочтение13 мин
Количество просмотров6.8K
image image image

Как все настроить: пошаговая инструкция с пояснениями и мыслями вслух.

Решил поделится собственным опытом развертывания центра сертификации EJBCA в продакшн-системе. На Хабре уже есть хорошая обзорная статья по установке EJBCA, однако не всегда типовые конфигурации подходят для реальных нужд.
Когда же нужен центр сертификации (Certification Authority или CA) на предприятии? Нет нужды развертывать собственную инфраструктуру открытых ключей (PKI) если необходимо выпустить несколько SSL сертификатов для публичных веб-серверов. Более того, это крайне не рекомендуется, так как существует два варианта развития событий:

  • ваш новоиспеченный CA будет добавлен в Microsoft Root Certificate Program, Apple Root Certificate Program, The Opera Rootstore и в различные дистрибутивы GNU/Linux и т.п. Это очень дорого и долго. Имеет смысл только если вы собираетесь массово продавать SSL сертификаты для конечных пользователей. Для других целей этот CA использовать не получится из-за ограниченных параметров KeyUsage.
  • ваш новоиспеченный CA будет подписан СА, который входит в цепочку сертификатов распространяемых по вышеперечисленным программам. Это может быть промежуточный или корневой CA. Однако, программы распространения корневых CA ограничивают область применения выпущенных сертификатов. Например в среде Windows значение параметра KeyUsage корневого сертификата распространяется на все пользовательские сертификаты всех промежуточных центров, подписанных эти корневым CA.
    Получается, что пользовательский сертификат, подписанный публичным центром сертификации, не получится использовать, например, для авторизации по смарт-карте. Так же не будет возможности архивировать закрытые ключи. Безусловно, все эти ограничения можно искусственно преодолеть, но это идет в разрез с рекомендациями и требует участия конечных пользователей.

Итак, серверные SSL сертификаты лучше заказывать у крупных игроков на рынке. Если же речь идет о машинных сертификатах для доступа к корпоративным сетевым ресурсам, о сертификатах авторизации по смарт-карте, о сертификатах для подписи или шифрования почтовых сообщений — вот тогда необходимо развертывать собственный центр сертификации с различными модулями (OCSP-ответчик, Autoenroll, внешний RA и т.п.)
Вот нормализованный список задач для которых надо устанавливать PKI на предприятии:
  • Внедрение защищённых механизмов аутентификации — смарт-карты, сертификаты для аутентификации в IIS/VPN;
  • Внедрение защищённых сетевых протоколов — L2TP, SSL, IPsec;
  • Внедрение защищённой почты с шифрованием и/или подписью писем;
  • Внедрение цифровых подписей документов и файлов, что гарантирует их целостность и альтернативу ручной подписи.
  • Внедрение защищённых файловых хранилищ с шифрованием особо конфиденциальной информации.

Условия моей задачи следующие:
  1. Операционная система — Debian 6.0 64-bit в минимальной конфигурации.
  2. Сервер не имеет доступа в интернет.
  3. Тип центра сертификации — Issuing CA, т.е. он будет выпускать сертификаты конечным пользователям, при этом не являясь корневым CA.
  4. Закрытый ключ CA должен храниться в HSM (Hardware Security Module) LunaSA.
  5. База данных CA — MySQL.
  6. Все лишнее должно быть или не установлено, или удалено.
  7. Доступ к разделу администратора должен предоставляться по SSL сертификату, выданному сторонним центром сертификации.

Приступим:
Подразумеваем, что у нас есть SSH доступ к установленной системе debian-6.0-amd64-minimal на сервере и на HSM уже создан раздел, у нас есть доступ к HSM по портам 22 и 1792, плюс есть пароль для раздела, раздел активирован.

Подготовка к установке


Скачиваем необходимые пакеты и переносим их на сервер в установочный каталог. Вот список всех компонентов:
alien ant ant-optional binutils bzip2 ca-certificates ca-certificates-java curl debhelper defoma dpkg-dev file fontconfig fontconfig-config gettext gettext-base html2text intltool-debian java-common libaccess-bridge-java libaccess-bridge-java-jni libasound2 libasyncns0 libatk1.0-0 libavahi-client3 libavahi-common-data libavahi-common3 libcairo2 libcap2 libcroco3 libcups2 libcurl3 libdatrie1 libdb4.7 libdbd-mysql-perl libdbi-perl libdpkg-perl libelf1 libexpat1 libflac8 libfontconfig1 libfreetype6 libgif4 libglib2.0-0 libgomp1 libgtk2.0-0 libgtk2.0-common libice6 libidn11 libjasper1 libjaxp1.3-java libjpeg62 liblcms1 liblua5.1-0 libmagic1 libmysql-java libmysqlclient16 libnet-daemon-perl libnspr4-0d libnss3-1d libogg0 libpango1.0-0 libpango1.0-common libpcap0.8 libpcre3 libpixman-1-0 libplrpc-perl libpng12-0 libpulse0 librpm1 librpmbuild1 librpmio1 libsm6 libsndfile1 libssh2-1 libthai-data libthai0 libtiff4 libtimedate-perl libunistring0 libvorbis0a libvorbisenc2 libxcb-render-util0 libxcb-render0 libxcomposite1 libxcursor1 libxdamage1 libxerces2-java libxext6 libxfixes3 libxft2 libxi6 libxinerama1 libxml2 libxrandr2 libxrender1 libxtst6 make mysql-client-5.1 mysql-common mysql-server mysql-server-5.1 mysql-server-core-5.1 nano nmap openjdk-6-jdk openjdk-6-jre openjdk-6-jre-headless openjdk-6-jre-lib openssl patch perl perl-base perl-modules po-debconf psmisc rpm rpm-common rpm2cpio shared-mime-info telnet ttf-dejavu-core tzdata tzdata-java ucf x11-common


Если у вас есть аналогичный сервер с доступом в интернет, то можно запустить команду
# apt-get clean
# apt-get -d install nano ant openjdk-6-jdk libmysql-java alien mysql-server

и потом скопировать *.deb файлы из каталога /var/cache/apt/archives/ на сервер EJBCA.
На сервере EJBCA создаем установочный каталог и копируем пакеты
# mkdir -p /root/install/deb
# cd /root/install/deb
# scp<источник>:*.deb .

Затем надо подключить каталог с установочными пакетами в качестве репозитария (доступа в интернет на сервере EJBCA нет). Необходимо сформировать файл Packages.gz
# dpkg -i dpkg-dev_1.15.8.11_all.deb
# dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz

Указываем на каталог в списке источников
# echo 'deb file:///root/install/deb /' > /etc/apt/sources.list
Обновляем репозитарий
# apt-get update
Устанавливаем компоненты системы
# apt-get install nano ant openjdk-6-jdk libmysql-java alien
Надо ответить Yes на оба задаваемых вопроса

Устанавливаем сервер MySQL

# apt-get install mysql-server
Надо ответить Yes на оба задаваемых вопроса
Определяем пароль администратора сервера MySQL
Для поддержки Unicode создаем файл конфигурации:
# nano /etc/mysql/conf.d/utf-8.cnf
[client]
default-character-set=utf8
[mysqld]
default-character-set=utf8
default-collation=utf8_unicode_ci
character-set-server=utf8
init-connect='SET NAMES utf8'
character-set-client = utf8


Перезапускаем MySQL
# service mysql restart
Подготавливаем БД для установки EJBCA
# mysql –p
Cоздаем базу и пользователя, даем пользователю права.
mysql> create database ejbca;
mysql> grant all privileges on ejbca.* to 'ejbca'@'localhost' identified by '<password>';
mysql> flush privileges;
mysql> quit;

Создаем пользователей в операционной системе.
# adduser --system --shell /bin/bash --group jboss
# adduser --system --shell /bin/bash --group ejbca
# usermod -a -G jboss ejbca

Настраиваем окружение
# rm /usr/lib/jvm/java-1.6.0-openjdk
# ln -s /usr/lib/jvm/java-6-openjdk /usr/lib/jvm/latest
# nano /etc/profile

После “export PATH” добавляем следующее:
JAVA_HOME="/usr/lib/jvm/latest"
export JAVA_HOME
export PATH=$PATH:$JAVA_HOME/bin

ANT_HOME="/usr/share/ant"
export ANT_HOME
export PATH=$PATH:$ANT_HOME/bin

export JBOSS_HOME=/opt/jboss
export PATH=$PATH:$JBOSS_HOME/bin

export PATH=$PATH:/usr/lunasa/bin

Обновляем переменные окружения
# . /etc/profile

Установка JBOSS


JBOSS — это сервер приложений Java. Так как EJBCA целиком написан на Java, то необходимо настроить среду для компиляции и выполнения EJBCA.
Скачиваем jboss-5.1.0.GA-jdk6.zip и копируем на сервер
# cd /opt
# scp<источник>:jboss-5.1.0.GA-jdk6.zip .

Распаковываем и затем удаляем архив
# jar -xvf jboss-5.1.0.GA-jdk6.zip
# rm jboss-5.1.0.GA-jdk6.zip

Присваиваем права доступа
# chown -R jboss.jboss /opt/jboss-5.1.0.GA
# chmod -R o= /opt/jboss-5.1.0.GA

Для гибкого обновления в будущем делаем софтлинк на ресурс jboss
# ln -s jboss-5.1.0.GA jboss
Скрипт автозагрузки можно загрузить тут. Скачайте его и скопируйте в каталог /etc/init.d/
Делаем скрипт исполняемым
# chmod +x /etc/init.d/ejbca
Создаем конфигурационный файл jboss
# mkdir /etc/jboss
# chmod 750 /etc/jboss
# nano /etc/jboss/ejbca.conf

user=ejbca
group=ejbca
javaHome=/usr/lib/jvm/latest
javaOpts=(-XX:PermSize=96m -XX:MaxPermSize=128m -Xms128m -Xmx512m -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000)
jbossHome=/opt/jboss
jbossConf=ejbca
jbossBind=0.0.0.0
jbossClasspath=/usr/share/java/mysql.jar


Присваиваем права доступа
# chmod 640 /etc/jboss/ejbca.conf

Создаем и настраиваем папку виртуального сервера
# cd /opt/jboss/server/
# cp -pr default ejbca
# chown -R ejbca.ejbca ejbca


Удаляем ненужные компонента JBOSS
# su - ejbca
$ rm -rf /opt/jboss/server/ejbca/deploy/ROOT.war/
$ rm -rf /opt/jboss/server/ejbca/deploy/jmx-console.war/
$ rm -rf /opt/jboss/server/ejbca/deploy/management/
$ rm -rf /opt/jboss/server/ejbca/deploy/admin-console.war/
$ exit


Установка EJBCA


Скачиваем ejbca_4_0_7.zip и копируем на сервер
# cd /opt
# scp<источник>:ejbca_4_0_7.zip .

Распаковываем и затем удаляем архив
# jar -xvf ejbca_4_0_7.zip
# rm ejbca_4_0_7.zip


Присваиваем права доступа
# chown -R ejbca.ejbca /opt/ejbca_4_0_7/
# chmod -R o= /opt/ejbca_4_0_7/


Для гибкого обновления в будущем делаем софтлинк на ресурс ejbca
# ln -s ejbca_4_0_7 ejbca

Задаем основные параметры EJBCA
# nano /opt/ejbca/conf/ejbca.properties
appserver.home=/opt/jboss
appserver.type=jboss
jboss.config=ejbca
ejbca.productionmode=ca


Для дальнейшей работы с HSM компилируем clientToolBox и ejbca-ejb-cli
# cd /opt/ejbca
# ant clientToolBox
# ant ejbca-ejb-cli

Делаем все скрипты в папке bin исполняемыми
# chmod +x bin/*.sh

Настраиваем доступ к базе данных

# nano /opt/ejbca/conf/database.properties
database.name=mysql
database.url=jdbc:mysql://127.0.0.1:3306/ejbca?characterEncoding=UTF-8
database.driver=com.mysql.jdbc.Driver
database.username=ejbca
database.password=<пароль пользователя ejbca>


Настраиваем доступ к почтовому серверу

# nano /opt/ejbca/conf/mail.properties
mail.user=ejbca_user
mail.password=<пароль ejbca_user>
mail.smtp.host=<IP или FQDN почтового сервера>
mail.smtp.port=25
mail.smtp.auth=true/false
mail.from=<ejbca-donotreply@domain.com>
web.contentencoding=UTF-8


Настраиваем параметры web сервера

# nano /opt/ejbca/conf/web.properties
java.trustpassword=<пароль для JKS>
superadmin.cn=EJBCA Admin
superadmin.dn=CN=${superadmin.cn}
superadmin.password=<пароль админа>
superadmin.batch=false
httpsserver.password=<пароль web-сервера>
httpsserver.hostname=<FQDN сервера EJBCA>
httpsserver.dn=CN=${httpsserver.hostname}
httpserver.pubhttp=8080
httpserver.pubhttps=8442
httpserver.privhttps=8443
httpsserver.bindaddress.pubhttp=0.0.0.0
httpsserver.bindaddress.pubhttps=0.0.0.0
httpsserver.bindaddress.privhttps=0.0.0.0
web.contentencoding=UTF-8
hardtoken.diplaysensitiveinfo=true
web.docbaseuri=disabled
web.reqcertindb=false # этот параметр важен!
web.renewalenabled=false


Присваиваем права доступа
# chown ejbca.ejbca /opt/ejbca/conf/*.properties
# chmod 640 /opt/ejbca/conf/*.properties


Запускаем компиляцию и конфигурирование EJBCA
# su - ejbca
$ cd /opt/ejbca
$ ant bootstrap
$ exit


Теперь необходимо настроить EJBCA таким образом, чтобы авторизация администратора происходила по сертификату, выданному внешним центром сертификации. В стандартной установке EJBCA генерирует самоподписанный сертификат, устанавливает его в систему, выпускает SSL сертификат для web-сервера и создает PKCS#12 файл с парой ключей для пользователя superadmin (если в файле web.properties прописано superadmin.batch=true). Нам такая самодеятельность не нужна, необходим полный контроль над процессом.
Подразумевается, что у нас уже есть закрытый ключ и сертификат в файле PKCS#12 для web-сервера. DN сертификата должен совпадать с параметром httpsserver.dn в файле web.properties. Заказать файл p12 можно у продавцов SSL сертификатов. Если будете генерировать серверный сертификат самостоятельно, но необходимо верно указать критический KeyUsage — Digital Signature и Key Encipherment.
Создаем каталог для хранения сертификатов и ключей
# mkdir /opt/ejbca/p12
# cd /opt/ejbca/p12

Копируем серверный файл PKCS#12 (назовем его webserver.p12)
# scp<источник>:webserver.p12 .
Создаем хранилище сертификатов JKS и импортируем туда наши данные
# keytool -v -importkeystore -srckeystore webserver.p12 -srcstoretype PKCS12 -destkeystore tomcat.jks -deststoretype JKS
Копируем сертификат внешнего CA (назовем его CA_cert.cer)
# scp<источник>:CA_cert.cer .
Устанавливаем его в оба локальных хранилища
# keytool -import -alias cacert-file CA_cert.cer -keystore tomcat.jks
# keytool -import -trustcacerts -file CA_cert.cer -keystore truststore.jks -storepass <пароль для JKS> -alias externalca

Присваиваем права доступа
# chmod +x *.jks

Прописываем автозагрузку и запускаем сервер EJBCA

# update-rc.d ejbca defaults
# service ejbca start

Проверяем, что сервер запустился нормально
# su – ejbca
$ tail -f /opt/jboss/server/ejbca/log/server.log
$ exit

В зависимости от конфигурации сервера запуск EJBCA может занять от 5 секунд до 7 минут. Это мой личный опыт.
Сейчас необходимо установить доверие к стороннему центру сертификации в EJBCA и запустить службу авторизации.
# cd /opt/ejbca
# bin/ejbca.sh ca importcacert <DN внешнего CA без "CN=" в начале> CA_cert.cer -initauthorization -superadmincn <CN администратора>

DN внешнего CA мы знаем из CA_cert.cer, CN администратора должен совпадать с параметром superadmin.cn в файле web.properties. После этого надо послать запрос во внешний CA на генерацию пары ключей для администратора с заданным CN. В результате будет получен файл PKCS#12, который потом надо будет импортировать в браузер.

Останавливаем EJBCA

# service ejbca stop
Сейчас, когда сертификаты установлены в систему и служба аторизации по сертификатам активирована, можно запустить установку системы.
# su - ejbca
$ cd /opt/ejbca
$ ant deploy
$ exit

При этом сертификаты из каталога /opt/ejbca/p12 будут скопированы в хранилища сертификатов /opt/jboss/server/ejbca/conf/keystore/, которые использует Tomcat.
Присваиваем права доступа
# chmod +x /opt/jboss/server/ejbca/conf/keystore/*.jks

Запускаем EJBCA

# service ejbca start
Теперь самое время импортировать администраторский p12 в браузер. Думаю, что читающие эту статью знают как это сделать. :-)

Настройка подключения к HSM


Мы хотим хранить закрытый ключ нашего CA в специальном криптографическом устройстве. Стойкость PKI при использовании HSM значительно выше, чем при использовании программных хранилищ. Скомпрометировать закрытый ключ в HSM практически невозможно, так как процесс генерации происходит внутри устройства, а извлечение (импорт) закрытого ключа во большинстве устройствах отсутствует по определению. Можно делать бэкапы на специальные PCMCIA карты или смарт-карты, которые тоже по сути являются маленькими HSM.
У меня в распоряжении оказался LunaSA HSM производства SafeNet. Не существует пакетов клиентской части для Debian x64, есть только RPM пакеты для RHEL. Но ничего не мешает использовать alien для установки RPM пакетов на Debian.
Создаем установочный каталог и копируем файлы клиентской части HSM
# mkdir -p /root/install/hsm
# cd /root/install/hsm
# scp<источник>:*.* .

Затем последовательно устанавливаем все пакеты
# alien -i -c <имя RPM пакета>
Настраиваем сопряжение с HSM
# cd /usr/lunasa
Копируем SSL сертификат с HSM
# ctp admin@{LunaSA IP}:server.pem .
Добавляем сервер в список доверенных
# vtl addServer -n {LunaSA IP} -c server.pem
Создаем клиентскую пару ключей
# vtl createCert -n {IP или FQDN сервера EJBCA}
Копируем клиентский сертификат на HSM
# ctp cert/client/<IP или FQDN сервера EJBCA>.pem admin@{LunaSA IP}:
Регистрируем клиента на HSM
# ssh admin@{LunaSA IP}

lunash:>client register -client {alias} -hostname {IP или FQDN сервера EJBCA}
lunash:>client assignPartition -client {IP или FQDN сервера EJBCA} -partition {наименование раздела}
lunash:> exit

Проверяем подключение к HSM
# vtl verify
The following Luna SA Slots/Partitions were found:

Slot Serial # Label
==== ======== =====
slot nr Serial nr partition name


Теперь подготавливаем данные для генерации ключа в HSM. Можно присвоить ключу метку. Для этого надо перекодировать строку метки в последовательность ASCII символов. Для этого замечательно подходит утилита xxd
# echo -ne 'HABRAHABR - Test EJBCA'|xxd -c 256 -ps
484142524148414252202d205465737420454a424341

Потом это значение надо записать в параметр CKA_LABEL конфигурационного файла, причем в начале последовательности надо добавить 0h.
Создаем файл с установками
# cd /opt/ejbca
# nano /opt/ejbca/conf/lunasa.conf

name=LunaSA
library=/usr/lunasa/lib/libCryptoki2_64.so
slotListIndex = 0

attributes(generate,*,*) = {
  CKA_TOKEN = true
  CKA_LABEL = 0h484142524148414252202d205465737420454a424341
}
attributes(generate,CKO_PUBLIC_KEY,*) = {
  CKA_ENCRYPT = true
  CKA_VERIFY = true
  CKA_WRAP = true
}
attributes(generate, CKO_PRIVATE_KEY,*) = {
  CKA_EXTRACTABLE = false
  CKA_DECRYPT = true
  CKA_SIGN = true
  CKA_UNWRAP = true
}


Запускаем генерацию ключа

# /opt/ejbca/dist/clientToolBox/ejbcaClientToolBox.sh PKCS11HSMKeyTool generate conf/lunasa.conf 4096 '{DN внешнего CA без "CN=" в начале}'
4096 — это размер ключа в битах
Надо будет ввести пароль раздела HSM.
Теперь будем работать в консоли администратора. Открываем в браузере адрес https://{FQDN сервера EJBCA}:8443/ejbca/adminweb/index.jsp
Сервер запросит клиентский сертификат, надо указать ранее импортированный сертификат администратора.
  • Жмем “Edit Certificate Authorities” в группе CA Functions
  • Вводим имя для нового CA в поле Add CA и жмем Create…


Заполняем параметры создаваемого центра сертификации

CA Token Type: PKCS#11
Hard CA Token Properties:
sharedLibrary /usr/lunasa/lib/libCryptoki2_64.so
defaultKey <DN внешнего CA без "CN=" в начале и без кавычек>
slot = 1
pin <пароль раздела HSM>

Значение поля pin может быть паролем в открытом или закодированном виде. Конечно, лучше пароль закодировать. Это можно сделать с помощью команды:
# /opt/ejbca/bin/ejbca.sh encryptpwd
Кодирование пароля не гарантирует его безопасность, но значительно снижает вероятность компрометации при случайном просмотре посторонними лицами.
Authentication Code: <пароль раздела HSM>
Subject DN: DN внешнего CA
Signed By: External CA
Default CRL Dist. Point: <точка распространения CRL для этого CA>
остальные параметры настраивайте в соответствии с вашими требованиями
  • Жмем Make Certificate request…
  • Находим файл с сертификатом подписывающего CA, и всех центров сертификации в цепочке сертификатов, включая корневой CA. Указываем этот файл в поле «Path to certificate chain about to sign CA»
  • Нажимаем «Make Certificate Request»

Если все настроено правильно, то на экране появится текст запроса к подписывающему CA в формате PEM. Так же внизу будут ссылки на скачивание файла с запросом.
  • Сохраняем запрос в файл PEM и передаем на подпись CA верхнего уровня. После подписания надо сохранить готовый сертификат нашего CA в формате PEM в папку на локальной машине.
  • В консоли администратора выбираем наш CA списка. Статус CA должен быть «Waiting for Certificate Response». Жмем Edit CA.
  • Перематываем окно книзу и нажимаем «Receive Certificate Response»
  • Указываем на сохраненный файл с сертификатом нашего CA в поле «Path to certificate signed by external CA»
  • Жмем «Receive Certificate Response»

Радуемся, что все успешно импортировалось. Статус нашего CA должен стать Active.
Остался последний штрих. Надо импортировать подписанный сертификат на HSM.
Копируем файл с сертификатом на сервер EJBCA и выполняем
# cd /opt/ejbca
# /opt/ejbca/dist/clientToolBox/ejbcaClientToolBox.sh PKCS11HSMKeyTool installcert /usr/lunasa/lib/libCryptoki2_64.so 1 <имя файла с сертификатом CA>

Удаляем сертификат, выходим
# rm <имя файла с сертификатом CA>
# exit

Вот и все, установка закончена. В итоге в системе зарегистрировано два центра сертификации, первый внешний и используется только для проверки клиентских SSL сертификатов при доступе к панели администратора. Второй — это наш рабочий центр сертификации, который не является корневым. В моем случае рабочий CA был второго уровня, корневой центр сертификации используется только для подписи промежуточных CA и для периодической генерации CRL. Все остальное время он физически отключен, что совершенно исключает возможность компрометации закрытого ключа.
Такая конфигурация успешно внедрена в очень крупном финансовом предприятии.
На подходе статья про настройку OCSP, Autoenrollment и внешнего RA на базе EJBCA.
Спасибо за внимание!

Список использованных при написании статьи ресурсов:
EJBCA Installation
Vadims Podans's blog
Branko Majic's detailed guide
Теги:
Хабы:
+4
Комментарии4

Публикации

Истории

Работа

Ближайшие события