Простые пароли не защищают, а сложные невозможно запомнить. Поэтому они так часто оказываются на стикере под клавиатурой или на мониторе. Чтобы пароли оставались в головах “забывчивых” пользователей и надёжность защиты не терялась – есть двухфакторная аутентификация (2ФА).

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

Кроме того, в госучреждениях бывает, что хотят, чтобы всё работало по ГОСТу. О таком варианте 2ФА для входа в Линукс и пойдёт речь. Начну издалека.

PAM-модули


Подключаемые модули аутентификации (Pluggable Authentication Modules, PAM) — это модули со стандартным API и реализациями различных механизмов аутентификации в приложениях.
Все утилиты и приложения, умеющие работать с PAM, подхватывают их и могут использовать для аутентификации пользователя.
На практике это работает примерно так: команда login обращается к PAM, который выполняет все необходимые проверки с помощью указанных в конфигурационном файле модулей и возвращает результат обратно команде login.

librtpam


Разработанный компанией «Актив» модуль добавляет двухфакторную аутентификацию пользователей по смарт-картам или USB-токенам с помощью асимметричных ключей по последним стандартам отечественной криптографии.

Рассмотрим принцип его работы:
  • на токене хранится сертификат пользователя и его закрытый ключ;
  • сертификат сохранён в домашнем каталоге пользователя как доверенный.


Процесс аутентификации происходит следующим образом:
  1. На Рутокене выполняется поиск личного сертификата пользователя.
  2. Запрашивается PIN-код токена.
  3. Происходит подпись случайных данных на закрытом ключе непосредственно в чипе Рутокена.
  4. Полученная подпись проверяется с помощью открытого ключа из сертификата пользователя.
  5. Модуль возвращает вызвавшему приложению результат проверки подписи.


Можно аутентифицироваться по ключам ГОСТ Р 34.10-2012 (длины 256 или 512 бит) или устаревшему ГОСТ Р 34.10-2001.

За безопасность ключей можно не беспокоиться – они генерируются непосредственно в Рутокене и никогда не покидают его память во время криптографических операций.



Рутокен ЭЦП 2.0 сертифицирован ФСБ и ФСТЭК по НДВ 4, поэтому может применяться в информационных системах, обрабатывающих конфиденциальную информацию.

Практическое использование


Подойдёт практически любой современный Линукс, для примера мы будем использовать xUbuntu 18.10.

1) Устанавливаем необходимые пакеты


sudo apt-get install libccid pcscd opensc
Если хотите добавить блокировку рабочего стола скринсейвером – дополнительно установите пакет libpam-pkcs11.

2) Добавляем PAM-модуль с поддержкой ГОСТов


Загружаем библиотеку с https://download.rutoken.ru/Rutoken/PAM/
Копируем содержимое папки PAM librtpam.so.1.0.0 в системную папку
/usr/lib/ или /usr/lib/x86_64-linux-gnu/или /usr/lib64

3) Устанавливаем пакет с librtpkcs11ecp.so


Загружаем и устанавливаем DEB- или RPM-пакет по ссылке: https://www.rutoken.ru/support/download/pkcs/

4) Проверяем, что Рутокен ЭЦП 2.0 работает в системе


В терминале выполняем
$ pkcs11-tool --module /usr/lib/librtpkcs11ecp.so -T
Если увидите строку Rutoken ECP <no label> – значит всё хорошо.

5) Считываем сертификат


Проверяем, что на устройстве есть сертификат
$ pkcs11-tool --module /usr/lib/librtpkcs11ecp.so -O
Если после строчки:
Using slot 0 with a present token (0x0)
  • выводится информация о ключах и сертификатах, то необходимо считать сертификат и сохранить на диск. Для этого выполните следующую команду, где вместо {id} нужно подставить ID-сертификата, который вы увидели в выводе предыдущей команды:
    $ pkcs11-tool --module /usr/lib/librtpkcs11ecp.so -r -y cert --id {id} --output-file cert.crt
    В случае если файл cert.crt создан переходим к пункту 6).
  • нет ничего, значит устройство пустое. Обратитесь к администратору или создайте ключи и сертификат самостоятельно, следуя следующему пункту.


5.1) Создаём тестовый сертификат


Внимание! Описанные способы создания ключей и сертификатов подходят для тестирования и не предназначены для применения в боевом режиме. Для этого нужно использовать ключи и сертификаты, изданные доверенным центром сертификации вашей организации или аккредитованным удостоверяющим центром.
PAM-модуль создан защищать локальные компьютеры и подразумевает работу в небольших организациях. Поскольку пользователей немного, Администратор может сам следить за отзывом сертификатов и вручную блокировать учетные записи, как и за сроком действия сертификатов. PAM-модуль пока не умеет проверять сертификаты по CRL и строить цепочки доверия.


Простой путь (через браузер)


Для получения тестового сертификата используйте веб-сервис «Центр регистрации Рутокен». Процесс займёт не более 5 минут.

Путь гика (через консоль и, возможно, компилятор)


