Snowflake 로그 수집

다음에서 지원:

이 문서에서는 Snowflake 로그를 Google Security Operations에 수집하는 방법을 설명합니다. Cloud Storage V2 (권장) 또는 Amazon S3 V2의 두 가지 방법을 사용하여 수집을 구성할 수 있습니다. 두 방법 모두 Snowflake 측에서 동일한 메커니즘을 사용합니다. 예약된 작업이 계정 사용량 데이터를 외부 스테이지로 언로드하고 Google SecOps가 피드로 내보낸 파일을 읽습니다.

Snowflake는 SNOWFLAKE.ACCOUNT_USAGE 스키마에 계정 활동을 저장하는 클라우드 데이터 플랫폼입니다. LOGIN_HISTORY 뷰는 클라이언트 IP 주소, 인증 요소, 실패 이유 등 인증 시도를 기록합니다. QUERY_HISTORY 뷰는 사용자, 역할, 웨어하우스, 터치된 객체를 비롯하여 계정에서 실행된 모든 명령문을 기록합니다.

시작하기 전에

다음 기본 요건이 충족되었는지 확인합니다.

  • Google SecOps 인스턴스
  • 스토리지 통합 (기본적으로 ACCOUNTADMIN만 이 권한을 보유함), 데이터베이스, 웨어하우스, 스테이지, 작업을 만들 수 있는 역할로 Snowflake에 액세스
  • Cloud Storage V2: Cloud Storage API가 사용 설정되어 있고 버킷을 만들고, Identity and Access Management (IAM) 역할을 만들고, 버킷 IAM 정책을 관리할 수 있는 권한이 있는 Google Cloud 프로젝트
  • Amazon S3 V2: S3 버킷, IAM 정책, IAM 역할, IAM 사용자를 생성하기 위한 AWS에 대한 액세스 권한

Snowflake 계정 사용 데이터에 대한 액세스 권한 부여

SNOWFLAKE.ACCOUNT_USAGE 뷰는 액세스 권한이 명시적으로 부여될 때까지 ACCOUNTADMIN에서만 읽을 수 있습니다. 내보내기를 위한 전용 역할을 만들고 이 문서에서 내보내는 뷰를 포함하는 두 데이터베이스 역할을 부여합니다.

  1. Snowflake에 로그인하고 워크시트를 엽니다.
  2. 내보내기 역할을 만들고 다음과 같이 계정 사용량 뷰에 대한 읽기 액세스 권한을 부여합니다.

    USE ROLE ACCOUNTADMIN;
    
    CREATE ROLE IF NOT EXISTS SECOPS_EXPORTER;
    
    GRANT DATABASE ROLE SNOWFLAKE.SECURITY_VIEWER TO ROLE SECOPS_EXPORTER;
    GRANT DATABASE ROLE SNOWFLAKE.GOVERNANCE_VIEWER TO ROLE SECOPS_EXPORTER;
    
  3. 내보내기에서 사용하는 데이터베이스, 스키마, 웨어하우스를 만들고 다음과 같이 역할에 부여합니다.

    CREATE DATABASE IF NOT EXISTS SECOPS_EXPORT;
    CREATE SCHEMA IF NOT EXISTS SECOPS_EXPORT.ACTIVITY;
    
    CREATE WAREHOUSE IF NOT EXISTS SECOPS_EXPORT_WH
        WITH WAREHOUSE_SIZE = 'XSMALL'
        AUTO_SUSPEND = 60
        AUTO_RESUME = TRUE
        INITIALLY_SUSPENDED = TRUE;
    
    GRANT USAGE ON DATABASE SECOPS_EXPORT TO ROLE SECOPS_EXPORTER;
    GRANT USAGE, CREATE STAGE, CREATE TABLE, CREATE PROCEDURE, CREATE TASK, CREATE FILE FORMAT
        ON SCHEMA SECOPS_EXPORT.ACTIVITY TO ROLE SECOPS_EXPORTER;
    GRANT USAGE, OPERATE ON WAREHOUSE SECOPS_EXPORT_WH TO ROLE SECOPS_EXPORTER;
    GRANT EXECUTE TASK ON ACCOUNT TO ROLE SECOPS_EXPORTER;
    GRANT ROLE SECOPS_EXPORTER TO USER <YOUR_USER>;
    
    • <YOUR_USER>을 내보내기를 소유한 Snowflake 사용자로 바꿉니다.

Cloud Storage 버킷 만들기

  1. Google Cloud 콘솔로 이동합니다.
  2. 프로젝트를 선택하거나 새 프로젝트를 만듭니다.
  3. 탐색 메뉴에서 Cloud Storage> 버킷으로 이동합니다.
  4. 버킷 만들기를 클릭합니다.
  5. 다음 구성 세부정보를 제공합니다.

    설정 값
    버킷 이름 지정 전역적으로 고유한 이름 (예: snowflake-activity-logs)을 입력합니다.
    위치 유형 필요에 따라 선택 (리전, 이중 리전, 멀티 리전)
    위치 위치를 선택합니다 (예: us-central1).
    스토리지 클래스 Standard (자주 액세스하는 로그에 권장)
    액세스 제어 균일 (권장)
    보호 조치 선택사항: 객체 버전 관리 또는 보관 정책 사용 설정
  6. 만들기를 클릭합니다.

