Back
Ida5b6c7d8-5e6f-7a8b-9c0d-1e2f3a4b5c6d
RulenameTailscale Premium: Subnet router throughput anomaly
DescriptionIdentifies when a subnet router (gateway node bridging the tailnet to an on-prem or cloud subnet) handles 3x or more its 7-day baseline traffic in the last hour. Spikes can indicate exfiltration or scanning. Requires Tailscale Premium or Enterprise.
SeverityLow
TacticsExfiltration
CommandAndControl
TechniquesT1572
T1041
Required data connectorsTailscalePremiumCCF
KindScheduled
Query frequency1h
Query period8d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Tailscale%20%28CCF%29/Analytic%20Rules/TailscalePremiumSubnetRouterThroughputAnomaly.yaml
Version1.0.0
Arm templatea5b6c7d8-5e6f-7a8b-9c0d-1e2f3a4b5c6d.json
Deploy To Azure
let baselineDays = 7d;
let recent = 1h;
let multiplier = 3.0;
let recentTraffic =
    Tailscale_Network_CL
    | where TimeGenerated > ago(recent)
    | where HasSubnetTraffic
    | mv-expand t = SubnetTraffic
    | extend Bytes = tolong(t.txBytes) + tolong(t.rxBytes)
    | summarize RecentBytes = sum(Bytes) by NodeId, SrcNodeName, SrcUser, SrcOs, SrcTags=tostring(SrcTags);
let baseline =
    Tailscale_Network_CL
    | where TimeGenerated between (ago(baselineDays + recent) .. ago(recent))
    | where HasSubnetTraffic
    | mv-expand t = SubnetTraffic
    | extend Bytes = tolong(t.txBytes) + tolong(t.rxBytes)
    | summarize TotalBaselineBytes = sum(Bytes) by NodeId
    | extend BaselineHourlyBytes = TotalBaselineBytes / 168.0;
recentTraffic
| join kind=inner baseline on NodeId
| where RecentBytes > BaselineHourlyBytes * multiplier
| extend Multiplier = round(RecentBytes / BaselineHourlyBytes, 1), RecentMB = round(RecentBytes / 1024.0 / 1024.0, 2), BaselineHourlyMB = round(BaselineHourlyBytes / 1024.0 / 1024.0, 2)
| project NodeId, SrcNodeName, SrcUser, SrcOs, SrcTags, RecentMB, BaselineHourlyMB, Multiplier
| order by Multiplier desc
queryFrequency: 1h
entityMappings:
- fieldMappings:
  - columnName: SrcNodeName
    identifier: HostName
  entityType: Host
- fieldMappings:
  - columnName: SrcUser
    identifier: FullName
  entityType: Account
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    lookbackDuration: P1D
    matchingMethod: AllEntities
    enabled: true
    reopenClosedIncident: false
triggerThreshold: 0
triggerOperator: gt
severity: Low
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Tailscale%20%28CCF%29/Analytic%20Rules/TailscalePremiumSubnetRouterThroughputAnomaly.yaml
query: |
  let baselineDays = 7d;
  let recent = 1h;
  let multiplier = 3.0;
  let recentTraffic =
      Tailscale_Network_CL
      | where TimeGenerated > ago(recent)
      | where HasSubnetTraffic
      | mv-expand t = SubnetTraffic
      | extend Bytes = tolong(t.txBytes) + tolong(t.rxBytes)
      | summarize RecentBytes = sum(Bytes) by NodeId, SrcNodeName, SrcUser, SrcOs, SrcTags=tostring(SrcTags);
  let baseline =
      Tailscale_Network_CL
      | where TimeGenerated between (ago(baselineDays + recent) .. ago(recent))
      | where HasSubnetTraffic
      | mv-expand t = SubnetTraffic
      | extend Bytes = tolong(t.txBytes) + tolong(t.rxBytes)
      | summarize TotalBaselineBytes = sum(Bytes) by NodeId
      | extend BaselineHourlyBytes = TotalBaselineBytes / 168.0;
  recentTraffic
  | join kind=inner baseline on NodeId
  | where RecentBytes > BaselineHourlyBytes * multiplier
  | extend Multiplier = round(RecentBytes / BaselineHourlyBytes, 1), RecentMB = round(RecentBytes / 1024.0 / 1024.0, 2), BaselineHourlyMB = round(BaselineHourlyBytes / 1024.0 / 1024.0, 2)
  | project NodeId, SrcNodeName, SrcUser, SrcOs, SrcTags, RecentMB, BaselineHourlyMB, Multiplier
  | order by Multiplier desc
