Microsoft Defender for Server Reference Architecture and Deployment Guide

When coming to deploying Defender for Servers within Microsoft Defender for Cloud, there are a number of considerations and factors which need focus to ensure a successful implementation. My goal here is to provide a reference architecture with steps that show at a high level the core areas of focus, calling out core integrations and reference points in how this is managed throughout the Microsoft tooling ecosystem. This is targeted specifically for Defender for Server deployments, so doesn’t necessarily cover things for CSPM or other tools. I also will cover FinOps and cost forecasting.

Here are the steps outlined in the deck:

  1. Check management group hierarchy meets organisational compliance and privacy reqs
  2. Define different administrative roles for Defender for Servers and apply across all subscriptions (Sec Reader / Admin)
  3. Determine deployment model (manual, policy, or IaC with Automations API etc)
  4. Enable Defender for Cloud, triggering the registration of the Microsoft.Security resource provider via policy or manual
  5. Enable Defender for Servers (P1 or P2), RG and default workspace created in subscription region. Optional to configure via Policy or IAC
  6. Optional: Configure Policy to control onboarding (restrict auto-provisioning)
  7. Onboard ARC agent for non-Azure VMs, ARC-less method in preview
  8. Check pre-reqs
  9. Install onboarding package (enable MDAV / MDE), start with a pilot ring.
  10. Detection test.
  11. Deploy Azure Monitor Agent, ARC Agent, Qualys Agent, or Guest Configuration agent via policy or manual.
  12. Enable Defender for Servers on the Log Analytics Workspace. Workspace auto created per location. MDE integration default on. Optional: Create custom workspace, and scale with policy.
  13. More than 1 month retention of logs required in ALA? CSPM auditing or visualisation requirements (PBI or workbooks)?
  14. SIEM connector for alert visibility?
  15. GCP or AWS connector?
  16. Automation (logic app) for alerts received
  17. Method of install and management (auto-provision, SCCM, CHEF, GPO, Intune (MEM), MDE-attach, manual)
  18. Network reqs, proxy, private link?
  19. Endpoint update strategy for MS update
  20. Endpoint configuration (passive mode, exclusions)?
  21. Portal config (live response, block mode etc)

It’s also worth noting that enabling is a subscription wide setting, which will become a problem if you have Windows clients, firewall NVAs or other VMs that you don’t want Defender for Server installed on. You can block the install, but you can’t block being charged for it. Billing happens hourly (randomly polls the VM every hour to check whether it was up for that hour) and only bills when not in a starting and shutdown deallocated power state. It’s also worth noting that you should have Sentinel enabled on the DfS workspace to benefit from the free 500mb grant in P2, which includes only specific log types, and ingestion over that daily aggregated limit will be charged, as well as additional retention (1+ month). If you have sentinel enabled on the workspace, logs sent which generate ingestion will also show up in cost and billing as Security Center, but if you break it down, it shows as ALA cost (see below), part number for MDC is AAA-97320.

If you want to see the breakdown of cost per computer, or filter on the computer name, you can use the below to see, in addition to the cost workbooks natively in Defender for Cloud or Sentinel

find where TimeGenerated > ago(1d) project _BilledSize, _IsBillable, Computer, _ResourceId

| where _isBillable=true and isnotempty(Computer) 

| where Computer contains “”

| summarize billedData = format_bytes(sumif(_BilledSize, _IsBillable=~true)),

            freeData   = format_bytes(sumif(_BilledSize, _IsBillable=~false)),

            billedData1 = sumif(_BilledSize, _IsBillable=~true),

            freeData1  = sumif(_BilledSize, _IsBillable=~false) 

by Computer

| extend total_d = billedData1 + freeData1

| extend Total_Data = format_bytes(total_d)

| project-away billedData1, freeData1, total_d            

| order by billedData desc

You can also see by subscription using the below.

find where TimeGenerated > ago(1d) project _BilledSize, _IsBillable, Computer, _ResourceId, _SubscriptionId

| where _isBillable=true and isnotempty(Computer)

| summarize billedData = format_bytes(sumif(_BilledSize, _IsBillable=~true)),

           freeData   = format_bytes(sumif(_BilledSize, _IsBillable=~false)),

           billedData1 = sumif(_BilledSize, _IsBillable=~true),

           freeData1  = sumif(_BilledSize, _IsBillable=~false)

by _SubscriptionId

| extend total_d = billedData1 + freeData1

| extend Total_Data = format_bytes(total_d)

| project-away billedData1, freeData1, total_d           

| order by billedData desc

Leave a Reply