איסוף יומני ביקורת של Slack

נתמך ב:

במאמר הזה מוסבר איך להטמיע יומני ביקורת של Slack ב-Google Security Operations באמצעות פונקציות Google Cloud Run או Amazon S3 עם AWS Lambda.

יומני הביקורת של Slack מספקים תיעוד מפורט של אירועים שקשורים לאבטחה בארגון שלכם ב-Slack Enterprise Grid. בעזרת Audit Logs API אפשר לעקוב אחרי פעולות של משתמשים, כמו התחברות, הורדת קבצים, התקנת אפליקציות ושינויים אדמיניסטרטיביים, למטרות תאימות וניטור לצורכי אבטחה.

לפני שמתחילים

חשוב לוודא שמתקיימות הדרישות המוקדמות הבאות:

  • מכונה של Google SecOps.
  • תוכנית Slack Enterprise Grid עם גישת בעלים לארגון.

  • גישה מיוחדת לאחד מהבאים:

    • ‫Google Cloud (לאפשרות 1: פונקציות Cloud Run ו-Cloud Scheduler), או
    • AWS (לאפשרות 2: S3, ‏ IAM, ‏ Lambda, ‏ EventBridge).

איסוף פרטי הכניסה ל-Slack

יצירת אפליקציית Slack

ה-API של יומני הביקורת ב-Slack דורש טוקן OAuth של משתמש עם היקף auditlogs:read. צריך לקבל את הטוקן הזה על ידי התקנת אפליקציה ברמת הארגון ב-Enterprise Grid, ולא ברמת סביבת העבודה.

  1. נכנסים ל-Slack בתור הבעלים של הארגון ב-Enterprise Grid.
  2. נכנסים לדף האפליקציות של Slack API.
  3. לוחצים על יצירת אפליקציה חדשה.
  4. בוחרים באפשרות מאפס.
  5. מספקים את פרטי ההגדרה הבאים:
    • שם האפליקציה: מזינים שם תיאורי (לדוגמה, Google SecOps Audit Integration).
    • בחירת סביבת עבודה לפיתוח האפליקציה: בוחרים את סביבת העבודה של Slack לפיתוח (כל סביבת עבודה בארגון).
  6. לחצו על Create App.

הגדרת היקפי ההרשאות של OAuth

  1. בדף ההגדרות של האפליקציה, בוחרים באפשרות OAuth & Permissions (הרשאות ו-OAuth) מתוך תפריט הניווט הימני.
  2. עוברים לקטע היקפים.
  3. בקטע User Token Scopes (לא Bot Token Scopes), לוחצים על Add an OAuth Scope.
  4. מוסיפים את היקף ההרשאות הבא:
    • auditlogs:read — ההיקף הזה מאפשר גישה ל-Audit Logs API של הארגון ב-Enterprise Grid.
  5. בקטע Bot Token Scopes, לוחצים על Add an OAuth Scope.
  6. מוסיפים את ההיקף הבא:
    • users:read — קיים כדי שיהיה אפשר להתקין את האפליקציה ברמת הארגון.

התקנת האפליקציה בארגון ב-Enterprise

‫Audit Logs API קורא אירועים מכל הארגון ב-Enterprise, ולכן צריך להתקין את האפליקציה ברמת הארגון ולא בסביבת עבודה אחת. ב-Slack יש שתי דרכים לעשות את זה. שתי השיטות יוצרות את אותו טוקן OAuth של משתמש ברמת הארגון. משתמשים באחת מהן.

אפשרות א': התקנה מהגדרות האפליקציה (אפליקציה ברמת הארגון)

זהו הנתיב מתוך הדף Developing apps for Enterprise orgs של Slack. היא לא צריכה כתובת URL להפניה אוטומטית, לא הפצה ציבורית ולא שירות אינטרנט.

  1. בדף ההגדרות של האפליקציה, בתפריט הניווט הימני, בוחרים באפשרות אפליקציות ברמת הארגון.
  2. לוחצים על הבעת הסכמה.
  3. בהודעת האישור, לוחצים על כן, אני רוצה להצטרף.

  4. נכנסים בתור הבעלים של הארגון ב-Enterprise.

  5. בסרגל הניווט הימני, לוחצים על OAuth & Permissions (OAuth והרשאות).

  6. לוחצים על Install to Organization (התקנה בארגון).

  7. בודקים את ההרשאות הנדרשות במסך האישור ולוחצים על אישור.

אפשרות ב': הפצה ציבורית וכתובת URL שניתן לשתף

