Компоненты файла политики.
Как уже было сказано, ядром Systrace являются файлы политики, в которых описаны разрешенные системные вызовы и их параметры для конкретных приложений. Файлы политик должны быть помещены в каталог /etc/systrace. Если в этом каталоге файлы политик не найдены, Systrace будет искать их в каталоге ~/.systrace.
Имя файла политик зависит от приложения, для которого надо эту политику применить, например, если нам надо применить политику для /bin/login, файл политики будет называться bin_login, то есть все слэши в полном имени файла заменяются знаками подчеркивания, а первый слэш - удаляется.
Синтаксис.
Типичный пример файла политики:
linux-fsread: filename eq "/etc/ld.so.preload" then permit linux-fsread: filename eq "/etc/ld.so.cache" then permit
Первая строка указывает приложение, к которому будет применена политика (в данном случае /bin/login), сразу после данного показывается режим эмуляции - Linux. Если у вас FreeBSD (или OpenBSD), можно указать режим native.
Основные строки файла политик указываются в формате:
Для большей гибкости допускаются сравнения:
Действиями могут быть permit (разрешить), ask (спросить) и deny (запретить). По умолчанию все системные вызовы запрещены, поэтому можно не указывать deny. Опция log применяется для протоколирования этого системного вызова.
Сравнения.
Оператор сравнения позволяет сравнить аргументы, переданные системному вызову с конкретным значением. Первый терм - это аргумент, а второй - значение, с которым можно сравнить аргумент. Рассмотрим правило:
Оно дает возможность процессу «привязываться» к TCP-порту. Заметно лучше было бы разрешение привязываться к конкретному адресу/порту. Подкорректируем это правило так, чтобы процессу разрешалось привязываться к любому IP-адресу, но только к 22 порту:
Можно использовать следующие операторы сравнения:
- match — совпадение с базовым именем файла, например, /bin/*;
- eq — оператор эквивалентности, сравниваются два терма, например filename eq "/bin/sh";
- ne — обратный предыдущему оператор (истинный, если термы не равны);
- sub — терм 2 - это подстрока терма 1, например
filename sub "/dev";
- nsub — обратный предыдущему оператор;
- re — сравнение по регулярному выражению, например filename re "A/dev/".
Примеры:
- системный вызов будет разрешен, если filename содержит подстроку /bin linux-open: filename sub "/bin" then permit
- запретить открытие файла /etc/file linux-open: filename eq "/etc/file" deny[eperm]
- то же самое, но записанное иначе: linux-open: filename ne "/etc/file" permit
Создание псевдонимов.
Большинство системных вызовов работают аналогично, поэтому надо использовать одни и те же правила для группы системных вызовов. В данный момент поддерживается два псевдонима:
- fsread — псевдоним для access(), lstat(), readlink() и stat().
- fswrite — псевдоним для mkdir(), rmdir() и unlink().
Вызов ореп() тесно связан с чтением и записью (все зависит от переданного аргумента), поэтому он представляется псевдонимом для fsread и fswrite.
Действия.
Как уже было сказано, можно разрешать (permit), запрещать (deny) системные вызовы и запрашивать разрешение (ask). Можно использовать опцию log для логирования. Если используется действие deny, то нужно указать причину запрета, то есть отправить обратно приложению сообщение об ошибке. Рассмотрим несколько примеров:
linux-fsread: filename eq "/etc/inetd. conf" deny [eperrrt]
linux-fsread: filename eq "/etc/inetd.conf" deny[epipe]
В первом случае возвращается ошибка «Нет такого файла или каталога (No such file or directory, enoent)», во втором - «Операция не разрешена (operation not permitted, eperm)», а третий случай можно употреблять, если файл запрашивается по сети (например, по NFS) - обрыв канала. Со списком всех доступных кодов ошибок надо ознакомиться в файле /usr/include/asm-i386/errno.h.
Действие permit тоже содержит расширения, позволяющие указывать ID пользователя, от имени которого будет выполнен этот системный вызов. Например, для разрешения сервису, запущенному от имени обычного пользователя, подключаться к порту с номером меньше 1024 (обычно это требует привилегий root), применяется следующее правило:
С помощью данного метода можно избежать установки лишних битов SUID/SGID.