Oracle Cloud Infrastructure Audit ログを収集する

以下でサポートされています。

このドキュメントでは、Amazon S3 を使用して Oracle Cloud Infrastructure Audit ログを Google Security Operations に取り込む方法について説明します。

始める前に

次の前提条件を満たしていることを確認します。

  • Google SecOps インスタンス。
  • 次の権限を持つ Oracle Cloud Infrastructure アカウント:
    • Service Connector Hub
    • Oracle Functions
    • Vault とシークレット
    • 動的グループと IAM ポリシー
    • ロギング
  • 次の作成と管理を行う権限を持つ AWS アカウント:
    • S3 バケット
    • IAM ユーザーとポリシー

Amazon S3 バケットを作成する

  1. AWS Management Console にログインします。
  2. [S3] > [バケットを作成] に移動します。
  3. 次の構成の詳細を入力します。
    • バケット名: 一意の名前(oci-audit-logs-bucket など)を入力します。
    • AWS リージョン: リージョン(us-east-1 など)を選択します。
    • 他のオプションはデフォルト設定のままにします。
  4. [バケットを作成] をクリックします。
  5. 後で使用するために、バケットの名前リージョンを保存します。

OCI Functions 用の IAM ユーザーを AWS に作成する

  1. AWS Management Console にログインします。
  2. [IAM] > [ユーザー] > [ユーザーを追加] に移動します。
  3. 次の構成の詳細を入力します。
    • ユーザー名: ユーザー名を入力します(例: oci-functions-s3-user)。
    • アクセスの種類: [アクセスキー - プログラムによるアクセス] を選択します。
  4. [Next: Permissions] をクリックします。
  5. [既存のポリシーを直接アタッチする] をクリックします。
  6. AmazonS3FullAccess ポリシーを検索して選択します。
  7. [Next: Tags] をクリックします。
  8. [次へ: 確認] をクリックします。
  9. [Create user] をクリックします。
  10. 重要: 成功ページで、次の認証情報をコピーして保存します。
    • アクセスキー ID
    • シークレット アクセスキー

AWS 認証情報を OCI Vault に保存する

AWS 認証情報を安全に保存するには、関数コードにハードコードするのではなく、Oracle Cloud Infrastructure Vault を使用する必要があります。

Vault とマスター暗号鍵を作成する

  1. Oracle Cloud Console にログインします。
  2. [Identity and Security] > [Vault] に移動します。
  3. Vault がない場合は、[Vault を作成] をクリックします。
  4. 次の構成の詳細を入力します。
    • コンパートメントに作成: コンパートメントを選択します。
    • 名前: 名前を入力します(例: oci-functions-vault)。
  5. [Create Vault] をクリックします。
  6. Vault が作成されたら、Vault 名をクリックして開きます。
  7. [マスター暗号鍵] で、[鍵を作成] をクリックします。
  8. 次の構成の詳細を入力します。
    • 保護モード: ソフトウェア
    • 名前: 名前を入力します(例: oci-functions-key)。
    • Key Shape: Algorithm: AES
    • 鍵の形状: 長さ: 256 ビット
  9. [キーを作成] をクリックします。

AWS 認証情報用のシークレットを作成する

  1. Vault の [シークレット] で、[シークレットを作成] をクリックします。
  2. AWS アクセスキーの次の構成の詳細を指定します。
    • コンパートメントで作成: コンパートメントを選択します。
    • 名前: aws-access-key
    • 説明: S3 の AWS アクセスキー
    • 暗号鍵: 作成したマスター暗号鍵を選択します。
    • シークレット タイプの内容: プレーン テキスト
    • シークレットの内容: AWS アクセスキー ID を貼り付けます。
  3. [シークレットの作成] をクリックします。
  4. このシークレットの OCIDocid1.vaultsecret.oc1... のような形式)をコピーして保存します。
  5. [シークレットを作成] をもう一度クリックして、2 つ目のシークレットを作成します。
  6. AWS シークレット キーの次の構成の詳細を指定します。
    • コンパートメントで作成: コンパートメントを選択します。
    • 名前: aws-secret-key
    • 説明: S3 の AWS シークレット キー
    • 暗号鍵: 同じマスター暗号鍵を選択します。
    • シークレット タイプの内容: プレーン テキスト
    • シークレットの内容: AWS シークレット アクセスキーを貼り付けます。
  7. [シークレットの作成] をクリックします。
  8. このシークレットの OCID をコピーして保存します。