זה הנתיב מדף Audit Logs API של Slack. הפעלת ההפצה הציבורית לא מוסיפה את האפליקציה ל-Slack Marketplace, אלא רק מאפשרת להתקין אותה מחוץ לסביבת העבודה לפיתוח.

  1. בדף ההגדרות של האפליקציה, בוחרים באפשרות OAuth & Permissions (OAuth והרשאות) בתפריט הניווט הימני.
  2. בקטע כתובות URL להפניה אוטומטית, לוחצים על הוספת כתובת URL חדשה להפניה אוטומטית, מזינים כתובת URL, לוחצים על הוספה ואז על שמירת כתובות ה-URL.

  3. בתפריט הניווט הימני, לוחצים על ניהול ההפצה.

  4. בקטע שיתוף האפליקציה עם סביבות עבודה אחרות, מוודאים שבכל ארבעת הקטעים של רשימת המשימות מופיע סימן וי ירוק. אם מופיע סימן X אדום ליד קטע מסוים, מרחיבים אותו ומשלימים את הפעולה הנדרשת.

  5. מסמנים את תיבת הסימון בדקתי והסרתי מידע שמוטמע בקוד.

  6. לוחצים על הפעלת הפצה ציבורית.

  7. נכנסים בתור הבעלים של הארגון ב-Enterprise.

  8. בקטע Share Your App with Your Workspace, מעתיקים את Sharable URL ופותחים אותה בדפדפן.

  9. במסך ההתקנה, פותחים את התפריט הנפתח בפינה השמאלית העליונה ובוחרים באפשרות Enterprise organization, ולא בסביבת עבודה ספציפית.

  10. בודקים את ההרשאות הנדרשות ולוחצים על אישור.

אחזור פרטי הכניסה

  1. בסיום ההתקנה, חוזרים לדף OAuth & Permissions.
  2. בקטע OAuth Tokens, מאתרים את User OAuth Token.
  3. האסימון מתחיל ב-xoxp-.
  4. לוחצים על העתקה ושומרים את האסימון הזה בצורה מאובטחת.

    חשוב: זהו ה-SLACK_ADMIN_TOKEN של פונקציית Cloud Run או פונקציית Lambda. מאחסנים אותו באופן מאובטח. הוא מספק גישת קריאה לכל יומני הביקורת בארגון Enterprise Grid.

  5. רושמים את מזהה הארגון:

    1. פותחים את Slack בדפדפן אינטרנט באמצעות כתובת ה-URL של הארגון (לדוגמה, acmeinc.enterprise.slack.com).
    2. אחרי שהדף נטען, קוראים את כתובת ה-URL. הפורמט הוא https://app.slack.com/client/EXXXXXXX/CXXXXXXX.
    3. מעתיקים את המחרוזת שמתחילה ב-E. זהו מזהה הארגון.

אימות ההרשאות

כדי לוודא שלאפליקציה יש את ההרשאות הנדרשות:

  1. נכנסים לדף האפליקציות של Slack API.
  2. בוחרים את האפליקציה הרצויה.
  3. בתפריט הניווט הימני, לוחצים על OAuth & Permissions (הרשאות ו-OAuth).
  4. בקטע OAuth Tokens (טוקנים של OAuth), מוודאים שמוצג User OAuth Token (טוקן OAuth של משתמש) (מתחיל ב-xoxp-).
  5. בקטע Scopes, מוודאים שהערך auditlogs:read מופיע בקטע User Token Scopes.

בדיקת הגישה ל-API

  • לפני שממשיכים בתהליך השילוב, בודקים את הטוקן:

    SLACK_TOKEN="xoxp-your-token-here"
    
    curl -H "Authorization: Bearer $SLACK_TOKEN" \
      "https://api.slack.com/audit/v1/logs?limit=1"
    

תגובה מוצלחת מכילה מערך entries עם אירועים ביומן הביקורת. אם מופיעה השגיאה invalid_auth או missing_scope, צריך לבדוק את האסימון ואת ההיקפים.

אפשרות 1: הגדרת ייצוא של יומני ביקורת של Slack באמצעות פונקציות Google Cloud Run

באפשרות הזו משתמשים בפונקציות של Google Cloud Run וב-Cloud Scheduler כדי לאסוף יומני ביקורת של Slack ולהטמיע אותם ישירות ב-Google SecOps באמצעות סקריפטים להטמעה של Google SecOps.

לפני שמתחילים (אפשרות 1)