Snowflake용 커스텀 Cloud Storage 역할 만들기

  1. Google Cloud 콘솔에서 IAM 및 관리자 > 역할로 이동합니다.
  2. 역할 만들기를 클릭합니다.
  3. 다음 구성 세부정보를 제공합니다.
    • 제목: Snowflake Unload를 입력합니다.
    • ID: snowflake_unload를 입력합니다.
    • 역할 출시 단계: 정식 버전을 선택합니다.
  4. 권한 추가를 클릭하고 다음 권한을 추가합니다.
    • storage.buckets.get
    • storage.objects.create
    • storage.objects.delete
    • storage.objects.list
  5. 만들기를 클릭합니다.

Cloud Storage용 Snowflake 스토리지 통합 만들기

  1. Snowflake 워크시트에서 다음과 같이 스토리지 통합을 만듭니다.

    USE ROLE ACCOUNTADMIN;
    
    CREATE STORAGE INTEGRATION SECOPS_GCS_INT
        TYPE = EXTERNAL_STAGE
        STORAGE_PROVIDER = 'GCS'
        ENABLED = TRUE
        STORAGE_ALLOWED_LOCATIONS = ('gcs://snowflake-activity-logs/snowflake/');
    
    GRANT USAGE ON INTEGRATION SECOPS_GCS_INT TO ROLE SECOPS_EXPORTER;
    
    • 여기에서 snowflake-activity-logs을 내 버킷 이름으로 바꿉니다.
  2. 다음과 같이 통합을 위해 Snowflake에서 만든 서비스 계정을 가져옵니다.

    DESC STORAGE INTEGRATION SECOPS_GCS_INT;
    
  3. STORAGE_GCP_SERVICE_ACCOUNT 속성의 값을 복사합니다. 값의 형식은 다음과 같습니다.

    service-account-id@project1-123456.iam.gserviceaccount.com
    

Snowflake 서비스 계정에 버킷 액세스 권한 부여

  1. Google Cloud 콘솔에서 Cloud Storage > 버킷으로 이동합니다.
  2. 만든 버킷 (예: snowflake-activity-logs)을 클릭합니다.
  3. 권한 탭으로 이동합니다.
  4. 액세스 권한 부여를 클릭합니다.
  5. 다음 구성 세부정보를 제공합니다.
    • 주 구성원 추가: STORAGE_GCP_SERVICE_ACCOUNT 값을 붙여넣습니다.
    • 역할 할당: Snowflake 언로드를 선택합니다.
  6. 저장을 클릭합니다.

파일 형식 및 외부 스테이지 만들기

  1. Snowflake 워크시트에서 버킷에 쓰는 파일 형식과 스테이지를 다음과 같이 만듭니다.

    USE ROLE SECOPS_EXPORTER;
    USE SCHEMA SECOPS_EXPORT.ACTIVITY;
    
    CREATE OR REPLACE FILE FORMAT SECOPS_JSON_FORMAT
        TYPE = JSON;
    
    CREATE OR REPLACE STAGE SECOPS_EXPORT_STAGE
        URL = 'gcs://snowflake-activity-logs/snowflake/'
        STORAGE_INTEGRATION = SECOPS_GCS_INT
        FILE_FORMAT = SECOPS_JSON_FORMAT;
    

내보내기 상태 테이블 만들기

내보내기는 각 뷰에서 읽은 거리를 추적합니다. 이 워터마크가 없으면 실행할 때마다 전체 뷰가 다시 내보내지고 동일한 이벤트가 다시 수집됩니다.

  1. 다음과 같이 상태 테이블을 만들고 시드합니다.

    CREATE TABLE IF NOT EXISTS SECOPS_EXPORT_STATE (
        VIEW_NAME STRING NOT NULL,
        LAST_EXPORTED TIMESTAMP_LTZ NOT NULL,
        WINDOW_END TIMESTAMP_LTZ
    );
    
    INSERT INTO SECOPS_EXPORT_STATE (VIEW_NAME, LAST_EXPORTED)
        SELECT 'LOGIN_HISTORY', DATEADD('day', -7, CURRENT_TIMESTAMP())
        UNION ALL
        SELECT 'QUERY_HISTORY', DATEADD('day', -7, CURRENT_TIMESTAMP());
    