tactics:
- Exfiltration
- CommandAndControl
queryPeriod: 8d
relevantTechniques:
- T1572
- T1041
requiredDataConnectors:
- connectorId: TailscalePremiumCCF
  dataTypes:
  - Tailscale_Network_CL
id: a5b6c7d8-5e6f-7a8b-9c0d-1e2f3a4b5c6d
kind: Scheduled
version: 1.0.0
description: |
  Identifies when a subnet router (gateway node bridging the tailnet to an on-prem or cloud subnet) handles 3x or more its 7-day baseline traffic in the last hour. Spikes can indicate exfiltration or scanning. Requires Tailscale Premium or Enterprise.
status: Available
name: 'Tailscale Premium: Subnet router throughput anomaly'
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/a5b6c7d8-5e6f-7a8b-9c0d-1e2f3a4b5c6d')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/a5b6c7d8-5e6f-7a8b-9c0d-1e2f3a4b5c6d')]",
      "properties": {
        "alertRuleTemplateName": "a5b6c7d8-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
        "customDetails": null,
        "description": "Identifies when a subnet router (gateway node bridging the tailnet to an on-prem or cloud subnet) handles 3x or more its 7-day baseline traffic in the last hour. Spikes can indicate exfiltration or scanning. Requires Tailscale Premium or Enterprise.\n",
        "displayName": "Tailscale Premium: Subnet router throughput anomaly",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "SrcNodeName",
                "identifier": "HostName"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "SrcUser",
                "identifier": "FullName"
              }
            ]
          }
        ],
        "incidentConfiguration": {
          "createIncident": true,
          "groupingConfiguration": {
            "enabled": true,
            "lookbackDuration": "P1D",
            "matchingMethod": "AllEntities",
            "reopenClosedIncident": false
          }
        },
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Tailscale%20%28CCF%29/Analytic%20Rules/TailscalePremiumSubnetRouterThroughputAnomaly.yaml",
        "query": "let baselineDays = 7d;\nlet recent = 1h;\nlet multiplier = 3.0;\nlet recentTraffic =\n    Tailscale_Network_CL\n    | where TimeGenerated > ago(recent)\n    | where HasSubnetTraffic\n    | mv-expand t = SubnetTraffic\n    | extend Bytes = tolong(t.txBytes) + tolong(t.rxBytes)\n    | summarize RecentBytes = sum(Bytes) by NodeId, SrcNodeName, SrcUser, SrcOs, SrcTags=tostring(SrcTags);\nlet baseline =\n    Tailscale_Network_CL\n    | where TimeGenerated between (ago(baselineDays + recent) .. ago(recent))\n    | where HasSubnetTraffic\n    | mv-expand t = SubnetTraffic\n    | extend Bytes = tolong(t.txBytes) + tolong(t.rxBytes)\n    | summarize TotalBaselineBytes = sum(Bytes) by NodeId\n    | extend BaselineHourlyBytes = TotalBaselineBytes / 168.0;\nrecentTraffic\n| join kind=inner baseline on NodeId\n| where RecentBytes > BaselineHourlyBytes * multiplier\n| extend Multiplier = round(RecentBytes / BaselineHourlyBytes, 1), RecentMB = round(RecentBytes / 1024.0 / 1024.0, 2), BaselineHourlyMB = round(BaselineHourlyBytes / 1024.0 / 1024.0, 2)\n| project NodeId, SrcNodeName, SrcUser, SrcOs, SrcTags, RecentMB, BaselineHourlyMB, Multiplier\n| order by Multiplier desc\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P8D",
        "severity": "Low",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl",
          "Exfiltration"
        ],
        "techniques": [
          "T1041",
          "T1572"
        ],
        "templateVersion": "1.0.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}