Часть 3
Часть 1,
Часть 2
Теперь, когда вы овладели использованием детального аудита во всех типах сред, научитесь использовать его дополнительные возможности в сервере Oracle Database 10g
.
В предыдущих двух частях этой серии статей, я представил вам концепции детального аудита (FGA, Fine-Grained Auditing), используемого для отслеживания выполнения операторов SELECT в сервере Oracle9i Database и последующих версиях. Я также объяснил, как использовать эти средства в сложных средах, таких, как веб-приложения, применяя в них контексты приложений и идентификаторы клиентов. Эти две статьи содержат достаточную информацию для того, чтобы сформировать систему FGA в почти всех типах систем базы данных, какими бы сложными они ни были. В этой третьей и заключительной части я рассмотрю усовершенствования FGA в сервере Oracle Database 10g.
FGA в сервере Oracle9i Database
Кратко резюмируем преимущества, обеспечиваемые использованием FGA. Более подробное обсуждение см. в
части 1 и
части 2 этой серии статей.
Обычный аудит (с помощью оператора AUDIT) записывает используемый оператор, такой, как оператор SELECT или INSERT, а также информацию о том, кто выдал его, с какого терминала, когда и некоторые другие сведения. Однако самый важный момент – какая конкретная запись была изменена и какое изменение было сделано непосредственно в данных – не фиксируется. Вместо этого многие пользователи пишут триггеры для перехвата значений данных до и после изменения и записи их в определяемые пользователями таблицы. Но триггеры срабатывают только при выполнении DML-операторов, таких, как INSERT, UPDATE и DELETE, аудит же основного средства доступа – оператора SELECT – не может быть выполнен таким способом.
Следовательно, достоинство средств FGA в том, что они перехватывают только операторы SELECT. Вместе с триггерами и утилитой LogMiner средства FGA обеспечивают механизм аудита всех типов доступа к данным, связанного и несвязанного с изменением значений данных.
FGA не только восполняет пробел в аудите операторов SELECT, но также обеспечивает и некоторые другие интересные дополнительные выгоды, облегчающие работу администратора базы данных. Например, FGA позволяет определяемой пользователем процедуре выполняться каждый раз, когда выполняется указанное условие аудита, так что вы можете считать его триггером операторов SELECT – средство, которое иным способом реализовать нельзя. Этот прием может быть очень полезен, например, чтобы отправлять электронные письма аудитору безопасности всякий раз, когда кто-то выбирает записи из платежной ведомости для служащих, зарабатывающих более 1 миллиона долларов; также удобно генерировать записи аудита в определяемых пользователями таблицах, которыми можно манипулировать без ограничений, существующими для таблицы FGA_LOG$ в схеме SYS; удобно использовать записи аудита для определения типа доступа к данным с целью поиска возможно лучшего механизма индексации и т.п.
По этой, а также и другим причинам место FGA – среди самых важных средств в инструментарии администратора базы данных. Однако в сервере Oracle9i Database отсутствует одна важная возможность – возможность выполнения аудита операторов, отличных от оператора SELECT.
Все типы DML-операторов
В сервере Oracle Database 10g средства FGA стали функционально полными – они позволяют выполнять аудит всех типов DML-операторов, а не только операторов SELECT.
Рассмотрим пример. В
части 1 этой серии статей я использовал таблицу по имени ACCOUNTS (счета). Правило FGA (FGA policy), определенное для этой таблицы, было следующим:
begin
dbms_fga.add_policy (
object_schema => 'BANK',
object_name => 'ACCOUNTS',
policy_name => 'ACCOUNTS_ACCESS',
audit_column => 'BALANCE',
audit_condition => 'BALANCE >= 11000'
);
end;
В сервере Oracle 9i Database это правило позволяло выполнять аудит только операторов SELECT. Однако в сервере Oracle Database 10g вы можете расширить список операторов, включив в него также операторы INSERT, UPDATE и DELETE. Это делается с помощью нового параметра:
statement_types => 'INSERT, UPDATE, DELETE, SELECT'
Этот параметр включает аудит всех типов операторов, перечисленных в нем. Вы можете также создавать отдельные правила для каждого типа операторов, что позволит вам по желанию включать или отключать правила; это удобно, в частности, для управления генерацией записей аудита с целью управления пространством, занятым ими. Однако по умолчанию параметр statement_type включает аудит только операторов SELECT.
После добавления правила с этим новым параметром при выполнении следующего оператора в таблице FGA_LOG$ появляется запись аудита, например:
update accounts set balance = 1200 where balance >= 3000;
Заметим, эта запись аудита вставляется в автономной транзакции, поэтому она останется в таблице даже после отката оператора UPDATE. Вы можете проверить наличие записи аудита из другого сеанса:
select lsqltext from fga_log$;
LSQLTEXT
--------------------------------------------------------
update accounts set balance = 3100 where balance >= 3000
В этой записи также содержатся все другие значимые детали, такие, как имя таблицы, имя правила и идентификатор транзакции.
Сравнение с подходом на основе триггеров
Итак, что можно сделать с помощью средств FGA и чего нельзя сделать с помощью старого подхода на основе триггеров?
До СУБД Oracle Database 10g аудит DML-операторов выполнялся с помощью триггеров, подобными следующему (примечание: это – не настоящий код, а только показательный пример):
CREATE TRIGGER XXXXX
ON Таблица
AFTER INSERT OR UPDATE OR DELETE
FOR EACH ROW
BEGIN
INSERT INTO AUDIT_LOG
Старое значение, Новое значение, Время.....
END
Этот триггер "захватывает" старые и новые значения и заносит их в таблицу AUDIT_LOG. Если требуется, такую процедуру можно выполнить также и в автономной транзакции. Самая большая проблема состоит в том, что этот триггер срабатывает для каждой строки, а не один раз для каждого оператора. Например, следующий оператор инициирует запуск триггера 10,000 раз и запись 10,000 строк в таблицу аудита:
update accounts set balance = 1200 where balance >= 3000;
Этот подход может серьезно подорвать производительность выполнения оператора обновления и может даже привести к его сбою из-за проблем с пространством в журнале аудита. Использование триггера операторов вместо "строкового" триггера также не решит проблему, поскольку он не может "захватывать" никаких новых или старых значений из отдельных строк. Напротив, в подходе с использованием FGA создается только одна запись, и вставка выполняется только один раз при каждом выполнении оператора, а не для каждой обрабатываемой строки, что незначительно влияет на производительность, если вообще влияет.
В FGA вы можете указывать только нужные столбцы, чтобы ограничить генерацию записей аудита только теми столбцами, к которым выполняется доступ. В триггерах такая функциональная возможность достигается с помощью предложения WHERE, вставляемого в тело триггера. Однако здесь имеется очень важное различие – в триггерах столбцы проверяются только тогда, когда они изменяются, а не при любом доступе. В FGA события аудита инициируются при каждом обращении к столбцам независимо от того, изменяются они или нет. Это свойство делает FGA более универсальным механизмом, чем триггеры.
Другое преимущество – применимость средств FGA. Иногда, когда триггеры INSTEAD OF, определенные на представлении, модифицируют его базовую таблицу, другой триггер INSTEAD OF не может перехватить изменения, сделанные другим триггером, и, следовательно, они не могут быть зарегистрированы. А средства FGA, установленные на представлениях или таблицах, перехватывают изменения независимо от их источника – пользовательских операторов или триггеров.
А вообще есть ли какие-то ситуации, в которых триггеры являются лучшей альтернативой по сравнению со средствами FGA? Таких ситуаций может быть две:
- вспомните, средства FGA вставляют записи аудита, используя автономные транзакции, которые фиксируются в их собственном контексте. Если в DML-операторе возникает ошибка или выполняется его откат, вставленная запись аудита не откатывается. Если пользователь что-то модифицирует, но не фиксирует это, изменение не производится, а запись аудита создается в любом случае. Это может приводить к появлению отдельных ложноположительных записей в таблице аудита, потенциально нежелательной ситуации. При последующем анализе таблицы аудита с использованием номеров SCN, извлекаемых ретроспективными запросами, можно, вероятно, обнаружить эту проблему, но процесс анализа может быть достаточно сложным. Но если этот риск не приемлем, то подход на основе триггеров более предпочтителен по сравнению со средствами FGA;
- средства FGA записывают SQL-операторы, выполняемые пользователем, и номера SCN, но не значения данных до и после изменения. Для извлечения этих значений следует применять отдельное средство, использующее ретроспективные запросы к таблицам. Поскольку выполнение ретроспективных запросов зависит от информации, содержащейся в сегментах отката и ограниченной по времени, данное средство, может быть, и не извлечет старые значения, измененные достаточно давно. Подход на основе триггеров позволяет фиксировать изменения в их источнике, следовательно, регистрация старых и новых значений гарантируется.
Поведение средств FGA во время изменения данных
Можно выполнять детальный аудит изменения данных. При этом возникают некоторые интересные вопросы о поведении FGA в различных сценариях. Рассмотрим наш пример, в котором правила FGA определены для аудита операторов UPDATE с условием аудита BALANCE > = 3000 и столбцом аудита BALANCE.
Сценарий 1
Перед изменением: BALANCE = 1000
Пользователь выполняет оператор:
update accounts set balance = 1200 where ACCOUNT_NO = ....
Старый и новый остатки на счете (balance) меньше 3,000, и условие аудита не выполняется; следовательно, аудит этого оператора
не выполняется.
Сценарий 2
Перед изменением: BALANCE = 1000
Пользователь выполняет оператор:
update accounts set balance = 3200 where ACCOUNT_NO = ....
Новый остаток на счете больше 3,000, и условие аудита выполняется; следовательно, аудит этого оператора
будет выполнен.
Сценарий 3
Перед изменением: BALANCE = 3200
Пользователь выполняет оператор:
update accounts set balance = 1200 where ACCOUNT_NO = ....
Новый остаток на счете меньше 3,000, но старый остаток больше. Следовательно, условие аудита выполняется, и аудит этого оператора будет выполнен.
Сценарий 4
Пользователь вставляет строку со старым значением столбца BALANCE < 3000.
insert into accounts values (9999,1200,'X');
Остаток на счете стал равен 1,200, условие аудита не выполняется, и аудит этого оператора не будет выполнен. Если бы значение столбца остатков было больше или равно 3,000, аудит был бы выполнен.
Сценарий 5
Пользователь вставляет строку с неопределенным (null) значением столбца остатков:
insert into accounts (account_no, status) values (9997, 'X');
Остаток на счете имеет неопределенное значение, и никакого значения по умолчанию для этого столбца не имеется; условие аудита не выполняется (в результате сравнения NULL >= 3000 всегда получается FALSE), и аудит этого оператора не будет выполнен.
Важное замечание: если бы столбец аудита
имел значение по умолчанию, превышающее 3,000, аудит оператора все равно не был бы выполнен даже несмотря на то, что значение столбца остатков вставленной строки превышает 3,000.
Все важные столбцы?
Рассмотрим правило аудита, определенное для таблицы ACCOUNTS следующим образом:
begin
dbms_fga.add_policy (
object_schema => 'ANANDA',
object_name => 'ACCOUNTS',
policy_name => 'ACCOUNTS_SEL',
audit_column => 'ACCOUNT_NO, BALANCE',
audit_condition => 'BALANCE >= 3000',
statement_types => 'SELECT'
);
end;
Как видите, правило аудита определено для столбцов аудита ACCOUNT_NO (номер счета) и BALANCE (остаток на счете). Предположим, если остаток на счете 9995 равен 3,200 и пользователь выполнит следующий оператор:
select balance from accounts where account_no = 9995;
то будет выполнен аудит оператора, поскольку данные выбирались из столбца остатков и остаток равен 3,200, больше чем 3,000, что удовлетворяет условию аудита. Оператор будет инициировать событие аудита независимо от того, какие столбцы выбирались (любые из трех).
В некоторых случаях может быть важна комбинация столбцов, а не определенный столбец. Например, если пользователь хочет узнать суммарный остаток на счетах, он выполняет оператор:
select sum(balance) from accounts;
Этот запрос довольно невинен: он определенно не идентифицирует владельца банковского счета и остаток на счете. Политика безопасности (security policy) банка Acme Bank может не требовать аудита таких запросов. Однако аудит следующего запроса должен быть выполнен, так как он идентифицирует конкретный банковский счет:
select balance from accounts where account_no = 9995
По умолчанию выполняется аудит всех операторов независимо от комбинации используемых столбцов. Это приводит к появлению в журнале аудита большого количества ненужных записей и, возможно, к некоторым проблемам с ограничениями пространства. Чтобы уменьшить количество записей аудита, вы можете разрешить генерацию записей аудита только тогда, когда в запросе используются желательные комбинации столбцов. Определяя правило, вы можете использовать новый параметр:
audit_column_opts => DBMS_FGA.ALL_COLUMNS
Этот параметр заставит FGA создавать записи аудита только тогда, когда запрос обращается к обоим столбцам: ACCOUNT_NO и BALANCE. Например, следующий запрос инициирует создание записи аудита:
select account_no, balance from accounts;
Но этот запрос не будет инициировать создание записи аудита:
select account_no from accounts;
Использование этого параметра позволит ограничить объем информации аудита до более приемлемого размера. Если желателен режим аудита по умолчанию, то есть при обращении к любому из столбцов аудита, то вы можете использовать другое значение этого же параметра:
audit_column_opts => DBMS_FGA.ANY_COLUMNS
Регистрация значений переменных связывания
В сервере Oracle Database 10g в журнал обычного аудита может записываться дополнительная информация, такая, как значения переменных связывания, используемых в запросах. Этот режим включается установкой параметра инициализации:
audit_trail = DB_EXTENDED
Возможно, не имеет смысла сохранять значения переменных связывания в журнале аудита FGA. Если вы хотите прекратить запись значений переменных связывания, вы можете использовать еще один параметр процедуры add_policy():
audit_trail => DB
По умолчанию переменные связывания записываются, и значение этого параметра устанавливается как DB_EXTENDED.
Обобщение вышеизложенного
Теперь, когда вы узнали о нескольких новых параметрах FGA в сервере Oracle Database 10g, посмотрим, как сейчас выглядит определение скрипта для создания правил аудита.
В скрипте мы определяем четыре различных правила, соответствующих четырем типам операторов. Правила для операторов SELECT показаны ниже; здесь мы решили не записывать значения переменных связывания и инициировать события аудита только тогда, когда в запросе используются оба столбца ACCOUNT_NO и BALANCE:
begin
dbms_fga.add_policy (
object_schema => 'ANANDA',
object_name => 'ACCOUNTS',
policy_name => 'ACCOUNTS_SEL',
audit_column => 'ACCOUNT_NO, BALANCE',
audit_condition => 'BALANCE >= 3000',
statement_types => 'SELECT',
audit_column_opts => DBMS_FGA.ALL_COLUMNS,
audit_trail => DB
);
end;
Так же мы создадим подобные правила для операторов INSERT, UPDATE и DELETE. Они могут произвольно быть включенными или выключенными.
Комбинируем обычный и детальный аудит
В сервере Oracle Database 10g средства обычного аудита были также значительно улучшены. Управляемые с помощью оператора AUDIT средства обычного аудита могут теперь регистрировать дополнительную полезную информацию, такую, как:
- расширенные, гранулированные отметки времени;
- идентификаторы процессов операционной системы;
- идентификаторы транзакций (когда запись аудита генерируется для транзакции, модифицирующей данные, например, обновляющей их, записывается идентификатор транзакции, который позднее можно использовать для соединения с представлением DBA_TRANSACTION_QUERY для идентификации точного оператора, SQL-операторов для отката транзакции, идентификатора строки и т.п.);
- текст SQL-операторов;
- значения переменных связывания;
- номер SCN во время изменения.
Как видите, по содержанию и возможностям обычный аудит походит на детальный аудит. Но, как администратор базы данных, вы заинтересованы в получении всех записей аудита, а не только одного типа. Новое представление DBA_COMMON_AUDIT_TRAIL объединяет записи аудита FGA и обычного аудита. Чтобы проверить оба журнала аудита, используйте следующий запрос:
select * from dba_common_audit_trail;
Это представление объединяет представления DBA_AUDIT_TRAIL и DBA_FGA_AUDIT_TRAIL, извлекая важную информацию из каждого. Оно создается в словаре данных следующим образом:
select 'Standard Audit', SESSIONID,
PROXY_SESSIONID, STATEMENTID, ENTRYID, EXTENDED_TIMESTAMP, GLOBAL_UID,
USERNAME, CLIENT_ID, Null, OS_USERNAME, USERHOST, OS_PROCESS, TERMINAL,
INSTANCE_NUMBER, OWNER, OBJ_NAME, Null, NEW_OWNER,
NEW_NAME, ACTION, ACTION_NAME, AUDIT_OPTION, TRANSACTIONID, RETURNCODE,
SCN, COMMENT_TEXT, SQL_BIND, SQL_TEXT,
OBJ_PRIVILEGE, SYS_PRIVILEGE, ADMIN_OPTION, GRANTEE, PRIV_USED,
SES_ACTIONS, LOGOFF_TIME, LOGOFF_LREAD, LOGOFF_PREAD, LOGOFF_LWRITE,
LOGOFF_DLOCK, SESSION_CPU
from DBA_AUDIT_TRAIL
UNION ALL
select 'Fine Grained Audit', SESSION_ID,
PROXY_SESSIONID, STATEMENTID, ENTRYID, EXTENDED_TIMESTAMP, GLOBAL_UID,
DB_USER, CLIENT_ID, EXT_NAME, OS_USER, USERHOST, OS_PROCESS, Null,
INSTANCE_NUMBER, OBJECT_SCHEMA, OBJECT_NAME, POLICY_NAME, Null,
Null, Null, STATEMENT_TYPE, Null, TRANSACTIONID, Null,
SCN, COMMENT$TEXT, SQL_BIND, SQL_TEXT,
Null, Null, Null, Null, Null,
Null, Null, Null, Null, Null,
Null, Null
from DBA_FGA_AUDIT_TRAIL
Аудит FGA и обычный аудит: различия
Если стандартный и детальный аудит похожи в сервере Oracle Database 10g, вы вполне вправе спросить, в каких случаях выбор будет явно в пользу средств FGA? Рассмотрим различия:
- стандартный аудит должен быть включен на уровне базы данных установкой параметра AUDIT_TRAIL (журнал аудита). Этот параметр не является динамическим: вы должны перезапустить экземпляр Oracle, чтобы он вступил в силу. Напротив, FGA не требует никаких изменений параметров;
- включенная опция стандартного аудита для объекта остается такой постоянно. Чтобы дезактивировать ее, вы должны удалить эту опцию аудита, используя оператор NOAUDIT. Это может быть неудобно, потому что удаление опции аудита для таблицы приводит также к удалению информации о метаданных. Средства FGA, однако, могут быть временно отключены и вновь включены без какой-либо потери информации о метаданных;
- средства FGA могут обрабатывать только четыре типа операторов: SELECT, INSERT, UPDATE и DELETE. Регулярный аудит, напротив, может обрабатывать много других операторов и привилегий, даже соединения и отсоединения сеансов от базы данных;
- средства стандартного аудита создают только одну запись для сеанса (режим by session) или одну запись при каждом доступе к объекту (режим by access). Это умеренное потребление пространства важно для управления пространством в таблицах журнала аудита. Средства FGA более расточительны: они срабатывают при каждом доступе, что приводит к большему росту журнала аудита;
- стандартный аудит может использоваться для обнаружения любых попыток взлома; при записи в журнал аудита, если попытка была неудачной, записывается код ошибки. Средства FGA не умеют этого делать;
- средства стандартного аудита могут записывать журнал аудита в таблицы базы данных или в файлы операционной системы. Последний режим полезен, когда доступ к журналу имеет только аудитор, а не администратор базы данных. В ОС Windows записи аудита могут вноситься в файл регистрации событий системы Event Log. Эта опция позволяет защищать целостность записей аудита. Журнал аудита FGA пишется только в таблицу базы данных FGA_LOG$. В FGA вы можете создать определяемые пользователями обработчики событий аудита, чтобы писать в файлы ОС, но их целостность не гарантируется;
- средства стандартного аудита могут быть настроены для аудита объектов, создаваемых по умолчанию. Эта возможность становится чрезвычайно полезной в тех случаях, когда таблицы создаются во время исполнения. Опция аудита объектов, создаваемых по умолчанию, позволяет включать аудит без вмешательства администратора базы данных. Это невозможно в FGA; правила аудита нужно создавать для существующей таблицы, а это можно сделать только после фактического создания таблицы;
- в FGA средства аудита становятся намного более гибкими – только тогда, когда выполняется доступ к определенным столбцам, когда выполняется определенное условие и т.д. Эта многосторонность удобна, если необходимо управлять ростом журнала аудита;
- переменные связывания в SQL-операторах в FGA записываются в журнал аудита по умолчанию. Для обычного аудита в параметре инициализации audit_trail для этого должно быть установлено значение db_extended;
- требуемые привилегии различны: для выполнения обычного аудита требуется соответствующая системная привилегия или привилегия выполнения оператора аудита; для FGA требуется только привилегия выполнения пакета dbms_fga.
Данное сравнение позволяет понять, почему средства FGA в определенных случаях могут оказаться полезными. Расширенные средства обычного аудита в сервере Oracle Database 10g обеспечивают решение некоторых задач, которое раньше было невозможно, например, регистрацию значений переменных связывания.
Часть 2
Арап Нанда (Arup Nanda) (arup@proligence.com) - основатель компании Proligence (Нью-Йорк), предоставляющей высокоспециализированную расширенную поддержку решений Oracle и обучение методам обеспечения информационной безопасности. В 2003 г. он был удостоен награды "Oracle's DBA of the Year"( администратор года баз данных Oracle). Арап - соавтор книги Oracle Privacy Security Auditing (издательство Rampant TechPress, 2003) - "Средства аудита в СУБД Oracle, обеспечивающие информационную безопасность".