Raccogliere i log di controllo di Tines

Supportato in:

Questo documento spiega come importare i log di controllo di Tines in Google Security Operations utilizzando Amazon S3.

Prima di iniziare

Assicurati di soddisfare i seguenti prerequisiti:

  • Un'istanza Google SecOps.
  • Accesso privilegiato a Tines.
  • Accesso privilegiato ad AWS (S3, Identity and Access Management (IAM), Lambda, EventBridge).

Recuperare l'URL di Tines

  1. Nel browser, apri l'interfaccia utente di Tines per il tuo tenant.
  2. Copia il dominio dalla barra degli indirizzi. Lo utilizzerai come TINES_BASE_URL.
    • Formato: https://<tenant-domain> (ad esempio, https://<tenant-domain>.tines.com).

Valori da salvare per i passaggi successivi:

  • TINES_BASE_URL. Ad esempio, https://<domain>.tines.com
  • TINES_API_KEY: il token che crei nei passaggi successivi
  1. Vai al menu di navigazione > Chiavi API.
  2. Fai clic su + Nuova chiave.
  3. Seleziona Chiave API del servizio.
  4. Inserisci un nome descrittivo (ad esempio, SecOps Audit Logs).
  5. Fai clic su Crea.
  6. Copia immediatamente il token generato e salvalo in modo sicuro. Lo utilizzerai come TINES_API_KEY.

Opzione 2: chiave API personale (se le chiavi di servizio non sono disponibili)

  1. Vai al menu di navigazione > Chiavi API.
  2. Fai clic su + Nuova chiave.
  3. Seleziona Chiave API personale.
  4. Inserisci un nome descrittivo.
  5. Fai clic su Crea.
  6. Copia il token generato e salvalo in modo sicuro.

Concedi l'autorizzazione di lettura degli audit log

  1. Accedi come proprietario del tenant (o chiedi a un proprietario di farlo).
  2. Vai a Impostazioni > Amministratore > Amministrazione utenti (o fai clic sul nome del tuo team nel menu in alto a sinistra e seleziona Utenti).
  3. Trova l'utente del service account associato alla tua chiave API di servizio (avrà lo stesso nome della tua chiave API).
    • Se utilizzi una chiave API personale, trova invece il tuo account utente.
  4. Fai clic sull'utente per aprire il suo profilo.
  5. Nella sezione Tenant permissions (Autorizzazioni tenant), attiva AUDIT_LOG_READ.
  6. Fai clic su Salva.

(Facoltativo) Verifica l'accesso API

  1. Testa l'endpoint utilizzando curl o qualsiasi client HTTP:

    curl -X GET "https://<tenant-domain>/api/v1/audit_logs?per_page=1" \
        -H "Authorization: Bearer <TINES_API_KEY>" \
        -H "Content-Type: application/json"
    
  2. Dovresti ricevere una risposta JSON con le voci del log di controllo.

  3. Puoi anche verificare l'esistenza dei log di controllo andando a Impostazioni > Monitoraggio > Log di controllo nell'interfaccia utente (richiede l'autorizzazione AUDIT_LOG_READ).

Configura il bucket AWS S3

  1. Crea un bucket Amazon S3 seguendo questa guida utente: Creazione di un bucket
  2. Salva il nome e la regione del bucket per riferimento futuro (ad esempio, tines-audit-logs).

Configura il ruolo e il criterio IAM per i caricamenti S3 di Lambda

  1. Nella console AWS, vai a IAM > Policy > Crea policy > Scheda JSON.
  2. Copia e incolla i seguenti criteri.
  3. JSON delle policy (sostituisci tines-audit-logs se hai inserito un nome del bucket diverso):

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowPutObjects",
          "Effect": "Allow",
          "Action": "s3:PutObject",
          "Resource": "arn:aws:s3:::tines-audit-logs/*"
        },
        {
          "Sid": "AllowGetStateObject",
          "Effect": "Allow",
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::tines-audit-logs/tines/audit/state.json"
        }
      ]
    }
    
  4. Fai clic su Avanti > Crea criterio.

  5. Assegna al criterio il nome TinesLambdaS3Policy.

  6. Vai a IAM > Ruoli > Crea ruolo > Servizio AWS > Lambda.

  7. Allega il TinesLambdaS3Policy appena creato.

  8. Assegna al ruolo il nome TinesAuditToS3Role e fai clic su Crea ruolo.