내보내기 절차 만들기

  1. 다음과 같이 두 뷰를 모두 언로드하고 워터마크를 진행하는 절차를 만듭니다.

    CREATE OR REPLACE PROCEDURE SECOPS_EXPORT_ACTIVITY()
    RETURNS STRING
    LANGUAGE SQL
    AS
    $$
    BEGIN
        UPDATE SECOPS_EXPORT_STATE
            SET WINDOW_END = DATEADD('hour', -3, CURRENT_TIMESTAMP());
    
        COPY INTO @SECOPS_EXPORT_STAGE/login_history/
            FROM (
                SELECT OBJECT_CONSTRUCT(
                    'application', 'snowflake',
                    'log_type', 'login_history',
                    'EVENT_TIMESTAMP', EVENT_TIMESTAMP,
                    'EVENT_TYPE', EVENT_TYPE,
                    'USER_NAME', USER_NAME,
                    'CLIENT_IP', CLIENT_IP,
                    'REPORTED_CLIENT_TYPE', REPORTED_CLIENT_TYPE,
                    'REPORTED_CLIENT_VERSION', REPORTED_CLIENT_VERSION,
                    'FIRST_AUTHENTICATION_FACTOR', FIRST_AUTHENTICATION_FACTOR,
                    'SECOND_AUTHENTICATION_FACTOR', SECOND_AUTHENTICATION_FACTOR,
                    'IS_SUCCESS', IS_SUCCESS,
                    'ERROR_CODE', ERROR_CODE,
                    'ERROR_MESSAGE', ERROR_MESSAGE)
                FROM SNOWFLAKE.ACCOUNT_USAGE.LOGIN_HISTORY
                WHERE EVENT_TIMESTAMP > (SELECT LAST_EXPORTED FROM SECOPS_EXPORT_STATE WHERE VIEW_NAME = 'LOGIN_HISTORY')
                    AND EVENT_TIMESTAMP <= (SELECT WINDOW_END FROM SECOPS_EXPORT_STATE WHERE VIEW_NAME = 'LOGIN_HISTORY')
            )
            FILE_FORMAT = (TYPE = JSON)
            INCLUDE_QUERY_ID = TRUE;
    
        UPDATE SECOPS_EXPORT_STATE
            SET LAST_EXPORTED = WINDOW_END
            WHERE VIEW_NAME = 'LOGIN_HISTORY';
    
        COPY INTO @SECOPS_EXPORT_STAGE/query_history/
            FROM (
                SELECT OBJECT_CONSTRUCT(
                    'application', 'snowflake',
                    'log_type', 'query_history',
                    'START_TIME', START_TIME,
                    'END_TIME', END_TIME,
                    'QUERY_ID', QUERY_ID,
                    'QUERY_TYPE', QUERY_TYPE,
                    'EXECUTION_STATUS', EXECUTION_STATUS,
                    'ERROR_MESSAGE', ERROR_MESSAGE,
                    'USER_NAME', USER_NAME,
                    'ROLE_NAME', ROLE_NAME,
                    'WAREHOUSE_NAME', WAREHOUSE_NAME,
                    'WAREHOUSE_SIZE', WAREHOUSE_SIZE,
                    'DATABASE_NAME', DATABASE_NAME,
                    'SCHEMA_NAME', SCHEMA_NAME,
                    'SESSION_ID', SESSION_ID,
                    'BYTES_SCANNED', BYTES_SCANNED,
                    'ROWS_PRODUCED', ROWS_PRODUCED,
                    'TOTAL_ELAPSED_TIME', TOTAL_ELAPSED_TIME)
                FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
                WHERE START_TIME > (SELECT LAST_EXPORTED FROM SECOPS_EXPORT_STATE WHERE VIEW_NAME = 'QUERY_HISTORY')
                    AND START_TIME <= (SELECT WINDOW_END FROM SECOPS_EXPORT_STATE WHERE VIEW_NAME = 'QUERY_HISTORY')
            )
            FILE_FORMAT = (TYPE = JSON)
            INCLUDE_QUERY_ID = TRUE;
    
        UPDATE SECOPS_EXPORT_STATE
            SET LAST_EXPORTED = WINDOW_END
            WHERE VIEW_NAME = 'QUERY_HISTORY';
    
        RETURN 'Export completed';
    END;
    $$;
    

절차의 각 요소에는 이유가 있습니다.

  • 창은 현재 시간보다 3시간 뒤에 닫힙니다. Snowflake는 최대 2시간의 지연 시간으로 LOGIN_HISTORY를 채우고 최대 45분으로 QUERY_HISTORY를 채우므로 지금 종료되는 윈도우는 뷰가 아직 구체화되지 않은 행을 건너뜁니다. 따라서 이벤트가 발생한 후 약 3시간이 지나면 Google SecOps에 도달합니다. 지연 시간을 줄이면 완전성이 신선도로 바뀝니다.
  • WINDOW_END는 언로드 전에 테이블에 작성되므로 COPY INTO 문에서 사용되는 값과 LAST_EXPORTED에 다시 작성되는 값이 동일합니다. 두 번째 문에서 현재 시간을 다시 계산하면 그 사이에 발생한 모든 항목이 건너뛰게 됩니다.
  • 각 LAST_EXPORTED 업데이트는 자체 COPY INTO 문 뒤에 실행됩니다. 언로드가 실패하면 절차가 중지되고 워터마크가 원래 위치에 유지되며 다음 실행에서는 건너뛰지 않고 해당 창이 반복됩니다.
  • INCLUDE_QUERY_ID = TRUE는 모든 파일 이름에 UUID를 추가합니다. 이 옵션이 없으면 언로드된 파일의 이름이 data_0_0_0로 지정되고 동일한 경로로 반복되는 내보내기가 충돌하여 Snowflake에서 스테이지의 중복 데이터 소스로 문서화됩니다.