Проверьте версию OpenSC
$ opensc-tool --version
Если версия меньше чем 0.20, то обновитесь или соберите ветку pkcs11-tool с поддержкой ГОСТ-2012 из нашего GitHub-а (на момент выхода этой статьи релиз 0.20 ещё не выпущен) или из ветки master основного проекта OpenSC не позднее коммита 8cf1e6f

Генерируем ключевую пару с параметрами:
--key-type: GOSTR3410-2012-512:А (ГОСТ-2012 512 бит c парамсетом А), GOSTR3410-2012-256:A (ГОСТ-2012 256 бит с парамсетом A)

--id: идентификатор объекта (CKA_ID) в виде двузначных номеров символов в hex из таблицы ASCII. Используйте только ASCII-коды печатных символов, т.к. id нужно будет передать OpenSSL в виде строки. Например, ASCII-кодам “3132” соответствует строка «12». Для удобства, можно воспользоваться онлайн-сервисом конвертации строки в ASCII-коды.

$ ./pkcs11-tool --module /usr/lib/librtpkcs11ecp.so --keypairgen --key-type GOSTR3410-2012-512:A -l --id 3132

Далее будем создавать сертификат. Ниже будет описано два пути: первый через УЦ (мы будем использовать тестовые УЦ), второй – самоподписанный. Для этого сначала надо установить и настроить OpenSSL версии 1.1 или новее для работы с Рутокен через специальный модуль rtengine используя руководство Установка и настройка OpenSSL.
Например: для ‘--id 3132’ в OpenSSL надо указывать "pkcs11:id=12".

Можно воспользоваться услугами тестового УЦ, коих много, например, вот, вот и вот, для этого создадим запрос на сертификат

Другой вариант – можно поддаться лени и создать самоподписанный
$ openssl req -utf8 -new -keyform engine -key "pkcs11:id=12" -engine rtengine -out req.csr

Загружаем сертификат на устройство
$ openssl req -utf8 -x509 -keyform engine -key "pkcs11:id=12" -engine rtengine -out cert.cer

6) Регистрируем сертификат в системе


Убедитесь, что ваш сертификат выглядит как base64 файл:



Если ваш сертификат выглядит так:



то нужно сконвертировать сертификат из формата DER в PEM-формат(base64)

$ openssl x509 -in cert.crt -out cert.pem -inform DER -outform PEM
Снова проверяем, что теперь все в порядке.

Добавляем сертификат в список доверенных сертификатов
$ mkdir ~/.eid
$ chmod 0755 ~/.eid
$ cat cert.pem >> ~/.eid/authorized_certificates
$ chmod 0644 ~/.eid/authorized_certificates

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

7) Настраиваем аутентификацию


Настройка нашего модуля PAM совершенно стандартна и делается точно также, как и настройки других модулей. Создаём в файл /usr/share/pam-configs/rutoken-gost-pam содержащий полное имя модуля, включен ли он по умолчанию, приоритет модуля и параметры аутентификации.
В параметрах аутентификации есть требования к успешности операции:
  • required (требуемый): такие модули должны вернуть положительный ответ. Если результат вызова модуля содержит отрицательный ответ, это приведёт к ошибке аутентификации. Запрос будет сброшен, но остальные модули будут вызваны.
  • requisite (необходимый): похож на required, но сразу же приводит к сбою аутентификации и игнорирует остальные модули.
  • sufficient (достаточный): если перед таким модулем ни один из модулей required или sufficient не вернул отрицательного результата, то модуль вернёт положительный ответ. Оставшиеся модули будут проигнорированы.
  • optional (дополнительный): если в стеке нет модулей required и ни один из модулей sufficient не вернул положительного результата, то хотя бы один из модулей optional должен вернуть положительный ответ.

Полное содержание файла /usr/share/pam-configs/rutoken-gost-pam:
Name: Rutoken PAM GOST
Default: yes
Priority: 800
Auth-Type: Primary
Auth: sufficient /usr/lib/librtpam.so.1.0.0 /usr/lib/librtpkcs11ecp.so




сохраняем файл, после этого выполняем
$ sudo pam-auth-update
в появившемся окне ставим звёздочку около Rutoken PAM GOST и нажимаем OK



8) Проверяем настройку


Чтобы понять что всё настроено, но при этом не потерять возможность входа в систему введите команду
$ sudo login
Введите имя пользователя. Всё настроено правильно, если система потребует PIN-код устройства.



9) Настраиваем блокировку компьютера при извлечении токена


В состав пакета libpam-pkcs11 входит утилита pkcs11_eventmgr, которая позволяет выполнять различные действия при возникновении событий PKCS#11.
Для настройки pkcs11_eventmgr служит файл конфигурации: /etc/pam_pkcs11/pkcs11_eventmgr.conf
Для различных дистрибутивов Линукс, команда которая вызывает блокировку учетной записи при извлечении смарт-карт или токена будет отличаться. См. event card_remove.
Пример файла конфигурации представлен ниже:

