Partager via


Interroger des données cartographiques à partir de VM Insights

Lorsque vous activez les processus et les dépendances, dans VM Insights, les données d’inventaire des ordinateurs et des processus sont collectées pour soutenir la fonctionnalité de cartographie. Outre l’analyse de ces données avec la carte, vous pouvez l’interroger directement avec Log Analytics. Cet article décrit les données disponibles et fournit des exemples de requêtes.

VM Insights collecte des métriques de performances et de connexion, les données d’inventaire des ordinateurs et processus et des informations sur l’état d’intégrité, puis les transfère à l’espace de travail Log Analytics dans Azure Monitor. Ces données sont disponibles pour la requête dans Azure Monitor. Vous pouvez appliquer ces données à divers scénarios tels que la planification de la migration, l’analyse de la capacité, la détection et la résolution de problèmes de performances à la demande.

Important

Des processus et des dépendances des insights de machine virtuelle doivent être activés pour permettre la création des tables décrites dans cet article.

Mapper des enregistrements

Un enregistrement par heure est généré pour chaque processus et ordinateur, en plus des enregistrements générés lorsqu’un processus ou ordinateur démarre ou est ajouté aux insights de machine virtuelle. Les champs et les valeurs de la table VMComputer correspondent aux champs de la ressource Machine dans l’API ServiceMap Azure Resource Manager. Les champs et les valeurs de la table VMProcess correspondent aux champs de la ressource Processus dans l'API ServiceMap Azure Resource Manager. Le champ _ResourceId correspond au champ de nom dans la ressource Resource Manager équivalente.

Il existe des propriétés générées en interne que vous pouvez utiliser pour identifier les ordinateurs et processus uniques :

  • Ordinateur : utilisez _ResourceId pour identifier de manière unique un ordinateur dans un espace de travail Log Analytics.
  • Processus : utilisez _ResourceId pour identifier de façon unique un processus dans un espace de travail Log Analytics.

Étant donné que plusieurs enregistrements peuvent exister pour un processus et un ordinateur donnés au cours d’une période spécifique, les requêtes peuvent renvoyer plusieurs enregistrements pour un même ordinateur ou processus. Pour n’inclure que le tout dernier enregistrement, ajoutez | summarize arg_max(TimeGenerated, *) by ResourceId à la requête.

Connexions et ports

VMConnection et VMBoundPort fournissent des informations sur les connexions d’une machine (entrantes et sortantes) et sur les ports de serveur qui sont ouverts/actifs sur celles-ci. Les métriques de connexion sont également exposées via des API permettant d’obtenir une métrique spécifique pendant une fenêtre de temps. Les connexions TCP qui résultent de l’acceptation sur un socket d’écoute sont entrantes, tandis que celles créées en se connectant à une adresse IP et à un port donnés sont sortantes. La propriété Direction représente la direction d’une connexion, qui peut être définie sur la valeur inbound ou outbound.

Les enregistrements inclus dans ces tables sont générés à partir des données rapportées par l'agent de dépendances. Chaque enregistrement représente une observation sur un intervalle de temps d’une minute. La propriété TimeGenerated indique le début de l’intervalle de temps. Chaque enregistrement contient des informations identifiant l’entité respective, à savoir la connexion ou le port, ainsi que des métriques associées à cette entité. Actuellement, seule l’activité réseau utilisant TCP sur IPv4 est rapportée.

À des fins de gestion des coûts et de la complexité, les enregistrements de connexion ne représentent pas des connexions réseau physiques individuelles. Plusieurs connexions réseau physiques sont groupées dans une connexion logique, qui est ensuite reflétée dans la table concernée. Ainsi, les enregistrements de la table VMConnection représentent un regroupement logique et non les connexions physiques individuelles observées. Les connexions réseau physiques dont les attributs suivants présentent la même valeur au cours d’un intervalle d’une minute donné sont agrégées au sein d’un unique enregistrement logique dans VMConnection.

Métriques

VMConnection et VMBoundPort incluent des données de métriques avec des informations sur le volume de données envoyées et reçues sur une connexion logique ou un port réseau donné (BytesSent, BytesReceived). Le temps de réponse est également inclus. Il s’agit de la durée pendant laquelle l’appelant attend une demande envoyée via une connexion pour être traitée et pour recevoir une réponse par le point de terminaison distant (ResponseTimeMax, ResponseTimeMin, ResponseTimeSum). Le temps de réponse rapporté est une estimation du temps de réponse réel du protocole d’application sous-jacent. Il est calculé à l'aide d'une heuristique basée sur l'observation du flux de données entre la source et la destination d'une connexion réseau physique. Conceptuellement, c'est la différence entre le moment où le dernier octet d'une requête quitte l'expéditeur et le moment où le dernier octet de la réponse lui revient. Ces deux timestamps sont utilisés pour délimiter les événements de requête et de réponse sur une connexion physique donnée. La différence entre eux représente le temps de réponse d’une requête unique.