내보내기 작업 예약

  1. 다음과 같이 작업을 만들고 시작합니다.

    CREATE OR REPLACE TASK SECOPS_EXPORT_TASK
        WAREHOUSE = SECOPS_EXPORT_WH
        SCHEDULE = 'USING CRON 0 * * * * UTC'
        AS CALL SECOPS_EXPORT_ACTIVITY();
    
    ALTER TASK SECOPS_EXPORT_TASK RESUME;
    
  2. 다음과 같이 일정을 기다리지 않고 설정을 확인하기 위해 작업을 한 번 실행합니다.

    EXECUTE TASK SECOPS_EXPORT_TASK;
    
  3. 다음과 같이 실행 결과와 단계에 도달한 파일을 확인합니다.

    SELECT NAME, STATE, ERROR_MESSAGE, SCHEDULED_TIME
    FROM TABLE(INFORMATION_SCHEMA.TASK_HISTORY(TASK_NAME => 'SECOPS_EXPORT_TASK'))
    ORDER BY SCHEDULED_TIME DESC
    LIMIT 5;
    
    LIST @SECOPS_EXPORT_STAGE;
    

Google SecOps 서비스 계정 가져오기

Google SecOps는 고유한 서비스 계정을 사용하여 Cloud Storage 버킷에서 데이터를 읽습니다. 이 서비스 계정에 버킷 액세스 권한을 부여해야 합니다.

  1. SIEM 설정 > 피드로 이동합니다.
  2. 새 피드 추가를 클릭합니다.
  3. 단일 피드 구성을 클릭합니다.
  4. 피드 이름 필드에 피드 이름을 입력합니다(예: Snowflake activity logs).
  5. 소스 유형으로 Google Cloud Storage V2를 선택합니다.
  6. 로그 유형으로 Snowflake를 선택합니다.
  7. 서비스 계정 가져오기를 클릭합니다.
  8. 고유한 서비스 계정 이메일이 표시됩니다. 예를 들면 다음과 같습니다.

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  9. 다음 단계에서 사용할 수 있도록 이 이메일 주소를 복사합니다.

  10. 다음을 클릭합니다.

  11. 다음 입력 매개변수의 값을 지정합니다.

    • 스토리지 버킷 URL: 다음 접두사 경로를 사용하여 Cloud Storage 버킷 URI를 입력합니다.

      gs://snowflake-activity-logs/snowflake/
      
    • 소스 삭제 옵션: 환경설정에 따라 삭제 옵션을 선택합니다.

      • 파일 삭제 안함: 소스에서 파일을 삭제하지 않습니다 (테스트에 권장).
      • 전송된 파일 및 빈 디렉터리 삭제: 가져오기가 완료되면 소스에서 파일과 빈 디렉터리를 삭제합니다.
    • 최대 파일 기간: 지난 일수 동안 수정된 파일을 포함합니다 (기본값은 180일).

    • 애셋 네임스페이스: 애셋 네임스페이스

    • 수집 라벨: 이 피드의 이벤트에 적용할 라벨

  12. 다음을 클릭합니다.

  13. 확정 화면에서 새 피드 구성을 검토한 다음 제출을 클릭합니다.

Google SecOps 서비스 계정에 IAM 권한 부여

Google SecOps 서비스 계정에는 Cloud Storage 버킷에 대한 두 가지 역할이 필요합니다. 로그 객체를 읽는 Storage Object Viewer 역할과 버킷 메타데이터를 읽는 버킷 수준 역할입니다.

  1. Cloud Storage> 버킷으로 이동합니다.
  2. 버킷 이름을 클릭합니다.
  3. 권한 탭으로 이동합니다.
  4. 액세스 권한 부여를 클릭합니다.
  5. 다음 구성 세부정보를 제공합니다.
    • 주 구성원 추가: Google SecOps 서비스 계정 이메일을 붙여넣습니다.
    • 역할 할당: 다음 두 가지를 모두 선택합니다.
      • 스토리지 객체 뷰어: 로그 객체를 읽습니다.
      • 스토리지 기존 버킷 리더: 버킷 메타데이터를 읽습니다. 전송된 파일 및 빈 디렉터리 삭제 삭제 옵션을 선택한 경우 삭제 권한도 부여하는 스토리지 기존 버킷 작성자를 대신 선택합니다.
  6. 저장을 클릭합니다.

