VM Security Log to Event Hub for SIEM integration

Streaming VM security log to Event Hub and add Event Hub to an Event Hub listener in SIEM is a common step in building SOC. Microsoft has separate articles for Windows and Linux where they give information on diagnostics agent configuration for Event Hub. Although these articles are very helpful they are still not ‘enough for lazy people‘ who would need to have a minimal understanding on how to deploy as well as sample template for testing purpose.

To fill that gap, this article is going to write a bit more in addition to Microsoft article. It also provides sample script and minimalist Azure ARM template deployment for both Windows and Linux virtual machines so you can test and evaluate your SIEM integration.

Disclaimer: This article is not going to give you any benchmark on Event Hub.

Pre-requisites

Before you can complete the deployment, you need to prepare Event Hub. You can use the following script for creating an Event Hub.

$resourceGroupName = "azsec-rg"
$location = "westus"

$eventHubNameSpaceName = "azsec-eventhub"
$windowsEventHubName = "windows_vm"
$linuxEventHubName = "linux_vm"
$windowsAuthorizationRuleName = "windows-policy"
$linuxAuthorizationRuleName = "linux-policy"


# Create Event Hub Namespace
New-AzureRmEventHubNamespace -ResourceGroupName $resourceGroupName `
                              -NamespaceName $eventHubNameSpaceName `
                              -SkuName "Standard"
                              -Location $location

# Create Windows Event Hub                             
New-AzureRmEventHub -ResourceGroupName $resourceGroupName `
                    -NamespaceName $eventHubNameSpaceName 
                    -EventHubName $windowsEventHubName `
                    -MessageRetentionInDays 3

# Create Linux Event Hub                             
New-AzureRmEventHub -ResourceGroupName $resourceGroupName `
                    -NamespaceName $eventHubNameSpaceName 
                    -EventHubName $linuxEventHubName `
                    -MessageRetentionInDays 3

# Create Windows Authorization Rule (Policy)
New-AzureRmEventHubAuthorizationRule -ResourceGroupName $resourceGroupName `
                                     -NamespaceName $eventHubNameSpaceName `
                                     -EventHubName $windowsEventHubName `
                                     -AuthorizationRuleName $windowsAuthorizationRuleName `
                                     -Rights @("Listen","Send")

# Create Linux Authorization Rule (Policy)
New-AzureRmEventHubAuthorizationRule -ResourceGroupName $resourceGroupName `
                                     -NamespaceName $eventHubNameSpaceName `
                                     -EventHubName $linuxEventHubName `
                                     -AuthorizationRuleName $linuxAuthorizationRuleName `
                                     -Rights @("Listen","Send")

# Get Windows Event Hub Shared Access Key
Get-AzureRmEventHubKey -ResourceGroupName $resourceGroupName ` 
                       -NamespaceName $eventHubNameSpaceName `
                       -EventHubName $windowsEventHubName `
                       -AuthorizationRuleName $windowsAuthorizationRuleName

# Get Windows Event Hub Shared Access Key
$linuxSharedAccessKey = Get-AzureRmEventHubKey -ResourceGroupName $resourceGroupName `
                       -NamespaceName $eventHubNameSpaceName `
                       -EventHubName $linuxEventHubName `
                       -AuthorizationRuleName $linuxAuthorizationRuleName

# Get Linux Event Hub SAS URL
[Reflection.Assembly]::LoadWithPartialName("System.Web")| out-null
$uri = "https//" + $eventHubNameSpaceName + ".servicebus.windows.net/" + $linuxEventHubName
$linuxSharedAccessKey = $linuxSharedAccessKey
$expires = ([DateTimeOffset]::Now.ToUnixTimeSeconds())+180
$signatureString=[System.Web.HttpUtility]::UrlEncode($uri)+ "`n" + [string]$expires
$HMAC = New-Object System.Security.Cryptography.HMACSHA256
$HMAC.key = [Text.Encoding]::ASCII.GetBytes($linuxSharedAccessKey)
$signature = $HMAC.ComputeHash([Text.Encoding]::ASCII.GetBytes($signatureString))
$signature = [Convert]::ToBase64String($Signature)
$sasUrl = "SharedAccessSignature sr=" + [System.Web.HttpUtility]::UrlEncode($uri) + "&sig=" + [System.Web.HttpUtility]::UrlEncode($signature) + "&se=" + $Expires + "&skn=" + $linuxEventHubName
Write-Host -ForegroundColor Yellow "Your Linux Event Hub SAS URL is:" $sasUrl

Security Log

For Windows, security related events are stored in Security category in Windows Event log.  With Linux security related events are stored in different places. They can be in var/log/audit. They can be from var/log/lastlog (last login). It depends on how you define a security event. But there is a stadard protocol called Syslog that helps stream Linux log. 

In Azure infrastructure context, Security event (Windows) and Syslog (Linux) can be captured from Diagnostics Log. That said, to collect such a log, you need to deploy diagnostics agent extension on target VMs.

Windows Deployment

Fresh deployment is simply when you want to bundle Event Hub integration into your ARM template and expect VM log to be sent to Event Hub after the virtual machine is provisioned.

Whether you are going to deploy Windows or Linux VMs, the diagnostic agent extension definition should look like as follows:

{
    "type": "Microsoft.Compute/virtualMachines/extensions",
    "name": "[concat(parameters('vmName'), '/VMDiagnosticsSettings')]",
    "location": "[parameters('location')]",
    "apiVersion": "2019-03-01",
    "dependsOn": [
        "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]"
    ],
    "properties": {
        "publisher": "Microsoft.Azure.Diagnostics",
        "type": "IaaSDiagnostics",
        "typeHandlerVersion": "1.5",
        "autoUpgradeMinorVersion": true,
        "settings": {
            "WadCfg": {
                "DiagnosticMonitorConfiguration": {
                    "overallQuotaInMB": 4096,
                    "DiagnosticInfrastructureLogs": {
                        "scheduledTransferLogLevelFilter": "Error"
                    },
                    "WindowsEventLog": {
                        "scheduledTransferPeriod": "PT1M",
                        "DataSource": [
                            {
                                "name": "Security!*[System[(band(Keywords,13510798882111488))]]"
                            }
                        ],
                        "sinks": "EventHubWindows"
                    }
                },
                "SinksConfig": {
                    "Sink": [
                        {
                            "name": "EventHubWindows",
                            "EventHub": {
                                "Url": "[parameters('windowsEventHubUrl')]",
                                "SharedAccessKeyName": "[parameters('windowsEventHubAuthorizationRuleName')]",
                                "usePublisherId": false
                            }
                        }
                    ]
                }
            }
        },
        "protectedSettings": {
            "storageAccountName": "[parameters('configStorageAccountName')]",
            "storageAccountKey": "[parameters('configStorageAccountKey')]",
            "EventHub": {
                "Url": "[parameters('windowsEventHubUrl')]",
                "SharedAccessKeyName": "[parameters('windowsEventHubAuthorizationRuleName')]",
                "SharedAccessKey": "[parameters('windowsEventHubAuthorizationRuleNameAccessKey')]"
            }
        }
    }
}

There are two main settings in a VM extension definition:

  • Public setting: where you define the configuration
  • Private setting (protected): where you supply secret value for configuration.

Look at the Windows template above, you must have the following things defined under WadCfg :

  • DiagnosticMonitorConfiguration
  • SinksConfig

In DiagnosticMonitorConfiguration pay attention to WindowsEventLog property. The definition indicates the data source that the agent needs to collect. In this article, Security Event is a target data source. You can collect Application and System log (also from Windows Events log).

SinksConfig is where you reference sink name and your Event Hub where Windows VM log is sent to. This definition tells Azure deployment that data defined in a sink named EventHubWindows will be collected, and sent to Event Hub.

In protectedSettingsprotectedSettings  storage account is where private configuration is stored. Event Hub ‘s definition is simply the target Event Hub. This definition is similar to sink configuration. The main difference is Event Hub’s access key of an existing policy. This could be the key of namespace however I strongly suggest you to create a policy under Windows event hub (entity). (Follow Pre-requisites section to grab your value).

Linux Fresh Deployment

It is pretty much similar to Windows deployment. You still need to deploy diagnostic agent extension. However, there are some key differences:

  • Event Hub SAS URL: unlike Windows deployment, you need to supply SAS URL only.
  • Storage Account SAS Token: while Windows deployment uses Storage account access key, Linux deployment requires SAS token.
  • Storage Account endpoint: it is just a fixed value https://core.windows.net 
  • Sink configuration is in protected setting.
{
    "type": "Microsoft.Compute/virtualMachines/extensions",
    "apiVersion": "2018-06-01",
    "name": "[concat(parameters('vmName'), '/LinuxDiagnostic')]",
    "location": "[parameters('location')]",
    "dependsOn": [
        "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]"
    ],
    "properties": {
        "publisher": "Microsoft.Azure.Diagnostics",
        "type": "LinuxDiagnostic",
        "typeHandlerVersion": "3.0",
        "autoUpgradeMinorVersion": true,
        "settings": {
            "StorageAccount": "[parameters('configStorageAccountName')]",
            "sampleRateInSeconds": 15,
            "ladCfg": {
                "diagnosticMonitorConfiguration": {
                    "eventVolume": "Medium",
                    "syslogEvents": {
                        "sinks": "EventHubSysLog",
                        "syslogEventConfiguration": {
                            "LOG_AUTHPRIV": "LOG_DEBUG",
                            "LOG_SYSLOG": "LOG_DEBUG"
                        }
                    }
                }
            }
        },
        "protectedSettings": {
            "storageAccountName": "[parameters('configStorageAccountName')]",
            "storageAccountSasToken": "[parameters('configStorageAccountSas')]",
            "storageAccountEndPoint": "https://core.windows.net",
            "sinksConfig": {
                "sink": [
                    {
                        "name": "EventHubSysLog",
                        "type": "EventHub",
                        "sasURL": "[parameters('linuxEventHubSasUrl')]"
                    }
                ]
            }
        }
    }
}

In public setting, you need to define configuration under ladCfg . Pay attention to syslogEvents where you need to define what you want to collect. The sample gives you two facilities: LOG_SYSLOG and LOG_AUTHPRIV. LOG_DEBUG is severity because I need debug-level information.

Check this article for supported facility and severity.

The protected setting definition requires storage account name and its sas token, including endpoint. Provide information about your sink and supply Event Hub SAS URL.

Testing Event Hub data

Once you complete the deployment (of course without any deployment error or failure), it is time for testing. There are several ways to grab Event Hub messages. You can write a small utility to read data. You can also use Stream Analytics to write data to a blob storage. In this article I’d like to introduce Process data feature – allow you to write a query to preview Event Hub data. This feature requires Event Hub Standard plan.

Sample data sent from Windows VM to Event Hub

Sample ARM templates for the deployment can be found in this repository (https://github.com/azsec/vm-eventhub-integration-arm-templates)

This entry was posted in Security Operation and tagged , . Bookmark the permalink.

2 Responses to VM Security Log to Event Hub for SIEM integration

  1. Pingback: Security Monitoring and Detection Tips for your Storage Account – Part 3

  2. Pingback: Deploy a healthy development Windows virtual machine

Leave a Reply

Your email address will not be published. Required fields are marked *