ודאו שאתם עומדים בדרישות המוקדמות הנוספות הבאות:

  • פרויקט ב- Google Cloud שבו מופעלים ממשקי ה-API הבאים:
    • Cloud Run Admin API
    • Eventarc API
    • Pub/Sub API
    • Cloud Scheduler API
    • Secret Manager API
  • הרשאות ליצירת פונקציות Cloud Run, נושאי Pub/Sub, טריגרים של Eventarc, משימות של Cloud Scheduler וסודות ב-Secret Manager.
  • קובץ JSON של חשבון שירות ב-Google SecOps.

קבלת חשבון השירות של Google SecOps

  1. נכנסים למסוף Google SecOps.
  2. עוברים אל SIEM Settings > Collection Agents (הגדרות SIEM > סוכני איסוף).
  3. לוחצים על Download כדי להוריד את קובץ האימות להטמעת נתונים.
  4. שומרים את קובץ ה-JSON בצורה מאובטחת. תעלו את הקובץ הזה כסוד ב-Google Secret Manager.

הכנת קוד הפונקציה

מורידים את קובצי הפריסה ממאגר GitHub של Google SecOps ingestion-scripts:

  1. מתיקיית slack, מורידים את:
    • .env.yml
    • main.py
    • requirements.txt
  2. מתיקיית הבסיס של המאגר, מורידים את כל הספרייה common עם כל הקבצים שלה.

    ספריית הפריסה צריכה להיות במבנה הבא:

        ```
        deployment_directory/
        ├── common/
        │   ├── __init__.py
        │   ├── auth.py
        │   ├── env_constants.py
        │   ├── ingest.py
        │   ├── status.py
        │   └── utils.py
        ├── .env.yml
        ├── main.py
        └── requirements.txt
        ```
    

הגדרת סודות ב-Google Secret Manager

אחסון פרטי כניסה רגישים ב-Secret Manager כדי שפונקציית Cloud Run תוכל לגשת אליהם בצורה מאובטחת.

יצירת סוד לחשבון השירות של Google SecOps

  1. במסוףGoogle Cloud , עוברים אל Security > Secret Manager.
  2. לוחצים על Create Secret.
  3. מספקים את פרטי ההגדרה הבאים:
    • Name: מזינים chronicle-service-account.
    • Secret value: מדביקים את כל התוכן של קובץ ה-JSON של חשבון השירות של Google SecOps.
  4. לוחצים על Create Secret.
  5. מעתיקים את שם המשאב של הסוד. הפורמט הוא:

    projects/PROJECT_ID/secrets/chronicle-service-account/versions/latest
    

יצירת סוד לטוקן של Slack

  1. בדף Secret Manager, לוחצים על Create Secret.
  2. מזינים את פרטי ההגדרה הבאים:
    • שם: מזינים slack-admin-token.
    • ערך סודי: מדביקים את טוקן ה-OAuth של משתמש Slack (מתחיל ב-xoxp-).
  3. לוחצים על Create Secret.
  4. מעתיקים את שם המשאב של הסוד. הפורמט הוא:

    projects/PROJECT_ID/secrets/slack-admin-token/versions/latest
    

הגדרת משתני סביבה

  1. פותחים את הקובץ .env.yml בספריית הפריסה ומגדירים את משתני הסביבה:

    CHRONICLE_CUSTOMER_ID: "<your-chronicle-customer-id>"
    CHRONICLE_REGION: "us"
    CHRONICLE_SERVICE_ACCOUNT: "projects/<PROJECT_ID>/secrets/chronicle-service-account/versions/latest"
    CHRONICLE_NAMESPACE: ""
    POLL_INTERVAL: "5"
    SLACK_ADMIN_TOKEN: "projects/<PROJECT_ID>/secrets/slack-admin-token/versions/latest"
    
    • מחליפים את מה שכתוב בשדות הבאים:

      • ‫<your-chronicle-customer-id>: מספר הלקוח שלכם ב-Google SecOps.
      • ‫<PROJECT_ID>: מזהה הפרויקט ב- Google Cloud .
      • ‫CHRONICLE_REGION: האזור שלכם ב-Google SecOps. ערכים חוקיים: us, ‏ asia-northeast1, ‏ asia-south1, ‏ asia-southeast1, ‏ australia-southeast1, ‏ europe, ‏ europe-west2, ‏ europe-west3, ‏ europe-west6, ‏ europe-west9, ‏ europe-west12, ‏ me-central1, ‏ me-central2, ‏ me-west1, ‏ northamerica-northeast2, ‏ southamerica-east1.
      • ‫POLL_INTERVAL: מרווח התדירות (בדקות) שבו הפונקציה מופעלת. המשך הזה חייב להיות זהה למרווח הזמן של המשימה ב-Cloud Scheduler.
  2. שומרים את קובץ ה-.env.yml.