Cet algorithme est une approximation qui peut fonctionner de façon plus ou moins efficace selon le protocole d’application réel utilisé pour une connexion réseau donnée. Par exemple, l'approche actuelle fonctionne bien pour les protocoles basés sur les requêtes-réponses tels que HTTP(S), mais ne fonctionne pas avec les protocoles unidirectionnels ou basés sur les files d'attente de messages.

Voici quelques points importants à prendre en compte :

  1. Si un processus accepte des connexions sur la même adresse IP, mais sur plusieurs interfaces réseau, un enregistrement distinct pour chaque interface est rapporté.
  2. Les enregistrements avec une adresse IP générique ne contiennent aucune activité. Ils sont inclus pour représenter le fait qu’un port de la machine est ouvert pour le trafic entrant.
  3. Pour réduire la verbosité et le volume de données, les enregistrements avec adresse IP générique sont omis en présence d’un enregistrement correspondant (pour le même processus, port et protocole) avec une adresse IP spécifique. Lorsqu’un enregistrement d’adresse IP générique est omis, la propriété d’enregistrement IsWildcardBind avec l’adresse IP spécifique est définie sur la valeur True. Ce paramètre indique que le port est exposé sur toutes les interfaces de la machine à l’origine du rapport.
  4. Pour les ports liés à une interface spécifique uniquement, IsWildcardBind a la valeur False.

Affectation de noms et classification

Pour plus de commodité, l’adresse IP de l’extrémité distante d’une connexion est incluse dans la propriété RemoteIp. Pour les connexions entrantes, RemoteIp est identique à SourceIp, tandis que pour les connexions sortantes, elle est identique à DestinationIp. La propriété RemoteDnsCanonicalNames représente les noms canoniques DNS rapportés par la machine pour RemoteIp. La propriété RemoteDnsQuestions représente les questions DNS rapportées par la machine pour RemoteIp. La propriété RemoveClassification est réservée pour une utilisation ultérieure.

Adresses IP malveillantes

Chaque propriété RemoteIp de la table VMConnection est comparée à un ensemble d’adresses IP associées à une activité malveillante connue. Si RemoteIp est identifié comme malveillant, les propriétés suivantes sont remplies. Si l’adresse IP n’est pas considérée comme malveillante, les propriétés sont vides.

  • MaliciousIp
  • IndicatorThreadType
  • Description
  • TLPLevel
  • Confidence
  • Severity
  • FirstReportedDateTime
  • LastReportedDateTime
  • IsActive
  • ReportReferenceLink
  • AdditionalInformation

Exemple de requêtes de carte

Liste de tous les ordinateurs connus

VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId

Date et heure du dernier redémarrage de la machine virtuelle

let Today = now(); VMComputer | extend DaysSinceBoot = Today - BootTime | summarize by Computer, DaysSinceBoot, BootTime | sort by BootTime asc

Résumé des machines virtuelles Azure par image, emplacement et référence SKU

VMComputer | where AzureLocation != "" | summarize by Computer, AzureImageOffering, AzureLocation, AzureImageSku

Répertorier la capacité de mémoire physique de tous les ordinateurs gérés

VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId | project PhysicalMemoryMB, Computer

Répertorier le nom de l’ordinateur, le DNS, l’adresse IP et le système d’exploitation

VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId | project Computer, OperatingSystemFullName, DnsNames, Ipv4Addresses

Rechercher tous les processus contenant « sql » dans la ligne de commande

VMProcess | where CommandLine contains_cs "sql" | summarize arg_max(TimeGenerated, *) by _ResourceId

Rechercher un ordinateur (enregistrement le plus récent) par nom de ressource

search in (VMComputer) "m-4b9c93f9-bc37-46df-b43c-899ba829e07b" | summarize arg_max(TimeGenerated, *) by _ResourceId

Rechercher une machine (enregistrement le plus récent) par adresse IP

search in (VMComputer) "10.229.243.232" | summarize arg_max(TimeGenerated, *) by _ResourceId

Répertorier tous les processus sur une machine spécifiée

VMProcess | where Machine == "m-559dbcd8-3130-454d-8d1d-f624e57961bc" | summarize arg_max(TimeGenerated, *) by _ResourceId

Répertorier tous les ordinateurs exécutant SQL Server

VMComputer | where AzureResourceName in ((search in (VMProcess) "*sql*" | distinct Machine)) | distinct Computer

Répertorier toutes les versions de produit uniques de CURL dans mon centre de données

VMProcess | where ExecutableName == "curl" | distinct ProductVersion

Tendances en matière d’octets envoyés et reçus

VMConnection | summarize sum(BytesSent), sum(BytesReceived) by bin(TimeGenerated,1hr), Computer | order by Computer desc | render timechart