pkcs11_eventmgr
{
    # Запуск в бэкграунде
    daemon = true;
     
    # Настройка сообщений отладки
    debug = false;
 
    # Время опроса в секундах
    polling_time = 1;
 
    # Установка тайм-аута на удаление карты
    # По-умолчанию 0
    expire_time = 0;
 
    # Выбор pkcs11 библиотеки для работы с Рутокен
    pkcs11_module = usr/lib/librtpkcs11ecp.so;
 
    # Действия с картой
    # Карта вставлена:
    event card_insert {
        # Оставляем значения по умолчанию (ничего не происходит)
        on_error = ignore ;
 
        action = "/bin/false";
    }
 
    # Карта извлечена
    event card_remove {
        on_error = ignore;
         
        # Вызываем функцию блокировки экрана
        
        # Для GNOME 
        action = "dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock";
        
        # Для XFCE
        # action = "xflock4";
        
        # Для Astra Linux (FLY)
        # action = "fly-wmfunc FLYWM_LOCK";
    }
 
    # Карта долгое время извлечена
    event expire_time {
        # Оставляем значения по умолчанию (ничего не происходит)
        on_error = ignore;
 
        action = "/bin/false";
    }
}


После этого добавьте приложение pkcs11_eventmgr в автозагрузку. Для этого отредактируйте файл .bash_profile:
$ nano /home/<имя_пользователя>/.bash_profile
Добавьте в конец файла строку pkcs11_eventmgr и перезагрузитесь.

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



Заключение


ПК с Linux в российских госструктурах становятся все популярнее, а настроить надёжную двухфакторную аутентификацию в этой ОС не всегда просто. Будем рады этим руководством помочь решить “проблему паролей” и надёжно защитить доступ к ПК, не затратив на это много времени.

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


  1. saipr
    25.07.2019 23:39

    Рутокен ЭЦП-2.0 хорошая машина из серии "сами умеют всё считать". Кстати и и Рутокен ЭЦП тоже.
    Он успешно тестировался и с cryptoarmpkcs при создании подписи CAdes-XLT1 и в GnuPG/SMIME при использовании токенов PKCS#11 с поддержкой российской припрографии. Особенно он хорош при работе с порталом Госуслуг.


  1. sandello
    26.07.2019 11:03

    А зачем ставить ваш librtpkcs11ecp Исключительно для работы вашего же pam-модуля и ГОСТ? На текущий момент Рутокен ЭЦП / Рутокен ЭЦП 2.0 успешно работает с RSA без «внешних» библиотек. По крайней мере, ssh и openconnect.


    1. PavelAndreevich Автор
      26.07.2019 11:44

      librtpkcs11ecp нужна в первую очередь, чтобы работать с аппаратными неизвлекаемыми ключами. В таком варианте, при подписании, токен будет использовать внутреннее криптоядро.

      Вероятно вы используете программные ключи(например, pkcs-15) и криптопровайдер находится в вас на компьютере. В этом случае, в момент подписания, ключи с токена попадают в оперативную память компьютера.


      1. sandello
        26.07.2019 11:57

        Гм… Работа начинается с «pkcs15-init --create-pkcs15», ключи генерятся «pkcs11-tool --keypairgen …». Это будут программные ключи?


        1. PavelAndreevich Автор
          26.07.2019 13:30

          Извиняюсь, был не прав. Связка pkcs15-init, pkcs11-tool, opensc-pkcs11.so также создает неизвлекаемые ключи.

          Но opensc-pkcs11.so считает, что структура внутри устройства всегда строго соответствует PKCS#15. В реальной жизни это не так, по двум причинам — PKCS#15 появился на 5 лет позже PKCS#11 и каждый вендор уже придумал свою структуру; сам PKCS#15 не получил распространения и вообще не развивается.

          Мы, как производитель, гарантируем работу устройств с нашей PKCS#11 библиотекой.
          Мы также стараемся поддерживать работу с opensc-pkcs11.so, но такая поддержка ограничена.

          Если Вы отформатируете токен с помощью pkcs15-init, то создаваемые объекты на токене будут видится с помощью opensc-pkcs11.so.
          Если же токен был отформатирован нашими средствами, то создаваемые объекты будут видится с помощью нашей PKCS#11 библиотеки.

          Мы рекомендуем использовать именно нашу PKCS#11 библиотеку, так как она лучше поддерживается.


          1. sandello
            26.07.2019 14:48

            Спасибо за пояснения. Провел несколько экспериментов, ваша библиотека работает с токеном, отфарматированным в pkcs15-init


            1. PavelAndreevich Автор
              26.07.2019 15:49

              После форматирования токена через pkcs15-init, Вы можете работать с нашим PKCS#11. Но в этом случае через opensc-pkcs11.so объекты, созданные через librtpkcs11ecp, будут недоступны.


      1. saipr
        26.07.2019 14:45

        librtpkcs11ecp нужна в первую очередь, чтобы работать с ГОСТ-ой криптографией!!!!


        1. sandello
          26.07.2019 14:47

          Это понятно. Я про RSA