Antimalware in the Windows Azure

On most (or perhaps even all?) of the production servers I’ve worked on, antivirus/antimalware detection apps are often not installed for a variety of reasons – performance, risk of false positives or certain processes getting closed down unexpectedly, or the simple fact most production machines are under strict access control and deployment restrictions.

Still, it’s a nice option to have, and it’s now possible to set this up easily in Windows Azure roles.   Somewhat quietly, the team released a CTP of Microsoft Endpoint Protection for Windows Azure, a plug in that makes it straightforward to configure your Azure roles to automatically install and configure the Microsoft Endpoint Protection (MEP) software. 

The download includes the necessary APIs to make it simple to configure.  Upon initial startup of the VM, the Microsoft Endpoint Protection software is installed and configured, downloading the binaries from Windows Azure storage from a datacenter of your choosing.  Note: *you* don’t have store anything in Windows Azure Storage; rather, the binaries are kept at each datacenter so the download time is fast and bandwidth-free, provided you pick the datacenter your app resides in.

So, to get started, I’ve downloaded and installed the MSI package from the site.    Next, I’ve added the antimalware module to the ServiceDefinition file like so:

 <?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="MEP" xmlns="https://schemas.microsoft.com/ServiceHosting
    /2008/10/ServiceDefinition">
  <WebRole name="WebRole1" vmsize="ExtraSmall">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
    </Endpoints>
    <Imports>
      <Import moduleName="Antimalware" />
      <Import moduleName="Diagnostics" />
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
  </WebRole>
</ServiceDefinition>

Specifically, I added Antimalware to the <imports> section.  The other modules are for diagnostics (not needed necessarily but useful, as you’ll see in a bit) and remote access, so we can log into the server via RDP.

 

Next, the ServiceConfiguration will configure a bunch of options.  Each setting is spelled out in the document on the download page:

 

 <?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="MEP" xmlns="https://schemas.microsoft.com/
    ServiceHosting/2008/10/ServiceConfiguration" osFamily="1" osVersion="*">
  <Role name="WebRole1">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" 
            value="xxx" />
      <Setting name="Microsoft.WindowsAzure.Plugins.Antimalware.ServiceLocation" 
            value="North Central US" />
      <Setting name="Microsoft.WindowsAzure.Plugins.Antimalware.EnableAntimalware" 
            value="true" />
      <Setting name="Microsoft.WindowsAzure.Plugins.Antimalware.EnableRealtimeProtection" 
            value="true" />
      <Setting name="Microsoft.WindowsAzure.Plugins.Antimalware.EnableWeeklyScheduledScans" 
            value="true" />
      <Setting name="Microsoft.WindowsAzure.Plugins.Antimalware.DayForWeeklyScheduledScans" 
            value="1" />
      <Setting name="Microsoft.WindowsAzure.Plugins.Antimalware.TimeForWeeklyScheduledScans" 
            value="120" />
      <Setting name="Microsoft.WindowsAzure.Plugins.Antimalware.ExcludedExtensions" 
            value="txt|log" />
      <Setting name="Microsoft.WindowsAzure.Plugins.Antimalware.ExcludedPaths" 
            value="e:\approot\custom" />
      <Setting name="Microsoft.WindowsAzure.Plugins.Antimalware.ExcludedProcesses" 
            value="d:\program files\app.exe" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled" 
            value="true" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername" 
            value="xxx" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword" 
            value="xxx" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration" 
            value="2013-03-21T23:59:59.000-04:00" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled" 
            value="true" />
    </ConfigurationSettings>
    <Certificates>
      <Certificate name="Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption" 
        thumbprint="xxx" thumbprintAlgorithm="sha1" />
    </Certificates>
  </Role>
</ServiceConfiguration>

Many of these settings are self-explanatory, but essentially, we’re setting up weekly scans at 2am on Sunday, excluding app.exe, and everything in e:\approot\custom.   We’re also skipping txt and log files.  Also, the MEP bits will be pulled from the North Central US datacenter.  It’s not a big deal if your app is outside of North Central– it’s just that the install takes a few moments longer (the default is South Central).  (And, technically, since bandwidth going into the datacenter is currently free, the bandwidth isn’t an issue.) 

If we log into the box (the role must be RDP enabled to do this) we’ll see these settings reflected in MEP.

Weekly scans:

image

Excluding app.exe:

image

 

And skipping txt and log files:

image

Finally, we can also set up the Windows Azure Diagnostics agent to transfer relevant event log entries to storage – in this example, we’re just adding the antimalware entries explicitly, though getting verbose information like this is probably not desirable:

 private void ConfigureDiagnosticMonitor()
 {
     DiagnosticMonitorConfiguration diagnosticMonitorConfiguration = 
        DiagnosticMonitor.GetDefaultInitialConfiguration();

     diagnosticMonitorConfiguration.Directories.ScheduledTransferPeriod = 
        TimeSpan.FromMinutes(1d);
     diagnosticMonitorConfiguration.Directories.BufferQuotaInMB = 100;

     diagnosticMonitorConfiguration.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);
     diagnosticMonitorConfiguration.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;

     diagnosticMonitorConfiguration.WindowsEventLog.DataSources.Add("Application!*");
     diagnosticMonitorConfiguration.WindowsEventLog.DataSources.Add("System!*");
     diagnosticMonitorConfiguration.WindowsEventLog.ScheduledTransferPeriod = 
        TimeSpan.FromMinutes(1d);
     
     //Antimalware settings:
     diagnosticMonitorConfiguration.WindowsEventLog.DataSources.Add(
        "System!*[System[Provider[@Name='Microsoft Antimalware']]]");
     diagnosticMonitorConfiguration.WindowsEventLog.ScheduledTransferPeriod = 
        System.TimeSpan.FromMinutes(1d);
 
     PerformanceCounterConfiguration performanceCounterConfiguration =
        new PerformanceCounterConfiguration();
     performanceCounterConfiguration.CounterSpecifier = @"\Processor(_Total)\% Processor Time";
     performanceCounterConfiguration.SampleRate = System.TimeSpan.FromSeconds(10d);
     diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(
        performanceCounterConfiguration);
     diagnosticMonitorConfiguration.PerformanceCounters.ScheduledTransferPeriod = 
        TimeSpan.FromMinutes(1d);
    
     DiagnosticMonitor.Start(wadConnectionString, diagnosticMonitorConfiguration);
 } 

To filter the event logs from MEP, we can add some filtering like so (adding the Level 1, 2, and 3 to the filter so we’re skipping the verbose level 4 stuff):

 diagnosticMonitorConfiguration.WindowsEventLog.DataSources
    .Add("System!*[System[Provider[@Name='Microsoft Antimalware'] and 
    (Level=1 or Level=2 or Level=3)]]");

After deploying the role and waiting a few minutes, the entries are written into Azure table storage, in the WADWindowsEventLogsTable.  In this case, I’m looking at them using Cloud Storage Studio (although, for diagnostics and performance counters, their Azure Diagnostics Manager product is fantastic for this kind of thing):

image

While not everyone needs or desires this functionality, it’s a great option to have (particularly if the system is part of a file intake or distribution system).