Crea la funzione Lambda

  1. Nella console AWS, vai a Lambda > Funzioni > Crea funzione.
  2. Fai clic su Crea autore da zero.
  3. Fornisci i seguenti dettagli di configurazione:

    Impostazione Valore
    Nome tines_audit_to_s3
    Tempo di esecuzione Python 3.13
    Architettura x86_64
    Ruolo di esecuzione TinesAuditToS3Role
  4. Dopo aver creato la funzione, apri la scheda Codice, elimina lo stub e incolla il seguente codice (tines_audit_to_s3.py).

    #!/usr/bin/env python3
    # Lambda: Pull Tines Audit Logs to S3 (no transform)
    
    import os, json, time, urllib.parse
    from urllib.request import Request, urlopen
    from urllib.error import HTTPError, URLError
    import boto3
    
    S3_BUCKET      = os.environ["S3_BUCKET"]
    S3_PREFIX      = os.environ.get("S3_PREFIX", "tines/audit/")
    STATE_KEY      = os.environ.get("STATE_KEY", "tines/audit/state.json")
    LOOKBACK_SEC   = int(os.environ.get("LOOKBACK_SECONDS", "3600"))  # default 1h
    PAGE_SIZE      = int(os.environ.get("PAGE_SIZE", "500"))  # Max is 500 for Tines
    MAX_PAGES      = int(os.environ.get("MAX_PAGES", "20"))
    TIMEOUT        = int(os.environ.get("HTTP_TIMEOUT", "60"))
    HTTP_RETRIES   = int(os.environ.get("HTTP_RETRIES", "3"))
    TINES_BASE_URL = os.environ["TINES_BASE_URL"]
    TINES_API_KEY  = os.environ["TINES_API_KEY"]
    
    s3 = boto3.client("s3")
    
    def _iso(ts: float) -> str:
        return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(ts))
    
    def _load_state() -> dict:
        try:
            obj = s3.get_object(Bucket=S3_BUCKET, Key=STATE_KEY)
            b = obj["Body"].read()
            return json.loads(b) if b else {}
        except Exception:
            return {}
    
    def _save_state(st: dict) -> None:
        s3.put_object(
            Bucket=S3_BUCKET, Key=STATE_KEY,
            Body=json.dumps(st, separators=(",", ":")).encode("utf-8"),
            ContentType="application/json",
        )
    
    def _req(url: str) -> dict:
        attempt = 0
        while True:
            try:
                req = Request(url, method="GET")
                req.add_header("Authorization", f"Bearer {TINES_API_KEY}")
                req.add_header("Accept", "application/json")
                req.add_header("Content-Type", "application/json")
                with urlopen(req, timeout=TIMEOUT) as r:
                    data = r.read()
                return json.loads(data.decode("utf-8"))
            except HTTPError as e:
                if e.code in (429, 500, 502, 503, 504) and attempt < HTTP_RETRIES:
                    retry_after = 1 + attempt
                    try:
                        retry_after = int(e.headers.get("Retry-After", retry_after))
                    except Exception:
                        pass
                    time.sleep(max(1, retry_after))
                    attempt += 1
                    continue
                raise
            except URLError:
                if attempt < HTTP_RETRIES:
                    time.sleep(1 + attempt)
                    attempt += 1
                    continue
                raise
    
    def _write(payload, page: int) -> str:
        ts = time.gmtime()
        key = f"{S3_PREFIX}{time.strftime('%Y/%m/%d/%H%M%S', ts)}-tines-audit-{page:05d}.json"
        s3.put_object(
            Bucket=S3_BUCKET, Key=key,
            Body=json.dumps(payload, separators=(",", ":")).encode("utf-8"),
            ContentType="application/json",
        )
        return key
    
    def _extract_items(payload) -> list:
        if isinstance(payload, list):
            return payload
        if isinstance(payload, dict):
            audit_logs = payload.get("audit_logs")
            if isinstance(audit_logs, list):
                return audit_logs
        return []
    
    def _extract_newest_ts(items: list, current: str | None) -> str | None:
        newest = current
        for it in items:
            # Use created_at as the timestamp field
            t = it.get("created_at")
            if isinstance(t, str) and (newest is None or t > newest):
                newest = t
        return newest
    
    def lambda_handler(event=None, context=None):
        st = _load_state()
        since = st.get("since") or _iso(time.time() - LOOKBACK_SEC)
    
        page = 1
        pages = 0
        total = 0
        newest_ts = since
    
        while pages < MAX_PAGES:
            # Build URL with query parameters
            # Note: Tines audit logs API uses 'after' parameter for filtering
            base_url = f"{TINES_BASE_URL.rstrip('/')}/api/v1/audit_logs"
            params = {
                "after": since,  # Filter for logs created after this timestamp
                "page": page,
                "per_page": PAGE_SIZE
            }
            url = f"{base_url}?{urllib.parse.urlencode(params)}"
    
            payload = _req(url)
            _write(payload, page)
            items = _extract_items(payload)
            total += len(items)
            newest_ts = _extract_newest_ts(items, newest_ts)
            pages += 1
    
            # Check if there's a next page using meta.next_page_number
            meta = payload.get("meta") or {}
            next_page = meta.get("next_page_number")
    
            if not next_page:
                break
            page = next_page
    
        if newest_ts and newest_ts != since:
            st["since"] = newest_ts
            _save_state(st)
    
        return {"ok": True, "pages": pages, "items": total, "since": st.get("since")}
    
    if __name__ == "__main__":
        print(lambda_handler())
    
  5. Vai a Configurazione > Variabili di ambiente.

  6. Fai clic su Modifica > Aggiungi nuova variabile di ambiente.

  7. Inserisci le variabili di ambiente fornite nella tabella seguente, sostituendo i valori di esempio con i tuoi valori.

    Variabili di ambiente

    Chiave Valore di esempio
    S3_BUCKET tines-audit-logs
    S3_PREFIX tines/audit/
    STATE_KEY tines/audit/state.json
    TINES_BASE_URL https://your-tenant.tines.com
    TINES_API_KEY your-tines-api-key
    LOOKBACK_SECONDS 3600
    PAGE_SIZE 500
    MAX_PAGES 20
    HTTP_TIMEOUT 60
    HTTP_RETRIES 3
  8. Dopo aver creato la funzione, rimani sulla relativa pagina (o apri Lambda > Funzioni > la tua funzione).

  9. Seleziona la scheda Configurazione.

  10. Nel riquadro Configurazione generale, fai clic su Modifica.

  11. Modifica Timeout impostando 5 minuti (300 secondi) e fai clic su Salva.

