Description: Sentinel supports ingesting RFC 5424 syslog messages from external sources through the use of the Azure Monitor Agent (AMA). Microsoft's documentation on the deployment is available here.
This guide assumes you have a Linux VM running within your Azure environment with Microsoft's prerequisites here.
In summary, to start off this guide you'll need:
- Microsoft Sentinel added to a workspace.
- A Linux VM setup with the AMA installed and forwarding logs.
- Port 514 (or your custom one) opened on the log forwarder VM security group.
- Optional - TLS can be setup based on your preferred syslog daemon:
Step 1: Data Connector Configuration
Head over to your Azure Sentinel deployment, then Data connectors, and finally Content hub.
Search for "Syslog via AMA" to reveal the Syslog data connector, then install the package if not installed already.
With the Syslog via AMA data connector installed, head over to your Sentinel instances Data connectors page, then open the connector page for Syslog via AMA.
Select Create data collection rule
Name your DCR.
Select your Log forwarding VM.
Select your minimum log collection level. By default we send local0.crit tagged messages.
Validate and create your DCR.
With the DCR created and installed, grab and run the installation script on your syslog forwarder VM.
Step 2: Validate Data Flow
Confirm your syslog daemon is listening on your port of choice.
Send a test RFC5424 message:
echo -n "<10>1 $(date -u +"%Y-%m-%dT%H:%M:%S.%NZ") localhost canary 1234 - Hello World Chirp Chirp!" | nc -u -w0 localhost 514
Step 3: Console Configuration
Contact Support@canary.tools to have your Log forwarder configured onto your Console.
We'll need the following details of the setup:
Hostname / IP
Port (514 Default)
Protocol (TCP/UDP)
TLS Certificate (Optional but recommended.)
Once configured, details are available in the Global Settings -> Syslog menu on your Canary Console.
Note: Syslog message transport can be tested by sending a couple test messages to your forwarder. Head over to the "Syslog" menu option, type a number in "Send N Test Messages", then press "Test".
Step 4: Checking logs
Console logs can be queried by heading over to your Sentinel instance, then selecting the "Logs" slide out menu.
Selecting LogManagement, then Syslog, allows you to check all incoming raw syslog messages.
Logs can also be easily found using the below query.
Syslog | where HostName == "ThinkstCanary"
You can also parse your syslog messages using the below KQL query.
Syslog | where HostName == "ThinkstCanary" | extend SyslogMessage = replace_string(SyslogMessage, @"#011", " | ") | extend kv_pairs = extract_all(@"(?:^|\| )([^\|=]+)=([^\|]+)", SyslogMessage) | mv-expand pair = kv_pairs | extend Key = trim(" ", tostring(pair[0])), Value = trim(" ", tostring(pair[1])) | summarize AdditionalData = make_bag(bag_pack(Key, Value)), CanaryAlert = take_any(SyslogMessage) by TimeGenerated | extend // Create new columns for the fields you care about. Simply reference the fields in the AdditionalData object. BackgroundContext = tostring(AdditionalData.["Background Context"]), CanaryIP = tostring(AdditionalData.CanaryIP), Description = tostring(AdditionalData.Description), DestinationPort = toint(AdditionalData.["Dst Port"]), Reminder = tostring(AdditionalData.Reminder), SourceIP = tostring(AdditionalData.SourceIP), TimeOccured = tostring(AdditionalData.Timestamp)
You're done! ;-)
Analytics Rule to create incidents from alerts.
With Canary alert data now flowing into your Sentinel instance, you may want to generate incidents from new alerts, this is entirely optional and below we'll create an analytics rule to automatically make that happen.
Step 1: Import the Analytics Rule
Head over to your Azure Sentinel blade here. From here select your Sentinel instance, and import a predefined Analytics Rule.
You’ll need at least one Canary —not CanaryToken— alert sent to Sentinel before this rule can be successfully imported.
The below schema can be saved as a file locally and uploaded using the Import option.
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "workspace": { "type": "String" } }, "resources": [ { "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/48ca2eee-c942-4cca-88ad-cdfc35ff721e')]", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/48ca2eee-c942-4cca-88ad-cdfc35ff721e')]", "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules", "kind": "NRT", "apiVersion": "2023-12-01-preview", "properties": { "displayName": "Canary Alerts To Incidents", "description": "Creates Sentinel Incidents from Thinkst Canary Alerts", "severity": "High", "enabled": true, "query": "Syslog\n| where HostName == \"ThinkstCanary\"\n| extend SyslogMessage = replace_string(SyslogMessage, @\"#011\", \" | \")\n| extend kv_pairs = extract_all(@\"(?:^|\\| )([^\\|=]+)=([^\\|]+)\", SyslogMessage)\n| mv-expand pair = kv_pairs\n| extend Key = trim(\" \", tostring(pair[0])), Value = trim(\" \", tostring(pair[1]))\n| summarize AdditionalData = make_bag(bag_pack(Key, Value)), CanaryAlert = take_any(SyslogMessage) \n by TimeGenerated\n| extend\n Description = tostring(AdditionalData.Description),\n SourceIP = tostring(AdditionalData.SourceIP),\n ReverseDNS = tostring(AdditionalData.ReverseDNS)\n| where AdditionalData.Description <> \"Fake Location\"", "suppressionDuration": "PT5H", "suppressionEnabled": false, "tactics": [ "Exfiltration", "LateralMovement" ], "techniques": [], "subTechniques": [], "alertRuleTemplateName": null, "incidentConfiguration": { "createIncident": true, "groupingConfiguration": { "enabled": false, "reopenClosedIncident": false, "lookbackDuration": "PT5H", "matchingMethod": "AllEntities", "groupByEntities": [], "groupByAlertDetails": [], "groupByCustomDetails": [] } }, "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "alertDetailsOverride": { "alertDisplayNameFormat": "Alert from Thinkst Canary", "alertDescriptionFormat": "{{Description}} at {{TimeGenerated}}", "alertDynamicProperties": [] }, "customDetails": { "Events": "AdditionalData" }, "entityMappings": [ { "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "SourceIP" } ] }, { "entityType": "Host", "fieldMappings": [ { "identifier": "HostName", "columnName": "ReverseDNS" } ] } ], "sentinelEntitiesMappings": null, "templateVersion": null } } ] }
You'll now find the rule has been added.
Incidents will now be automatically created on new Canary alerts.