Sophos SIEM: verificare HTTP Ingest e parser con un esempio
Questo esempio collega una fonte JSON sintetica a HTTP Ingest, a un Custom Parser per lo schema Auth e a una ricerca mirata. Mostra così il percorso tra le singole guide a HTTP Ingest e ai Custom Parser. L’esempio segnala soltanto login fittizi di laboratorio; non esegue un’autenticazione utente reale e non verifica credenziali.
Preparare il laboratorio e definire il successo
Servono un tenant di test con subscription Next-Gen SIEM, un ruolo autorizzato Admin o Super Admin e un computer approvato con Python 3 e accesso HTTPS all’endpoint di ingest assegnato. La pianificazione SIEM spiega licenza e limiti di conservazione. Un accesso XDR esistente da solo non basta per trasporto personalizzato e Custom Parser.
Il contratto del laboratorio è intenzionalmente ristretto: un messaggio JSON per POST, il formato di campi riportato sotto e la sorgente fissa avanet-lab-source. La guida HTTP descrive POST HTTPS con token Bearer, ma non stabilisce un body di risposta, codice di stato o contenitore del payload universale per tutte le fonti. Prima del test di invio controllare l’endpoint effettivamente fornito e i suoi requisiti correnti. Se quella specifica erogazione richiede una struttura del body diversa, adattarla prima sulla base della relativa documentazione; il modello non è una specifica API di ingest universale.
Prima di iniziare documentare tenant, responsabile, nome dell’integrazione, nome del parser e momento del test. Il risultato atteso comprende tre evidenze separate:
- La fonte di laboratorio approvata ha inviato esattamente il messaggio previsto.
- Il parser associa correttamente i valori sorgente fittizi allo schema Auth.
- Il messaggio è reperibile nel tenant corretto con ora, sorgente e identificativo di test appropriati.
Un successo HTTP, un connettore verde o uno script sintatticamente valido da soli non superano questa accettazione. Non si prevede né un rilevamento né una gestione MDR di questo evento di laboratorio.
Formato di test e modello completo del parser
La fonte di laboratorio usa questa singola riga JSON:
{"product":"avanet-siem-lab","schema_version":1,"event_type":"logon","sensor_id":"avanet-lab-source","user":"pilot-user","src_ip":"192.0.2.25","session_id":"avanet-lab-20261029T101500Z","time":"2026-10-29T10:15:00Z","result":"success"}
192.0.2.25 è un indirizzo di documentazione. pilot-user non è un utente tenant. La session_id identifica questo ciclo di laboratorio fittizio, non la sessione di un’autenticazione reale. Nel successivo test di invio lo script genera un’ora UTC corrente e un nuovo identificativo; l’ora fissa dell’esempio serve soltanto per l’editor del parser.
In Security Operations > Integrations > Custom Parsers > Add Custom Parser creare un nuovo parser denominato AVANET_LAB_JSON_AUTH. Selezionare Standalone, formato sorgente JSON e schema di destinazione Auth. Non sovrascrivere né ampliare parser globali esistenti. Il modello completo seguente descrive esclusivamente il formato di laboratorio mostrato:
!SCHEMA=scwx.auth
!CONFIRMWITH=PATTERN
!CONFIRMSTRING=^\{"product":"avanet-siem-lab","schema_version":1,"event_type":"logon","sensor_id":"avanet-lab-source","user":"[^"]+","src_ip":"[^"]+","session_id":"[^"]+","time":"[^"]+","result":"(success|failure)"\}$
!TRIMALLOFF
!SAMPLE={"product":"avanet-siem-lab","schema_version":1,"event_type":"logon","sensor_id":"avanet-lab-source","user":"pilot-user","src_ip":"192.0.2.25","session_id":"avanet-lab-20261029T101500Z","time":"2026-10-29T10:15:00Z","result":"success"}
json = JSON(originalData$)
sensorType$ = "AVANET_SIEM_LAB"
sensorId$ = json["$.sensor_id"]
sourceUserName$ = json["$.user"]
sourceAddress$ = json["$.src_ip"]
sessionId$ = json["$.session_id"]
authSystem$ = json["$.product"]
eventTimeUsec$ = DATETIME(json["$.time"], "2006-01-02T15:04:05Z07:00")
authCategory$ = 10
action$ = IF json["$.result"] == "failure" THEN 8 ELSE 1
actionResult$ = IF json["$.result"] == "success" THEN 10 ELSE 20
La Confirm String è intenzionalmente limitata a questa esatta serializzazione compatta con ordine fisso dei campi. Un JSON indentato o con un ordine diverso non corrisponde. Per una fonte reale, riprogettare il modello di riconoscimento sulla base di messaggi originali rappresentativi; una ricerca generica della sola parola «logon» non sarebbe un sostituto equivalente.
Per questo laboratorio, i campi Auth utilizzati e i relativi valori enum fissi sono associati come segue:
| Valore grezzo | Campo del parser | Normalizzazione attesa |
|---|---|---|
sensor_id | sensorId$ | sensor_id |
user | sourceUserName$ | source_user_name |
src_ip | sourceAddress$ | source_address |
session_id | sessionId$ | session_id |
time UTC | eventTimeUsec$ | event_time_usec |
| Login di laboratorio | authCategory$ = 10 | ACCOUNT_LOGON |
success | action$ = 1, actionResult$ = 10 | LOGON, SUCCESS |
failure | action$ = 8, actionResult$ = 20 | FAILURE, FAILED |
I numeri sono enum dello schema, non livelli di gravità scelti liberamente. Il modello temporale Go in DATETIME() conserva l’indicatore UTC o un offset di fuso ISO-8601. Nell’editor confrontare valore grezzo e tempo normalizzato in microsecondi. Il modello non imposta autonomamente né tenantId$ né resourceId$; non sostituire questi valori con identificativi tenant o evento inventati.
Verificare nell’editor senza attivare il parser
Incollare la singola riga di esempio in Sample Message. Aprire Parse Message e poi Source Destination Mapping. Confrontare schema, utente, indirizzo, ora, esito ed extractor path con la tabella. Un avviso relativo a un altro parser deve essere chiarito prima dell’attivazione.
Inserire quindi diversi messaggi singoli come controprove:
- Cambiare
resultinfailure: si attendonoaction=8eaction_result=20. - Cambiare
productinother-lab: il messaggio non deve essere assegnato a questo parser. - Cambiare
resultinunknowno rimuovereuser: il messaggio non deve essere normalizzato come login riuscito; la Confirm String ristretta dovrebbe escluderlo. - Inserire un’ora non valida: un errore o l’assenza di un valore temporale corretto blocca l’approvazione. Non accettare l’ora di importazione come successo apparente.
Run Test verifica schema ed Extractor Paths di tutti i campioni inseriti. Sophos raccomanda campioni diversi e 12–15 esecuzioni del test, controllando il percorso del parser effettivamente utilizzato. Parse Message fornisce la Parsed Source Message e il Source Destination Mapping per la verifica del singolo messaggio. Un test non salva il parser; Save e Deploy sono passaggi distinti. Il salvataggio non dimostra un test riuscito. Lasciare inizialmente disattivato un nuovo parser. Su parser già attivi le modifiche avrebbero effetto immediato al salvataggio; per questo il laboratorio usa un nuovo parser dedicato. Il runbook generale sui parser spiega attivazione e percorso di ritorno.
Preparare un singolo invio HTTP
Dopo l’approvazione nel tenant di test, creare un’integrazione separata AVANET-LAB-HTTP in Security Operations > Integrations > Marketplace > Custom > HTTP Ingest > Set Up. Acquisire subito Integration Key e URL nel Secret Store approvato; Sophos li mostra una sola volta. Non riconfigurare ancora una fonte esistente.
Il seguente esempio Python invia esattamente un messaggio generato autonomamente. URL e chiave vengono richiesti senza mostrarli e non sono memorizzati come argomenti della riga di comando, variabili shell o parti del sorgente. La normale verifica TLS rimane attiva; i redirect HTTP non vengono seguiti, affinché la chiave Bearer non raggiunga un’altra destinazione. Lo script non contiene deliberatamente tentativi automatici, perché senza comportamento confermato potrebbero produrre eventi duplicati.
import datetime
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request
import uuid
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
url = getpass.getpass("Integration URL: ").strip()
key = getpass.getpass("Integration Key: ")
parsed = urllib.parse.urlsplit(url)
if parsed.scheme != "https" or not parsed.hostname or parsed.username or parsed.password or parsed.fragment:
raise SystemExit("Nur die freigegebene HTTPS-URL ohne eingebettete Zugangsdaten verwenden.")
now = datetime.datetime.now(datetime.timezone.utc)
time_text = now.strftime("%Y-%m-%dT%H:%M:%SZ")
run_id = "avanet-lab-" + now.strftime("%Y%m%dT%H%M%SZ") + "-" + uuid.uuid4().hex[:8]
event = {
"product": "avanet-siem-lab",
"schema_version": 1,
"event_type": "logon",
"sensor_id": "avanet-lab-source",
"user": "pilot-user",
"src_ip": "192.0.2.25",
"session_id": run_id,
"time": time_text,
"result": "success",
}
request = urllib.request.Request(
url,
data=json.dumps(event, separators=(",", ":")).encode("utf-8"),
headers={"Authorization": "Bearer " + key, "Content-Type": "application/json"},
method="POST",
)
print("Testkennung:", run_id, "UTC:", time_text)
try:
with urllib.request.build_opener(NoRedirect()).open(request, timeout=15) as response:
print("HTTP-Status:", response.status)
except urllib.error.HTTPError as error:
print("HTTP-Fehler:", error.code, "— nicht automatisch erneut senden.")
except urllib.error.URLError:
print("Verbindungs- oder TLS-Fehler — URL, Vertrauenskette und Netzwerkweg prüfen.")
Salvare il codice in un file di laboratorio locale senza valori segreti ed eseguirlo con Python 3. L’URL deve provenire esattamente dall’integrazione di laboratorio approvata; il codice non verifica la proprietà di un host HTTPS arbitrario. Non inserire chiave e URL in registrazioni pubbliche della console o nei ticket. Lo script non genera dati di clienti, password o sessioni produttive.
Una risposta HTTP non conferma da sola che l’evento sia stato acquisito e normalizzato. Con un timeout non è chiaro se il server abbia già accettato il messaggio. Prima di trasmetterlo di nuovo, cercare quindi l’identificativo di test annotato. Per 401/403 chiarire credenziali assegnate e stato dell’approvazione, senza ampliare diritti per tentativi. Per 4xx dovuti al formato del body, verificare il requisito specifico di ingest anziché provare involucri JSON arbitrari.
Cercare messaggio grezzo ed evento normalizzato
Verificare prima il trasporto separatamente. In Data Lake Search > Query Editor, cercare l’identificativo di test stampato in una finestra temporale ristretta:
FROM generic WHERE original_data CONTAINS 'avanet-lab-20261029T101500Z' earliest=-1h
Sostituire il valore di esempio con l’identificativo effettivamente stampato. In Original Data, prodotto, identificativo sorgente, utente, ora ed esito devono corrispondere alla riga inviata. Il sensor_id dell’evento generico può essere determinato dal percorso di acquisizione. Il nome visualizzato dell’integrazione non è quindi automaticamente il corretto identificativo di ricerca. Se si vuole filtrare anche per sensor_id, acquisire prima il valore effettivamente presente.
Dopo aver superato i test nell’editor, attivare consapevolmente il nuovo parser di laboratorio e inviare un nuovo messaggio di test. Non si presume che i dati grezzi già acquisiti vengano normalizzati nuovamente a posteriori. Cercare l’evento Auth atteso con i campi di laboratorio definiti:
FROM auth WHERE sensor_id = 'avanet-lab-source' AND session_id = 'avanet-lab-20261029T101500Z' earliest=-1h
Anche qui sostituire l’identificativo. Nel risultato verificare Normalized Data: source_user_name=pilot-user, source_address=192.0.2.25, ora corrispondente alla sorgente, action=1, auth_category=10 e action_result=10, oppure i relativi nomi enum visualizzati nella UI. L’extractor path deve appartenere al parser di laboratorio. Confrontare tutti questi valori prima di approvare la normalizzazione.
Per il tentativo negativo controllato, cambiare nel proprio generatore soltanto result in failure, creare un nuovo identificativo e inviare di nuovo esattamente una volta. Lo schema dovrebbe ora mostrare action=8 e action_result=20. Un ulteriore esito di normalizzazione riuscito per unknown o un identificativo prodotto estraneo sarebbe invece motivo di interruzione.
Circoscrivere gli errori e smontare il laboratorio
Nessun messaggio grezzo: Verificare ora di invio e identificativo di test, risposta del trasporto, tenant corretto, finestra temporale e fonte. Non considerare l’assenza di risultati come unica prova di un guasto del trasporto; la ricerca grezza generica richiede i parametri avanzati e l’accesso a original_data è limitato nel tempo.
Messaggio grezzo presente, nessun risultato Auth: Controllare stato del parser, serializzazione esatta, Confirm String, schema e percorso del parser. Non ampliare parser produttivi per acquisire in qualche modo l’evento di laboratorio.
Risultato Auth con esito o ora errati: Confrontare separatamente sorgente e mappatura. Disattivare il parser e correggere lo stato dello script salvato; non riempire i campi con valori predefiniti inventati.
Dopo l’accettazione arrestare il proprio mittente e disattivare tramite Disable soltanto il parser di laboratorio appena creato. Così termina la sua normalizzazione aggiuntiva; dati generici ed eventi già memorizzati non vengono considerati eliminati. Rimuovere l’integrazione di laboratorio solo dopo aver chiarito il percorso di sostituzione/revoca della sua chiave e ottenuto l’approvazione. La rimozione non deve modificare un’integrazione condivisa o un’altra fonte di dati.
La manutenzione successiva segue il flusso SIEM: documentare insieme formato sorgente e versione del parser, ripetere l’accettazione dopo modifiche e pianificare separatamente conservazione e gestione degli allarmi.