יוצרים נושא Pub/Sub

‫Cloud Scheduler מפעיל את פונקציית Cloud Run דרך נושא Pub/Sub.

  1. במסוף GCP, עוברים אל Pub/Sub > Topics.
  2. לוחצים על Create topic.
  3. בשדה Topic ID, מזינים את הערך slack-audit-trigger.
  4. לוחצים על יצירה.

פריסת פונקציית Cloud Run

  1. פותחים חלון של Terminal או Cloud Shell במסוף Google Cloud . עוברים לספריית הפריסה ומריצים את הפקודה הבאה:

    gcloud run deploy slack-audit-to-chronicle \
      --source . \
      --function main \
      --base-image google-22/python312 \
      --region <REGION> \
      --service-account <SERVICE_ACCOUNT_EMAIL> \
      --env-vars-file .env.yml \
      --memory 512Mi \
      --timeout 540 \
      --max-instances 1 \
      --no-allow-unauthenticated
    
    • מחליפים את <REGION> באזור (לדוגמה, us-central1) ואת <SERVICE_ACCOUNT_EMAIL> בכתובת האימייל של חשבון השירות שבו רוצים להשתמש בפונקציית Cloud Run.
  2. יוצרים את הטריגר של Pub/Sub לפונקציה:

    gcloud eventarc triggers create slack-audit-trigger \
      --location <REGION> \
      --destination-run-service slack-audit-to-chronicle \
      --destination-run-region <REGION> \
      --event-filters "type=google.cloud.pubsub.topic.v1.messagePublished" \
      --transport-topic projects/<PROJECT_ID>/topics/slack-audit-trigger \
      --service-account <SERVICE_ACCOUNT_EMAIL>
    
    • מחליפים את <PROJECT_ID> במזהה הפרויקט ב- Google Cloud .
  3. מחכים עד שהפריסה תסתיים.

הגדרת Cloud Scheduler

  1. במסוף GCP, נכנסים לדף Cloud Scheduler > Create job.
  2. מספקים את פרטי ההגדרה הבאים:

    הגדרה ערך
    שם slack-audit-scheduler
    אזור בוחרים את אותו אזור שבו פרסתם את פונקציית Cloud Run.
    תדירות */5 * * * * (כל 5 דקות, בהתאם לערך POLL_INTERVAL)
    אזור זמן בחירת אזור זמן (מומלץ לבחור ב-UTC)
  3. לוחצים על Continue.

  4. בקטע Configure the execution (הגדרת ההפעלה):

    • ‫Target type: בוחרים באפשרות Pub/Sub.
    • נושא: בוחרים באפשרות slack-audit-trigger.
    • גוף ההודעה: מזינים run.
  5. לוחצים על יצירה.

אפשרויות לתדירות התזמון

בוחרים את התדירות בהתאם לנפח היומן ולדרישות לגבי זמן האחזור:

תדירות ביטוי Cron תרחיש לדוגמה
כל 5 דקות */5 * * * * רגיל (מומלץ)
כל 15 דקות */15 * * * * נפח חיפושים בינוני
כל שעה 0 * * * * נפח החיפושים נמוך

בדיקת השילוב (אפשרות 1)

  1. במסוף Cloud Scheduler, מאתרים את המשימה (slack-audit-scheduler).
  2. לוחצים על Force run כדי להפעיל את המשימה באופן ידני.
  3. מחכים כמה שניות.
  4. עוברים אל Cloud Run.
  5. לוחצים על שם השירות (slack-audit-to-chronicle).
  6. לוחצים על הכרטיסייה Logs.
  7. מוודאים שהפונקציה בוצעה בהצלחה. מחפשים:

    Retrieving the Slack Audit logs since: YYYY-MM-DDTHH:MM:SSZ
    Processing logs...
    Retrieved X audit logs from the API call
    Logs processed successfully.
    

אפשרות 2: הגדרת ייצוא של יומני ביקורת של Slack באמצעות AWS S3

באפשרות הזו, משתמשים ב-AWS Lambda כדי לאסוף את יומני הביקורת של Slack ולאחסן אותם ב-Amazon S3, ואז מגדירים פיד של Google SecOps כדי להטמיע את היומנים.

לפני שמתחילים (אפשרות 2)

ודאו שאתם עומדים בדרישות המוקדמות הנוספות הבאות:

  • חשבון AWS עם הרשאות ליצור קטגוריות S3, משתמשים/תפקידים/כללי מדיניות של IAM, פונקציות Lambda וכללי EventBridge.

