Перевод - Dsvolk.ru

advertisement
Исходный текст данной статьи находится по адресу
http://otn.oracle.com/oramag/oracle/03-jul/o43security.html
Technology SECURITY
Now Securing Every Row
By Darl Kuhn and Steve Roughton
Перевод выполнил Sergey V Dolgov dsv@pptus.oilnet.ru
Oracle Label Security позволяет контролировать доступ к каждой строке.
Вопросы безопасности являются ключевыми в большинстве бизнес-приложений.
Зачастую появляется необходимость ограничивать доступ пользователей к отдельным
записям, осуществлять аудит или организовывать документооборот в соответствии с
политикой безопасности компании. Построение защищенного программного обеспечения
задача комплексная и неординарная, при этом администрирование политики безопасности
подобного приложения в масштабах предприятия может являться очень сложной задачей.
Как разработчик схемы данных Вы можете решить подобную задачу путем добавления
дополнительной колонки к таблицам и создавая соответствующие виды для
пользователей. В качестве администратора БД Вы вероятно создадите роли и назначите
им соответствующие права. В то же время разработчик приложения может написать
несколько пакетов PL/SQL для инкапсуляции защищенных транзакций внутри
приложения. Все эти подходы правильны, однако все они имеют множество недостатков.
Например можно воспользоваться SQL*Plus для обхода защиты на уровне приложения.
Oracle9i имеет компонент, который помогает решить подобные проблемы: Oracle Label
Security. Впервые представленный в Oracle8i Release 3 (8.1.7), Oracle Label Security
позволяет реализовать политику безопасности компании.
Oracle Label Security представляет собой набор процедур и ограничений (constraints)
встроенных в ядро БД, которые позволяют осуществить контроль за доступом на уровне
записей. Для использования Oracle Label Security, необходимо создать одну или несколько
политик безопасности, каждая из которых содержит набор меток (label). Метки
используются для определения того, какой пользователь к каким данным имеет доступ.
После создания политики нужно применить ее к защищаемым таблицам и дать
пользователям права на соответствующие метки. Oracle Label Security изменяет запросы и
вычисляет уровни доступа «на лету» для реализации созданной политики.
При разборе SQL выражения Oracle определяет входит ли в запрос какая-либо из
защищенных таблиц. После чего дописывает соответствующее условие в выражение
WHERE. Поскольку все это происходит внутри ядра БД этот механизм невозможно
обойти в не зависимости от источника SQL выражения.
Как это работает?
Здесь представлен простой пример, иллюстрирующий работу Oracle Label Security.
Создадим таблицу под названием documents, содержащую четыре записи и определим два
уровня безопасности: PUBLIC и INTERNAL. Каждый уровень также имеет цифровое
обозначение: 1000 и 2000 соответственно. Затем назначим уровни каждой строке таблицы.
Далее показано содержимое таблицы:
SQL> SELECT * FROM documents;
DOCID
DOCNAME
LEVEL
---------------------1
SHARE_WARE
PUBLIC
2
WEST_PAYROLL
INTERNAL
3
EAST_SALES
INTERNAL
4
COMP_PAYROLL
INTERNAL
DOC_LABEL
--------1000
2000
2000
2000
Предположим, что в нашей БД заведены два пользователя: EMP и MGR. Назначим им
уровни доступа следующим образом:
EMP назначим уровень PUBLIC только для чтения.
MGR назначим уровень PUBLIC и INTERNAL для чтения и записи.
Таким образом, пользователь EMP может увидеть только строку 1, в то время как MGR
имеет полный доступ ко всем четырем строкам.
Что же произойдет при обращении этих пользователей к БД? Предположим, что EMP
пытается выполнить запрос вида:
SELECT * FROM documents;
БД Oracle9i в процессе разбора выражения определяет, что запрашиваемая таблица
является защищенной.В результате чего механизм Oracle Label Security добавляет условие
WHERE с соответствующим выражением:
SELECT * FROM documents
WHERE doc_label = 1000;
Вот результат запроса, полученный пользователем EMP:
DOCID
----1
DOCNAME
---------SHARE_WARE
LEVEL
-----PUBLIC
DOC_LABEL
--------1000
На этом этапе Вы можете спросить: «Почему бы просто не создать вид, который
предоставляет пользователю соответствующую часть данных?». В действительности, если
реализуемая политика безопасности достаточно проста и имеет всего несколько уровней
доступа, то предложенный Вами путь вполне может оказаться оправданным.
Но предположим, что требования к безопасности изменились и Вам нужно пересмотреть
права доступа многих сотен пользователей в нескольких организациях, изменить
иерархию прав доступа и т.п. К тому же предположим, что организации расположены в
разных странах, каждая из которых имеет свои законы и правила. Располагая механизмом
видов реализация этой задачи становится очень трудоемкой.
Реализация подобной политики безопасности с использованием Oracle Label Security даже
проще чем Вы можете предполагать.
Практический пример.
Реализация защиты при помощи Oracle Label Security состоит из следующих 10 этапов:










