Analytic rule catalog
Tailscale Device Tailscale SSH newly enabled
Back
| Id | f0a1b2c3-4567-8901-23de-f12345670041 |
| Rulename | Tailscale: Device Tailscale SSH newly enabled |
| Description | Identifies when Tailscale SSH is enabled on a device that previously did not have it. SSH provides authenticated shell access over the tailnet using Tailscale identity, broadening attack surface if unexpected. Verify and confirm the SSH ACL covers it. |
| Severity | Medium |
| Tactics | Persistence LateralMovement |
| Techniques | T1021 T1098 |
| Required data connectors | TailscaleCCF |
| Kind | Scheduled |
| Query frequency | 1h |
| Query period | 2d |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Tailscale%20%28CCF%29/Analytic%20Rules/TailscaleDeviceSshNewlyEnabled.yaml |
| Version | 1.0.0 |
| Arm template | f0a1b2c3-4567-8901-23de-f12345670041.json |
let recent =
Tailscale_Devices_CL
| where TimeGenerated > ago(1h)
| summarize arg_max(TimeGenerated, *) by DeviceId
| where SshEnabled == true
| project DeviceId, DeviceName, Hostname, User, Os, ClientVersion, LastSeen;
let prior =
Tailscale_Devices_CL
| where TimeGenerated between (ago(2d) .. ago(1h))
| summarize arg_max(TimeGenerated, *) by DeviceId
| where SshEnabled == true
| distinct DeviceId;
recent
| join kind=leftanti prior on DeviceId
| project TimeGenerated = now(), DeviceName, Hostname, User, Os, ClientVersion, LastSeen
incidentConfiguration:
groupingConfiguration:
lookbackDuration: P1D
reopenClosedIncident: false
matchingMethod: AllEntities
enabled: true
createIncident: true
name: 'Tailscale: Device Tailscale SSH newly enabled'
triggerOperator: gt
query: |
let recent =
Tailscale_Devices_CL
| where TimeGenerated > ago(1h)
| summarize arg_max(TimeGenerated, *) by DeviceId
| where SshEnabled == true
| project DeviceId, DeviceName, Hostname, User, Os, ClientVersion, LastSeen;
let prior =
Tailscale_Devices_CL
| where TimeGenerated between (ago(2d) .. ago(1h))
| summarize arg_max(TimeGenerated, *) by DeviceId
| where SshEnabled == true
| distinct DeviceId;
recent
| join kind=leftanti prior on DeviceId
| project TimeGenerated = now(), DeviceName, Hostname, User, Os, ClientVersion, LastSeen
queryFrequency: 1h
description: |
Identifies when Tailscale SSH is enabled on a device that previously did not have it. SSH provides authenticated shell access over the tailnet using Tailscale identity, broadening attack surface if unexpected. Verify and confirm the SSH ACL covers it.
id: f0a1b2c3-4567-8901-23de-f12345670041
triggerThreshold: 0
queryPeriod: 2d
version: 1.0.0
kind: Scheduled
status: Available
severity: Medium
requiredDataConnectors:
- connectorId: TailscaleCCF
dataTypes:
- Tailscale_Devices_CL
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Tailscale%20%28CCF%29/Analytic%20Rules/TailscaleDeviceSshNewlyEnabled.yaml
relevantTechniques:
- T1021
- T1098
tactics:
- Persistence
- LateralMovement
entityMappings:
- fieldMappings:
- identifier: HostName
columnName: Hostname
entityType: Host
- fieldMappings:
- identifier: FullName
columnName: User
entityType: Account
{
"$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/f0a1b2c3-4567-8901-23de-f12345670041')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/f0a1b2c3-4567-8901-23de-f12345670041')]",
"properties": {
"alertRuleTemplateName": "f0a1b2c3-4567-8901-23de-f12345670041",
"customDetails": null,
"description": "Identifies when Tailscale SSH is enabled on a device that previously did not have it. SSH provides authenticated shell access over the tailnet using Tailscale identity, broadening attack surface if unexpected. Verify and confirm the SSH ACL covers it.\n",
"displayName": "Tailscale: Device Tailscale SSH newly enabled",
"enabled": true,
"entityMappings": [
{
"entityType": "Host",
"fieldMappings": [
{
"columnName": "Hostname",
"identifier": "HostName"
}
]
},
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "User",
"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/TailscaleDeviceSshNewlyEnabled.yaml",
"query": "let recent =\n Tailscale_Devices_CL\n | where TimeGenerated > ago(1h)\n | summarize arg_max(TimeGenerated, *) by DeviceId\n | where SshEnabled == true\n | project DeviceId, DeviceName, Hostname, User, Os, ClientVersion, LastSeen;\nlet prior =\n Tailscale_Devices_CL\n | where TimeGenerated between (ago(2d) .. ago(1h))\n | summarize arg_max(TimeGenerated, *) by DeviceId\n | where SshEnabled == true\n | distinct DeviceId;\nrecent\n| join kind=leftanti prior on DeviceId\n| project TimeGenerated = now(), DeviceName, Hostname, User, Os, ClientVersion, LastSeen\n",
"queryFrequency": "PT1H",
"queryPeriod": "P2D",
"severity": "Medium",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"LateralMovement",
"Persistence"
],
"techniques": [
"T1021",
"T1098"
],
"templateVersion": "1.0.0",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}