Creare una pianificazione EventBridge

  1. Vai a Amazon EventBridge > Scheduler > Crea pianificazione.
  2. Fornisci i seguenti dettagli di configurazione:
    • Programma ricorrente: Tariffa (1 hour).
    • Target: la tua funzione Lambda tines_audit_to_s3.
    • Nome: tines-audit-1h
  3. Fai clic su Crea pianificazione.

Crea un utente IAM con autorizzazione di sola lettura e chiavi per Google SecOps

  1. Nella console AWS, vai a IAM > Utenti.
  2. Fai clic su Add users (Aggiungi utenti).
  3. Fornisci i seguenti dettagli di configurazione:
    • Utente: inserisci secops-reader.
    • Tipo di accesso: seleziona Chiave di accesso - Accesso programmatico.
  4. Fai clic su Crea utente.
  5. Collega la criterio per la lettura minima (personalizzata): Utenti > secops-reader > Autorizzazioni > Aggiungi autorizzazioni > Collega le norme direttamente > Crea norma.
  6. JSON:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["s3:GetObject"],
          "Resource": "arn:aws:s3:::tines-audit-logs/*"
        },
        {
          "Effect": "Allow",
          "Action": ["s3:ListBucket"],
          "Resource": "arn:aws:s3:::tines-audit-logs"
        }
      ]
    }
    
  7. Name = secops-reader-policy.

  8. Fai clic su Crea criterio > cerca/seleziona > Avanti > Aggiungi autorizzazioni.

  9. Crea la chiave di accesso per secops-reader: Credenziali di sicurezza > Chiavi di accesso.

  10. Fai clic su Crea chiave di accesso.

  11. Scarica il .CSV. Incollerai questi valori nel feed.

Configurare un feed in Google SecOps per importare i log di controllo di Tines

  1. Vai a Impostazioni SIEM > Feed.
  2. Fai clic su + Aggiungi nuovo feed.
  3. Nel campo Nome feed, inserisci un nome per il feed (ad esempio, Tines Audit Logs).
  4. Seleziona Amazon S3 V2 come Tipo di origine.
  5. Seleziona Tines come Tipo di log.
  6. Fai clic su Avanti.
  7. Specifica i valori per i seguenti parametri di input:
    • URI S3: s3://tines-audit-logs/tines/audit/
    • Opzioni di eliminazione dell'origine: seleziona l'opzione di eliminazione in base alle tue preferenze.
    • Età massima del file: includi i file modificati nell'ultimo numero di giorni. Il valore predefinito è 180 giorni.
    • ID chiave di accesso: chiave di accesso utente con accesso al bucket S3.
    • Chiave di accesso segreta: chiave segreta dell'utente con accesso al bucket S3.
    • Spazio dei nomi dell'asset: lo spazio dei nomi dell'asset.
    • Etichette di importazione: l'etichetta applicata agli eventi di questo feed.
  8. Fai clic su Avanti.
  9. Controlla la nuova configurazione del feed nella schermata Finalizza e poi fai clic su Invia.

Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.