OCI Functions の動的グループを作成する

  1. Oracle Cloud Console にログインします。
  2. [ID とセキュリティ> ID > 動的グループ] に移動します。
  3. [動的グループを作成] をクリックします。
  4. 次の構成情報を提供してください。

    • 名前: oci-functions-dynamic-group
    • 説明: Vault シークレットにアクセスする OCI Functions の動的グループ
    • 一致ルール: 次のルールを入力します(<your_compartment_ocid> はコンパートメントの OCID に置き換えます)。

      ALL {resource.type = 'fnfunc', resource.compartment.id = '<your_compartment_ocid>'}
      
  5. [作成] をクリックします。

Vault アクセス用の IAM ポリシーを作成する

  1. Oracle Cloud Console にログインします。
  2. [ID とセキュリティ> ID > ポリシー] に移動します。
  3. ポリシーを作成するコンパートメントを選択します。
  4. [Create Policy] をクリックします。
  5. 次の構成情報を提供してください。

    • 名前: oci-functions-vault-access-policy
    • 説明: OCI Functions が Vault からシークレットを読み取れるようにする
    • ポリシー ビルダー: [手動エディタを表示] を切り替えます。
    • ポリシー ステートメント: 次のように入力します(<compartment_name> はコンパートメント名に置き換えます)。

      allow dynamic-group oci-functions-dynamic-group to manage secret-family in compartment <compartment_name>
      
  6. [作成] をクリックします。

OCI 関数アプリケーションを作成する

  1. Oracle Cloud Console にログインします。
  2. [Developer Services] > [Applications]([Functions] の下) に移動します。
  3. [アプリケーションを作成] をクリックします。
  4. 次の構成の詳細を入力します。
    • 名前: 名前を入力します(例: oci-logs-to-s3-app)。
    • VCN: コンパートメント内の VCN を選択します。
    • サブネット: 1 つ以上のサブネットを選択します。
  5. [作成] をクリックします。

OCI 関数を作成してデプロイする

  1. Oracle Cloud Console で、右上にある Cloud Shell アイコンをクリックします。
  2. Cloud Shell が初期化されるまで待ちます。

関数を作成する

  1. Cloud Shell で、関数用の新しいディレクトリを作成します。

    mkdir pushlogs
    cd pushlogs
    
  2. 新しい Python 関数を初期化します。

    fn init --runtime python
    
  3. これにより、func.pyfunc.yamlrequirements.txt の 3 つのファイルが作成されます。