Identification des machines virtuelles Azure qui transmettent le plus grand nombre d’octets

VMConnection | join kind=fullouter(VMComputer) on $left.Computer == $right.Computer | summarize count(BytesSent) by Computer, AzureVMSize | sort by count_BytesSent desc

Tendances en matière d’état du lien

VMConnection | where TimeGenerated >= ago(24hr) | where Computer == "acme-demo" | summarize dcount(LinksEstablished), dcount(LinksLive), dcount(LinksFailed), dcount(LinksTerminated) by bin(TimeGenerated, 1h) | render timechart

Tendance en matière d'échecs de connexion

VMConnection | where Computer == "acme-demo" | extend bythehour = datetime_part("hour", TimeGenerated) | project bythehour, LinksFailed | summarize failCount = count() by bythehour | sort by bythehour asc | render timechart

Ports liés

VMBoundPort
| where TimeGenerated >= ago(24hr)
| where Computer == 'admdemo-appsvr'
| distinct Port, ProcessName

Nombre de ports ouverts sur différentes machines

VMBoundPort
| where Ip != "127.0.0.1"
| summarize by Computer, Machine, Port, Protocol
| summarize OpenPorts=count() by Computer, Machine
| order by OpenPorts desc

Noter les processus dans votre espace de travail en fonction du nombre de ports qu’ils ont ouvert

VMBoundPort
| where Ip != "127.0.0.1"
| summarize by ProcessName, Port, Protocol
| summarize OpenPorts=count() by ProcessName
| order by OpenPorts desc

Agréger le comportement de chaque port

Cette requête peut ensuite être utilisée pour noter les ports par activité (par exemple, les ports avec le plus de trafic entrant/sortant, les ports avec le plus de connexions).

VMBoundPort
| where Ip != "127.0.0.1"
| summarize BytesSent=sum(BytesSent), BytesReceived=sum(BytesReceived), LinksEstablished=sum(LinksEstablished), LinksTerminated=sum(LinksTerminated), arg_max(TimeGenerated, LinksLive) by Machine, Computer, ProcessName, Ip, Port, IsWildcardBind
| project-away TimeGenerated
| order by Machine, Computer, Port, Ip, ProcessName

Synthétiser les connexions sortantes d’un groupe de machines

// the machines of interest
let machines = datatable(m: string) ["m-82412a7a-6a32-45a9-a8d6-538354224a25"];
// map of ip to monitored machine in the environment
let ips=materialize(VMComputer
| summarize ips=makeset(todynamic(Ipv4Addresses)) by MonitoredMachine=AzureResourceName
| mvexpand ips to typeof(string));
// all connections to/from the machines of interest
let out=materialize(VMConnection
| where Machine in (machines)
| summarize arg_max(TimeGenerated, *) by ConnectionId);
// connections to localhost augmented with RemoteMachine
let local=out
| where RemoteIp startswith "127."
| project ConnectionId, Direction, Machine, Process, ProcessName, SourceIp, DestinationIp, DestinationPort, Protocol, RemoteIp, RemoteMachine=Machine;
// connections not to localhost augmented with RemoteMachine
let remote=materialize(out
| where RemoteIp !startswith "127."
| join kind=leftouter (ips) on $left.RemoteIp == $right.ips
| summarize by ConnectionId, Direction, Machine, Process, ProcessName, SourceIp, DestinationIp, DestinationPort, Protocol, RemoteIp, RemoteMachine=MonitoredMachine);
// the remote machines to/from which we have connections
let remoteMachines = remote | summarize by RemoteMachine;
// all augmented connections
(local)
| union (remote)
//Take all outbound records but only inbound records that come from either //unmonitored machines or monitored machines not in the set for which we are computing dependencies.
| where Direction == 'outbound' or (Direction == 'inbound' and RemoteMachine !in (machines))
| summarize by ConnectionId, Direction, Machine, Process, ProcessName, SourceIp, DestinationIp, DestinationPort, Protocol, RemoteIp, RemoteMachine
// identify the remote port
| extend RemotePort=iff(Direction == 'outbound', DestinationPort, 0)
// construct the join key we'll use to find a matching port
| extend JoinKey=strcat_delim(':', RemoteMachine, RemoteIp, RemotePort, Protocol)
// find a matching port
| join kind=leftouter (VMBoundPort 
| where Machine in (remoteMachines) 
| summarize arg_max(TimeGenerated, *) by PortId 
| extend JoinKey=strcat_delim(':', Machine, Ip, Port, Protocol)) on JoinKey
// aggregate the remote information
| summarize Remote=makeset(iff(isempty(RemoteMachine), todynamic('{}'), pack('Machine', RemoteMachine, 'Process', Process1, 'ProcessName', ProcessName1))) by ConnectionId, Direction, Machine, Process, ProcessName, SourceIp, DestinationIp, DestinationPort, Protocol

Étapes suivantes