יצירת קטגוריה ב-Amazon S3

  1. יוצרים קטגוריה ב-Amazon S3 לפי ההוראות במדריך למשתמש Creating a bucket.
  2. שומרים את שם הקטגוריה ואת האזור שלה לעיון בעתיד (לדוגמה, slack-audit-logs).

הגדרת מדיניות ותפקידים ב-IAM להעלאות ל-S3

  1. בכרטיסייה JSON ב-AWS Console, עוברים אל IAM > Policies > Create policy >.
  2. מעתיקים ומדביקים את המדיניות הבאה. אם השתמשתם בשם אחר לקטגוריה, מחליפים את slack-audit-logs:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowPutObjects",
          "Effect": "Allow",
          "Action": "s3:PutObject",
          "Resource": "arn:aws:s3:::slack-audit-logs/*"
        },
        {
          "Sid": "AllowGetStateObject",
          "Effect": "Allow",
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::slack-audit-logs/slack-audit-state.json"
        }
      ]
    }
    
  3. לוחצים על הבא.

  4. מזינים את שם המדיניות SlackAuditS3Policy.

  5. לוחצים על יצירת מדיניות.

  6. עוברים אל IAM > Roles > Create role > AWS service > Lambda.

  7. מצרפים את המדיניות החדשה שנוצרה SlackAuditS3Policy.

  8. נותנים לתפקיד את השם SlackAuditToS3Role ולוחצים על יצירת תפקיד.

יצירת פונקציית Lambda

  1. ב-AWS Console, עוברים אל Lambda > Functions > Create function.
  2. לוחצים על יצירה מאפס.
  3. מספקים את פרטי ההגדרה הבאים:

    הגדרה ערך
    שם slack_audit_to_s3
    זמן ריצה Python 3.13
    ארכיטקטורה x86_64
    תפקיד ההרצה SlackAuditToS3Role
  4. לוחצים על Create function.

  5. אחרי שיוצרים את הפונקציה, פותחים את הכרטיסייה Code, מוחקים את ה-stub ומדביקים את הקוד הבא (slack_audit_to_s3.py).

    #!/usr/bin/env python3
    # Lambda: Pull Slack Audit Logs (Enterprise Grid) to S3 (JSONL format)
    import os, json, time, urllib.parse
    from urllib.request import Request, urlopen
    from urllib.error import HTTPError, URLError
    import boto3
    
    BASE_URL = "https://api.slack.com/audit/v1/logs"
    TOKEN = os.environ["SLACK_AUDIT_TOKEN"]
    BUCKET = os.environ["S3_BUCKET"]
    PREFIX = os.environ.get("S3_PREFIX", "slack/audit/")
    STATE_KEY = os.environ.get("STATE_KEY", "slack-audit-state.json")
    LIMIT = int(os.environ.get("LIMIT", "200"))
    MAX_PAGES = int(os.environ.get("MAX_PAGES", "20"))
    LOOKBACK_SEC = int(os.environ.get("LOOKBACK_SECONDS", "3600"))
    HTTP_TIMEOUT = int(os.environ.get("HTTP_TIMEOUT", "60"))
    HTTP_RETRIES = int(os.environ.get("HTTP_RETRIES", "3"))
    RETRY_AFTER_DEFAULT = int(os.environ.get("RETRY_AFTER_DEFAULT", "2"))
    # Optional server-side filters (comma-separated 'action' values)
    ACTIONS = os.environ.get("ACTIONS", "").strip()
    
    s3 = boto3.client("s3")
    
    def _get_state() -> dict:
        try:
            obj = s3.get_object(Bucket=BUCKET, Key=STATE_KEY)
            st = json.loads(obj["Body"].read() or b"{}")
            return {"cursor": st.get("cursor")}
        except Exception:
            return {"cursor": None}
    
    def _put_state(state: dict) -> None:
        body = json.dumps(state, separators=(",", ":")).encode("utf-8")
        s3.put_object(
            Bucket=BUCKET, Key=STATE_KEY, Body=body, ContentType="application/json"
        )
    
    def _http_get(params: dict) -> dict:
        qs = urllib.parse.urlencode(params, doseq=True)
        url = f"{BASE_URL}?{qs}" if qs else BASE_URL
        req = Request(url, method="GET")
        req.add_header("Authorization", f"Bearer {TOKEN}")
        req.add_header("Accept", "application/json")
        attempt = 0
        while True:
            try:
                with urlopen(req, timeout=HTTP_TIMEOUT) as r:
                    return json.loads(r.read().decode("utf-8"))
            except HTTPError as e:
                # Respect Retry-After on 429/5xx
                if e.code in (429, 500, 502, 503, 504) and attempt < HTTP_RETRIES:
                    retry_after = 0
                    try:
                        retry_after = int(
                            e.headers.get("Retry-After", RETRY_AFTER_DEFAULT)
                        )
                    except Exception:
                        retry_after = RETRY_AFTER_DEFAULT
                    time.sleep(max(1, retry_after))
                    attempt += 1
                    continue
                raise
            except URLError:
                if attempt < HTTP_RETRIES:
                    time.sleep(RETRY_AFTER_DEFAULT)
                    attempt += 1
                    continue
                raise
    
    def _write_page(data: dict, page_idx: int) -> str:
        """Extract entries from Slack API response and write as JSONL."""
        entries = data.get("entries") or []
        if not entries:
            return None
        lines = [json.dumps(entry, separators=(",", ":")) for entry in entries]
        body = "\n".join(lines).encode("utf-8")
        ts = time.strftime("%Y/%m/%d/%H%M%S", time.gmtime())
        key = f"{PREFIX}{ts}-slack-audit-p{page_idx:05d}.json"
        s3.put_object(
            Bucket=BUCKET, Key=key, Body=body, ContentType="application/json"
        )
        return key
    
    def lambda_handler(event=None, context=None):
        state = _get_state()
        cursor = state.get("cursor")
        params = {"limit": LIMIT}
        if ACTIONS:
            params["action"] = [a.strip() for a in ACTIONS.split(",") if a.strip()]
        if cursor:
            params["cursor"] = cursor
        else:
            # First run (or reset): fetch a recent window by time
            params["oldest"] = int(time.time()) - LOOKBACK_SEC
        pages = 0
        total = 0
        last_cursor = None
        while pages < MAX_PAGES:
            data = _http_get(params)
            _write_page(data, pages)
            entries = data.get("entries") or []
            total += len(entries)
            # Cursor for next page
            meta = data.get("response_metadata") or {}
            next_cursor = meta.get("next_cursor") or data.get("next_cursor")
            if next_cursor:
                params = {"limit": LIMIT, "cursor": next_cursor}
                if ACTIONS:
                    params["action"] = [
                        a.strip() for a in ACTIONS.split(",") if a.strip()
                    ]
                last_cursor = next_cursor
                pages += 1
                continue
            break
        if last_cursor:
            _put_state({"cursor": last_cursor})
        return {
            "ok": True,
            "pages": pages + (1 if total or last_cursor else 0),
            "entries": total,
            "cursor": last_cursor,
        }
    
    if __name__ == "__main__":
        print(lambda_handler())
    