func.py を更新する

  • func.py の内容を次のコードに置き換えます。

    import io
    import json
    import logging
    import boto3
    import oci
    import base64
    import os
    from fdk import response
    
    def handler(ctx, data: io.BytesIO = None):
        """
        OCI Function to push audit logs from OCI Logging to AWS S3
        """
        try:
            # Parse incoming log data from Service Connector
            funDataStr = data.read().decode('utf-8')
            funData = json.loads(funDataStr)
    
            logging.getLogger().info(f"Received {len(funData)} log entries")
    
            # Replace these with your actual OCI Vault secret OCIDs
            secret_key_id = "ocid1.vaultsecret.oc1..<your_secret_key_ocid>"
            access_key_id = "ocid1.vaultsecret.oc1..<your_access_key_ocid>"
    
            # Replace with your S3 bucket name
            s3_bucket_name = "oci-audit-logs-bucket"
    
            # Use Resource Principals for OCI authentication
            signer = oci.auth.signers.get_resource_principals_signer()
            secret_client = oci.secrets.SecretsClient({}, signer=signer)
    
            def read_secret_value(secret_client, secret_id):
                """Retrieve and decode secret value from OCI Vault"""
                response = secret_client.get_secret_bundle(secret_id)
                base64_secret_content = response.data.secret_bundle_content.content
                base64_secret_bytes = base64_secret_content.encode('ascii')
                base64_message_bytes = base64.b64decode(base64_secret_bytes)
                secret_content = base64_message_bytes.decode('ascii')
                return secret_content
    
            # Retrieve AWS credentials from OCI Vault
            awsaccesskey = read_secret_value(secret_client, access_key_id)
            awssecretkey = read_secret_value(secret_client, secret_key_id)
    
            # Initialize boto3 session with AWS credentials
            session = boto3.Session(
                aws_access_key_id=awsaccesskey,
                aws_secret_access_key=awssecretkey
            )
            s3 = session.resource('s3')
    
            # Process each log entry
            for i in range(0, len(funData)):
                # Use timestamp as filename
                filename = funData[i].get('time', f'log_{i}')
                # Remove special characters from filename
                filename = filename.replace(':', '-').replace('.', '-')
    
                logging.getLogger().info(f"Processing log entry: {filename}")
    
                # Write log entry to temporary file
                temp_file = f'/tmp/{filename}.json'
                with open(temp_file, 'w', encoding='utf-8') as f:
                    json.dump(funData[i], f, ensure_ascii=False, indent=4)
    
                # Upload to S3
                s3_key = f'{filename}.json'
                s3.meta.client.upload_file(
                    Filename=temp_file,
                    Bucket=s3_bucket_name,
                    Key=s3_key
                )
    
                logging.getLogger().info(f"Uploaded {s3_key} to S3 bucket {s3_bucket_name}")
    
                # Clean up temporary file
                os.remove(temp_file)
    
            return response.Response(
                ctx,
                response_data=json.dumps({
                    "status": "success",
                    "processed_logs": len(funData)
                }),
                headers={"Content-Type": "application/json"}
            )
    
        except Exception as e:
            logging.getLogger().error(f"Error processing logs: {str(e)}")
            return response.Response(
                ctx,
                response_data=json.dumps({
                    "status": "error",
                    "message": str(e)
                }),
                headers={"Content-Type": "application/json"},
                status_code=500
            )
    
    • secret_key_id は、AWS シークレット キーの実際の Vault シークレット OCID に置き換えます。
    • access_key_id は、AWS アクセスキーの実際の Vault シークレット OCID に置き換えます。
    • s3_bucket_name は、実際の S3 バケット名に置き換えます。

func.yaml を更新する

func.yaml の内容を次のように置き換えます。

  schema_version: 20180708
  name: pushlogs
  version: 0.0.1
  runtime: python
  build_image: fnproject/python:3.9-dev
  run_image: fnproject/python:3.9
  entrypoint: /python/bin/fdk /function/func.py handler
  memory: 256

requirements.txt を更新する

  • requirements.txt の内容を次のように置き換えます。

    fdk>=0.1.56
    boto3
    oci
    

関数をデプロイする

  1. アプリケーションを使用するように Fn コンテキストを設定します。

    fn use context <region-context>
    fn update context oracle.compartment-id <compartment-ocid>
    
  2. 関数をデプロイします。

    fn -v deploy --app oci-logs-to-s3-app
    
  3. デプロイが完了するまで待ちます。関数が正常にデプロイされたことを示す出力が表示されます。

  4. 関数が作成されたことを確認します。

    fn list functions oci-logs-to-s3-app
    

OCI 監査ログを関数に送信するサービス コネクタを作成する

  1. Oracle Cloud Console にログインします。
  2. [分析と AI] > [メッセージング] > [Service Connector Hub] に移動します。
  3. サービス コネクタを作成するコンパートメントを選択します。
  4. [サービス コネクタを作成] をクリックします。

Service Connector の詳細を構成する

  1. 次の構成情報を提供してください。

サービス コネクタ情報: * コネクタ名: わかりやすい名前を入力します(例: audit-logs-to-s3-connector)。 * 説明: 省略可能な説明(例: 「OCI 監査ログを AWS S3 に転送する」)。 * リソース コンパートメント: コンパートメントを選択します。