방법 2: Amazon S3 V2

로그가 Amazon S3에 저장되어야 하는 경우 이 방법을 사용하세요. 스토리지 통합과 스테이지를 제외하고 Snowflake 측은 동일하므로 방법 1의 내보내기 절차와 작업은 변경 없이 재사용됩니다.

Amazon S3 버킷 구성

  1. 이 사용자 가이드(버킷 만들기)에 따라 Amazon S3 버킷을 만듭니다.
  2. 나중에 참조할 수 있도록 버킷 이름과 리전을 저장합니다. 예를 들면 snowflake-activity-logs입니다.

Snowflake AWS IAM 정책 구성

  1. AWS Management Console에 로그인합니다.
  2. IAM을 검색하여 선택합니다.
  3. 계정 설정을 선택합니다.
  4. 엔드포인트 목록의 보안 토큰 서비스 (STS)에서 계정이 있는 Snowflake 리전을 찾습니다.
  5. STS 상태가 비활성인 경우 전환 버튼을 활성으로 이동합니다.
  6. 정책을 선택합니다.
  7. 정책 만들기를 선택합니다.
  8. 정책 편집기에서 JSON을 선택합니다.
  9. Snowflake가 하나의 버킷과 폴더 경로로 데이터를 언로드하는 데 필요한 권한을 부여하는 다음 정책을 복사하여 붙여넣습니다.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:PutObject",
                    "s3:GetObject",
                    "s3:GetObjectVersion",
                    "s3:DeleteObject",
                    "s3:DeleteObjectVersion"
                ],
                "Resource": "arn:aws:s3:::snowflake-activity-logs/snowflake/*"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "s3:ListBucket",
                    "s3:GetBucketLocation"
                ],
                "Resource": "arn:aws:s3:::snowflake-activity-logs",
                "Condition": {
                    "StringLike": {
                        "s3:prefix": [
                            "snowflake/*"
                        ]
                    }
                }
            }
        ]
    }
    
  10. 다음을 클릭합니다.

  11. 정책 이름(예: snowflake_access)과 설명(선택사항)을 입력합니다.

  12. 정책 만들기를 클릭합니다.

Snowflake AWS IAM 역할 구성

  1. IAM에서 역할을 선택합니다.
  2. 역할 만들기를 클릭합니다.
  3. 신뢰할 수 있는 항목 유형으로 AWS 계정을 선택합니다.
  4. 다른 AWS 계정을 선택합니다.
  5. 계정 ID 필드에 AWS 계정 ID를 임시로 입력합니다. 나중에 신뢰 관계를 수정하고 Snowflake에 액세스 권한을 부여합니다.
  6. 외부 ID 필요 옵션을 선택합니다.
  7. 0000와 같은 자리표시자 ID를 입력합니다. 나중에 스토리지 통합의 외부 ID로 바꿉니다.
  8. 다음을 클릭합니다.
  9. 앞에서 만든 IAM 정책을 선택합니다.
  10. 다음을 클릭합니다.
  11. 역할 이름과 설명을 입력합니다.
  12. 역할 만들기를 클릭합니다.
  13. 역할 요약 페이지에서 역할 ARN 값을 복사하여 저장합니다.

Amazon S3용 Snowflake 스토리지 통합 만들기

  1. Snowflake 워크시트에서 다음과 같이 스토리지 통합을 만듭니다.

    USE ROLE ACCOUNTADMIN;
    
    CREATE STORAGE INTEGRATION SECOPS_S3_INT
        TYPE = EXTERNAL_STAGE
        STORAGE_PROVIDER = 'S3'
        ENABLED = TRUE
        STORAGE_AWS_ROLE_ARN = '<IAM_ROLE_ARN>'
        STORAGE_ALLOWED_LOCATIONS = ('s3://snowflake-activity-logs/snowflake/');
    
    GRANT USAGE ON INTEGRATION SECOPS_S3_INT TO ROLE SECOPS_EXPORTER;
    
    • <IAM_ROLE_ARN>을 저장한 역할 ARN으로 바꿉니다.
  2. 다음과 같이 통합을 위해 Snowflake에서 만든 AWS ID를 가져옵니다.

    DESC INTEGRATION SECOPS_S3_INT;
    
  3. 다음 속성의 값을 다음과 같이 복사하여 저장합니다.

    • STORAGE_AWS_IAM_USER_ARN
    • STORAGE_AWS_EXTERNAL_ID

