Skip to content
Masahiko Sawada edited this page Dec 15, 2016 · 2 revisions

Design

できているもの、できていないもの関係なく設計のメモ。

設定ファイル

設定ファイルはpostgresql.confとは別に用意する。これは、悪意を持ったユーザが故意にログ出力設定を変更し、証跡を消すことを防ぐため。 pgaudit.config_fileに指定されたファイルをパースして、メモリに展開する。 pgaudit_scan.lで定義。

以下、設定ファイル例。

[output] # outputセクション
logger = 'serverlog'

[options] # optionsセクション
role = 'audit_role'
log_catalog = off
log_format = 'csv'
log_level = NOTICE

[connection rule]
database = 'postgres'
timestamp = '00:00:00 - 12:00:00'
log_error = on
log_replication = on

[connection rule]
database = 'postgres'
host = 'management_host'
timestamp = '13:00:00-14:00:00'
log_error = off

[SQL rule]
class = 'READ, WRITE, FUNCTION'
database = 'postgres, hoge_db'
table = 'hoge_table, bar_table'
log_sql = on
log_error = off
log_parameter = on

[SQL rule]
class = 'READ, WRITE, MISC'
database = 'postgres, hoge_db'
log_sql = off
log_error = on

以下詳細。

  • 設定ファイルはoptions, output, connection rule, SQL ruleの4つのセクションを持つことが可能。
    • output, optionsは設定ファイル内で一つだけ指定可能かつ指定必須。
    • connection rule, SQL ruleは複数指定可能だが、指定しなくても良い。指定しなかった場合は、ログ出力しない。
  • 各設定値の扱い
    • 論理値を入れるパラメータ(log_parameterなど)→on, off, true, false, 1, 0で設定
      • シングルクォーテーションなしで記載
      • 例) log_parameter = on
    • その他→シングルクォーテーションで囲む(例、'5432, 5555'とか'postgres, hoge_database')
      • 数値であってもカンマ区切りで複数指定する可能性があるため、シングルクォーテーションで囲む。
      • 例) remote_port = '5432'
    • timestampについてはHH:MM:SS-HH:MM:SSを一塊として、カンマ区切りで指定する。
      • 例) timestamp = '00:00:00 - 12:00:00, 13:00:00-14:00:00'
    • 間のスペースはすべて無視される。  - 日付のフォーマットに合わなかったら、パースエラーとする。
    • 大文字、小文字の区別はしない。
      • ただし、formatについては大文字、小文字を意識して出力する。
  • 演算子
    • = → ルールに一致するものをログに出す
    • != → ルールに一致しないものをログに出す
      • 例) object_id != 'public.hoge_table'
  • #以降はコメントとして扱う。コメントは行の途中でも可能。

optionsセクション

  • 以下のパラメータが指定可能(カッコ内はデフォルト)
    • role, log_format(csv). log_level(LOG)

connection rule, SQL ruleセクション

  • 各ルールに関するパラメータ
    • すべてのルール共通で指定できるもの(カッコ内はデフォルト)
      • timestamp, database, audit_role, application_name, remote_host, remote_port, log_error(on)
    • connection ruleセクションは加えて以下が設定可能(カッコ内はデフォルト)
      • log_replication(on)
      • log_replication = onだとレプリケーション接続(pg_basebackupを含む)についてもログに出す
    • SQL ruleセクションは加えて以下が設定可能(カッコ内はデフォルト)
      • class, object_type, object_name, log_sql(on), log_parameter(off), log_catalog(on), log_statement_once(off)
        • classに設定できるものは、DDL FUNCTION, MISC, READ, ROLE, WRITE, ALLの7つで、指定必須。
        • log_sql = onのときはSQL本文を出力する(Object Audit的な振る舞いが可能)
        • log_parameter = onのときはPreparedStatementのパラメータを出力する
  • 監査ログの出力項目は固定とする。
    • SQL STATEでフィルタを掛けることはできないが監査ログ内にSQL STATEを表示する欄は用意する
  • 起動、停止ログは常に監査ログとして出力する

イベントのログ出力(メイン処理)

処理のメインとなる関数(hook等)をpgaudit.c、pgaudit.hに定義

ログ出力の設計は以下のとおり。

  • 出力内部関数
    • SESSIONログはlog_audit_eventまたは、emit_log_hookで出力する。
      • log_audit_event()関数
        • 基本的にすべてのイベントはlog_audit_eventを通り、
          1. apply_all_rules()がtrue かつ
          2. stackItem->granted == false  のイベントがSESSIONログとして出力される。
    • emit_log_hook()関数
      • emit_log_hookですべてのログを引っ掛けて、目的のログかどうかを文字列一致で判定して、出力する。(advancedでやっている方法踏襲)
      • なにか他にいい方法があれば採用したい。
    • pgaudit内でのログ出力はAUDIT_EREPORT(ereport相当)、AUDIT_ELOG(elog相当)を使用する  - これは、emit_log_hookの無限ループにならないようにするために用意した。
  • 監査ログ以外のサーバログの扱い
    • 設定ファイルでlog_levelが設定できるが、これは監査ログのみを対象とする。通常の運用で出すpgauditのログには適用されないようにする。
  • 監査ログの内容
    • 監査に必要な固定の内容のデータを出力。(いつ、誰が、どこから、何をした、など)
    • 出力形式は、optionsセクションのformatで指定。
      • csvの例) ap_srv,10000,SELECT,TABLE,SELECT * FROM rel;
      • ssvの例) ap_srv 10000 SELECT TABLE SELECT * FROM rel;

ルールの判定

  • ルールが未定儀=出力しない
  • ルールセクション自体の記述がない場合は、ルールがないということになるので監査ログ出力はしない。
  • 各ルールに指定されている項目にすべて該当した場合に監査ログを出力する。
    • 複数のルールにマッチしたイベントは、マッチした分だけのログが出力される  - なので一つのSQLで複数の監査ログが出力される可能性もある。

syslog対応

基本的にはadvancedブランチにあるやり方を踏襲すれば良いはず。

Clone this wiki locally