איסוף יומנים של 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
- גישה ל-Snowflake עם תפקיד שיכול ליצור שילובים של אחסון (רק
ACCOUNTADMINמקבל את ההרשאה הזו כברירת מחדל), מסדי נתונים, מחסני נתונים, אזורי אחסון ומשימות - Cloud Storage V2: Google Cloud פרויקט שבו מופעל Cloud Storage API, והרשאות ליצירת קטגוריות, ליצירת תפקידים בניהול זהויות והרשאות גישה (IAM) ולניהול מדיניות IAM של קטגוריות
- Amazon S3 V2: גישה עם הרשאות ל-AWS כדי ליצור קטגוריות S3, כללי מדיניות של IAM, תפקידי IAM ומשתמשי IAM
הענקת גישה לנתוני השימוש בחשבון Snowflake
התצוגות של SNOWFLAKE.ACCOUNT_USAGE ניתנות לקריאה על ידי ACCOUNTADMIN רק עד שניתנת גישה במפורש. יוצרים תפקיד ייעודי לייצוא ומעניקים לו את שני תפקידי מסד הנתונים שכוללים את התצוגות שהמסמך הזה מייצא.
- נכנסים ל-Snowflake ופותחים גיליון עבודה.
יוצרים את תפקיד הייצוא ומעניקים לו הרשאת קריאה לתצוגות של השימוש בחשבון באופן הבא:
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;יוצרים את מסד הנתונים, הסכימה ומחסן הנתונים שמשמשים לייצוא, ומעניקים להם את ההרשאות לתפקיד באופן הבא:
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 שהוא הבעלים של הייצוא.
- מחליפים את
שיטה 1: Cloud Storage V2 (מומלץ)
יצירת קטגוריה של Cloud Storage
- עוברים אל Google Cloud המסוף.
- בוחרים פרויקט או יוצרים פרויקט חדש.
- בתפריט הניווט, עוברים אל Cloud Storage > Buckets.
- לוחצים על Create bucket.
מספקים את פרטי ההגדרה הבאים:
הגדרה ערך Name your bucket (שם הקטגוריה) מזינים שם ייחודי גלובלית (לדוגמה, snowflake-activity-logs)סוג המיקום בוחרים לפי הצרכים (אזור, שני אזורים, מספר אזורים) Location בוחרים את המיקום (לדוגמה, us-central1).סוג אחסון (storage class) רגיל (מומלץ ליומנים שמתבצעת אליהם גישה לעיתים קרובות) בקרת גישה אחיד (מומלץ) כלים להגנה אופציונלי: הפעלת ניהול גרסאות של אובייקטים או מדיניות שמירת נתונים לוחצים על יצירה.
יצירת תפקיד בהתאמה אישית ב-Cloud Storage עבור Snowflake
- במסוף Google Cloud , עוברים אל IAM & Admin > Roles (ניהול הרשאות גישה (IAM) & אדמין > תפקידים).
- לוחצים על יצירת תפקיד.
- מספקים את פרטי ההגדרה הבאים:
- תפקיד: מזינים
Snowflake Unload - מזהה: מזינים
snowflake_unload - שלב ההשקה של התפקיד: בוחרים באפשרות זמינות לכלל המשתמשים (GA).
- תפקיד: מזינים
- לוחצים על Add permissions ומוסיפים את ההרשאות הבאות:
storage.buckets.getstorage.objects.createstorage.objects.deletestorage.objects.list
לוחצים על יצירה.
יצירת שילוב אחסון ב-Snowflake ל-Cloud Storage
יוצרים את שילוב האחסון בגיליון עבודה של 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בשם הקטגוריה.
- מחליפים את
כדי לאחזר את חשבון השירות ש-Snowflake יצר לאינטגרציה, מבצעים את הפעולות הבאות:
DESC STORAGE INTEGRATION SECOPS_GCS_INT;מעתיקים את הערך של המאפיין
STORAGE_GCP_SERVICE_ACCOUNT. הערך הוא בפורמט הבא:service-account-id@project1-123456.iam.gserviceaccount.com
נותנים לחשבון השירות של Snowflake גישה לקטגוריה
- במסוף Google Cloud , נכנסים אל Cloud Storage > Buckets.
- לוחצים על הקטגוריה שיצרתם (לדוגמה,
snowflake-activity-logs). - עוברים לכרטיסייה Permissions.
- לוחצים על הענקת גישה.
- מספקים את פרטי ההגדרה הבאים:
- Add principals (הוספת ישויות): מדביקים את הערך
STORAGE_GCP_SERVICE_ACCOUNT. - הקצאת תפקידים: בוחרים באפשרות Snowflake Unload
- Add principals (הוספת ישויות): מדביקים את הערך
- לוחצים על Save.
יצירת פורמט הקובץ ושלב חיצוני
בגיליון עבודה של Snowflake, יוצרים את פורמט הקובץ ואת השלב שכותב ל-bucket באופן הבא:
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;
יצירת טבלת מצבי ייצוא
הייצוא עוקב אחרי המיקום שבו הוא קרא בכל תצוגה. בלי סימן המים הזה, כל הפעלה תייצא מחדש את כל התצוגה ואותם אירועים ייקלטו שוב.
יוצרים את טבלת המצבים ומאכלסים אותה באופן הבא:
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());
יצירת תהליך הייצוא
יוצרים את הפרוצדורה שמבטלת את הטעינה של שתי התצוגות ומקדמת את סימן המים באופן הבא:
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; $$;
לכל רכיב בהליך יש סיבה:
- החלון נסגר שלוש שעות אחרי השעה הנוכחית. מערכת Snowflake מאכלסת את
LOGIN_HISTORYעם השהיה של עד שעתיים, ואתQUERY_HISTORYעם השהיה של עד 45 דקות. לכן, חלון שמסתיים עכשיו ידלג על שורות שהתצוגה המפורטת שלהן עדיין לא נוצרה. לכן, האירועים מגיעים אל Google SecOps בערך שלוש שעות אחרי שהם קורים. קיצור משך הזמן שחלף מאז העדכון משפר את הרעננות של הנתונים, אבל על חשבון השלמות שלהם. - הערך של
WINDOW_ENDנכתב לטבלה לפני ההעברה, כך שהערך שמשמש את ההצהרהCOPY INTOוהערך שנכתב בחזרה ל-LAST_EXPORTEDזהים. חישוב מחדש של השעה הנוכחית בהצהרה השנייה ידלג על כל מה שקרה בין לבין. - כל עדכון של
LAST_EXPORTEDמופעל אחרי ההצהרה שלוCOPY INTO. אם פריקה נכשלת, התהליך נעצר, סימן המים נשאר במקום שבו הוא היה, וההרצה הבאה חוזרת על החלון הזה במקום לדלג עליו. -
INCLUDE_QUERY_ID = TRUEמוסיף UUID לכל שם קובץ. בלי ההרשאה הזו, הקבצים שלא נטענו נקראיםdata_0_0_0, והייצוא החוזר לאותה נתיב גורם להתנגשות, שמתועדת ב-Snowflake כמקור של נתונים משוכפלים באזור הזמני.
תזמון משימת הייצוא
כדי ליצור ולהפעיל את המשימה:
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;כדי להריץ את המשימה פעם אחת ולאמת את ההגדרה בלי לחכות ללוח הזמנים, פועלים לפי השלבים הבאים:
EXECUTE TASK SECOPS_EXPORT_TASK;כדי לבדוק את התוצאה של ההרצה ואת הקבצים שהגיעו לשלב הזה:
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. צריך להעניק לחשבון השירות הזה גישה לדלי.
- עוברים אל SIEM Settings > Feeds (הגדרות SIEM > פידים).
- לוחצים על הוספת פיד חדש.
- לוחצים על Configure a single feed (הגדרת פיד יחיד).
- בשדה שם הפיד, מזינים שם לפיד (לדוגמה,
Snowflake activity logs). - בוחרים באפשרות Google Cloud Storage V2 בתור סוג המקור.
- בוחרים באפשרות Snowflake בתור סוג היומן.
- לוחצים על קבלת חשבון שירות.
תוצג כתובת האימייל בחשבון שירות ייחודי, לדוגמה:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comמעתיקים את כתובת האימייל הזו לשימוש בשלב הבא.
לוחצים על הבא.
מציינים ערכים לפרמטרים הבאים של הקלט:
URL של קטגוריה של Cloud Storage: מזינים את ה-URI של קטגוריה של Cloud Storage עם נתיב הקידומת:
gs://snowflake-activity-logs/snowflake/
אפשרות למחיקת המקור: בוחרים את אפשרות המחיקה לפי ההעדפה שלכם:
- אף פעם לא למחוק קבצים: אף פעם לא למחוק קבצים מהמקור (מומלץ לבדיקה).
- מחיקת קבצים שהועברו וספריות ריקות: מחיקת קבצים וספריות ריקות מהמקור אחרי השלמת אחזור מוצלח.
הגיל המקסימלי של הקובץ: כולל קבצים ששונו במספר הימים האחרון (ברירת המחדל היא 180 ימים)
מרחב השמות של הנכס: מרחב השמות של הנכס
תוויות להוספה: התווית שתתווסף לאירועים מהפיד הזה
לוחצים על הבא.
בודקים את ההגדרות של הפיד החדש במסך סיום ולוחצים על שליחה.
הענקת הרשאות IAM לחשבון השירות של Google SecOps
לחשבון השירות של Google SecOps צריך להיות מוקצות שתי הרשאות בקטגוריה של Cloud Storage: Storage Object Viewer כדי לקרוא את אובייקטי היומן, והרשאה ברמת הקטגוריה כדי לקרוא את המטא-נתונים של הקטגוריה.
- עוברים אל Cloud Storage > Buckets (קטגוריות).
- לוחצים על שם הקטגוריה.
- עוברים לכרטיסייה Permissions.
- לוחצים על הענקת גישה.
- מספקים את פרטי ההגדרה הבאים:
- Add principals (הוספת ישויות מורשות): מדביקים את כתובת האימייל בחשבון של חשבון השירות של Google SecOps
- הקצאת תפקידים: בוחרים את שתי האפשרויות הבאות:
- צפייה באובייקט אחסון: קריאת אובייקטים של יומנים.
- קריאה בקטגוריה באחסון מדור קודם: קריאת המטא-נתונים של הקטגוריה. אם בחרתם באפשרות המחיקה מחיקת קבצים שהועברו וספריות ריקות, במקום זאת בוחרים באפשרות Storage Legacy Bucket Writer, שמעניקה גם את הרשאת המחיקה.
- לוחצים על Save.
שיטה 2: Amazon S3 V2
משתמשים בשיטה הזו כשהיומנים צריכים להגיע ל-Amazon S3. הצד של Snowflake זהה, מלבד שילוב האחסון והשלב, ולכן נעשה שימוש חוזר בהליך הייצוא ובמשימה משיטה 1 ללא שינויים.
הגדרת קטגוריה ב-Amazon S3
- יוצרים קטגוריה ב-Amazon S3 לפי המדריך למשתמש בנושא יצירת קטגוריה.
- שומרים את השם והאזור של הקטגוריה לעיון עתידי. לדוגמה,
snowflake-activity-logs.
הגדרת מדיניות Snowflake AWS IAM
- נכנסים למסוף הניהול של AWS.
- מחפשים את IAM ולוחצים עליו.
- בוחרים באפשרות הגדרות חשבון.
- בקטע Security Token Service (STS) ברשימה Endpoints, מאתרים את האזור של Snowflake שבו נמצא החשבון שלכם.
- אם הסטטוס של ה-STS הוא לא פעיל, מעבירים את המתג למצב פעיל.
- לוחצים על מדיניות.
- לוחצים על יצירת מדיניות.
- בעורך המדיניות, בוחרים באפשרות JSON.
מעתיקים ומדביקים את המדיניות הבאה, שמעניקה ל-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/*" ] } } } ] }לוחצים על הבא.
מזינים שם מדיניות (לדוגמה,
snowflake_access) ותיאור אופציונלי.לוחצים על יצירת מדיניות.
הגדרת תפקיד IAM ב-AWS ל-Snowflake
- ב-IAM, בוחרים באפשרות Roles (תפקידים).
- לוחצים על יצירת תפקיד.
- בוחרים באפשרות חשבון AWS כסוג היישות המהימנה.
- בוחרים באפשרות חשבון AWS אחר.
- בשדה Account ID (מספר החשבון), מזינים באופן זמני את מספר החשבון שלכם ב-AWS. אפשר לשנות את יחסי האמון מאוחר יותר ולהעניק גישה ל-Snowflake.
- בוחרים באפשרות Require external ID (דרישת מזהה חיצוני).
- מזינים מזהה של placeholder, למשל
0000. אחר כך מחליפים אותו במזהה החיצוני של שילוב האחסון. - לוחצים על הבא.
- בוחרים את מדיניות ה-IAM שיצרתם קודם.
- לוחצים על הבא.
- מזינים שם ותיאור לתפקיד.
- לוחצים על יצירת תפקיד.
- בדף סיכום התפקיד, מעתיקים ושומרים את הערך של Role ARN.
יצירת שילוב אחסון של Snowflake עבור Amazon S3
יוצרים את שילוב האחסון בגיליון עבודה של 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 של התפקיד ששמרתם.
- מחליפים את
כדי לאחזר את הזהות ב-AWS שנוצרה על ידי Snowflake לצורך השילוב:
DESC INTEGRATION SECOPS_S3_INT;מעתיקים ושומרים את הערכים של המאפיינים הבאים:
- STORAGE_AWS_IAM_USER_ARN
- STORAGE_AWS_EXTERNAL_ID
נותנים למשתמש Snowflake IAM גישה לקטגוריה
- עוברים אל AWS Management Console.
- בוחרים באפשרות IAM > Roles (ניהול הרשאות גישה > תפקידים).
- בוחרים את התפקיד שיצרתם קודם.
- לוחצים על הכרטיסייה יחסי אמון.
- לוחצים על עריכת מדיניות הרשאות השיתוף.
מעדכנים את מסמך המדיניות עם ערכי הפלט
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>" } } } ] }לוחצים על עדכון המדיניות.
יצירת פורמט הקובץ, אחסון אובייקטים במחסן ביניים וייצוא שלהם
בגיליון עבודה של Snowflake, יוצרים את פורמט הקובץ ואת השלב שכותב ל-bucket באופן הבא:
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;יוצרים את טבלת המצב, את הפרוצדורה ואת המשימה בדיוק כמו שמתואר בשיטה 1, בקטעים יצירת טבלת מצב הייצוא, יצירת פרוצדורת הייצוא ותזמון משימת הייצוא. ההצהרות מתייחסות לשלב לפי שם, ולכן לא צריך לשנות אותן.
הגדרת AWS IAM ל-Google SecOps
- נכנסים למסוף הניהול של AWS.
- יוצרים משתמש לפי מדריך המשתמש הזה: יצירת משתמש IAM.
- בוחרים את המשתמש שנוצר.
- לוחצים על הכרטיסייה פרטי כניסה לאבטחה.
- בקטע Access Keys, לוחצים על Create Access Key.
- בוחרים באפשרות שירות של צד שלישי בתור תרחיש השימוש.
- לוחצים על הבא.
- אופציונלי: מוסיפים תג תיאור.
- לוחצים על Create access key (יצירת מפתח גישה).
- לוחצים על הורדת קובץ CSV כדי לשמור את מפתח הגישה ואת מפתח הגישה הסודי לעיון עתידי.
- לוחצים על סיום.
- לוחצים על הכרטיסייה הרשאות.
- בקטע Permissions policies, לוחצים על Add permissions.
- לוחצים על הוספת הרשאות.
- בוחרים באפשרות צירוף מדיניות ישירות.
- מחפשים את המדיניות AmazonS3FullAccess ובוחרים בה.
- לוחצים על הבא.
- לוחצים על הוספת הרשאות.
הגדרת פיד ב-Google SecOps להטמעה של יומני Snowflake
- עוברים אל SIEM Settings > Feeds (הגדרות SIEM > פידים).
- לוחצים על הוספת פיד חדש.
- בדף הבא, לוחצים על הגדרת פיד יחיד.
- בשדה שם הפיד, מזינים שם לפיד (לדוגמה,
Snowflake activity logs). - בוחרים באפשרות Amazon S3 V2 בתור סוג המקור.
- בוחרים באפשרות Snowflake בתור סוג היומן.
- לוחצים על הבא.
מציינים ערכים לפרמטרים הבאים של הקלט באופן הבא:
- S3 URI:
s3://snowflake-activity-logs/snowflake/ - אפשרות למחיקת מקור: בוחרים את אפשרות המחיקה לפי ההעדפה שלכם
- הגיל המקסימלי של הקובץ: כולל קבצים ששונו במספר הימים האחרון (ברירת המחדל היא 180 ימים)
- מזהה מפתח הגישה: מפתח הגישה של המשתמש עם גישה לקטגוריית S3
- מפתח גישה סודי: מפתח סודי של משתמש עם גישה לקטגוריית S3
- מרחב השמות של הנכס: מרחב השמות של הנכס
- תוויות להוספה: התווית שתתווסף לאירועים מהפיד הזה
- S3 URI:
לוחצים על הבא.
בודקים את ההגדרות של הפיד החדש במסך סיום ולוחצים על שליחה.
טבלת מיפוי 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.