Snowflake IAM 사용자에게 버킷 액세스 권한 부여

  1. AWS Management Console로 이동합니다.
  2. IAM > 역할을 선택합니다.
  3. 앞에서 만든 역할을 선택합니다.
  4. 트러스트 관계 탭을 선택합니다.
  5. 트러스트 정책 수정을 클릭합니다.
  6. 다음과 같이 DESC INTEGRATION 출력 값으로 정책 문서를 업데이트합니다.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "<STORAGE_AWS_IAM_USER_ARN>"
                },
                "Action": "sts:AssumeRole",
                "Condition": {
                    "StringEquals": {
                        "sts:ExternalId": "<STORAGE_AWS_EXTERNAL_ID>"
                    }
                }
            }
        ]
    }
    
  7. 정책 업데이트를 클릭합니다.

파일 형식 만들기, 스테이징, 객체 내보내기

  1. Snowflake 워크시트에서 버킷에 쓰는 파일 형식과 스테이지를 다음과 같이 만듭니다.

    USE ROLE SECOPS_EXPORTER;
    USE SCHEMA SECOPS_EXPORT.ACTIVITY;
    
    CREATE OR REPLACE FILE FORMAT SECOPS_JSON_FORMAT
        TYPE = JSON;
    
    CREATE OR REPLACE STAGE SECOPS_EXPORT_STAGE
        URL = 's3://snowflake-activity-logs/snowflake/'
        STORAGE_INTEGRATION = SECOPS_S3_INT
        FILE_FORMAT = SECOPS_JSON_FORMAT;
    
  2. 내보내기 상태 테이블 만들기, 내보내기 절차 만들기, 내보내기 작업 예약 섹션의 방법 1에 설명된 대로 상태 테이블, 절차, 작업을 정확하게 만듭니다. 명령문은 이름으로 단계를 참조하므로 변경할 필요가 없습니다.

Google SecOps용 AWS IAM 구성

  1. AWS Management Console에 로그인합니다.
  2. 이 사용자 가이드(IAM 사용자 만들기)에 따라 사용자를 만듭니다.
  3. 생성된 사용자를 선택합니다.
  4. 보안용 사용자 인증 정보 탭을 선택합니다.
  5. 액세스 키 섹션에서 액세스 키 만들기를 클릭합니다.
  6. 사용 사례로 서드 파티 서비스를 선택합니다.
  7. 다음을 클릭합니다.
  8. 선택사항: 설명 태그를 추가합니다.
  9. 액세스 키 만들기를 클릭합니다.
  10. .csv 파일 다운로드를 클릭하여 나중에 참고할 수 있도록 액세스 키와 보안 비밀 액세스 키를 저장합니다.
  11. 완료를 클릭합니다.
  12. 권한 탭을 선택합니다.
  13. 권한 정책 섹션에서 권한 추가를 클릭합니다.
  14. 권한 추가를 선택합니다.
  15. 정책을 직접 연결을 선택합니다.
  16. AmazonS3FullAccess 정책을 검색하여 선택합니다.
  17. 다음을 클릭합니다.
  18. 권한 추가를 클릭합니다.

Snowflake 로그를 수집하도록 Google SecOps에서 피드 구성

  1. SIEM 설정 > 피드로 이동합니다.
  2. 새 피드 추가를 클릭합니다.
  3. 다음 페이지에서 단일 피드 구성을 클릭합니다.
  4. 피드 이름 필드에 피드 이름을 입력합니다(예: Snowflake activity logs).
  5. 소스 유형으로 Amazon S3 V2를 선택합니다.
  6. 로그 유형으로 Snowflake를 선택합니다.
  7. 다음을 클릭합니다.
  8. 다음과 같이 입력 매개변수의 값을 지정합니다.

    • S3 URI: s3://snowflake-activity-logs/snowflake/
    • 소스 삭제 옵션: 환경설정에 따라 삭제 옵션을 선택합니다.
    • 최대 파일 기간: 지난 일수 동안 수정된 파일을 포함합니다 (기본값은 180일).
    • 액세스 키 ID: S3 버킷에 대한 액세스 권한이 있는 사용자 액세스 키
    • 보안 비밀 액세스 키: S3 버킷에 액세스할 수 있는 사용자 보안 비밀 키
    • 애셋 네임스페이스: 애셋 네임스페이스
    • 수집 라벨: 이 피드의 이벤트에 적용할 라벨
  9. 다음을 클릭합니다.

  10. 확정 화면에서 새 피드 구성을 검토한 다음 제출을 클릭합니다.

UDM 매핑 테이블

