|
Основные понятия
С традиционной точки зрения средства управления
доступом позволяют специфицировать и контролировать действия, которые
субъекты (пользователи и процессы) могут выполнять надобъектами (информацией и
другими компьютерными ресурсами). В данном разделе речь идет о логическом
управлении доступом, которое, в отличие от физического, реализуется
программными средствами. Логическое управление доступом - это основной
механизм многопользовательских систем, призванный обеспечить
конфиденциальность и целостность объектов и, до некоторой степени, их
доступность (путем запрещения обслуживания неавторизованных пользователей).
Рассмотрим формальную постановку задачи в
традиционной трактовке. Имеется совокупность субъектов и набор объектов.
Задача логического управления доступом состоит в том, чтобы для каждой пары
"субъект-объект" определить множество допустимых операций (зависящее,
быть может, от некоторых дополнительных условий) и контролировать
выполнение установленного порядка.
Отношение "субъекты-объекты" можно
представить в виде матрицы
доступа, в строках которой перечислены субъекты, в столбцах -
объекты, а в клетках, расположенных на пересечении строк и столбцов,
записаны дополнительные условия (например, время и место действия) и
разрешенные виды доступа. Фрагмент матрицы может выглядеть, например, так:
|
Таблица .1. Фрагмент матрицы доступа
|
|
|
Файл
|
Программа
|
Линия связи
|
Реляционная таблица
|
|
Пользователь 1
|
orw с системной консоли
|
e
|
rw с 8:00 до 18:00
|
|
|
Пользователь 2
|
|
|
|
a
|
"o" - обозначает разрешение на
передачу прав доступа другим
пользователям,
"r" - чтение,
"w" - запись,
"e" - выполнение,
"a" - добавление информации
Тема логического управления доступом - одна из
сложнейших в области информационной безопасности. Дело в том, что само
понятие объекта (а тем более видов доступа) меняется от сервиса к сервису.
Для операционной системы к объектам относятся файлы, устройства и процессы.
Применительно к файлам и устройствам обычно рассматриваются права на
чтение, запись, выполнение (для программных файлов), иногда на удаление и
добавление. Отдельным правом может быть возможность передачи полномочий доступа
другим субъектам (так называемое право владения). Процессы можно создавать
и уничтожать. Современные операционные системы могут поддерживать и другие
объекты.
Для систем управления реляционными базами данных
объект - это база данных, таблица, представление, хранимая процедура. К
таблицам применимы операции поиска, добавления, модификации и удаления
данных, у других объектов иные виды доступа.
Разнообразие объектов и применимых к ним операций
приводит к принципиальной децентрализации логического управления доступом.
Каждый сервис должен сам решать, позволить ли конкретному субъекту ту или
иную операцию. Теоретически это согласуется с современным
объектно-ориентированным подходом, на практике же приводит к значительным
трудностям. Главная проблема в том, что ко многим объектам можно получить
доступ с помощью разных сервисов (возможно, при этом придется преодолеть
некоторые технические трудности). Так, до реляционных таблиц можно
добраться не только средствами СУБД, но и путем непосредственного чтения файлов
или дисковых разделов, поддерживаемых операционной системой (разобравшись
предварительно в структуре хранения объектов базы данных). В результате при
задании матрицы доступа нужно принимать во внимание не только принцип
распределения привилегий для каждого сервиса, но и существующие связи между
сервисами (приходится заботиться о согласованности разных частей матрицы).
Аналогичная трудность возникает при экспорте/импорте данных, когда
информация о правах доступа, как правило, теряется (поскольку на новом
сервисе она не имеет смысла). Следовательно, обмен данными между различными
сервисами представляет особую опасность с точки зрения управления доступом,
а при проектировании и реализации разнородной конфигурации необходимо
позаботиться о согласованном распределении прав доступа субъектов к
объектам и о минимизации числа способов экспорта/импорта данных.
При принятии решения о предоставлении доступа
обычно анализируется следующая информация:
идентификатор субъекта (идентификатор
пользователя, сетевой адрес компьютера и т.п.). Подобные идентификаторы
являются основой произвольного
(или дискреционного) управления доступом;
атрибуты субъекта (метка безопасности, группа
пользователя и т.п.). Метки безопасности - основа принудительного (мандатного) управления
доступом.
Матрицу доступа, ввиду ее разреженности
(большинство клеток - пустые), неразумно хранить в виде двухмерного
массива. Обычно ее хранят по столбцам, то есть для каждого объекта
поддерживается список "допущенных" субъектов вместе с их правами.
Элементами списков могут быть имена групп и шаблоны субъектов, что служит
большим подспорьем администратору. Некоторые проблемы возникают только при
удалении субъекта, когда приходится удалять его имя из всех списков
доступа; впрочем, эта операция производится нечасто.
Списки доступа - исключительно гибкое средство. С
их помощью легко выполнить требование о гранулярности прав с точностью до
пользователя. Посредством списков несложно добавить права или явным образом
запретить доступ (например, чтобы наказать нескольких членов группы
пользователей). Безусловно, списки являются лучшим средством произвольного
управления доступом.
Удобной надстройкой над средствами логического
управления доступом являетсяограничивающий
интерфейс, когда пользователя лишают самой возможности попытаться
совершить несанкционированные действия, включив в число видимых ему
объектов только те, к которым он имеет доступ. Подобный подход обычно
реализуют в рамках системы меню (пользователю показывают лишь допустимые
варианты выбора) или посредством ограничивающих оболочек, таких как
restrictedshell в ОС Unix.
В заключение подчеркнем важность управления
доступом не только на уровне операционной системы, но и в рамках других
сервисов, входящих в состав современных приложений, а также, насколько это
возможно, на "стыках" между сервисами. Здесь на первый план
выходит существование единой политики безопасности организации, а также
квалифицированное и согласованное системное администрирование.
Ролевое управление доступом
При большом количестве пользователей традиционные
подсистемы управления доступом становятся крайне сложными для
администрирования. Число связей в них пропорционально произведению
количества пользователей на количество объектов. Необходимы решения в
объектно-ориентированном стиле, способные эту сложность понизить.
Таким решением является ролевое управление доступом (РУД).
Суть его в том, что между пользователями и их привилегиями появляются
промежуточные сущности - роли. Для каждого пользователя одновременно могут
быть активными несколько ролей, каждая из которых дает ему определенные
права (см. рис. 10.2).