הגדרת משתני סביבה ב-Lambda

  1. עוברים אל Configuration > Environment variables > Edit > Add environment variable.
  2. מזינים את משתני הסביבה הבאים ומחליפים את הערכים בערכים שלכם:

    מפתח ערך לדוגמה
    SLACK_AUDIT_TOKEN xoxp-... (אסימון משתמש ברמת הארגון עם auditlogs:read)
    S3_BUCKET slack-audit-logs
    S3_PREFIX slack/audit/
    STATE_KEY slack-audit-state.json
    LIMIT 200
    MAX_PAGES 20
    LOOKBACK_SECONDS 3600
    HTTP_TIMEOUT 60
    HTTP_RETRIES 3
    RETRY_AFTER_DEFAULT 2
    ACTIONS (אופציונלי, מסנן פעולות מופרד בפסיקים)
  3. לוחצים על Save.

  4. בוחרים את הכרטיסייה Configuration. בחלונית General configuration לוחצים על Edit.

  5. משנים את הערך של Timeout ל-5 minutes (300 שניות) ולוחצים על Save.

יצירת לוח זמנים של EventBridge

  1. עוברים אל Amazon EventBridge > Scheduler > Create schedule (מתזמן > יצירת תזמון).
  2. מזינים את פרטי ההגדרה הבאים:
    • שם: מזינים slack-audit-1h.
    • לו"ז חזרה: בוחרים באפשרות לו"ז מבוסס-תעריף.
    • ביטוי תעריף: מזינים 1 hours.
    • חלון זמן גמיש: בוחרים באפשרות מושבת.
  3. לוחצים על הבא.
  4. בוחרים יעד:
    • ‫Target API (ממשק ה-API לטירגוט): בוחרים באפשרות AWS Lambda Invoke.
    • פונקציית Lambda: בוחרים באפשרות slack_audit_to_s3.
  5. לוחצים על הבא.
  6. לוחצים על הבא (מדלגים על הגדרות אופציונליות).
  7. בודקים את הפרטים ולוחצים על יצירת לוח זמנים.

