Cómo conecté computadoras y usuarios a puertos de dispositivos de red en el programa de monitoreo Network MACMonitor

Soy un desarrollador del software de monitoreo de red Network MACMonitor .


En el proceso de desarrollo del programa, surgió una tarea: determinar qué computadoras están usando los usuarios y asociar esta información con los puertos de los dispositivos de red. En este artículo quiero escribir cómo logré hacer esto.


imagen


Comencé con consideraciones simples: para asociar un usuario con un puerto en un dispositivo de red, primero debe conectar la computadora con la que el usuario está trabajando a este puerto. Dado que el programa Network MACMonitor le permite encontrar direcciones mac en los puertos de los dispositivos de red, se decidió conectar las computadoras a los puertos utilizando direcciones mac. A continuación, debe conectar a los usuarios a las computadoras. Esta información se puede obtener interrogando a las computadoras de cualquier manera.


Vi dos opciones para resolver este problema:


  1. Escribir un agente de Windows e interrogarlo usando Network MACMonitor;
  2. Utilice el Instrumental de administración de Windows (WMI).

La versión con el agente de Windows tiene una serie de desventajas que fueron significativas para mí:


  • desarrollo de un protocolo seguro para la interacción de red de un agente de Windows con Network MACMonitor;
  • la necesidad de preinstalar el agente en las computadoras;
  • usando un lenguaje de programación diferente (escribo en Java), ya que considero que Java no es adecuado para escribir un agente: debido al gran consumo de memoria virtual y la necesidad de instalar JRE en todas las computadoras.

Debido a todas las desventajas anteriores, decidí detenerme en la opción usando WMI.


Desarrollo de clientes WMI


Dado que Network MACMonitor está escrito en Java, intenté encontrar una biblioteca Java multiplataforma lista para usar que implemente la funcionalidad del cliente WMI. Y luego me decepcionó: no existe tal biblioteca. Todas las bibliotecas existentes son envoltorios sobre las utilidades de Windows o (biblioteca j-Interop) requieren manipulación de registro adicional (cambio de propiedad y permisos en las ramas del registro) para activar WMI a través de un registro remoto. Como no había una biblioteca totalmente funcional para Java, decidí buscar una biblioteca o un cliente WMI escrito en cualquier otro lenguaje de programación. Y encontré un cliente WMI para Linux. Después de descargar y verificar su trabajo, me di cuenta de que es posible sondear computadoras con Windows desde Linux.


Si esto es posible, decidí escribir mi biblioteca en Java puro, lo que me permitiría sondear la computadora usando WMI.


Para escribir la biblioteca, se necesitaba documentación clara sobre el funcionamiento del protocolo WMI. Resultó que existe dicha documentación y es de dominio público.


Comencé a prepararme para escribir la biblioteca mirando la pila de red del protocolo WMI.


ProtocoloEspecificaciones
Instrumental de administración de Windows (WMI)MS-WMI, MS-WMIO
Modelo de objetos componentes distribuidos (DCOM)MS-DCOM
Llamada a procedimiento remoto (RPC)MS-RPCE
Protocolo de control de transmisión (TCP)-
Protocolo de internet (IP)-

Para que WMI funcione correctamente, se deben implementar todos los niveles de la pila.


Como WMI no está implementado en Java, pasé al siguiente protocolo en la pila: DCOM. Y aquí tuve suerte. Aunque la biblioteca j-Interop mencionada anteriormente no implementa la funcionalidad WMI, la funcionalidad DCOM se implementa en ella. Por lo tanto, queda por escribir una implementación del protocolo WMI, es decir, escribir una implementación de las especificaciones MS-WMI y MS-WMIO.


Comencé implementando la especificación MS-WMIO, que es responsable del formato de codificación de datos en los paquetes de red del protocolo WMI. De la especificación, aprendí que al codificar datos, se utiliza la especificación de sintaxis Backus-Naur extendida (ABNF, RFC 5234). La especificación MS-WMIO describe completamente el formato de codificación utilizando ABNF. Se sabe que si hay una gramática descrita en ABNF, entonces es posible crear un analizador para esta gramática. En Internet, encontré un generador de analizador ABNF para Java y lo ingresé con una gramática tomada de la especificación. Dado que el analizador generado funcionaba con cadenas y MS-WMIO describe un formato de codificación binario, la idea era simplemente reemplazar el analizador generado con cadenas por matrices y caracteres con bytes. Pero después de mirar la cantidad de archivos donde era necesario un reemplazo, y también de haber aprendido de la especificación MS-WMIO que a veces sería necesario trabajar con bits, me di cuenta de que sería muy difícil arreglar el analizador generado, y decidí abandonar esta idea. Pensé que escribir un analizador desde cero sería más rápido. Y ahora el analizador estaba listo.


¿Pero cómo verificar que el analizador está escrito correctamente si la especificación MS-WMI, que es responsable del funcionamiento del protocolo WMI, aún no está implementada? Entonces Wireshark, un analizador de tráfico de red, me ayudó. Después de haber realizado solicitudes WMI utilizando herramientas estándar de Windows (wbemtest), habiendo deshabilitado previamente el cifrado, recibí paquetes de red y los guardé en archivos binarios. Ya era posible usar estos archivos como datos de prueba para el analizador.


