Подробный гайд по программной блокировке Рутокенов в Linux - Часть 1

Гайд по программной блокировке Рутокенов в Linux. Разбираем связку PKCS#11, udev и sysfs для идентификации и отключения нескольких USB-токенов.

2026.11.09                  


Подробный гайд по программной блокировке Рутокенов в Linux - Часть 1Подробный гайд по программной блокировке Рутокенов в Linux - Часть 1

Коротко

1. Стандартный PKCS#11 не умеет программно «извлекать», выключать или блокировать USB-токен.

В PKCS#11 есть операции с сессиями, объектами, PIN и т.п., но нет стандартной функции вроде C_EjectToken() или C_DisableSlot(). Если такая возможность и существует, то только в проприетарном расширении Aktiv/Рутокен.


2. Стандартного способа получить из PKCS#11 соответствие «слот → USB-устройство» нет.

CK_SLOT_ID, slotDescription, CK_TOKEN_INFO не обязаны содержать путь в /sys, busnum, devnum или порт USB.




3. Если USB-дескриптор iSerial у всех Рутокенов одинаковый, например Aktiv_Rutoken_ECP, то udev не может различить токены по этому полю. В этом случае различить их можно только:

  • по уникальному внутреннему серийному номеру токена через PKCS#11/SDK;
  • по физическому порту/пути в дереве USB;
  • временным отключением конкретного USB-устройства и наблюдением, какой токен исчез из PKCS#11.

4. Наиболее универсальный и практичный способ для нескольких одновременно подключенных токенов — поочередно временно деавторизовать USB-устройства через /sys/.../authorized и смотреть, какой серийный номер токена исчез из PKCS#11. Так можно установить соответствие между serialNumber токена и конкретным sysfs-путем USB-устройства.


1. Что можно и нельзя через PKCS#11

Что можно

Через PKCS#11 можно:

- получить список слотов:

  C_GetSlotList(CK_TRUE, slots, &count);

- получить информацию о токене:

  CK_TOKEN_INFO tokenInfo;
  C_GetTokenInfo(slotID, &tokenInfo);
  • прочитать tokenInfo.serialNumber;
  • читать объекты токена: сертификаты, ключи, метки, CKA_ID и т.д.;
  • открывать/закрывать сессии;
  • выполнять криптографические операции.

Чего нельзя стандартно

В стандарте PKCS#11 нет штатного средства:

  • отключить токен от шины USB;
  • «вынуть» его программно;
  • запретить доступ к нему другим процессам;
  • получить путь /sys/bus/usb/devices/...;
  • получить busnum/devnum;
  • привязать CK_SLOT_ID к физическому порту.

То есть если задача именно в том, чтобы ОС перестала видеть устройство, нужно работать уже не с PKCS#11, а с USB-подсистемой Linux.


2. Чем блокировать Рутокен в Linux

Для программного отключения USB-устройства лучше всего использовать механизм USB authorization:

/sys/bus/usb/devices/<device>/authorized

Запись 0 запрещает использование устройства, запись 1 разрешает.

Например:

echo 0 > /sys/bus/usb/devices/1-2/authorized

или через tee, если нужен sudo:

echo 0 | sudo tee /sys/bus/usb/devices/1-2/authorized

Обратно:

echo 1 | sudo tee /sys/bus/usb/devices/1-2/authorized

После этого желательно подождать завершения событий udev:

sudo udevadm settle --timeout=5

Почему лучше authorized, а не remove

Есть также:

echo 1 > /sys/bus/usb/devices/1-2/remove

но это удаляет устройство из ядра, а для возвращения обычно нужен rescan или физическое переподключение. Это более жесткий вариант.

authorized=0 обычно удобнее:

  • обратимо;
  • не требует физического перетыкания;
  • не требует обязательного rescan;
  • подходит для сценария «запретить, если токен не разрешен».

3. Как найти нужное устройство в /sys

3.1. По busnum и devnum

Если вы видите устройство, например, в lsusb:

Bus 001 Device 005: ID 0a89:00b1 Aktiv Rutoken ECP

то можно найти соответствующий каталог в /sys.

Пример функции:

find_usb_syspath_by_busdev() {
    local bus="$1"
    local dev="$2"

    # Убираем ведущие нули, например 001 -> 1, 005 -> 5
    bus=$((10#$bus))
    dev=$((10#$dev))

    local d
    for d in /sys/bus/usb/devices/*; do
        [[ -f "$d/busnum" && -f "$d/devnum" ]] || continue

        if [[ "$(cat "$d/busnum")" == "$bus" && \
              "$(cat "$d/devnum")" == "$dev" ]]; then
            echo "$d"
            return 0
        fi
    done

    return 1
}

Пример:

find_usb_syspath_by_busdev 001 005

Может вернуть:

/sys/bus/usb/devices/1-2

3.2. Перечислить все потенциальные Рутокены

Например:

list_rutoken_usb_devices() {
    local d base v p

    for d in /sys/bus/usb/devices/*; do
        base="${d##*/}"

        # Пропускаем корневые хабы
        [[ "$base" == usb* ]] && continue

        # Пропускаем интерфейсы вида 1-2:1.0
        [[ "$base" == *:* ]] && continue

        [[ -f "$d/idVendor" && -f "$d/idProduct" ]] || continue

        v=$(cat "$d/idVendor")
        p=$(cat "$d/idProduct")

        # Важно: замените 0a89 и набор idProduct на реальные значения ваших Рутокенов.
        # idVendor у Aktiv часто 0a89, но точные значения лучше взять из:
        # lsusb -v | grep -i rutoken
        if [[ "$v" == "0a89" ]]; then
            echo "$d"
        fi
    done
}


Вызов:

list_rutoken_usb_devices

Может вернуть:

/sys/bus/usb/devices/1-2
/sys/bus/usb/devices/1-3
/sys/bus/usb/devices/2-1

Важно: не блокируйте устройства вида usb1, usb2 — это корневые концентраторы. Также не нужно блокировать интерфейсы вида 1-2:1.0. Блокировать лучше само устройство, например 1-2.


4. Как получить серийный номер токена через PKCS#11

Если у вас уже настроена работа с библиотекой Рутокен через pkcs11-tool, можно использовать её.

Например:

pkcs11-tool --module /usr/lib/librtpkcs11ecp.so --list-slots

или, в зависимости от установки:

pkcs11-tool --module /usr/lib64/librtpkcs11ecp.so --list-slots

Также можно использовать:

p11-kit list-tokens --verbose

Но для автоматизации удобнее извлекать серийные номера скриптом.

Пример:

PKCS11_MODULE="/usr/lib/librtpkcs11ecp.so"

list_pkcs11_serials() {
    pkcs11-tool --module "$PKCS11_MODULE" --list-slots 2>/dev/null |
        sed -n 's/.*Serial Number:[[:space:]]*//p' |
        sed 's/[[:space:]]*$//' |
        sort -u
}

Проверка:

list_pkcs11_serials

Может вернуть что-то вроде:

1234567890ABCDEF
FEDCBA0987654321

Важно:

  • серийный номер в CK_TOKEN_INFO обычно дополнен пробелами;
  • его надо обрезать и нормализовать;
  • не стоит привязываться к номеру слота CK_SLOT_ID: он может меняться между перезагрузками и переподключениями.

Информация предоставлена в ознакомительных целях. Применение описанных настроек в системах, должно осуществляться только после согласования с ответственными за информационную безопасность и в соответствии с требованиями ФСТЭК, ФСБ и иных уполномоченных органов.


Статью подготовил: Аверко Денис Сергеевич @Nymexis г. Омск (специалист по ЗИ)

Комментарии

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