Когда работал системным администратором, возникла у меня необходимость реализовать VPN на несколько десятков филиалов компании, интранет и почту на серверах в Москве с суровой защитой и доступом через VPN вообще отовсюду. При этом придумать всю систему и организовать её развёртывание предстояло в одно лицо. Бюджет был в тысячи полторы долларов, было это 4 года назад, некоторое время честно пытался найти более-менее приемлемое по цене ПО, потом нечестно пытался найти что-то на торрентах – пусто. В итоге – OpenSSL и OpenVPN. В этом вводном тексте хотелось бы поговорить об OpenSSL.
В конечном итоге были развёрнуты:
Описанное далее будет интересно скорее корпоративным технарям, нежели обычным пользователям. При условии, если: организация не государственная, есть цель сэкономить, есть желание попробовать некоторые «штуки» не вбухивая в R&D сумму с шестью нолями.
Предполагается, что читающие знакомы с понятиями VPN (в данном случае Virtual Private Network) и SSL (Secure Sockets Layer) и тем, что из себя представляют электронные сертификаты в формате x.509.
В полученной системе сертификаты можно было обновлять, отзывать, использовать для аутентификации, шифрования кода, файлов, почты, а в случае компрометации отозвать ветку, не убивая весь CA. Для этого пришлось очень внимательно отнестись к файлам настройки OpenSSL, построить процедуру генерации списка отозванных сертификатов (CRL – Certificate Revocation List) и корректную иерархию в CA. Только тогда выбранная реализация позволяла использовать сертификаты, в т.ч. и в автоматических процессах, где некому было нажимать кнопку «Да, я всё равно доверяю этому сертификату, хотя он и просрочен и выпущен неправильно и вообще не для этого предназначен».
Важно помнить (как оказалось), что выпуск и использование сертификатов электронной цифровой подписи это не только технический, но и организационный процесс, без которого преимущества использования подобного рода защиты сходят на нет. Диск с УЦ, к примеру, после выпуска всех сертификатов, лучше вынуть или отключить (если он USB) и убрать в сейф. И журнал завести.
Для интранет-сайта (первый эшелон – Apache, что там за ним было – не суть важно) была реализована многофакторная аутентификация. Обычно первым и единственным фактором при аутентификации выступает знание логина и пароля или логина и пин-кода; представляется серверу только клиент, а серверу не нужно доказывать что он — это он, отсюда возможность воровства логина/пароля и/или подмены сервера. В моём случае это было неприемлемо, поэтому к знанию логина/пароля добавилась необходимость иметь сертификат. Выгружались сертификаты из CA в формате PKCS12 (PFX) с паролем.
В конфиг сервера было добавлено что-то вроде:
Т.е. разрешить всем, чей сертификат выдан My LTD OpenSSL CA (в реальности, конечно, название другое)
Также можно ограничить доступ по именам:
В логи сервера пишется с помощью вот такой вот конструкции:
Полученный сертификат вместе с ключами устанавливали на компьютере пользователя (в реестр, зашифрованным на пин-коде), очень частый случай, при этом пользоваться сертификатом можно только на этом компьютере и в случае переустановки операционной системы сертификат, чаще всего, необходимо получать заново, если конечно закрытый ключ генерировался на компьютере, а не выдан вам на дискете при посещении УЦ, что можно считать профанацией с особым цинизмом, ведь по факту владельцами вашего якобы закрытого ключа становится (с возможностью проставлять за вас «электронную подпись») также и УЦ, а при определённом уровне разгильдяйства — все сменяющие друг друга админы в УЦ. Зато у УЦ появляется возможность предоставлять сервис по «восстановлению» сертификата.
Т.к. я был сам себе УЦ, то был избавлен и от такого «сервиса» и от копирования сертификатов «на память» техническими специалистами (и не очень).
Разъездным сотрудникам сертификаты выдавались на аппаратном носителе – USB-ключе Aladdin. Банки и УЦ предлагали (и предлагают) юридическим лицам для этой цели использовать дискеты или современный вариант — флешки. Это более удобно, но приводит к другой опасности — возможности сделать дубликат. В идеальном случае ключи и сертификаты должны храниться на смарт-карте, которая дополнительно защищена pin-кодом, имеет собственный крипто-процессор на борту, генератор случайных чисел, который, как считается, сильно понижает шансы потенциальных взломщиков, буде те решаться подобрать ваш ключ. Кроме того, смарт-карты практически не поддаются копированию.
USB-ключи Aladdin eToken как раз и являются такими картами, только в виде USB-брелка.
В случае аутентификации шифруется лишь небольшой объём данных, необходимый для процедуры, но при желании можно шифровать и весь трафик между клиентом и сервером. В случае, если сертификат нужно использовать для шифрования на сервере с большим количеством клиентов, в сервер нужно ставить уже что-то посерьёзнее например, крипто-плату, бесплатный IBM HTTP Server (тот-же Apache, фактически), даже какое-то их количество поддерживает.
Никто конечно не мешает использовать смарт-карты, которые выглядят как обычные пластиковые карты, но тогда на каждом рабочем месте, на котором такую карту нужно будет использовать, должен стоять картридер.
После того, как мы получили у УЦ сертификат, поместили его на «токен», и закрыли токен пин-кодом, мы получаем возможность выполнить двухфакторную двустороннюю аутентификацию. Фактор первый — мы имеем токен, фактор второй — знаем от него пин-код. А имея сертификат можем выполнить проверку, что сервер действительно тот, за кого себя выдаёт, в этом случае bobik.ru и bоbik.ru уже спутать не получится, потому, что русская «о» во втором варианте даст несовпадение имени (для компьютера это всё-таки разные буквы).
Благодаря тому, что в настройках сервера был прописан (и регулярно обновлялся) список отозванных сертификатов (CRL), всегда можно было оперативно приостановить доступ к сайту любого пользователя, в т.ч. в случае потери (или подозрения на потерю) USB-ключа, либо при увольнения сотрудника.
Многие отечественные CA местоположение CRL указывают, а выкладывать или обновлять сам список «забывают», и когда, скажем, тот-же Outlook не может проверить сертификат по списку отозванных и вывешивает предупреждение, консультант в CA по телефону может предложить вам это предупреждение проигнорировать. В случае, если клиентом является другой сервер, при невозможности проверки сертификата, он просто будет разрывать подключение.
В случае необходимости сертификат перевыпускался с тем же закрытым ключом, что позволяло не терять доступ к зашифрованным ранее данным.
В общем всем понятно, что сертификат – штука хорошая, осталось правильно его выпустить. После довольно продолжительной обкатки и изучения «документации» в несколько сотен страниц (на самом деле это был учебник по PKI и криптографии от «Интуита») выяснилось, что имеющиеся в инете на тот момент примеры конфигурации OpenSSL пригодны только для целей «на поиграться», я некоторое время сталкивался с тем, что выпущенные мной сертификаты то не работали в Outlook, то в Thunderbird, то в Firefox. Самым всеядным оказался IE.
Чтобы всё было чуть серьёзнее нужна небольшая рихтовка:
Следующим шагом наколенной автоматизации может являться написание интерфейса для просмотра списка сертификатов. Список имеет имя index.txt, понятный формат и я написал под него интерфейс на HTA. Для упрощения отладки HTA вызывал батники для отдельных процедур. Необходимый набор следующий:
В конечном итоге были развёрнуты:
- центр выдачи сертификатов (CA – Certificate Authority, он-же УЦ – Удостоверяющий Центр, в отечественной терминологии организация, уполномоченная выпускать сертификаты),
- интранет-сайт с авторизацией доступа по клиентским сертификатам,
- VPN с взаимной аутентификацией серверов, клиентов и динамической маршрутизацией,
- Авторизация клиентов на корпоративном IM сервере с помощью тех-же сертификатов.
Описанное далее будет интересно скорее корпоративным технарям, нежели обычным пользователям. При условии, если: организация не государственная, есть цель сэкономить, есть желание попробовать некоторые «штуки» не вбухивая в R&D сумму с шестью нолями.
Предполагается, что читающие знакомы с понятиями VPN (в данном случае Virtual Private Network) и SSL (Secure Sockets Layer) и тем, что из себя представляют электронные сертификаты в формате x.509.
СА
В полученной системе сертификаты можно было обновлять, отзывать, использовать для аутентификации, шифрования кода, файлов, почты, а в случае компрометации отозвать ветку, не убивая весь CA. Для этого пришлось очень внимательно отнестись к файлам настройки OpenSSL, построить процедуру генерации списка отозванных сертификатов (CRL – Certificate Revocation List) и корректную иерархию в CA. Только тогда выбранная реализация позволяла использовать сертификаты, в т.ч. и в автоматических процессах, где некому было нажимать кнопку «Да, я всё равно доверяю этому сертификату, хотя он и просрочен и выпущен неправильно и вообще не для этого предназначен».
Важно помнить (как оказалось), что выпуск и использование сертификатов электронной цифровой подписи это не только технический, но и организационный процесс, без которого преимущества использования подобного рода защиты сходят на нет. Диск с УЦ, к примеру, после выпуска всех сертификатов, лучше вынуть или отключить (если он USB) и убрать в сейф. И журнал завести.
Сайт
Для интранет-сайта (первый эшелон – Apache, что там за ним было – не суть важно) была реализована многофакторная аутентификация. Обычно первым и единственным фактором при аутентификации выступает знание логина и пароля или логина и пин-кода; представляется серверу только клиент, а серверу не нужно доказывать что он — это он, отсюда возможность воровства логина/пароля и/или подмены сервера. В моём случае это было неприемлемо, поэтому к знанию логина/пароля добавилась необходимость иметь сертификат. Выгружались сертификаты из CA в формате PKCS12 (PFX) с паролем.
В конфиг сервера было добавлено что-то вроде:
<Location /location1>
SSLOptions +FakeBasicAuth +StdEnvVars
SSLVerifyClient require
SSLVerifyDepth 2
SSLRequire %{SSL_CLIENT_I_DN_CN} in {"My LTD OpenSSL CA"}
Т.е. разрешить всем, чей сертификат выдан My LTD OpenSSL CA (в реальности, конечно, название другое)
Также можно ограничить доступ по именам:
<Location /location2>
SSLOptions +FakeBasicAuth +StdEnvVars
SSLVerifyClient require
SSLVerifyDepth 2
SSLRequire %{SSL_CLIENT_S_DN_CN} in {"Ivan A Ivanov", \
"Petr B Petrov"}
В логи сервера пишется с помощью вот такой вот конструкции:
CustomLog ../logs/ssl/ssl_request.log \
"\"%t\",\"%h\",\"%{SSL_CLIENT_S_DN_CN}x\",\"%r\",\"%s\"" env=!dontlogit
Распространение сертификатов
Полученный сертификат вместе с ключами устанавливали на компьютере пользователя (в реестр, зашифрованным на пин-коде), очень частый случай, при этом пользоваться сертификатом можно только на этом компьютере и в случае переустановки операционной системы сертификат, чаще всего, необходимо получать заново, если конечно закрытый ключ генерировался на компьютере, а не выдан вам на дискете при посещении УЦ, что можно считать профанацией с особым цинизмом, ведь по факту владельцами вашего якобы закрытого ключа становится (с возможностью проставлять за вас «электронную подпись») также и УЦ, а при определённом уровне разгильдяйства — все сменяющие друг друга админы в УЦ. Зато у УЦ появляется возможность предоставлять сервис по «восстановлению» сертификата.
Т.к. я был сам себе УЦ, то был избавлен и от такого «сервиса» и от копирования сертификатов «на память» техническими специалистами (и не очень).
Разъездным сотрудникам сертификаты выдавались на аппаратном носителе – USB-ключе Aladdin. Банки и УЦ предлагали (и предлагают) юридическим лицам для этой цели использовать дискеты или современный вариант — флешки. Это более удобно, но приводит к другой опасности — возможности сделать дубликат. В идеальном случае ключи и сертификаты должны храниться на смарт-карте, которая дополнительно защищена pin-кодом, имеет собственный крипто-процессор на борту, генератор случайных чисел, который, как считается, сильно понижает шансы потенциальных взломщиков, буде те решаться подобрать ваш ключ. Кроме того, смарт-карты практически не поддаются копированию.
USB-ключи Aladdin eToken как раз и являются такими картами, только в виде USB-брелка.
В случае аутентификации шифруется лишь небольшой объём данных, необходимый для процедуры, но при желании можно шифровать и весь трафик между клиентом и сервером. В случае, если сертификат нужно использовать для шифрования на сервере с большим количеством клиентов, в сервер нужно ставить уже что-то посерьёзнее например, крипто-плату, бесплатный IBM HTTP Server (тот-же Apache, фактически), даже какое-то их количество поддерживает.
Никто конечно не мешает использовать смарт-карты, которые выглядят как обычные пластиковые карты, но тогда на каждом рабочем месте, на котором такую карту нужно будет использовать, должен стоять картридер.
После того, как мы получили у УЦ сертификат, поместили его на «токен», и закрыли токен пин-кодом, мы получаем возможность выполнить двухфакторную двустороннюю аутентификацию. Фактор первый — мы имеем токен, фактор второй — знаем от него пин-код. А имея сертификат можем выполнить проверку, что сервер действительно тот, за кого себя выдаёт, в этом случае bobik.ru и bоbik.ru уже спутать не получится, потому, что русская «о» во втором варианте даст несовпадение имени (для компьютера это всё-таки разные буквы).
Списки отозванных сертификатов
Благодаря тому, что в настройках сервера был прописан (и регулярно обновлялся) список отозванных сертификатов (CRL), всегда можно было оперативно приостановить доступ к сайту любого пользователя, в т.ч. в случае потери (или подозрения на потерю) USB-ключа, либо при увольнения сотрудника.
Многие отечественные CA местоположение CRL указывают, а выкладывать или обновлять сам список «забывают», и когда, скажем, тот-же Outlook не может проверить сертификат по списку отозванных и вывешивает предупреждение, консультант в CA по телефону может предложить вам это предупреждение проигнорировать. В случае, если клиентом является другой сервер, при невозможности проверки сертификата, он просто будет разрывать подключение.
В случае необходимости сертификат перевыпускался с тем же закрытым ключом, что позволяло не терять доступ к зашифрованным ранее данным.
Доводка OpenSSL
В общем всем понятно, что сертификат – штука хорошая, осталось правильно его выпустить. После довольно продолжительной обкатки и изучения «документации» в несколько сотен страниц (на самом деле это был учебник по PKI и криптографии от «Интуита») выяснилось, что имеющиеся в инете на тот момент примеры конфигурации OpenSSL пригодны только для целей «на поиграться», я некоторое время сталкивался с тем, что выпущенные мной сертификаты то не работали в Outlook, то в Thunderbird, то в Firefox. Самым всеядным оказался IE.
Чтобы всё было чуть серьёзнее нужна небольшая рихтовка:
- если вы хотите, чтобы ваша система прожила больше года, перед выпуском корневого сертификата CA увеличьте количество дней до 3650, потом верните обратно, для пользовательских сертификатов лучше оставить год или полгода
- в секции [ CA_default ]
выставить параметр unique_subject в «yes» — это не позволит вам выпустить 2 идентичных сертификата - в секции [ user_cert ]
добавить
ExtendedKeyUsage = clientAuth
- секция для серверов может выглядеть так
[ server_cert ]
basicConstraints = CA:FALSE
nsCertType = server
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = nsSGC, serverAuth - в секции [ v3_ca]
изменить
basicConstraints = CA:TRUE, pathlen:5
- раскомментировать nsCertType и keyUsage
- добавить
extendedKeyUsage = serverAuth, clientAuth
Автоматизация выпуска сертификатов
Следующим шагом наколенной автоматизации может являться написание интерфейса для просмотра списка сертификатов. Список имеет имя index.txt, понятный формат и я написал под него интерфейс на HTA. Для упрощения отладки HTA вызывал батники для отдельных процедур. Необходимый набор следующий:
- отдельно вынесен файл настройки переменных окружения
- выпуск произвольного сертификата – минимум настроек, задаёт кучу вопросов, позволяет выпустить сертификат, скажем, для партнёров, потом подписать в нашем CA
- выпуск корневого сертификата CA – вызывается один раз или несколько раз, если строится дерево, ручками
- выпуск сертификата сервера – понятная штука, openssl вызывается с параметром -extensions server_cert, а в конфиге в секции [server_cert] должны быть нужные параметры, ещё одно отличие – не упаковывается в PFX и создаёт распакованные версии ключей, может понадобится некоторым серверам
- выпуск сертификата пользователя
- отзыв сертификата – интересный процесс: из архива (надо делать самому) выданных сертификатов извлекался нужный (по имени, но можно и по серийному номеру), потом по нему уже выполнялся отзыв
- обновление сертификата пользователя – сначала выполнялся отзыв старого сертификата (батником №6), потом создание нового сертификата (батником №5) для старого ключа
- обновление списка отозванных сертификатов – простая команда, но в моём случае сопровождалась запуском скрипта на Perl, который препарировал полученный список и помещал его в директорию (адресную книгу, как её ещё иногда называют) Lotus Domino, оттуда его было проще доставать (через LDAP, что является практически стандартным способом дистрибуции CRL)