はじめに
OCIのAuditサービスでは、デフォルトで監査ログは90日間保存され、ログの保持期間は最長365日間まで設定できます。
366日以上前の監査ログを保管するのにデータベースを使えば管理が楽になると考え、PL/SQL SDKを用いて、PL/SQLからAuditサービスの監査ログにアクセスしてみました。
1.事前準備
あらかじめ、以下の情報を確認しておきます。
・rootコンパートメントのOCID
・リージョン識別子(今回はap-tokyo-1)
また、SDKを使用するためのクレデンシャル(資格証明)を作成しておきます。
(今回はMY_SDK_CRED)
2.PL/SQLプロシージャの作成
早速、監査ログにアクセスするPL/SQLプロシージャを作成します。
今回作成するプロシージャは、引数として日本時間の日付をYYYY-MM-DD形式で受け取り、対象日の監査ログを取得して表示します。
CREATE OR REPLACE PROCEDURE audit_check(check_date IN varchar2)
IS
loop_flg NUMBER := 1;
num NUMBER := 0;
page VARCHAR2(1000) :='';
start_time TIMESTAMP WITH TIME ZONE;
end_time TIMESTAMP WITH TIME ZONE;
response dbms_cloud_oci_ad_audit_list_events_response_t;
response_body dbms_cloud_oci_ad_audit_audit_event_tbl;
json_obj json_object_t;
l_keys json_key_list;
BEGIN
-- セッションのNLS_TIMESTAMP_TZ_FORMATをRFC 3339に合わせて設定
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT=''YYYY-MM-DD"T"HH24:MI:SS"Z"''';
-- 対象期間の開始時間をUTCで設定
SELECT TO_TIMESTAMP_TZ(check_date||' 00:00:00.00','YYYY-MM-DD HH24:MI:SS.FF') -9/24 INTO start_time FROM dual;
-- 対象期間の終了時間をUTCで設定
SELECT TO_TIMESTAMP_TZ(check_date||' 23:59:59.99','YYYY-MM-DD HH24:MI:SS.FF') -9/24 INTO end_time FROM dual;
-- 複数ページがある場合のループ処理(デフォルトでは1ページあたり100レコード)
WHILE loop_flg = 1 LOOP
loop_flg := 0;
-- Audit情報を取得
response := DBMS_CLOUD_OCI_AD_AUDIT.list_events (
compartment_id => 'ocid1.tenancy.oc1..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
start_time => start_time,
end_time => end_time,
page => page,
region => 'ap-tokyo-1',
credential_name => 'MY_SDK_CRED'
);
-- responseからresponse_bodyを取得
response_body := response.response_body;
-- レスポンスヘッダの出力
dbms_output.put_line('Headers: ' || CHR(10) ||'------------');
json_obj := response.headers;
l_keys := json_obj.get_keys;
FOR i IN 1..l_keys.count LOOP
dbms_output.put_line(l_keys(i)||':'||json_obj.get(l_keys(i)).to_string);
-- レスポンスヘッダ内にopc-next-pageがあるか確認
-- もしある場合は次のページがあるのでpageをセットして再度list_eventsを実行
IF l_keys(i) = 'opc-next-page' THEN
loop_flg := 1;
page := RTRIM(SUBSTR(json_obj.get(l_keys(i)).to_string,3),'"');
END IF;
END LOOP;
-- ステータスコードの出力
dbms_output.put_line('Status Code: ' || CHR(10) || '------------' || CHR(10) || response.status_code);
dbms_output.put_line(CHR(10));
-- 取得した監査情報の出力
FOR i IN response_body.first .. response_body.last LOOP
num := num + 1;
dbms_output.put_line('No.:'||num);
dbms_output.put_line('Compartment Name:'||response_body(i).data.compartment_name);
dbms_output.put_line('Event Time:'||TO_CHAR(response_body(i).event_time at time zone 'Asia/Tokyo','YYYY-MM-DD HH24:MI:SS TZD'));
dbms_output.put_line('Principal Name:'||response_body(i).data.identity.principal_name);
dbms_output.put_line('Source:'||response_body(i).source);
dbms_output.put_line('Event Name:'||response_body(i).data.event_name);
dbms_output.put_line('Resource Name:'||response_body(i).data.resource_name);
dbms_output.put_line('AD:'||response_body(i).data.availability_domain);
dbms_output.put_line('Request Action:'||response_body(i).data.request.action);
dbms_output.put_line('Response Status:'||response_body(i).data.response.status);
dbms_output.put_line('---------------------------------------');
END LOOP;
END LOOP;
END;
/
3.PL/SQLプロシージャの実行
PL/SQLプロシージャが完成したので、監査ログを取得する日付をYYYY-MM-DD形式で指定して実行してみます。
exec audit_check('2020-11-01');
実行結果は以下のようになりました。
Headers:
------------
Connection:"close"
Date:"Mon, 02 Nov 2020 13:04:52 GMT"
opc-request-id:"3MPAK484F0/48B8AE98BCFE1B0828CC299876D98B0E/7DE7BB5059FE4A63FD8E
CCD1D0925E5B"
opc-next-page:"v2:AP36_Pj-_fT-9Pn--_zpsK25qKW4sP78_vzh_fzh__2Y_f72_Pz2_PyWsP78_v
zh_f3h_P2Y_Pz2_Pz2_PyWsPyw_Iz9-f789fr8__7__fz__vX_-Pj8jP36_Pj99Pv69Pj5__mMorjh_e
mwrbmopbiw_vz-_OH9_eH8_Zj8_Pb8_Pb8_Jaw_vz-_OH9_eH8_Zj9_vb8_Pb8_Jaw_bD8jP35_Pv1_v
799P38-_r0_f37-_qM_fr8-P799P70-f77_IyiuOH96Q=="
Vary:"Accept-Encoding"
Content-Type:"application/json"
X-Content-Type-Options:"nosniff"
Transfer-Encoding:"chunked"
Status Code:
------------
200
No.:1
Compartment Name:zeon
Event Time:2020-11-01 00:35:19 JST
Principal Name:oci-optimizer
Source:Compartments
Event Name:ListRegionSubscriptions
Resource Name:
AD:AD1
Request Action:GET
Response Status:200
---------------------------------------
No.:2
Compartment Name:
Event Time:2020-11-01 23:51:17 JST
Principal Name:XXX@XXXXXX.com
Source:Compartments
Event Name:GetTenancy
Resource Name:XXX
AD:AD1
Request Action:GET
Response Status:200
---------------------------------------
:
:
Headers:
------------
Connection:"close"
Date:"Mon, 02 Nov 2020 13:05:11 GMT"
opc-request-id:"3UEPV8CA12/6E630A5875E90E4FC0DAB6295D56E431/F60307B986E32726F91B
4EAADDD8886E"
Vary:"Accept-Encoding"
Content-Type:"application/json"
X-Content-Type-Options:"nosniff"
Transfer-Encoding:"chunked"
Status Code:
------------
200
No.:801
Compartment Name:zeon
Event Time:2020-11-01 23:52:31 JST
Principal Name:XXXX@XXXXXX.com
Source:ObjectStorage
Event Name:GetNamespace
Resource
Name:/n/?compartmentId=ocid1.tenancy.oc1..XXXXXXXXXXXXXXXXXXXXXXXXXXX
AD:NRT-AD-1
Request Action:GET
Response Status:200
---------------------------------------
No.:802
Compartment Name:zeon
Event Time:2020-11-01 23:54:01 JST
Principal Name:oci-optimizer
Source:Compartments
Event Name:ListRegionSubscriptions
Resource Name:
AD:AD1
Request Action:GET
Response Status:200
---------------------------------------
PL/SQL procedure successfully completed.
Elapsed: 00:00:20.943
無事、11月1日の監査ログを取得することができました。
まとめ
今回はPL/SQL SDKを用いて、Autonomous DatabaseからAuditサービスの監査情報にアクセスしてみました。
PL/SQL内で監査情報を取得できるので、監査情報をデータベースに保存しておくことも可能になります。
日次でこちらのプロシージャを自動を実行して前日分の監査ログをデータベースに保存することで、366日以上前の監査ログも保管しておくことが可能になりますね。