(אופציונלי) יצירת משתמש IAM לקריאה בלבד ב-Google SecOps

  1. עוברים אל AWS Console > IAM > Users > Create user (מסוף AWS > IAM > משתמשים > יצירת משתמש).
  2. מזינים את פרטי ההגדרה הבאים:
    • שם משתמש: מזינים secops-reader.
    • סוג גישה: בוחרים באפשרות גישה פרוגרמטית.
  3. לוחצים על הבא.
  4. בוחרים באפשרות Attach policies directly.
  5. לוחצים על יצירת מדיניות. בכרטיסייה JSON, מדביקים את הקוד הבא:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["s3:GetObject"],
          "Resource": "arn:aws:s3:::slack-audit-logs/*"
        },
        {
          "Effect": "Allow",
          "Action": ["s3:ListBucket"],
          "Resource": "arn:aws:s3:::slack-audit-logs"
        }
      ]
    }
    
  6. לוחצים על הבא.

  7. מזינים את שם המדיניות secops-reader-policy.

  8. לוחצים על יצירת מדיניות.

  9. חוזרים לדף ליצירת משתמשים, מרעננים את רשימת כללי המדיניות ובוחרים באפשרות secops-reader-policy.

  10. לוחצים על הבא.

  11. לוחצים על יצירת משתמש.

  12. בוחרים את המשתמש שנוצר secops-reader.

  13. עוברים אל Security credentials > Access keys > Create access key (פרטי כניסה לאבטחה > מפתחות גישה > יצירת מפתח גישה).

  14. בוחרים באפשרות שירות של צד שלישי.

  15. לוחצים על הבא.

  16. לוחצים על יצירת מפתח גישה.

  17. לוחצים על הורדת קובץ CSV כדי לשמור את פרטי הכניסה.

הגדרת פיד ב-Google SecOps כדי להטמיע יומני ביקורת של Slack

  1. עוברים אל SIEM Settings > Feeds (הגדרות SIEM > פידים).
  2. לוחצים על הוספת פיד חדש.
  3. לוחצים על Configure a single feed (הגדרת פיד יחיד).
  4. בשדה שם הפיד, מזינים שם לפיד (לדוגמה, Slack Audit Logs).
  5. בוחרים באפשרות Amazon S3 V2 בתור סוג המקור.
  6. בוחרים באפשרות ביקורת Slack בתור סוג היומן.
  7. לוחצים על הבא.
  8. מציינים ערכים לפרמטרים הבאים של הקלט:

    • ‫S3 URI: מזינים את ה-URI של קטגוריית S3 עם נתיב הקידומת:

      ```
      s3://slack-audit-logs/slack/audit/
      ```
      
      Replace `slack-audit-logs` with your actual S3 bucket name.
      
    • אפשרות מחיקת המקור: בוחרים את אפשרות המחיקה הרצויה.

    • גיל מקסימלי של קובץ: כולל קבצים ששונו במספר הימים האחרונים. ברירת המחדל היא 180 ימים.

    • ‫Access Key ID: מזהה מפתח הגישה של המשתמש עם גישה לקטגוריית S3 (ממשתמש secops-reader Identity and Access Management (IAM)).

    • מפתח גישה סודי: מפתח סודי של משתמש עם גישה לקטגוריית S3 (ממשתמש ה-IAM של secops-reader).

    • מרחב השמות של הנכס: מרחב השמות של הנכס.

    • תוויות להוספה: התווית שתתווסף לאירועים מהפיד הזה.

  9. לוחצים על הבא.

  10. בודקים את הגדרות הפיד החדש במסך סיום ולוחצים על שליחה.

טבלת מיפוי UDM