로그 필드 UDM 매핑 로직
column4_label additional.fields 병합됨
column7_label additional.fields 병합됨
first_authentication_factor_label additional.fields 병합됨
host_list additional.fields 병합됨
query_text_label additional.fields 병합됨
query_type_label additional.fields 병합됨
roleIds_list additional.fields 병합됨
roleNames_list additional.fields 병합됨
rolecount_label additional.fields 병합됨
user_count_label additional.fields 병합됨
has_principal extensions.auth.type 매핑됨: true → AUTHTYPE_UNSPECIFIED
START_TIME metadata.event_timestamp yyyy-MM-dd HH:mm:ss.SSS Z로 파싱됨
column2 metadata.event_timestamp yyyy-MM-dd HH:mm:ss.SSS Z로 파싱됨
column20 metadata.event_timestamp yyyy-MM-dd HH:mm:ss.SSS Z로 파싱됨
ts metadata.event_timestamp ISO8601로 파싱됨
event_type metadata.event_type 직접 매핑됨
has_principal metadata.event_type 매핑됨: true → NETWORK_CONNECTION, true → STATUS_UPDATE, true → USER_LOGIN
has_principal_user metadata.event_type 매핑됨: true → USER_UNCATEGORIZED
column10 metadata.product_event_type 직접 매핑됨
QUERY_ID metadata.product_log_id 직접 매핑됨
column1 metadata.product_log_id 직접 매핑됨
column6 metadata.product_version 직접 매핑됨
SESSION_ID network.http.session_id 직접 매핑됨
RECEIVED_BYTES network.received_bytes 이름이 변경됨/매핑됨
BYTES_SENT_OVER_THE_NETWORK network.sent_bytes 이름이 변경됨/매핑됨
SENT_BYTES network.sent_bytes 이름이 변경됨/매핑됨
APPLICATION principal.application 직접 매핑됨
data.user_name principal.asset.hostname 직접 매핑됨
CLIENT_IP principal.asset.ip 병합됨
IP principal.asset.ip 병합됨
column5 principal.asset.ip 병합됨
SOURCE_REGION principal.cloud.availability_zone 직접 매핑됨
SOURCE_CLOUD principal.cloud.environment 매핑됨: (?i)azure → MICROSOFT_AZURE, (?i)amazon → AMAZON_WEB_SERVICES, (?i)google …
data.user_name principal.hostname 직접 매핑됨
CLIENT_IP principal.ip 병합됨
IP principal.ip 병합됨
column5 principal.ip 병합됨
OS principal.platform 매핑됨: (?i)Linux → LINUX, (?i)windows → WINDOWS, (?i)mac/ios → MAC
OS_VERSION principal.platform_version 직접 매핑됨
SOURCE_CLOUD_label principal.resource.attribute.labels 병합됨
roles principal.user.attribute.roles 병합됨
data.role_name principal.user.role_name 직접 매핑됨
column9 principal.user.user_display_name 직접 매핑됨
USER_NAME principal.user.userid 직접 매핑됨
column10 principal.user.userid 직접 매핑됨
column3 principal.user.userid 직접 매핑됨
EXECUTION_STATUS security_result.action 매핑됨: (?i)success → action, (?i)fail → security_result_action_block
STATUS security_result.action 매핑됨: (?i)success → action, (?i)fail → action
action security_result.action 병합됨
security_result_action_block security_result.action 병합됨
OCSP_MODE security_result.action_details 직접 매핑됨
column11 security_result.action_details 직접 매핑됨
column3 security_result.action_details 직접 매핑됨
BYTES_DELETED_label security_result.detection_fields 병합됨
BYTES_READ_FROM_RESULT_label security_result.detection_fields 병합됨
BYTES_SCANNED_label security_result.detection_fields 병합됨
BYTES_SPILLED_TO_LOCAL_STORAGE_label security_result.detection_fields 병합됨
BYTES_SPILLED_TO_REMOTE_STORAGE_label security_result.detection_fields 병합됨
BYTES_WRITTEN_TO_RESULT_label security_result.detection_fields 병합됨
BYTES_WRITTEN_label security_result.detection_fields 병합됨
CHILD_QUERIES_WAIT_TIME_label security_result.detection_fields 병합됨
CLUSTER_NUMBER_label security_result.detection_fields 병합됨
COMPILATION_TIME_label security_result.detection_fields 병합됨
CREDITS_USED_CLOUD_SERVICES_label security_result.detection_fields 병합됨
DATABASE_ID_label security_result.detection_fields 병합됨
DATABASE_NAME_label security_result.detection_fields 병합됨
END_TIME_label security_result.detection_fields 병합됨
ERROR_MESSAGE_label security_result.detection_fields 병합됨
EXECUTION_TIME_label security_result.detection_fields 병합됨
EXTERNAL_FUNCTION_TOTAL_INVOCATIONS_label security_result.detection_fields 병합됨
EXTERNAL_FUNCTION_TOTAL_RECEIVED_BYTES_label security_result.detection_fields 병합됨
EXTERNAL_FUNCTION_TOTAL_RECEIVED_ROWS_label security_result.detection_fields 병합됨
EXTERNAL_FUNCTION_TOTAL_SENT_BYTES_label security_result.detection_fields 병합됨
EXTERNAL_FUNCTION_TOTAL_SENT_ROWS_label security_result.detection_fields 병합됨
INBOUND_DATA_TRANSFER_BYTES_label security_result.detection_fields 병합됨
IS_CLIENT_GENERATED_STATEMENT_label security_result.detection_fields 병합됨
LIST_EXTERNAL_FILES_TIME_label security_result.detection_fields 병합됨
OUTBOUND_DATA_TRANSFER_BYTES_label security_result.detection_fields 병합됨
PARTITIONS_SCANNED_label security_result.detection_fields 병합됨
PARTITIONS_TOTAL_label security_result.detection_fields 병합됨
PERCENTAGE_SCANNED_FROM_CACHE_label security_result.detection_fields 병합됨
QUERY_ACCELERATION_BYTES_SCANNED_label security_result.detection_fields 병합됨
QUERY_ACCELERATION_PARTITIONS_SCANNED_label security_result.detection_fields 병합됨
QUERY_ACCELERATION_UPPER_LIMIT_SCALE_FACTOR_label security_result.detection_fields 병합됨
QUERY_HASH_VERSION_label security_result.detection_fields 병합됨
QUERY_HASH_label security_result.detection_fields 병합됨
QUERY_LOAD_PERCENT_label security_result.detection_fields 병합됨
QUERY_PARAMETERIZED_HASH_VERSION_label security_result.detection_fields 병합됨
QUERY_TAG_label security_result.detection_fields 병합됨
QUERY_TYPE_label security_result.detection_fields 병합됨
QUEUED_OVERLOAD_TIME_label security_result.detection_fields 병합됨
QUEUED_PROVISIONING_TIME_label security_result.detection_fields 병합됨
QUEUED_REPAIR_TIME_label security_result.detection_fields 병합됨
RELEASE_VERSION_label security_result.detection_fields 병합됨
ROLE_TYPE_label security_result.detection_fields 병합됨
ROWS_DELETED_label security_result.detection_fields 병합됨
ROWS_INSERTED_label security_result.detection_fields 병합됨
ROWS_PRODUCED_label security_result.detection_fields 병합됨
ROWS_UNLOADED_label security_result.detection_fields 병합됨
ROWS_UPDATED_label security_result.detection_fields 병합됨
ROWS_WRITTEN_TO_RESULT_label security_result.detection_fields 병합됨
SCHEMA_ID_label security_result.detection_fields 병합됨
SCHEMA_NAME_label security_result.detection_fields 병합됨
TOTAL_ELAPSED_TIME_label security_result.detection_fields 병합됨
TRANSACTION_BLOCKED_TIME_label security_result.detection_fields 병합됨
TRANSACTION_ID_label security_result.detection_fields 병합됨
WAREHOUSE_ID_label security_result.detection_fields 병합됨
WAREHOUSE_NAME_label security_result.detection_fields 병합됨
WAREHOUSE_SIZE_label security_result.detection_fields 병합됨
WAREHOUSE_TYPE_label security_result.detection_fields 병합됨
authentication_factor_label security_result.detection_fields 병합됨
column4_label security_result.detection_fields 병합됨
column6_label security_result.detection_fields 병합됨
column7_label security_result.detection_fields 병합됨
column8_label security_result.detection_fields 병합됨
event_id_label security_result.detection_fields 병합됨
event_type_label security_result.detection_fields 병합됨
is_success_label security_result.detection_fields 병합됨
python_compiler_label security_result.detection_fields 병합됨
python_runtime_label security_result.detection_fields 병합됨
python_version_label security_result.detection_fields 병합됨
reported_client_type_label security_result.detection_fields 병합됨
reported_client_version_label security_result.detection_fields 병합됨
tracing_label security_result.detection_fields 병합됨
EXECUTION_STATUS security_result.summary 직접 매핑됨
STATUS security_result.summary 직접 매핑됨
column17 security_result.summary 직접 매핑됨
TARGET_REGION target.cloud.availability_zone 직접 매핑됨
TARGET_CLOUD target.cloud.environment 매핑됨: (?i)azure → MICROSOFT_AZURE, (?i)amazon → AMAZON_WEB_SERVICES, (?i)google …
TARGET_CLOUD_label target.resource.attribute.labels 병합됨
column2_label target.resource.attribute.labels 병합됨
column7_label target.resource.attribute.labels 병합됨
USER_NAME target.user.userid 직접 매핑됨
column4 target.user.userid 직접 매핑됨
해당 사항 없음 extensions.auth.type 상수: AUTHTYPE_UNSPECIFIED
해당 사항 없음 metadata.event_type 상수: NETWORK_CONNECTION
해당 사항 없음 metadata.product_name 상수: SNOWFLAKE
해당 사항 없음 metadata.vendor_name 상수: SNOWFLAKE
해당 사항 없음 principal.cloud.environment 상수: MICROSOFT_AZURE
해당 사항 없음 principal.platform 상수: LINUX
해당 사항 없음 target.cloud.environment 상수: MICROSOFT_AZURE

변경 로그

이 파서의 변경 로그 보기

도움이 더 필요하신가요? 커뮤니티 회원 및 Google SecOps 전문가에게 문의하여 답변을 받으세요.