Подробный гайд по программной блокировке Рутокенов в Linux - Часть 4
13. Как отслеживать события udev
Для событий нужно реагировать именно на usb_device, а не на интерфейсы.
Пример правила:
# /etc/udev/rules.d/90-rutoken-guard.rules
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTR{idVendor}=="0a89", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rutoken-guard.service"
Либо более простой, но менее предпочтительный вариант с RUN:
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTR{idVendor}=="0a89", RUN+="/usr/local/sbin/rutoken-event add %S%p"
Где %S%p даст что-то вроде:
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-2
Но RUN подходит только для быстрых действий. Долгие операции лучше выполнять через системный сервис.
Что передавать обработчику
Из события udev полезны:
DEVPATH;DEVNAME;ACTION;ID_VENDOR_ID;ID_MODEL_ID;ID_SERIAL;BUSNUM;DEVNUM.
Для блокировки обычно нужен DEVPATH:
echo 0 > /sys/$DEVPATH/authorized
Но убедитесь, что DEVPATH указывает именно на устройство, а не на интерфейс.
14. Если токены всегда в одних и тех же портах
Это самый надежный и наименее разрушительный вариант.
Можно один раз выполнить сопоставление:
serial 1234567890ABCDEF -> port 1-2
serial FEDCBA0987654321 -> port 1-3
Дальше использовать правила, которые разрешают только эти порты.
Например, концептуально:
# Разрешаем только конкретные порты для Рутокенов
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="0a89", KERNEL=="1-2", GOTO="rutoken_ok"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="0a89", KERNEL=="1-3", GOTO="rutoken_ok"
# Все остальные Рутокены блокируем
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="0a89", ATTR{authorized}="0"
LABEL="rutoken_ok"
Важно: синтаксис и порядок правил нужно проверять на конкретной системе. Иногда удобнее использовать не udev, а USBGuard.
Плюсы
- не нужно каждый раз отключать устройства для сопоставления;
- работает до загрузки пользовательских сервисов;
- можно применить рано через
initramfs/раннийudev; - меньше риска нарушить активные сессии.
Минусы
- токен должен быть всегда в том же физическом порту;
- замена порта, хаба или док-станции может изменить путь;
- если токен переткнули в другой порт, он может быть заблокирован.
15. Использование USBGuard
Если задача именно в политике допуска USB-устройств, стоит рассмотреть USBGuard.
Он позволяет задать правила вида:
- разрешить конкретный
idVendor:idProduct; - разрешить устройство по серийному номеру;
- разрешить только через конкретный порт;
- заблокировать всё остальное.
Но у вас есть ограничение:
USB iSerial одинаковый у всех Рутокенов
Поэтому USBGuard тоже не сможет различить их по серийному номеру, если этот номер не уникален.
Тем не менее, он хорошо подходит для сценария:
по умолчанию блокируем все Рутокены;
разрешаем только известные физические порты;
или разрешаем устройства после решения внешнего агента.
Для строгой безопасности это часто лучше, чем самописные udev-правила.
16. Практические рекомендации
16.1. Не храните CK_SLOT_ID как идентификатор
Номер слота может меняться.
Храните:
token serialNumber
и, если нужно:
USB port path
16.2. Нормализуйте серийный номер
Перед сравнением:
- обрезайте пробелы;
- убирайте завершающие пробелы;
- можно приводить к верхнему регистру;
- можно убирать двоеточия/разделители, если они есть.
Пример:
normalize_serial() {
echo "$1" | tr -d '[:space:]' | tr '[:lower:]' '[:upper:]'
}
16.3. Используйте блокировку через authorized
Для программного «извлечения» предпочтительно:
echo 0 > /sys/bus/usb/devices/1-2/authorized
а не физическое извлечение или remove.
16.4. Делайте политику отказобезопасной
Если невозможно точно определить, какой токен запрещен, лучше:
- заблокировать все Рутокены;
- или перевести систему в режим ожидания администратора;
- или разрешать только токены из белого списка по физическим портам.
Для безопасности лучше модель:
по умолчанию запрещено;
разрешено только явно известное.
16.5. Логируйте все действия
Например:
2026-11-07T12:34:56 Detected Rutoken USB device /sys/bus/usb/devices/1-2
2026-11-07T12:34:57 Token serial 1234567890ABCDEF appeared
2026-11-07T12:34:57 Token serial is allowed
2026-11-07T12:34:57 Device /sys/bus/usb/devices/1-2 authorized
И отдельно:
2026-11-07T12:35:10 Forbidden token serial FEDCBA0987654321 detected
2026-11-07T12:35:10 Device /sys/bus/usb/devices/1-3 disabled
17. Особый случай: токены подключены до старта программы
Это как раз ваш случай, когда токены могут быть воткнуты до загрузки ОС. В этом случае не нужно полагаться только на события подключения.
При старте сервиса нужно:
- Дождаться появления всех Рутокенов в
/sys. - Дождаться появления токенов в PKCS#11.
- Выполнить процедуру сопоставления.
- Заблокировать запрещенные.
- Только после этого разрешать работу пользовательским приложениям, если это возможно.
Например, можно сделать systemd-сервис:
[Unit]
Description=Rutoken Guard
After=systemd-udevd.service
Before=display-manager.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/rutoken-guard --initial-scan
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Для строгого режима может понадобиться более ранний запуск, вплоть до initramfs, но это уже отдельная большая тема.
18. Если нужна абсолютная гарантия без временного отключения
Тогда нужно одно из условий:
- У Рутокенов есть уникальный USB
iSerial. - Вендорская библиотека/SDK дает соответствие слота и USB-пути.
- Вы используете токены, привязанные к конкретным физическим портам.
- Вы используете управляемый USB-хаб с попортовым управлением питанием и привязываете токены к портам.
- Вы используете аппаратные средства контроля портов, например, док-станции с фиксированными портами и политику «только эти порты».
Если ничего из этого нет, полностью бесшовно различить несколько одинаковых по USB-дескриптору Рутокенов без обращения к токену или временного отключения нельзя.
19. Рекомендуемая схема для вашей задачи
Я бы рекомендовал такую архитектуру:
Этап 1. Инвентаризация
Один раз в режиме обслуживания:
- Подключить все разрешенные токены.
- Запустить скрипт сопоставления через временное отключение.
- Получить таблицу:
разрешенный серийный номер -> порт/устройство
- Сохранить её.
Этап 2. Повседневная политика
При старте системы:
- Перечислить USB-устройства Рутокенов.
- Перечислить токены в PKCS#11.
- Если токен один — сопоставить напрямую.
- Если несколько — выполнить контролируемое сопоставление.
- Запрещенные токены оставить с
authorized=0. - Разрешенные оставить включенными.
Этап 3. Строгая фиксация, если возможно
Если токены всегда в одних портах:
- зафиксировать порты;
- использовать
udevилиUSBGuard; - не выполнять динамическое сопоставление каждый раз.
20. Важно
Если опираться на стандартные средства:
- Не пытайтесь заблокировать токен через PKCS#11. Стандартного механизма для этого нет.
- Не пытайтесь построить постоянную привязку к номеру слота PKCS#11. Он может быть нестабильным.
- Используйте серийный номер токена из
CK_TOKEN_INFOкак логический идентификатор. - Для блокировки используйте
/sys/.../authorized. - Для сопоставления нескольких токенов применяйте метод временной деавторизации конкретного USB-устройства и наблюдения за исчезновением серийного номера в PKCS#11.
- Если нужна более строгая политика, привязывайте разрешенные токены к физическим портам и используйте
udev/USBGuard.
Если кратко, самая надежная формула такая:
PKCS#11 дает серийный номер токена.
Linux sysfs/udev дает управление конкретным USB-устройством.
Связь между ними устанавливается контролируемым временным отключением устройства.
Информация предоставлена в ознакомительных целях. Применение описанных настроек в системах, должно осуществляться только после согласования с ответственными за информационную безопасность и в соответствии с требованиями ФСТЭК, ФСБ и иных уполномоченных органов.