שדה ביומן מיפוי UDM היגיון
action metadata.product_event_type ממופה ישירות מהשדה action
actor.type principal.labels ממופה ישירות באמצעות המקש actor.type
actor.user.email principal.user.email_addresses מיפוי ישיר
actor.user.id principal.user.product_object_id מיפוי ישיר
actor.user.id principal.user.userid מיפוי ישיר
actor.user.name principal.user.user_display_name מיפוי ישיר
actor.user.team principal.user.group_identifiers מיפוי ישיר
context.ip_address principal.ip מיפוי ישיר
context.location.domain about.resource.attribute.labels ממופה ישירות באמצעות המקש context.location.domain
context.location.id about.resource.id מיפוי ישיר
context.location.name about.resource.name מיפוי ישיר
context.location.name about.resource.attribute.labels ממופה ישירות עם המפתח context.location.name
context.location.type about.resource.resource_subtype מיפוי ישיר
context.session_id network.session_id מיפוי ישיר
context.ua network.http.user_agent מיפוי ישיר
context.ua network.http.parsed_user_agent סוכן משתמש שנותח, שנגזר מהשדה context.ua
country principal.location.country_or_region מיפוי ישיר
date_create metadata.event_timestamp.seconds חותמת זמן של תקופת זמן המערכת שהומרה לאובייקט חותמת זמן
details.inviter.email target.user.email_addresses מיפוי ישיר
details.inviter.id target.user.product_object_id מיפוי ישיר
details.inviter.name target.user.user_display_name מיפוי ישיר
details.inviter.team target.user.group_identifiers מיפוי ישיר
details.reason security_result.description ממופה ישירות. אם מדובר במערך, הערכים מחוברים באמצעות פסיקים
details.type about.resource.attribute.labels ממופה ישירות באמצעות המקש details.type
details.type security_result.summary מיפוי ישיר
entity.app.id target.resource.id מיפוי ישיר
entity.app.name target.resource.name מיפוי ישיר
entity.channel.id target.resource.id מיפוי ישיר
entity.channel.name target.resource.name מיפוי ישיר
entity.channel.privacy target.resource.attribute.labels ממופה ישירות באמצעות המקש entity.channel.privacy
entity.file.filetype target.resource.attribute.labels ממופה ישירות באמצעות המקש entity.file.filetype
entity.file.id target.resource.id מיפוי ישיר
entity.file.name target.resource.name מיפוי ישיר
entity.file.title target.resource.attribute.labels ממופה ישירות עם המפתח entity.file.title
entity.huddle.date_end about.resource.attribute.labels ממופה ישירות עם המפתח entity.huddle.date_end
entity.huddle.date_start about.resource.attribute.labels ממופה ישירות עם המפתח entity.huddle.date_start
entity.huddle.id about.resource.attribute.labels ממופה ישירות באמצעות המקש entity.huddle.id
entity.huddle.participants.0 about.resource.attribute.labels ממופה ישירות באמצעות המקש entity.huddle.participants.0
entity.huddle.participants.1 about.resource.attribute.labels ממופה ישירות עם המפתח entity.huddle.participants.1
entity.type target.resource.resource_subtype מיפוי ישיר
entity.user.email target.user.email_addresses מיפוי ישיר
entity.user.id target.user.product_object_id מיפוי ישיר
entity.user.name target.user.user_display_name מיפוי ישיר
entity.user.team target.user.group_identifiers מיפוי ישיר
entity.workflow.id target.resource.id מיפוי ישיר
entity.workflow.name target.resource.name מיפוי ישיר
id metadata.product_log_id מיפוי ישיר
ip principal.ip מיפוי ישיר
user_agent network.http.user_agent מיפוי ישיר
user_id principal.user.product_object_id מיפוי ישיר
username principal.user.product_object_id מיפוי ישיר
metadata.event_type ברירת המחדל היא USER_COMMUNICATION; הערך מוגדר כ-USER_CREATION אם הפעולה היא user_created, כ-USER_LOGIN אם הפעולה היא user_login או user_login_failed, כ-USER_LOGOUT אם הפעולה היא user_logout, כ-USER_RESOURCE_ACCESS אם הפעולה תואמת ל-file_, כ-USER_RESOURCE_UPDATE_PERMISSIONS אם הפעולה תואמת ל-app_, ל-private_, ל-public_ או ל-auth_policy_, כ-USER_CHANGE_PERMISSIONS אם הפעולה תואמת ל-pref, ל-legal_hold_, ל-workflow_, ל-channel_, ל-user_deactivated, ל-user_reactivated, ל-role_change_ או ל-user_channel_
metadata.log_type מקודד באופן קשיח ל-SLACK_AUDIT
metadata.product_name הגדרה ל-Enterprise Grid אם date_create קיים, אחרת ל-Audit Logs אם user_id קיים
metadata.vendor_name הוזן קוד קשיח ל-Slack
extensions.auth.mechanism מקודד באופן קשיח ל-REMOTE
extensions.auth.type הערך שמוגדר הוא SSO אם הפעולה מכילה user_login או user_logout, אחרת MACHINE
security_result.action ברירת המחדל היא ALLOW. אם הפעולה היא user_login_failed, הערך שמוגדר הוא BLOCK.
target.application הערך הוא Slack אם date_create קיים, אחרת SLACK אם user_id קיים

יומן שינויים

צפייה ביומן השינויים של המנתח הזה

הבעיה עדיין לא נפתרה? קבלת תשובות מחברי הקהילה וממומחי Google SecOps.