Cuando se probó el analizador y se corrigieron los errores encontrados, procedí a implementar la especificación MS-WMI, que describe el funcionamiento del protocolo WMI.


La especificación MS-WMI se divide en servidor y cliente. Implementé parcialmente la parte del cliente, en la medida necesaria para sondear una computadora a través de WMI. En esta parte, también necesitaba Wireshark, pero ya para analizar la secuencia de paquetes de red durante el sondeo de WMI.


Intentando obtener los datos necesarios usando WMI


Después de escribir la biblioteca WMI, se convirtió en la tarea de usarla en el programa Network MACMonitor. Surgió la pregunta: ¿qué datos se deben obtener de las computadoras? Pensé que necesitaba obtener el nombre de la computadora, el dominio, el sistema operativo, el tiempo de encendido, las direcciones mac, las direcciones IP, los usuarios activos que trabajan en la computadora.


Pero surgió un problema muy importante: ¿cómo identificar de manera única una computadora durante el sondeo de WMI? Consideré las siguientes opciones:


  • dirección mac, posible cambio, posible no único;
  • nombre y dominio de la computadora (grupo de trabajo), posible cambio, no único (para grupo de trabajo);
  • el número de serie del disco duro donde está instalado el sistema operativo, se requieren derechos de administrador durante el sondeo de WMI, no verifiqué la unicidad, pero sospecho que es posible que no sea único;
  • el número de serie de la placa base, no único es posible, y con bastante frecuencia;
  • el identificador del sistema informático (propiedad UUID WMI de la clase Win32_ComputerSystemProduct ), la falta de uniformidad es posible, y con bastante frecuencia;
  • El tiempo de instalación del sistema operativo es la mejor de todas las opciones, pero la falta de uniformidad es posible al clonar el sistema o al implementar desde una imagen.

Ninguna opción le permite identificar de manera única la computadora, así que decidí identificarla de tres maneras:


  • número de serie de la placa base,
  • identificador del sistema informático
  • tiempo de instalación del sistema operativo.

Por supuesto, estos tres parámetros pueden coincidir en diferentes computadoras, pero con menos frecuencia que uno de ellos.


También se intentó obtener usuarios activos utilizando la clase WMI estándar: Win32_LogonSession . Entonces apareció el primer problema: resultó que Win32_LogonSession muestra todas las sesiones de usuario, incluso aquellas que ya se han completado. Comencé a pensar cómo filtrar las sesiones activas de las que terminaron. Descubrimos que esto se puede hacer usando la clase Win32_SessionProcess , que asocia instancias de las clases Win32_LogonSession con Win32_Process . Si el enlace a la sesión está presente en la lista de instancias de la clase Win32_SessionProcess (hay al menos un proceso con el identificador de esta sesión), entonces está activo. Luego, surgió la pregunta sobre cómo asociar una sesión con un usuario. Esto se puede hacer usando la clase Win32_LoggedOnUser , que une instancias de las clases Win32_LogonSession y Win32_UserAccount . Solo queda obtener instancias de la clase Win32_UserAccount que brinden información detallada sobre el usuario.


imagen


Pero aquí estaba decepcionado. Al usar WMI de forma remota, resultó que al intentar obtener instancias de la clase Win32_UserAccount , es posible obtener solo usuarios de computadoras locales. Es decir, resultó que usando herramientas WMI estándar, es imposible averiguar qué usuarios están activos en la computadora.


Desarrollo de un proveedor de WMI.


Debido a la imposibilidad de una identificación inequívoca de las computadoras y la imposibilidad de obtener información sobre usuarios activos que usan clases WMI estándar, se decidió ampliar la funcionalidad de WMI. Puede hacer esto describiendo sus clases de WMI en un archivo MOF y escribiendo un proveedor de WMI para obtener instancias de estas clases.


Se han descrito dos nuevas clases de WMI: NMBY_InstallInfo - para identificar una computadora y NMBY_LogonSession - para identificar usuarios activos de una computadora.


imagen


Luego se escribió un proveedor de WMI con el que puede obtener instancias de estas clases.


Se establecieron requisitos adicionales para el proveedor:


  • trabajar en un sistema sin .NET;
  • trabajar en el sistema operativo Windows XP y superior;
  • la capacidad de obtener información usando una cuenta no administrativa.

Por lo tanto, el proveedor se escribió en C ++ con WinApi.


En el proceso de redacción del proveedor, surgieron dificultades debido a la pequeña cantidad y calidad de la documentación sobre este tema, pero a pesar de esto, el proveedor se escribió con éxito.


Un proveedor escrito está disponible en la página de descarga . Se puede instalar y utilizar de forma gratuita.


Resumen


Como resultado, utilizando el programa Network MACMonitor se hizo posible:


  • Asociar usuarios con computadoras

imagen


  • Asociar computadoras con puertos en dispositivos de red

imagen


  • Asociar puertos de dispositivos de red con computadoras y usuarios

imagen


  • Ver el historial de registro de usuarios en las computadoras.

imagen


Sitio web del programa

Source: https://habr.com/ru/post/es416217/


All Articles