ソースを構成する

  1. [ソースを構成] で、次の操作を行います。
    • ソース: [Logging] を選択します。
    • コンパートメント: 監査ログを含むコンパートメントを選択します。
    • ロググループ: _Audit を選択します(これは監査ログのデフォルトのロググループです)。
    • ログ: [+ 別のログ] をクリックします。
    • コンパートメントの監査ログ(_Audit_Include_Subcompartment など)を選択します。

ターゲットを構成する

  1. [Configure Target] で、次の操作を行います。
    • ターゲット: [関数] を選択します。
    • コンパートメント: 関数アプリケーションを含むコンパートメントを選択します。
    • 関数アプリ: oci-logs-to-s3-app(先ほど作成したアプリケーション)を選択します。
    • 関数: pushlogs(デプロイした関数)を選択します。

ポリシーを構成

  1. [ポリシーを構成] で次の操作を行います。

    • 表示された必要な IAM ポリシー ステートメントを確認します。
    • [作成] をクリックして、必要なポリシーを自動的に作成します。
  2. [作成] をクリックして、サービス コネクタを作成します。

  3. サービス コネクタが作成されて有効になるまで待ちます。ステータスが [アクティブ] に変わります。

ログが AWS S3 に push されていることを確認する

  1. Oracle Cloud Console にログインします。
  2. 監査ログを生成するアクション(リソースの作成や変更など)を実行します。
  3. ログが処理されるまで 2 ~ 5 分待ちます。
  4. AWS Management Console にログインします。
  5. [S3] > [Buckets] に移動します。
  6. バケット(oci-audit-logs-bucket など)をクリックします。
  7. JSON ログファイルがバケットに表示されていることを確認します。

Google SecOps 用に AWS S3 バケットと IAM を構成する

Chronicle 用の IAM ユーザーを作成する

  1. AWS Management Console にログインします。
  2. [IAM] > [ユーザー] > [ユーザーを追加] に移動します。
  3. 次の構成の詳細を入力します。
    • ユーザー名: 「chronicle-s3-reader」と入力します。
    • アクセスの種類: [アクセスキー - プログラムによるアクセス] を選択します。
  4. [Next: Permissions] をクリックします。
  5. [既存のポリシーを直接アタッチする] をクリックします。
  6. AmazonS3ReadOnlyAccess ポリシーを検索して選択します。
  7. [Next: Tags] をクリックします。
  8. [次へ: 確認] をクリックします。
  9. [Create user] をクリックします。
  10. [CSV ファイルをダウンロード] をクリックして、アクセスキー IDシークレット アクセスキーを保存します。
  11. [閉じる] をクリックします。

省略可: 最小権限アクセスのカスタム IAM ポリシーを作成する

特定のバケットへのアクセスのみを制限する場合は、次の操作を行います。

  1. [IAM] > [ポリシー] > [ポリシーを作成] に移動します。
  2. [JSON] タブをクリックします。
  3. 次のポリシーを入力します。

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "s3:GetObject",
            "s3:ListBucket"
          ],
          "Resource": [
            "arn:aws:s3:::oci-audit-logs-bucket",
            "arn:aws:s3:::oci-audit-logs-bucket/*"
          ]
        }
      ]
    }
    
    • oci-audit-logs-bucket は、使用するバケット名に置き換えてください。
  4. [Next: Tags] をクリックします。

  5. [次へ: 確認] をクリックします。

  6. 次の構成情報を提供してください。

    • 名前: chronicle-s3-read-policy
    • 説明: OCI 監査ログバケットへの読み取り専用アクセス
  7. [ポリシーを作成] をクリックします。

  8. [IAM > ユーザー] に戻り、chronicle-s3-reader ユーザーを選択します。

  9. [権限を追加>ポリシーを直接アタッチする] をクリックします。

  10. chronicle-s3-read-policy を検索して選択します。

  11. 以前に追加した場合は、AmazonS3ReadOnlyAccess ポリシーを削除します。

  12. [権限を追加] をクリックします。