Установка Oracle Label Security
Создание политики безопасности
Определение уровней доступа
Определение подуровней (compartments) (необязательно)
Определение групп (необязательно)
Создание меток
Применение политики к таблице
Назначение меток пользователям
Назначение пользователям доступа к таблице посредством команды grant
Назначение меток соответствующим строкам таблицы
Работать с механизмами Oracle Label Security можно как посредством графической
утилиты Oracle Enterprise Manager's Policy Manager или напрямую, посредством
соответствующих пакетов PL/SQL. В нашем случае мы будем использовать пакеты
PL/SQL.
Шаг 1: Установка Oracle Label Security
Этот шаг необходимо выполнять только один раз для БД. Установка состоит из четырех
этапов:
Запустите Universal Installer.
Выберите и установите Oracle Label Security option.
Под пользователем SYS выполните скрипт $ORACLE_HOME/rdbms/ admin/catols.sql
следующим образом:
SQL> CONN sys/password AS SYSDBA;
SQL> @?/rdbms/admin/catols
Note: Скрипт catols.sql выполняет команду SHUTDOWN IMMEDIATE на последнем этапе
выполнения. Запустите БД заново.
SQL> SELECT username FROM dba_users;
Вы заметите появление нового пользователя LBACSYS в схеме которого находятся
объекты Oracle Label Security. Его пароль по умолчанию LBACSYS (смените его). Этот
пользователь будет управлять политиками безопасности.
Шаг 2: Создание политики безопасности.
Политика безопасности – это набор прав доступа. Метки доступа к строкам таблицы
всегда связаны с конкретной политикой.
В данном примере необходимо ограничить доступ к документам на уровне строк. На этом
этапе создадим политику безопасности и назовем ее DOC_POLICY. Для этого войдите под
пользователем LBACSYS и выполните процедуру sa_sysdb.create_policy:
SQL> CONN lbacsys/lbacsys
SQL> EXEC sa_sysdba.create_policy
('DOC_POLICY','DOC_LABEL');
Первый параметр, DOC_POLICY, это имя политики, второй параметр, DOC_LABEL, имя служебной колонки которую Oracle Label Security добавит к защищаемым таблицам.
Для того, чтобы убедиться в успешности выполненных действий:
SQL> SELECT policy_name, status
from DBA_SA_POLICIES;
POLICY_NAME STATUS
----------- ------DOC_POLICY ENABLED
Для отключения, включение или удаления политики можно воспользоваться следующими
командами:
SQL> EXEC sa_sysdba.disable_policy
('DOC_POLICY');
SQL> EXEC sa_sysdba.enable_policy
('DOC_POLICY');
SQL> EXEC sa_sysdba.drop_policy
('DOC_POLICY');
Шаг 3: Определение уровней доступа
Каждая политика безопасности должна содержать уровни доступа, которые определяют
класс доступа к таблице. В нашем примере создадим два уровня доступа: PUBLIC и
INTERNAL.
SQL> EXEC sa_components.create_level
('DOC_POLICY', 1000,
'PUBLIC', 'Public Level');
SQL> EXEC sa_components.create_level
('DOC_POLICY', 2000,
'INTERNAL', 'Internal Level');
Параметрами процедур являются: имя политики, цифровой идентификатор, сокращенное
наименование и длинное имя. Цифровой идентификатор определяет иерархию уровней
доступа: чем он больше, тем более «детальным» (sensitive) является данный уровень. В
нашем примере INTERNAL более sensitive чем PUBLIC. Просмотреть созданные уровни
можно так:
SQL> SELECT * FROM dba_sa_levels
ORDER BY level_num;
Шаг 4: Определение подуровней (необязательно)
Подуровни (compartments) позволяют разграничить доступ внутри уровня. В приведенном
примере мы имеем документы с одним и тем же уровнем доступа, но разные отделы
нашего предприятия должны видеть разную часть данных на одном и том же уровне.
Давайте создадим подуровни FINANCE и HUMAN_RESOURCE:
SQL> EXEC sa_components.create_compartment
('DOC_POLICY', 200,
'FIN', 'FINANCE');
SQL> EXEC sa_components.create_compartment
('DOC_POLICY', 100,
'HR', 'HUMAN_RESOURCE');
Параметрами при создании подуровней являются: наименование политики, цифровой
идентификатор, короткое и длинное наименования. Цифровой идентификатор в данном
случае не определяет уровень доступа. Он используется только для сортировки строк при
отображении информации о правах. Получить информацию об подуровнях можно из вида
DBA_SA_COMPARTMENTS.
Шаг 5: Определение групп (необязательно)
По аналогии с подуровнями использование групп является еще одним вспомогательным
инструментом разграничения доступа внутри уровня. Группы оказываются полезными
когда есть иерархия пользователей, как в случае с работниками организации.
При создании группы необходимо определить иерархию. В данном примере
ALL_REGIONS является родителем в данном дереве, а WEST_REGION и EAST_REGION
- потомками ALL_REGIONS.
SQL> EXEC sa_components.create_group
('DOC_POLICY', 10,
'ALL', 'ALL_REGIONS');
SQL> EXEC sa_components.create_group
('DOC_POLICY', 20, 'WEST',
'WEST_REGION', 'ALL');
SQL> EXEC sa_components.create_group
('DOC_POLICY', 30, 'EAST',
'EAST_REGION', 'ALL');
Подобно подуровням, группы имеют цифровой идентификатор, сокращенное и длинное
имена. Значение идентификатора не влияет на степень доступа и служит только для
сортировки. Информацию о группах можно получить из вида DBA_SA_GROUPS.
Шаг 6: Создание меток
Метка (label) – это комбинация уровня, подуровней и групп. Каждая метка должна
содержать один уровень и (необязательно) подуровни и/или группы. Метка позволяет
соединить вместе разные типы разрешений доступа для различных пользователей.
Метка является комбинацией сокращенных наименований уровня, подуровней и групп и
имеет следующий синтаксис:
level : compartment, ... compartment_n : group, .. group_n
Уровень, подуровни и группы разделяются двоеточием. При указании более одного
подуровня или группы они разделяются между собой запятыми.
Например, у Вас есть пользователи в финансовом отделе которые должны иметь доступ
только к внутренним (internal) документам. Метка будет следующей:
INTERNAL:FIN
Создадим четыре метки с разными степенями доступа к данным:
SQL> EXEC sa_label_admin.create_label
('DOC_POLICY', '10000',
'PUBLIC', TRUE);
SQL> EXEC sa_label_admin.create_label
('DOC_POLICY', '20200',
'INTERNAL:HR:WEST', TRUE);
SQL> EXEC sa_label_admin.create_label
('DOC_POLICY', '20400',
'INTERNAL:FIN:EAST', TRUE);
SQL> EXEC sa_label_admin.create_label
('DOC_POLICY', '30900',
'INTERNAL:HR,FIN:ALL', TRUE);
При создании метки ей необходимо присвоить цифровой идентификатор. Этот
идентификатор должен быть уникальным среди всех политик БД. Информацию о метках
можно извлечь из вида DBA_SA_LABELS.
Шаг 7: Применение политики к таблице
Для защиты таблицы необходимо применить к ней политику безопасности. Мы применим
политику DOC_POLICY к таблице DOCUMENTS владельцем которой является
пользователь APP. Oracle Label Security будет контролировать доступ на чтение/запись
для этой таблицы.
SQL> EXEC sa_policy_admin.apply_table_policy ( policy_name => 'DOC_POLICY' , schema_name => 'APP' , table_name => 'DOCUMENTS' , table_options => 'LABEL_DEFAULT,
READ_CONTROL,WRITE_CONTROL');
При выполнении этой процедуры Oracle9i добавляет к таблице documents колонку
DOC_LABEL. Имя колонки мы определили на втором шаге. Если посмотреть описание
таблицы documents мы увидим новую колонку DOC_LABEL:
SQL> DESC app.documents
Name
--------DOCID
DOCNAME
DOC_LABEL
Type
-----------NUMBER
VARCHAR2(30)
NUMBER(10)
Эту колонку также можно скрыть от пользователей установив параметр
TABLE_OPTIONS в значение HIDE во время выполнения процедуры применения
политики:
table_options => 'LABEL_DEFAULT,
READ_CONTROL,WRITE_CONTROL,HIDE'
Параметр TABLE_OPTIONS позволяет определить тип контроля доступа к таблице.
LABEL_DEFAULT определяет, что если в команде INSERT не указана ни какая метка, то
будет использована метка по умолчанию для данной сессии. Параметр READ_CONTROL
указывает что при выполнении операций SELECT, UPDATE и DELETE доступ будет
контролироваться механизмом меток. Параметр WRITE_CONTROL определяет, что
команды INSERT, UPDATE и DELETE будут контролироваться метками.
Определить, какие политики и к каким таблицам и схемам были применены можно
выполнив запрос к виду DBA_SA_TABLE_POLICIES.
Шаг 8: Назначение меток пользователям
Теперь нужно назначить пользователям права доступа в соответствии с политикой
безопасности. В нашем примере назначим метки трем пользователям следующим
образом:
MGR предоставим максимальные права доступа.
HR_EMP – доступ на чтение/запись к документам подуровня HR группы WEST.
EMP – доступ к документам PUBLIC на чтение/запись.
Листинг 1 показывает синтаксис назначения этих меток.
Просмотреть назначение меток пользователям можно в виде DBA_SA_USER_LABELS.
Шаг 9: Назначение доступа командой grant
Механизм Label Security работает дополняя традиционную систему предоставления прав
командой grant. Пользователи не смогут выполнять команды SELECT, INSERT, UPDATE,
или DELETE до тех пор, пока им не будут даны на это права. Когда запрос SQL
обращается к таблице Oracle Label Security в первую очередь сделает проверку на наличие
прав на доступ на уровне таблицы а затем, если к таблице применена политика
безопасности, будут проверены права доступа на уровне меток. Дадим пользователям
соответствующие права на таблицы:
SQL> CONN app/app
SQL> GRANT SELECT ON documents TO emp;
SQL> GRANT SELECT, UPDATE ON documents
TO hr_emp;
SQL> GRANT SELECT, UPDATE, INSERT
ON documents TO mgr;
Шаг 10: Назначение меток строкам таблицы
Необходимо чтобы каждая строка таблицы имела соответствующую метку. Метку можно
указывать в цифровой форме или используя функцию CHAR_TO_LABEL. Следующий
пример иллюстрирует оба способа. Войдя под именем MGR введем данные в таблицу
APP.DOCUMENTS следующим образом:
SQL> CONN mgr/mr_bigg
SQL> INSERT INTO app.documents VALUES
(1, 'SHARE_WARE',CHAR_TO_LABEL
('DOC_POLICY','PUBLIC'));
SQL> INSERT INTO app.documents VALUES
(2, 'WEST_PAYROLL', 20200);
SQL> INSERT INTO app.documents VALUES
(3, 'EAST_SALES', 20400);
SQL> INSERT INTO app.documents VALUES
(4, 'COMP_PAYROLL', 30900);
Что дальше
Прочтите документацию Oracle - Oracle Label Security Administrator's Guide
otn.oracle.com/documentation/oracle9i.html
Узнайте о безопасности Oracle на сайте education.oracle.com ключевое слово для поиска:
security
Если данные в таблице уже есть, вам надо будет занести в колонку меток (DOC_LABEL)
соответствующие значения. Т.к. таблица уже контролируется механизмом Oracle Label
Security, Вы должны для выполнения этой операции использовать пользователя,
имеющего права на изменение колонки меток. Вместо этого Вы можете временно
отключить проверку меток (перевести соответствующую политику безопасности в
положение disable), внести данные и заново включить ее. Если Вы используете для
занесения данных SQL*Loader, убедитесь, что заносящий данные пользователь имеет
необходимые привилегии.
При включении механизма проверки меток даже владелец таблицы не сможет читать или
изменять данные не имея соответствующих прав (если ему не назначена нужная метка).
Единственным отклонением от этого правила является то, что владелец может выполнить
операцию truncate даже не имея прав на удаление с точки зрения Oracle Label Security.
Манипуляции с данными
Теперь, войдя в базу под разными именами пользователей, Вы можете убедиться, что
можете манипулировать данными только в пределах назначенных Вам прав (посредством
меток и команды grant):
SQL> CONN mgr/mr_bigg
SQL> SELECT docname, doc_label
FROM app.documents;
DOCNAME
DOC_LABEL
--------------------SHARE_WARE
10000
WEST_PAYROLL
20200
EAST_SALES
20400
COMP_PAYROLL
30900
Пользователю HR_EMP тот же запрос вернет:
DOCNAME
------------SHARE_WARE
WEST_PAYROLL
DOC_LABEL
--------10000
20200
Пользователь EMP получит следующее:
DOCNAME
------------SHARE_WARE
DOC_LABEL
--------10000
При выполнении любого SQL-выражения по отношению к таблице APP.DOCUMENTS
Oracle9i сначала проверит права на доступ к таблице, данные командой grant, а затем –
права на уровне меток. Таким образом пользователи могут выполнять только
разрешенные им действия.
Советы администратору
Если Вы – администратор БД Вам придется иметь ввиду еще несколько моментов. При
экспорте данных защищенных Label Security, данные могут быть экспортированы только
пользователем, имеющим соответствующие привилегии. Например, если Вы будете
выполнять экспорт таблицы APP.DOCUMENTS под пользователем SYSTEM, получите
следующую ошибку:
EXP-00079: Data in table "DOCUMENTS" is protected.
Conventional path may only be exporting partial table.
. . exporting table DOCUMENTS 0 rows exported
Применить политику безопасности к схеме SYSTEM нельзя. Вам придется использовать
какую-нибудь другую схему, имеющую доступ на чтение к защищенной таблице.
Например, используя для этой цели пользователя EXPUSER нужно дать ему права на
доступ ко всем строкам защищенной таблицы:
SQL> EXEC sa_user_admin.set_user_privs
('DOC_POLICY','EXPUSER','READ');
Для того, чтобы назначить полный доступ на чтение и запись к защищенной таблице
используйте ключевое слово FULL:
SQL> EXEC sa_user_admin.set_user_privs
('DOC_POLICY','EXPUSER','FULL');
Обратите внимание, что любой пользователь имеющий привилегии SYSDBA (например
SYS) может просмотреть все данные не обращая внимания на защиту Label Security.
Несмотря на наличие любых привилегий (таких как FULL), Вы не сможете сделать
экспорт схемы LBACSYS. При попытке экспорта этой схемы возникнет ошибка:
"LBACSYS is not a valid username." Таким образом, необходимо использовать резервное
копирование Вашей БД на физическом уровне (горячий или холодный бэкап или RMAN)
для того, чтобы сохранить данные схемы LBACSYS.
Перед импортом защищенных метками данных в другую БД необходимо установить
Oracle Label Security. Также надо будет создать все политики и метки а также убедиться,
что импортирующий пользователь имеет соответствующие привилегии на запись. Более
детально об этом можно почитать в Oracle Label Security Administrator's Guide, Chapter 12.
Если механизмом Label Security защищаются большие объемы данных, Вам потребуется
оптимизация производительности. Для этого можно создать B-tree или bit-mapped индекс
на колонке, содержащей метки. Например, если у вас большое количество разных меток,
то использование индекса B-tree будет предпочтительным.
Oracle рекомендует анализировать схему LBACSYS также, как таблицы и индексы
приложения для повышения быстродействия. Мы рекомендуем проводить анализ схемы
LBACSYS при любом изменении в политиках безопасности.
Darl Kuhn (darl.kuhn@sun.comOracle RMAN Pocket Reference (O'Reilly & Associates, 2001).
Steve Roughton (steve.roughton@sun.com) is a staff engineer at Sun Microsystems, Inc., with
more than 20 years of development and DBA experience.
Related documents
Download