Я разработчик программы мониторинга сети.
В ходе разработки программы возникла задача: определить, на каких компьютерах работают пользователи, и связать эту информацию с портами сетевых устройств.
В этой статье я хочу написать, как мне удалось это сделать.
Я начал с простых рассуждений: чтобы связать пользователя с портом на сетевом устройстве, сначала необходимо связать с этим портом компьютер, на котором работает пользователь.
Поскольку программа Network MACMonitor позволяет находить mac-адреса на портах сетевых устройств, было принято решение связывать компьютеры с портами по mac-адресам.
Далее вам необходимо связать пользователей с компьютерами.
Эту информацию можно получить, каким-либо образом опросив компьютеры.
Я видел два варианта решения этой проблемы:
- Напишите агент Windows и опрашивайте его с помощью программы Network MACMonitor;
- Используйте инструментарий управления Windows (WMI).
- разработка безопасного протокола сетевого взаимодействия Windows-агента и программы Network MACMonitor;
- необходимость предварительной установки агента на компьютеры;
- используя другой язык программирования (пишу на Java), так как считаю, что Java для написания агента не подходит: из-за достаточно большого потребления виртуальной памяти и необходимости установки JRE на все компьютеры.
Разработка клиента WMI
Поскольку программа Network MACMonitor написана на Java, я попытался найти готовую кроссплатформенную Java-библиотеку, реализующую функционал WMI-клиента.И тут я разочаровался — такой библиотеки нет. Все существующие библиотеки либо являются обертками над утилитами Windows, либо (библиотека j-Interop) требуют дополнительных манипуляций с реестром (изменение владельца и разрешений для ветвей реестра) для активации WMI через удаленный реестр.
Поскольку полноценно работающей библиотеки для Java не было, я решил найти библиотеку или WMI-клиент, написанный на любом другом языке программирования.
И я нашел один WMI-клиент для Linux. Скачав и проверив его работу, я понял, что опрос Windows-компьютеров под управлением Linux возможен.
Поскольку это возможно, я решил написать собственную библиотеку на чистой Java, которая бы позволяла опрашивать компьютер через WMI. Для написания библиотеки нужна была понятная документация по работе протокола WMI. Оказалось, что такая документация существует и находится в свободном доступе.
Я начал подготовку к написанию библиотеки с рассмотрения сетевого стека протоколов WMI.
Протокол | Технические характеристики |
---|---|
Инструментарий управления Windows (WMI) | MS-WMI, MS-WMIO |
Объектная модель распределенных компонентов (DCOM) | MS-DCOM |
Удаленный вызов процедур (RPC) | MS-RPCE |
Протокол управления передачей (TCP) | - |
Интернет-протокол (IP) | - |
Поскольку WMI не реализован в Java, я перешел к следующему протоколу в стеке — DCOM. И тут мне повезло.
Хотя вышеупомянутая библиотека j-Interop не реализует функциональность WMI, она реализует функциональность DCOM. Итак, осталось написать реализацию протокола WMI, то есть написать реализацию спецификаций MS-WMI и MS-WMIO. Я начал с реализации спецификации MS-WMIO, отвечающей за формат кодирования данных в сетевых пакетах протокола WMI. Из спецификации я узнал, что для кодирования данных используется расширенная спецификация синтаксиса Бэкуса-Наура (ABNF, RFC 5234).
Спецификация MS-WMIO полностью описывает формат кодирования с использованием ABNF. Известно, что если есть грамматика, описанная в ABNF, то для этой грамматики можно создать парсер.
В Интернете я нашел генератор парсера ABNF для Java и предоставил ему на вход грамматику, взятую из спецификации.
Поскольку сгенерированный парсер работал со строками, а MS-WMIO описывает двоичный формат кодирования, идея заключалась в том, чтобы в сгенерированном парсере просто заменить строки массивами байтов, а символы - байтами.
Но посмотрев количество файлов, где необходима замена, а также узнав из спецификации MS-WMIO, что иногда потребуются битовые манипуляции, я понял, что исправить сгенерированный парсер будет очень сложно, и решил отказаться от этой идеи.
.
Я думал, что написать парсер с нуля будет быстрее.
И вот парсер был готов.
Но как проверить правильность написания парсера, если спецификация MS-WMI, отвечающая за функционирование протокола WMI, еще не реализована? Здесь мне помог Wireshark, анализатор сетевого трафика.
Сделав WMI-запросы стандартными средствами Windows (wbemtest), я после отключения шифрования получал сетевые пакеты и сохранял их в бинарные файлы.
Эти файлы уже могли использоваться в качестве тестовых данных для парсера.
После того как парсер был протестирован и найденные ошибки исправлены, я приступил к реализации спецификации MS-WMI, описывающей принцип работы протокола WMI. Спецификация MS-WMI разделена на серверную и клиентскую.
Клиентскую часть я реализовал частично, насколько это необходимо для опроса компьютера через WMI. Для этой части мне тоже понадобился Wireshark, но для анализа последовательности сетевых пакетов во время опроса WMI.
Попытка получить необходимые данные с помощью WMI
После написания библиотеки WMI встала задача использовать ее в программе Network MACMonitor. Возник вопрос: какие данные следует получать с компьютеров? Я подумал, что мне нужно получить имя компьютера, домен, операционную систему, время запуска, mac-адреса, ip-адреса, активных пользователей, которые работают на компьютере.Но возникла очень важная проблема: как однозначно идентифицировать компьютер при опросе WMI? Я рассмотрел следующие варианты:
- mac-адрес, изменяемый, возможен неуникальный;
- имя и домен компьютера (рабочая группа), изменяемые, неуникальные (для рабочей группы);
- серийный номер жесткого диска, на котором установлена операционная система, для опроса WMI необходимы права администратора, уникальность не проверял, но подозреваю, что неуникальность возможна;
- серийный номер материнской платы, возможна неуникальность, и довольно часто;
- идентификатор компьютерной системы (свойство UUID Класс WMI Win32_ComputerSystemProduct ), неединственность возможна, и довольно часто;
- время установки операционной системы, лучший из всех вариантов, но возможна неуникальность при клонировании системы, или при развертывании из образа.
- серийный номер материнской платы,
- идентификатор компьютерной системы,
- время установки операционной системы.
Также была предпринята попытка получить активных пользователей с помощью стандартного класса WMI: Win32_LogonSession .
Тут появилась первая проблема: оказалось, что Win32_LogonSession показывает все пользовательские сессии, даже те, которые уже завершились.
Я начал думать, как отфильтровать активные сессии от завершенных.
Я обнаружил, что это можно сделать с помощью класса Win32_SessionProcess , который связывает экземпляры классов Win32_LogonSession С Win32_Процесс .
Если ссылка на сеанс присутствует в списке экземпляров класса Win32_SessionProcess (есть хотя бы один процесс с идентификатором этой сессии), то она активна.
Дальше встал вопрос, как связать сессию с пользователем.
Это можно сделать с помощью класса Win32_LoggedOnUser , который связывает экземпляры классов Win32_LogonSession И Win32_UserAccount .
Остается только получить экземпляры класса Win32_UserAccount , которые предоставляют подробную информацию о пользователе.
Но здесь меня разочаровало.
При удаленном использовании WMI выяснилось, что при попытке получить экземпляры класса Win32_UserAccount ИМХО, можно завести только локальных пользователей компьютера.
То есть оказалось, что стандартными средствами WMI невозможно узнать, какие пользователи активны на компьютере.
Разработка провайдера WMI.
В связи с невозможностью однозначной идентификации компьютеров и невозможностью получения информации об активных пользователях с помощью стандартных классов WMI было решено расширить функциональные возможности WMI. Вы можете сделать это, описав классы WMI в файле MOF и написав поставщика WMI для получения экземпляров этих классов.Описаны два новых класса WMI: NMBY_InstallInfo – идентифицировать компьютер и NMBY_LogonSession – для определения активных пользователей компьютера.
Затем был написан WMI-провайдер, с помощью которого можно получать экземпляры этих классов.
К провайдеру были предъявлены дополнительные требования:
- работа в системе без .
NET;
- работа на операционной системе Windows XP и выше;
- возможность получения информации с использованием неадминистративной учетной записи.
Письменный провайдер доступен на странице загрузки .
Его можно установить и использовать бесплатно.
Нижняя граница
В результате с помощью программы Network MACMonitor стало возможным:- соединять пользователей с компьютерами;
- подключать компьютеры к портам сетевых устройств;
- связывать порты сетевых устройств с компьютерами и пользователями;
- просматривать историю регистрации пользователей на компьютерах.
Сайт программы Теги: #Сетевые технологии #программирование #ИТ-инфраструктура #Системное администрирование #мониторинг #разработка ПО
-
Обзор Ddos-Атак За Первый Квартал 2021 Года
19 Oct, 24 -
1967 Года Рождения И Младше.
19 Oct, 24 -
Россия – Родина Слонов
19 Oct, 24