Oracle Cloud Audit ログを取り込むように Google SecOps でフィードを構成する

  1. [SIEM 設定] > [フィード] に移動します。
  2. [Add New Feed] をクリックします。
  3. 次のページで [単一のフィードを設定] をクリックします。
  4. [フィード名] フィールドに、フィードの名前を入力します(例: Oracle Cloud Audit Logs)。
  5. [ソースタイプ] として [Amazon S3 V2] を選択します。
  6. [ログタイプ] として [Oracle Cloud Infrastructure] を選択します。
  7. [次へ] をクリックします。
  8. 次の入力パラメータの値を指定します。
    • S3 URI: S3 バケット URI(例: s3://oci-audit-logs-bucket/)を入力します。
    • Source deletion option: 必要に応じて削除オプションを選択します。
      • なし: テストと初期設定におすすめします。
      • 転送されたファイルを削除する: 取り込みが成功した後にファイルを削除します(本番環境でストレージ費用を管理する場合に使用します)。
    • ファイルの最大経過日数: 指定した日数以内に変更されたファイルを含めます。デフォルトは 180 日です。
    • アクセスキー ID: 作成した Chronicle IAM ユーザーのアクセスキー ID を入力します。
    • シークレット アクセスキー: 作成した Chronicle IAM ユーザーのシークレット アクセスキーを入力します。
    • アセットの名前空間: アセットの名前空間
    • Ingestion labels: このフィードのイベントに適用されるラベル。
  9. [次へ] をクリックします。
  10. [Finalize] 画面で新しいフィードの設定を確認し、[送信] をクリックします。

UDM マッピング テーブル

ログフィールド UDM マッピング ロジック
data.request.headers.authorization.0 event.idm.read_only_udm.additional.fields data.request.headers.authorization.0 から取得した値が、キー「Request Headers Authorization」の Key-Value ペアとして追加されます。
data.compartmentId event.idm.read_only_udm.additional.fields data.compartmentId から取得された値が、キー「compartmentId」の Key-Value ペアとして追加されます。
data.compartmentName event.idm.read_only_udm.additional.fields data.compartmentName から取得された値が、キー「compartmentName」で Key-Value ペアとして追加されます。
data.response.headers.Content-Length.0 event.idm.read_only_udm.additional.fields data.response.headers.Content-Length.0 から取得した値が、キー「Response Headers Content-Length」の Key-Value ペアとして追加されます。
data.response.headers.Content-Type.0 event.idm.read_only_udm.additional.fields data.response.headers.Content-Type.0 から取得された値が、キー「Response Headers Content-Type」で Key-Value ペアとして追加されます。
data.eventGroupingId event.idm.read_only_udm.additional.fields data.eventGroupingId から取得された値が、キー「eventGroupingId」で Key-Value ペアとして追加されます。
oracle.tenantiddata.identity.tenantId event.idm.read_only_udm.additional.fields 値は、存在する場合は oracle.tenantid から取得され、存在しない場合は data.identity.tenantId から取得されます。キーが「tenantId」の Key-Value ペアとして追加されます。
data.message event.idm.read_only_udm.metadata.description data.message から取得された値。
time event.idm.read_only_udm.metadata.event_timestamp time から取得された値が ISO8601 タイムスタンプとして解析されます。
event.idm.read_only_udm.metadata.event_type デフォルトでは GENERIC_EVENT に設定されています。プリンシパル(IP またはホスト名)とターゲット IP が存在する場合は NETWORK_CONNECTION に設定します。プリンシパルのみが存在する場合は STATUS_UPDATE に設定します。
time event.idm.read_only_udm.metadata.ingested_timestamp oracle.ingestedtime が空でない場合、値は time フィールドから取得され、ISO8601 タイムスタンプとして解析されます。
oracle.tenantid event.idm.read_only_udm.metadata.product_deployment_id oracle.tenantid から取得された値。
type event.idm.read_only_udm.metadata.product_event_type type から取得された値。
oracle.logid event.idm.read_only_udm.metadata.product_log_id oracle.logid から取得された値。
specversion event.idm.read_only_udm.metadata.product_version specversion から取得された値。
data.request.action event.idm.read_only_udm.network.http.method data.request.action から取得された値。
data.identity.userAgent event.idm.read_only_udm.network.http.parsed_user_agent data.identity.userAgent から取得された値が解析されます。
data.response.status event.idm.read_only_udm.network.http.response_code data.response.status から取得された値が整数に変換されます。
data.protocol event.idm.read_only_udm.network.ip_protocol data.protocol の数値は文字列表現に変換されます(例: 6 は「TCP」、17 は「UDP」になります)。
data.bytesOut event.idm.read_only_udm.network.sent_bytes data.bytesOut から取得された値が符号なし整数に変換されます。
data.packets event.idm.read_only_udm.network.sent_packets data.packets から取得された値が整数に変換されます。
data.identity.consoleSessionId event.idm.read_only_udm.network.session_id data.identity.consoleSessionId から取得された値。
id event.idm.read_only_udm.principal.asset.product_object_id id から取得された値。
source event.idm.read_only_udm.principal.hostname source から取得された値。
data.sourceAddressdata.identity.ipAddress event.idm.read_only_udm.principal.ip data.sourceAddressdata.identity.ipAddress の値がこのフィールドに統合されます。
data.sourcePort event.idm.read_only_udm.principal.port data.sourcePort から取得された値が整数に変換されます。
data.request.headers.X-Forwarded-For.0 event.idm.read_only_udm.principal.resource.attribute.labels data.request.headers.X-Forwarded-For.0 から取得した値が、キー「x forward」の Key-Value ペアとして追加されます。
oracle.compartmentid event.idm.read_only_udm.principal.resource.attribute.labels oracle.compartmentid から取得した値が、キー「compartmentid」の Key-Value ペアとして追加されます。
oracle.loggroupid event.idm.read_only_udm.principal.resource.attribute.labels oracle.loggroupid から取得された値が、キー「loggroupid」の Key-Value ペアとして追加されます。
oracle.vniccompartmentocid event.idm.read_only_udm.principal.resource.attribute.labels oracle.vniccompartmentocid から取得した値が、キー「vniccompartmentocid」の Key-Value ペアとして追加されます。
oracle.vnicocid event.idm.read_only_udm.principal.resource.attribute.labels oracle.vnicocid から取得された値が、キー「vnicocid」の Key-Value ペアとして追加されます。
oracle.vnicsubnetocid event.idm.read_only_udm.principal.resource.attribute.labels oracle.vnicsubnetocid から取得した値が、キー「vnicsubnetocid」の Key-Value ペアとして追加されます。
data.flowid event.idm.read_only_udm.principal.resource.product_object_id data.flowid から取得された値。
data.identity.credentials event.idm.read_only_udm.principal.user.attribute.labels 値は data.identity.credentials から取得され、キーが「credentials」の Key-Value ペアとして追加されます。
data.identity.principalName event.idm.read_only_udm.principal.user.user_display_name data.identity.principalName から取得された値。
data.identity.principalId event.idm.read_only_udm.principal.user.userid data.identity.principalId から取得された値。
data.action event.idm.read_only_udm.security_result.action デフォルトでは UNKNOWN_ACTION に設定されています。data.action が「REJECT」の場合、これは BLOCK に設定されます。data.action が「ACCEPT」の場合、これは ALLOW に設定されます。
data.endTime event.idm.read_only_udm.security_result.detection_fields data.endTime から取得された値が、キー「endTime」で Key-Value ペアとして追加されます。
data.startTime event.idm.read_only_udm.security_result.detection_fields data.startTime から取得された値が、キー「startTime」の Key-Value ペアとして追加されます。
data.status event.idm.read_only_udm.security_result.detection_fields data.status から取得された値が、キー「status」の Key-Value ペアとして追加されます。
data.version event.idm.read_only_udm.security_result.detection_fields data.version から値が取得され、キーが「version」の Key-Value ペアとして追加されます。
data.destinationAddress event.idm.read_only_udm.target.ip data.destinationAddress から取得された値。
data.destinationPort event.idm.read_only_udm.target.port data.destinationPort から取得された値が整数に変換されます。
data.request.path event.idm.read_only_udm.target.url data.request.path から取得された値。
event.idm.read_only_udm.metadata.product_name 「ORACLE CLOUD AUDIT」に設定します。
event.idm.read_only_udm.metadata.vendor_name 「ORACLE」に設定します。

さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。