Рис. 1 Пользователи,
объекты и роли.
Ролевой доступ нейтрален по отношению к конкретным
видам прав и способам их проверки; его можно рассматривать как
объектно-ориентированный каркас, облегчающий администрирование, поскольку
он позволяет сделать подсистему разграничения доступа управляемой при сколь
угодно большом числе пользователей, прежде всего за счет установления между
ролями связей, аналогичных наследованию в объектно-ориентированных
системах. Кроме того, ролей должно быть значительно меньше, чем
пользователей. В результате число администрируемых связей становится
пропорциональным сумме (а не произведению) количества пользователей и
объектов, что по порядку величины уменьшить уже невозможно.
Ролевой доступ развивается более 10 лет (сама идея
ролей, разумеется, значительно старше) как на уровне операционных систем,
так и в рамках СУБД и других информационных сервисов. В частности,
существуют реализации ролевого доступа для Web-серверов.
В 2001 году Национальный институт стандартов и
технологий США предложил проект стандарта ролевого управления доступом
(см. http://csrc.nist.gov/rbac/), основные положения
которого мы и рассмотрим.
Ролевое управление доступом оперирует следующими
основными понятиями:
пользователь (человек,
интеллектуальный автономный агент и т.п.);
сеанс работы
пользователя;
роль (обычно определяется
в соответствии с организационной структурой);
объект (сущность, доступ к
которой разграничивается; например, файл ОС или таблица СУБД);
операция (зависит от объекта;
для файлов ОС - чтение, запись, выполнение и т.п.; для таблиц СУБД -
вставка, удаление и т.п., для прикладных объектов операции могут быть более
сложными);
право доступа (разрешение выполнять определенные
операции над определенными объектами).
Ролям приписываются
пользователи и права доступа; можно считать, что они (роли) именуют отношения
"многие ко многим" между пользователями и правами. Роли могут
быть приписаны многим пользователям; один пользователь может быть приписан
нескольким ролям. Во время сеанса работы пользователя активизируется подмножество
ролей, которым он приписан, в результате чего он становится обладателем
объединения прав, приписанных активным ролям. Одновременно пользователь
может открыть несколько сеансов.
Между ролями может быть определено отношение
частичного порядка, называемое наследованием. Если роль r2 является
наследницей r1, то все права r1 приписываются r2, а все пользователи r2
приписываются r1. Очевидно, что наследование ролей соответствует наследованию классов в
объектно-ориентированном программировании, только правам доступа
соответствуют методы классов, а пользователям - объекты (экземпляры)
классов.
Отношение наследования является иерархическим,
причем права доступа и пользователи распространяются по уровням иерархии
навстречу друг другу. В общем случае наследование является множественным,
то есть у одной роли может быть несколько предшественниц (и, естественно,
несколько наследниц, которых мы будем называть также преемницами).
Можно представить себе формирование иерархии ролей, начиная с минимума
прав (и максимума пользователей), приписываемых роли "сотрудник",
с постепенным уточнением состава пользователей и добавлением прав (роли
"системный администратор", "бухгалтер" и т.п.), вплоть
до роли "руководитель" (что, впрочем, не значит, что руководителю
предоставляются неограниченные права; как и другим ролям, в соответствии с
принципом минимизации
привилегий, этой роли целесообразно разрешить только то, что
необходимо для выполнения служебных обязанностей). Фрагмент подобной
иерархии ролей показан на рис. 10.3.

Рис. 2. Фрагмент
иерархии ролей.
Для реализации еще одного упоминавшегося ранее
важного принципа информационной безопасности вводится понятие разделения обязанностей, причем в
двух видах: статическом и динамическом.
Статическое разделение
обязанностей налагает
ограничения на приписывание
пользователей ролям. В простейшем случае членство в некоторой роли
запрещает приписывание пользователя определенному множеству других ролей. В
общем случае данное ограничение задается как пара "множество ролей -
число" (где множество состоит, по крайней мере, из двух ролей, а число
должно быть больше 1), так что никакой пользователь не может быть приписан
указанному (или большему) числу ролей из заданного множества. Например,
может существовать пять бухгалтерских ролей, но политика безопасности
допускает членство не более чем в двух таких ролях (здесь число=3).
При наличии наследования ролей ограничение
приобретает несколько более сложный вид, но суть остается простой: при
проверке членства в ролях нужно учитывать приписывание пользователей
ролям-наследницам.
Динамическое разделение
обязанностей отличается
от статического только тем, что рассматриваются роли, одновременно активные
(быть может, в разных сеансах) для данного пользователя (а не те, которым
пользователь статически приписан). Например, один пользователь может играть
роль и кассира, и контролера, но не одновременно; чтобы стать контролером,
он должен сначала закрыть кассу. Тем самым реализуется так называемое временное ограничение доверия,
являющееся аспектом минимизации привилегий.
Рассматриваемый проект стандарта содержит
спецификации трех категорий функций, необходимых для администрирования РУД:
Административные функции (создание и
сопровождение ролей и других атрибутов ролевого доступа): создать/удалить
роль/пользователя, приписать пользователя/право роли или ликвидировать
существующую ассоциацию, создать/удалить отношение наследования между
существующими ролями, создать новую роль и сделать ее
наследницей/предшественницей существующей роли, создать/удалить ограничения
для статического/динамического разделения обязанностей.
Вспомогательные функции (обслуживание
сеансов работы пользователей): открыть сеанс работы пользователя с активацией
подразумеваемого набора ролей; активировать новую роль, деактивировать
роль; проверить правомерность доступа.
Информационные функции (получение сведений
о текущей конфигурации с учетом отношения наследования). Здесь проводится
разделение на обязательные и необязательные функции. К числу первых
принадлежат получение списка пользователей, приписанных роли, и списка
ролей, которым приписан пользователь.
Все остальные функции отнесены к разряду
необязательных. Это получение информации о правах, приписанных роли, о
правах заданного пользователя (которыми он обладает как член множества
ролей), об активных в данный момент сеанса ролях и правах, об операциях,
которые роль/пользователь правомочны совершить над заданным объектом, о
статическом/динамическом разделении обязанностей.
Можно надеяться, что предлагаемый стандарт поможет
сформировать единую терминологию и, что более важно, позволит оценивать
РУД-продукты с единых позиций, по единой шкале.
Управление доступом в Java-среде
Java - это
объектно-ориентированная система программирования, поэтому и управление
доступом в ней спроектировано и реализовано в объектном стиле. По этой
причине рассмотреть Java-среду для нас очень важно. Подробно о
Java-технологии и безопасности Java-среды рассказано в статье А. Таранова и
В. Цишевского "Java в три года" (JetInfo, 1998, 11-12). С
разрешения авторов далее используются ее фрагменты.
Прежде всего, остановимся на эволюции модели
безопасности Java. В JDK 1.0 была предложена концепция "песочницы" (sandbox)
- замкнутой среды, в которой выполняются потенциально ненадежные программы
(апплеты, поступившие по
сети). Программы, располагающиеся на локальном компьютере, считались
абсолютно надежными, и им было доступно все, что доступно виртуальной
Java-машине.
В число ограничений, налагаемых
"песочницей", входит запрет на доступ к локальной файловой
системе, на сетевое взаимодействие со всеми хостами, кроме источника
апплета, и т.п. Независимо от уровня достигаемой при этом безопасности (а
проблемы возникали и с разделением свой/чужой, и с определением источника
апплета), наложенные ограничения следует признать слишком обременительными:
возможности для содержательных действий у апплетов почти не остается.
Чтобы справиться с этой проблемой, в JDK 1.1 ввели
деление источников (точнее, распространителей) апплетов на надежные и
ненадежные (источник определялся по электронной подписи).Надежные апплеты
приравнивались в правах к "родному" коду. Сделанное послабление
решило проблемы тех, кому прав не хватало, но защита осталась неэшелонированной
и, следовательно, неполной.
В JDK 1.2 сформировалась модель безопасности,
используемая и в Java 2. От модели "песочницы" отказались.
Оформились три основных понятия:
-источник программы;
-право и множество прав;
-политика безопасности.
Источник программы определяется парой (URL,
распространители программы). Последние задаются набором цифровых
сертификатов.
Право - это абстрактное понятие, за которым, как и
положено в объектной среде,
стоят классы и объекты. В большинстве случаев право определяется двумя
цепочками символов - именем ресурса и действием. Например, в качестве
ресурса может выступать файл, а в качестве действия - чтение.
Важнейшим методом "правовых"
объектов является implies(). Он проверяет, следует ли одно право (запрашиваемое)
из другого (имеющегося).
Политика безопасности задает соответствие между
источником и правами поступивших из него программ (формально можно считать,
что каждому источнику соответствует своя "песочница"). В JDK 1.2
"родные" программы не имеют каких-либо привилегий в плане
безопасности, и политика по отношению к ним может быть любой. В результате
получился традиционный для современных ОС и СУБД механизм прав доступа со
следующими особенностями:
Java-программы выступают не от имени пользователя,
их запустившего, а от имени источника программы. (Это весьма глубокая и
прогрессивная трактовка, если ее правильно развить, см. следующий раздел);
нет понятия владельца ресурсов, который мог бы
менять права; последние задаются исключительно политикой безопасности
(формально можно считать, что владельцем всего является тот, кто формирует
политику);
механизмы безопасности снабжены объектной
оберткой.
Рассмотрим дисциплину контроля прав доступа более
формально.
Класс AccessController (встроенный менеджер безопасности)
предоставляет единый метод для проверки заданного права в текущем контексте
- checkPermission (Permission). Это лучше (по причине параметризуемости),
чем множество методов вида checkXXX, присутствующих в SecurityManager -
динамически изменяемом менеджере безопасности из ранних версий JDK.
Пусть текущий контекст выполнения состоит из N
стековых фреймов (верхний соответствует методу, вызвавшему
checkPermission(p)). Метод checkPermission реализует следующий алгоритм
(см. Листинг 10.1).
i = N;
while (i > 0) {
if (метод, породивший
i-й фрейм, не имеет проверяемого
права) {
throwAccessControlException
} elseif (i-й фрейм помечен как
привилегированный) {
return;
}
i = i - 1;
};
// Выясним, есть ли
проверяемое право у унаследованного контекста
inheritedContext.checkPermission
(p);
Листинг 1. Алгоритм работы метода
checkPermission класса AccessController. (html, txt)
Сначала в стеке ищется фрейм, не обладающий
проверяемым правом. Проверка производится до тех пор, пока либо не будет
исчерпан стек, либо не встретится "привилегированный" фрейм,
созданный в результате обращения к методу doPrivileged(PrivilegedAction)
класса AccessController. Если при порождении текущего потока выполнения был
сохранен контекст inheritedContext, проверяется и он. При положительном результате
проверки метод checkPermission(p) возвращает управление, при отрицательном
возникает исключительная ситуация AccessControlException.
Выбранный подход имеет один недостаток -
тяжеловесность реализации. В частности, при порождении нового потока
управления с ним приходится ассоциировать зафиксированный
"родительский" контекст и, соответственно, проверять последний в
процессе контроля прав доступа.
Отметим, что этот подход не распространяется на
распределенный случай (хотя бы потому, что контекст имеет лишь локальный
смысл, как, впрочем, и политика безопасности).
В целом средства управления доступом в JDK 1.2
можно оценить как "наполовину объектные". Реализация оформлена в
виде интерфейсов и
классов, однако по-прежнему разграничивается доступ к необъектным сущностям
- ресурсам в традиционном понимании. Не учитывается семантика доступа.
Имеют место и другие отмеченные выше концептуальные проблемы.
Возможный подход к управлению доступом в
распределенной объектной среде
Представляется, что в настоящее время проблема
управления доступом существует в трех почти не связанных между собой
проявлениях:
традиционные модели (дискреционная и мандатная);
модель "песочница" (предложенная для
Java-среды и близкой ей системы Safe-Tcl);
модель фильтрации (используемая в межсетевых
экранах).
На наш взгляд, необходимо объединить существующие
подходы на основе их развития и обобщения.
Формальная постановка задачи разграничения доступа
может выглядеть следующим образом.
Рассматривается множество объектов (в смысле
объектно-ориентированного программирования). Часть объектов может
являться контейнерами,
группирующими объекты-компоненты, задающими для них общий контекст,
выполняющими общие функции и реализующими перебор компонентов. Контейнеры
либо вложены друг в друга, либо не имеют общих компонентов.
С каждым объектом ассоциирован набор интерфейсов,
снабженных дескрипторами (ДИ).
К объекту можно обратиться только посредством ДИ. Разные интерфейсы могут
предоставлять разные методы и быть доступными для разных объектов.
Каждый контейнер позволяет опросить набор ДИ
объектов-компонентов, удовлетворяющих некоторому условию. Возвращаемый
результат в общем случае зависит от вызывающего объекта.
Объекты изолированы друг от друга. Единственным
видом межобъектного взаимодействия является вызов метода.
Структурируем множество всех ПРД, выделив четыре
группы правил:
-политика безопасности контейнера;
-ограничения на вызываемый метод;
-ограничения на вызывающий метод;
-добровольно налагаемые ограничения.
Правила, общие для всех объектов, входящих в
контейнер C, назовем политикой безопасности данного контейнера.
Пусть метод M1 объекта O1 в точке P1 своего
выполнения должен вызвать метод M объекта O. Правила, которым должен
удовлетворять M, можно разделить на четыре следующие подгруппы:
правила, описывающие требования к формальным параметрам вызова;
правила, описывающие требования к семантике M;
реализационные правила, накладывающие ограничения
на возможные реализации M;
правила, накладывающие ограничения на вызываемый
объект O.
Метод M объекта O, потенциально доступный для
вызова, может предъявлять к вызывающему объекту следующие группы
требований:
правила, описывающие требования к фактическим
параметрам вызова;
правила, накладывающие ограничения на вызывающий
объект.
Можно выделить три разновидности предикатов,
соответствующих семантике и/или особенностям реализации методов:
утверждения о фактических параметрах вызова метода
M в точке P1;
предикат, описывающий семантику метода M;
предикат, описывающий особенности реализации
метода M.
Перечисленные ограничения можно назвать
добровольными, поскольку они соответствуют реальному поведению объектов и
не связаны с какими-либо внешними требованиями.
Предложенная постановка задачи разграничения доступа
соответствует современному этапу развития программирования, она позволяет
выразить сколь угодно сложную политику безопасности, найти баланс между
богатством выразительных возможностей и эффективностью работы монитора
обращений.
|