В одной из наших предыдущих статей мы рассказывали про важность двухфакторной аутентификации на корпоративных порталах компаний. В прошлый раз мы продемонстрировали, как настроить безопасную аутентификацию в web-сервере IIS.

В комментариях нас просили написать инструкцию для самых распространенных web-серверов под Linux — nginx и Apache.

Вы просили — мы написали.

Что надо, чтобы начать?


  • Любой современный дистрибутив Linux. Я выполнял тестовую настройку в MX Linux 18.2_x64. Это конечно не серверный дистрибутив, но для Debian вряд ли будут какие-то отличия. Для других дистрибутивов могут слегка различаться пути до библиотек\конфигов.
  • Токен. Мы продолжаем использовать модель Рутокен ЭЦП PKI, которая идеально подходит по скоростным характеристикам для корпоративного применения.
  • Для работы с токеном в Linux необходимо установить следующие пакеты:
    libccid libpcsclite1 pcscd pcsc-tools opensc


Выписывание сертификатов


В предыдущих статьях мы опирались на то, что сертификаты сервера и клиентов будут выписываться с помощью Microsoft CA. Но раз уж мы настраиваем все в Linux, то заодно расскажем про альтернативный способ выписывания этих сертификатов — не покидая Linux.
В качестве CA будем использовать XCA (https://hohnstaedt.de/xca/), который доступен в любом современном дистрибутиве Linux. Все действия, которые мы будем совершать в XCA можно сделать и в режиме командной строки с помощью утилит OpenSSL и pkcs11-tool, но для большей простоты и наглядности в этой статье мы их приводить не будем.

Начало работы


  1. Устанавливаем:

    $ apt-get install xca
  2. И запускаем:

    $ xca
  3. Создаём нашу базу данных для CA — /root/CA.xdb
    Мы рекомендуем хранить базу данных Certificate Authority в папке, куда есть доступ только у администратора. Это важно для защиты закрытых ключей корневых сертификатов, которые используются для подписывания всех остальных сертификатов.

Создаём ключи и сертификат root CA


В основе инфраструктуры открытых ключей (PKI) лежит иерархическая система. Главным в этой системе является корневой центр сертификации или root CA. Его сертификат и надо создать в первую очередь.

  1. Создаём для CA закрытый ключ RSA-2048. Для этого на вкладке Private Keys нажимаем New Key и выбираем соответствующий тип.
  2. Задаём имя для новой ключевой пары. Я её назвал — CA Key.
  3. Выписываем сам сертификат CA, с использованием созданной ключевой пары. Для этого переходим на вкладку Certificates и нажимаем New Certificate.
  4. Обязательно выбираем SHA-256, потому что использование SHA-1 уже не может считаться безопасным.
  5. В качестве шаблона обязательно выбираем [default] CA. Не забудьте нажать на Apply all, иначе шаблон не применяется.
  6. На вкладке Subject выбираем нашу ключевую пару. Там же вы можете заполнить все основные поля сертификата.


Создаём ключи и сертификат https-сервера


  1. Аналогичным образом создаём для сервера закрытый ключ RSA-2048, я его назвал — Server Key.
  2. При создании сертификата выбираем, что сертификат сервера необходимо подписать на сертификате CA.
  3. Не забываем выбрать SHA-256.
  4. В качестве шаблона выбираем [default] HTTPS_server. Жмём на Apply all.
  5. После чего на вкладке Subject выбираем наш ключ и заполняем нужные поля.


Создаём ключи и сертификат для пользователя


  1. Закрытый ключ пользователя будет храниться на нашем токене. Для работы с ним необходимо установить PKCS#11 библиотеку с нашего сайта. Для популярных дистрибутивов мы распространяем готовые пакеты, которые лежат тут — https://www.rutoken.ru/support/download/pkcs/. У нас также есть сборки для arm64, armv7el, armv7hf, e2k, mipso32el, которые можно взять в нашем SDK — https://www.rutoken.ru/developers/sdk/. Кроме сборок для linux также есть сборки для macOS, freebsd и android.
  2. Добавляем новый PKCS#11 Provider в XCA. Для этого идём в меню Options на вкладку PKCS#11 Provider.
  3. Жмём Add и выбираем путь до библиотеки PKCS#11. В моём случае это \usr\lib\librtpkcs11ecp.so.
  4. Нам понадобится отформатированный токен Рутокен ЭЦП PKI. Скачиваем утилиту rtAdmin — https://dev.rutoken.ru/pages/viewpage.action?pageId=7995615
  5. Выполняем

    $ rtAdmin -f -q -z /usr/lib/librtpkcs11ecp.so -u <PIN-код пользователя>
  6. В качестве типа ключа выбираем — ключ RSA-2048 на Рутокен ЭЦП PKI. Я назвал этот ключ Client Key.

  7. Вводим PIN-код. И ждём завершения аппаратной генерации ключевой пары

  8. Сертификат для пользователя создаём по аналогии с сертификатом сервера. На этот раз выбираем шаблон [default] HTTPS_client и не забываем нажать Apply all.
  9. На вкладке Subject вводим информацию о пользователе. На запрос о сохранении сертификата на токен отвечаем утвердительно.

В итоге на вкладке Сертификаты в XCA должна получиться примерно такая картинка.


Этого минимального набора ключей и сертификатов достаточно для того, чтобы приступать к настройке непосредственно серверов.

Для настройки нам необходимо выполнить экспорт сертификата УЦ, сертификата сервера и закрытого ключа сервера.

Для этого надо выбрать нужную запись на соответствующей вкладке в XCA и нажать Export.

Nginx


Как установить и запустить nginx-сервер, писать не буду — на эту тему достаточно статей в интернете, не говоря уже об официальной документации. Приступим сразу к настройке HTTPS и двухфакторной аутентификации по токену.

Добавляем в секцию server в nginx.conf следующие строки:

server {
	listen 443 ssl;
	ssl_verify_depth 1;
	ssl_certificate /etc/nginx/Server.crt;
	ssl_certificate_key /etc/nginx/ServerKey.pem;
	ssl_client_certificate /etc/nginx/CA.crt;
	ssl_verify_client on;
}

Подробное описание всех параметров, касающихся настройки ssl в nginx можно найти тут — https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_client_certificate

Я лишь коротко опишу те, которые сам задал:

  • ssl_verify_client — указывает, что необходимо проверить цепочку доверия к сертификату.
  • ssl_verify_depth — определяет глубину поиска доверенного корневого сертификата в цепочке. Так как у нас сертификат клиента сразу подписан на корневом сертификате, то и глубина задана — 1. Если сертификат пользователя подписывается на промежуточном CA, то в этом параметре необходимо указать 2, и так далее.
  • ssl_client_certificate — указывает путь до доверенного корневого сертификата, который используется при проверке доверия к сертификату пользователя.
  • ssl_certificate/ssl_certificate_key — указывают путь до сертификата/закрытого ключа сервера.

Не забываем выполнить nginx -t, чтобы проверить, что в конфиге нет опечаток, а все файлики лежат где надо и так далее.

И собственно всё! Как видите настройка очень простая.

Проверяем работу в Firefox


Раз уж мы всё полностью делаем в Linux, то будем считать, что и наши пользователи тоже работают в Linux (если у них Windows, то смотрите инструкцию по настройке браузеров в предыдущей статье.

  1. Запускаем Firefox.
  2. Попробуем в начале зайти без токена. Получаем вот такую картинку:

  3. Заходим на about:preferences#privacy, и идём в Security Devices…
  4. Жмём Load, чтобы добавить новый PKCS#11 Device Driver и указываем путь до нашей librtpkcs11ecp.so.
  5. Для проверки того, что сертификат видится можно зайти в Certificate Manager. Отобразится запрос на ввод PIN-кода. После корректного ввода можно проверить, что на вкладке Your Certificates появился наш сертификат с токена.
  6. Теперь заходим с токеном. Firefox предлагает выбрать сертификат, который будет выбран на сервер. Выбираем наш сертификат.

  7. PROFIT!


Настройка выполняется один раз, и как видно в окне запроса на сертификат мы можем сохранить наш выбор. После этого при каждом входе на портал нам надо будет только вставить токен и ввести PIN-код пользователя, который был задан при форматировании. После такой аутентификации сервер уже знает какой пользователь на него зашёл и можно больше не делать никаких дополнительных окон для проверки, а сразу пускать пользователя в его личный кабинет.

Apache


Так же как и с nginx проблем с установкой apache ни у кого не должно возникнуть. Если же вы не знаете, как установить этот web-сервер, просто воспользуйтесь официальной документацией.

А мы приступаем к настройке нашего HTTPS и двухфакторной аутентификации:

  1. Для начала необходимо активировать mod_ssl:

    $ a2enmod ssl
  2. А затем включить настройки HTTPS сайта по умолчанию:

    $ a2ensite default-ssl
  3. Теперь редактируем файл конфигурации: /etc/apache2/sites-enabled/default-ssl.conf:

        SSLEngine on
        SSLProtocol all -SSLv2
    
        SSLCertificateFile	/etc/apache2/sites-enabled/Server.crt
        SSLCertificateKeyFile /etc/apache2/sites-enabled/ServerKey.pem
    
        SSLCACertificateFile /etc/apache2/sites-enabled/CA.crt
    
        SSLVerifyClient require
        SSLVerifyDepth  10

    Как видите, названия у параметров практически совпадает с названиями параметров в nginx, поэтому пояснять я их не буду. Опять же кому интересны подробности — добро пожаловать в документацию.
    Теперь перезапускаем наш сервер:

    $ service apache2 reload
    $ service apache2 restart


  4. Как видите настроить двухфакторную аутентификацию на любом веб-сервере, что в Windows, что в Linux дело одного часа максимум. А настройка браузеров занимает около 5 минут. Многие считают, что настройка и работа с двухфакторной аутентификацией это сложно и непонятно. Надеюсь наша статья хоть немного, но развенчивает этот миф.

Комментарии (22)


  1. rsashka
    27.06.2019 18:19

    Специально купил себе RuToken ЭП 2.0 микро «на побаловаться».
    Было очень интересно посмотреть, как он запустится под Linux.

    Запустился по инструкции с первого раза и даже определяется на nalog.ru
    image


    1. Neraverin Автор
      27.06.2019 18:44
      +1

      Мы сейчас как раз активно работаем над тем, чтобы Рутокен ЭЦП 2.0 работал с личным кабинетом юр. лица в налоговой без криптопровайдера. Так что следите за нашими анонсами.


    1. mkirya
      27.06.2019 18:45

      rsashka, с налоговой все взлетит, если пойти в кабинет ИП, а не Юрлица. Попробуйте, если будет такая возможность.
      Ну а с юрлицами тоже все будет, но попозже.


      1. rsashka
        27.06.2019 18:54

        Мне было нужно как раз с юрлицами.
        А токен чуть позже попробую заюзать на fips.ru
        Там как раз новый кабинет сделали.


  1. Zoomerman
    27.06.2019 21:35

    После такой аутентификации сервер уже знает какой пользователь на него зашёл и можно больше не делать никаких дополнительных окон для проверки, а сразу пускать пользователя в его личный кабинет.
    Не совсем понятно, откуда сервер будет знать, кто на него вошел? Понятно, что он получит сертификат из ключа, как предъявленный документ. Но ведь информация в сертификате еще должна как-то привязаться к аккаунту пользователя, нет? А что, если данные пользователя не зарегистрированы в системе? Авторегистрация? Как тогда определить права и роли автоматически?
    И где двухфакторная авторизация? Пин-код ключа — это не фактор вроде.


    1. Neraverin Автор
      27.06.2019 22:02

      Сервер получает информацию в сертификате, которая как вы правильно заметили должна быть привязана к аккаунту. Я в этой статье больше пишу про корпоративные порталы (смотрите статью на которую я ссылаюсь в начале). В корпоративных порталах авторегистрация редко предусмотрена, а права и роли задаются, например, при приеме на работе.
      Можно сделать и вариант с авторегистрацией, если у вас все пользователи по умолчанию с одними правами. А повышать их уже по запросу. Тоже весьма типичный сценарий.
      Что касается двухфакторности. Ключ к сертификату хранится на токене в неизвлекаемом виде, доступ к ключу можно получить только зная PIN-код. Выполнить вход под своей учеткой без токена не получится. Это первый фактор, так называемый фактор владения. А PIN-код — это второй фактор, фактор знания.


      1. Zoomerman
        27.06.2019 22:56

        Спасибо, понял по сертификату.
        По факторам получается, если хранить ключ в сейфе под кодовым замком, то получаем четырехфакторную идентификацию? (плюс код сейфа и сам сейф как фактор владения).
        Только на стороне портала (сервера) идентификация всё равно однофакторная остаётся — по сертификату и всего. Мне казалось, многофактор — это когда сам сервер проверяет идентификацию по нескольким каналам, а не заворачивание идентификационных данных в кучу обёрток.


        1. vov_i
          28.06.2019 17:19

          Про многофакторную аутентификацию ведется масса холиваров, нередко замешанных на маркетинговом буллшите. Часто путают 2-факторную аутентификацию, 2-этапную верификацию, многоканальную аутентификацию и т.д.
          С моей точки зрения в такой ситуации следует полагаться на авторитетные официальные источники. Например вот:
          csrc.nist.gov/glossary/term/Multi_Factor-Authentication


          1. Zoomerman
            29.06.2019 12:03

            Благодарю! Похоже, я тоже попался на эту удочку.
            И хотя описанная в статье схема полностью соответствует букве стандартов, для оператора сервера существует ненулевой риск сваливания в однофактор (если пользователь отменит запрос пин-кода или сделает его легко подбираемым).
            Описанная схема работы как раз и напоминает маркетинговый треш, когда вроде используется два фактора, но контролю поддаётся только один, и потому для безопасника это не выглядит как два фактора.


            1. Neraverin Автор
              29.06.2019 12:19

              Отменить запрос PIN-кода нельзя. И легко подобрать тоже. Многие безопасники смешивают пароли и PIN-коды, а этого делать не стоит. PIN проверяется и блокируется аппаратно. Количество попыток сильно ограничено. Стандартно 10, но можно и 3 поставить. И перебрать даже PIN из 4 цифр за 10 попыток шансов совсем мало. А пользователю эти 4 цифры запомнить просто. Это не сложные пароли из 10 символов, где заставляют вставлять спец. символы, буквы в разных регистрах и так далее.


              1. Zoomerman
                29.06.2019 12:54

                К сожалению, не могу согласиться.

                PIN проверяется и блокируется аппаратно. Количество попыток сильно ограничено.
                Увы, сделать аппаратный дубликат возможно. Потом его заблокировать и сделать еще один и так пока не надоест. То есть количество попыток не ограничено, если выйти в аппаратную плоскость.

                Плюс к этому — более половины пользователей токенов не меняют заводские пины (личная практика). Если пин 4 цифры — его легко подсмотреть и запомнить хотя бы 3 цифры, а четвертую подобрать за 10 стандартных попыток. На самом деле пины растекаются очень интенсивно, даже от банковских карточек.
                Вот на самом деле, почему не говорят, что банковская карточка использует двухфакторную аутентификацию? Ведь по сути у неё есть пин, а идентификатор клиента закодирован в чипе, 2 фактора на лицо.


                1. Neraverin Автор
                  29.06.2019 15:27
                  +1

                  Сделать аппаратный дубликат защищенного токена у вас вряд ли получится. А если и получится, то цена вопроса будет в миллионах и не рублей. Это далеко не так просто, как вам кажется.
                  В PIN-коде можно и буквы использовать. Тогда за 10 попыток уже не получится. Плюс надо же еще токен украсть. А это не так просто и самое главное очень заметно. Если я, например, ваш пароль узнал, то заметить это только по логам входа получится. А отсутствие физической железки сразу видно.
                  Аутентификацию может использовать сервис. А не карточка. Не говорят — потому что наличие самой карты при оплате в интернете не проверяется. Цифры с карты это не сама карта. А вот в банкомате — полноценная двухфакторная аутентификация.


                  1. Zoomerman
                    29.06.2019 16:37

                    Сделать аппаратный дубликат защищенного токена у вас вряд ли получится. А если и получится, то цена вопроса будет в миллионах и не рублей. Это далеко не так просто, как вам кажется.
                    Вот это совсем не так:

                    • Оборудование для самого жесткого вмешательства в аппаратную часть можно прикупить на али за пару килобаксов в комплексе.
                    • На сегодняшний день вроде нет чипов, интегрирующих АЛУ и ПЗУ на разных слоях одной микросхемы. А значит, извлечь и сделать дамп ПЗУ технически несложно.
                    • Сертификация ключей в любом органе (ФСБ, АНБ) подразумевает наличие алгоритмов восстановления ключа по обломкам его микросхем. А это то же самое, что создать дубликат ключа.
                    • Во всех стандартах NISTа попадание ключа в чужие руки расценивается как возможность появления дубликата и такой ключ должен быть максимально быстро заблокирован и при необходимости перевыпущен.

                    А вот в банкомате — полноценная двухфакторная аутентификация.
                    Тоже не факт. Если пин проверяется чипом карты, то это просто однофакторная аутентификация в двух разных сервисах — карта и банк. Реализация зависит от возможностей банкомата.

                    И с рутокенами тоже не факт, что пин проверяет ключ, а не установленное на компьютер ПО производителя — пруф между строк


                    1. Neraverin Автор
                      29.06.2019 19:40
                      +1

                      Ну раз уж мы решили разобраться глубоко, давайте разберемся.

                      На сегодняшний день вроде нет чипов, интегрирующих АЛУ и ПЗУ на разных слоях одной микросхемы.

                      Ошибаетесь. Более того технологий защиты у чипов предостаточно.

                      Сертификация ключей в любом органе (ФСБ, АНБ) подразумевает наличие алгоритмов восстановления ключа по обломкам его микросхем

                      Опять же ошибаетесь. Восстановление ключа для ФСБ имеет смысл при шифровании, а не подписи. И добиваются этого обычно другими способами, а не восстановлением по обломкам.

                      Конечно, если ключ был украден или утерян он должен быть заблокирован. Для этого и нужен PKI. Но тут скорее защищаются от того, что PIN тоже был скомпрометирован каким-то способом.

                      В Рутокене PIN проверяет ключ. Даже в том случае, если используется хранение контейнеров КриптоПро на токене. В том пруфе на который вы ссылаетесь, человек путает 2 понятия — неизвлекаемость и неэкспортируемость.


                      1. Zoomerman
                        29.06.2019 23:17

                        Ошибаетесь. Более того технологий защиты у чипов предостаточно.
                        Можете привести маркировку чипа, у которого ПЗУ находится под/поверх АЛУ? Не рядом, не на другом конце чипа, а именно в другом слое. Гугл не находит. Находит только те, где в одной плоскости компоновка. Я бы рад ошибаться, но пока не вижу опровержений.
                        Восстановление ключа для ФСБ имеет смысл при шифровании, а не подписи.
                        Не уверен, что мы можем оценивать и обсуждать мотивы подобных организаций.
                        В Рутокене PIN проверяет ключ. Даже в том случае, если используется хранение контейнеров КриптоПро на токене.
                        В Рутокене ПЗУ в кристалле процессора сделано? Подкинуть дубль файловой системы невозможно?
                        В том пруфе на который вы ссылаетесь, человек путает 2 понятия
                        Даже если так, пруф не о том, как извлечь ключ. Пруф о том, что если АЛУ ключа не защищает данные в ПЗУ, то вытянуть их можно от лёгкого до не очень сложного способами.
                        Но даже если защищает, а к ПЗУ есть доступ извне, программатором можно создать/восстановить дамп и АЛУ ничего не будет знать о том, сколько раз уже подбирался пин.

                        Эта тема не повод для спора. Я говорю, что большинство ключей можно скопировать. Вы говорите, что есть ключи, которые нельзя скопировать. Я отвечаю, что возможно на сегодняшний день так и есть, но через некоторое время и к таким ключам будут найдены подходы. Вы соглашаетесь, что нет ничего невозможного в будущем, на смену придут более защищенные ключи, которые в том будущем тоже будет тяжело скопировать. Остаемся при своих мнениях.


                        1. rsashka
                          30.06.2019 09:06

                          Этот спор упирается не в «можно или нельзя», а «сколько это будет стоить».
                          Можно сделать абсолютно все, но некоторые вещи можно сделать либо очень дорого, либо очень долго.


                        1. mmMike
                          01.07.2019 11:49

                          Еще года 4 назад активно занимался карточными технологиями.
                          Участвовал в семинарах Gemalto и NXP. В частности, посвященным аппаратной защите чипов карт от извлечения ключа разными методами. Однако, чипы предназначенные для карт (а токен это по сути чип карты+USB ридер), весьма надежно защищены от различных атак разных методов.
                          (про чипы для GSM карт, речь не идет. Они зачастую дешевле и проще в массе..)


                          И информацию (подробности) о защите (аппаратной и методов безопасного создания приложений карт) и методов взлома в Интернете, Вы особо найдете. Не надо думать что в Интернете есть все.


                          Тоже не факт. Если пин проверяется чипом карты, то это просто однофакторная аутентификация в двух разных сервисах — карта и банк. Реализация зависит от возможностей банкомата.

                          И да… Банкомат по стандартам НЕ работает с off-line PIN. Исключительно on-line PIN через EPP клавиатуру.


    1. mmMike
      28.06.2019 07:54

      Один из вариантов (например для REST Web API) настройки nginx — это что ни будь типа


      server {
          listen 443 ssl;
          ssl_verify_depth 1;
          ssl_certificate /etc/nginx/Server.crt;
          ssl_certificate_key /etc/nginx/ServerKey.pem;
          ssl_client_certificate /etc/nginx/CA.crt;
          ssl_verify_client on;
      
              location / {
              proxy_set_header X-TLS-iDN $ssl_client_i_dn;
              proxy_set_header X-TLS-sDN $ssl_client_s_dn;
             }
       }

      А уже сервис, принимающий запрос, понимает по атрибутам клиентского сертификата — кто конкретно пришел и какие у него права.
      Чисто для иллюстрации пример (можно и другие извращения с $ssl_client_.. придумать)


      Но вообще, USB токен для захода на сайт через браузер ИМХО не удобно. Уж лучше брелок с OTP паролем (как альтернатива SMS/Push), как второй фактор к обычному паролю (ну или самый дешевый вариант — OTP приложение под смартфон).


      А вот для аутентификации программных клиентов — аппаратный токен — само то..


      И да… Для безопасности бы, не помешало бы изменить ssl_session_timeout с 5m по умолчанию, на что то более разумное (меньшее значение)


  1. Newcss
    28.06.2019 16:39

    Все хорошо пока есть Windows и когда можно использовать любую Linux. Подскажите пожалуйста как обстоят дела с Astra Linux и планируется ли сертификация ФСТЭК? Уж больно часто приходится работать с гос.заказчиками и им очень хочется ЭЦП)


    1. vov_i
      28.06.2019 17:02

      C Astra Linux дела обстоят хорошо. Прошли очередной раунд тестирования на совместимость с Astra Linux Common Edition (версии 1.10,1.11,2.12) и Special Edition (версии 1.4,1.5).
      Сертификат ФСТЭК на ПАК Рутокен есть и действует. Так что гос.заказчиков можно успокоить. Если есть какие-то сомнения, задавайте вопросы. Если надо будет потестировать какую-то конкретную конфигурацию — обращайтесь, рассмотрим.


      1. Newcss
        28.06.2019 19:13

        Отлично. Про Common Edition я и не сомневаюсь, что работает, как раз интересно было про SE, но вы меня опередили ответом). А можно немного подробнее про Special Edition (1.5, либо 1.6). Для рутокена нужны драйвера — где можно взять сертифицированные? Или нужно делать отдельный запрос и осуществлять закупку? Просто как раз-таки стоит задача — Контроллер домена, авторизация, документооборот, ЭЦП…


        1. Neraverin Автор
          28.06.2019 20:40

          Для Astra SE мы рекомендуем брать токены из семейства Рутокен ЭЦП 2.0. Это CCID устройства, поэтому драйверы есть в самой ОС (в Astra SE тоже есть и все успешно работает). Может понадобится библиотека PKCS11 — она доступна как на нашем сайте, так и поставляется вместе с сертифицированной версией токена на диске.