Некоторое время назад прочитал статью (на Хабре, но повторно найти не удалось), в которой рассказывалось о том, как настроить отображение логинов авторизованных RADIUS-пользователей в веб-панели управления контроллером, установленном на *nix системе. Я воспринял, что то конкретное решение подходит лишь для *.nix, поэтому, вдохновившись, решил реализовать подобное на Windows + NPS (aka RADIUS-сервер).

Также под катом есть информация о том, как передавать данные из событий Windows в задачу планировщика.

Было




Будет




Информацию как настроить ТД и NPS не привожу, для ознакомления можно воспользоваться публикацией «Аутентификация беспроводных клиентов по учетным записям Active Directory». Хочу отметить, что в моем случае NPS сервер используется только для Wi-Fi авторизации, а Unifi Controller стоит на одной с ним машине. Ниже по тексту будут примечания, что делать, если ваша конфигурация отличается.

Перейдем непосредственно к реализации задуманного. Первым делом нам нужно «отловить» момент успешной авторизации пользователя и получить ключевую информацию, под которой я подразумеваю MAC-адрес клиентского устройства и логин авторизованного пользователя. Для этого необходимо создать в планировщике Windows задачу, триггером для которой будет событие успешной авторизации NPS сервером (Журнал: «Безопасность», источник: «Microsoft Windows security auditing.», код события: 6272). В действиях указываем наш будущий CMD (позже вернемся к нему).

Настройки триггера


Через GUI Windows настроить передачу данных из события в скрипт нельзя, но не проблема, экспортируем нашу задачу в XML и откроем ее в текстовом редакторе. Нас интересует блок EventTrigger:

<EventTrigger>
	<Enabled>true</Enabled>
	<Subscription><QueryList><Query Id="0" Path="Security"><Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and EventID=6272]]</Select></Query></QueryList></Subscription>
</EventTrigger>

В него нужно вставить блок ValueQueries с параметрами, «позаимствованными» из события:

<EventTrigger>
	<Enabled>true</Enabled>
	<Subscription><QueryList><Query Id="0" Path="Security"><Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and EventID=6272]]</Select></Query></QueryList></Subscription>
	<ValueQueries>
		<Value name="SubjectUserName">Event/EventData/Data[@Name='SubjectUserName']</Value>
		<Value name="CallingStationID">Event/EventData/Data[@Name='CallingStationID']</Value>
	</ValueQueries>
</EventTrigger>

Полный текст задачи, без необязательных параметров (хабрапарсер съел &gt; &lt;, а именно они должны быть в блоке Subscription вместо угловых скобок, иначе импорт не пройдет)
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <Triggers>
	<EventTrigger>
		<Enabled>true</Enabled>
		<Subscription><QueryList><Query Id="0" Path="Security"><Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and EventID=6272]]</Select></Query></QueryList></Subscription>
		<ValueQueries>
			<Value name="SubjectUserName">Event/EventData/Data[@Name='SubjectUserName']</Value>
			<Value name="CallingStationID">Event/EventData/Data[@Name='CallingStationID']</Value>
	</ValueQueries>
    </EventTrigger>
  </Triggers>
  <Actions Context="Author">
    <Exec>
      <Command>C:\name_for_mac_unifi.cmd</Command>
      <Arguments>$(SubjectUserName) $(CallingStationID)</Arguments>
    </Exec>
  </Actions>
</Task>


Возвращаемся к планировщику, удаляем созданное ранее задание и импортируем исправленный XML, добавляем в действиях к скрипту следующие аргументы: $(SubjectUserName) $(CallingStationID)

Об ивентах и параметрах
Информация о передаче параметров ивента в задачу была найдена тут.

Если NPS сервер обслуживает не только Wi-Fi сеть и на нем много политик, то по ссылке выше указано как добавить дополнительную фильтрацию в условия задачи (блок Subscription), в данном случае можно фильтровать по имени NPS политики.

Теперь, когда есть все необходимые данные, переходим к скрипту. В нем проводится правка базы mongo, используемой Unifi Controller'ом, а именно — в коллекции user записи с МАК адресом клиентского устройства устанавливается свойство name, равное логину пользователя (обычный update). В CMD это выглядит так:

@ECHO off
set user=%1
set mac=%2
:: меняем в маке - на :
set mac=%mac:-=:%

:: в случае если это первый логин устройства - мака в базе еще нет, ставим "sleep"
ping -n 60 127.0.0.1 > nul

:: mongo регистрозависим, поэтому средствами встроенного в mongo js приводим мак к нижнему регистру
mongo.exe 127.0.0.1:27117/ace  --eval "var mac='%mac%'; db.user.update({ mac:mac.toLowerCase()},{$set:{name:'%user%'} });"

Немного о MONGO клиенте и сервер
Среди бинарников mongo сервера поставляемого с Unifi Controller клиента нет. Его нужно скачать отдельно, при этом предлагаемый к скачиванию клиент был свежее сервера и выполнять апдейт не хотел. Решается скачиванием клиента той же версии.

Проверить версии клиента и сервера можно следующим образом:

C:\>mongo.exe 127.0.0.1:27117/ace
MongoDB shell version: 2.2.2
connecting to: 127.0.0.1:27117/ace
> db.version()
2.2.2
> version()
version: 2.2.2
>

Ссылки на скачивание этой версии на сайте MongoDB нет, но не проблема, берем ссылку на любую версию под нужную платформу:

fastdl.mongodb.org/win32/mongodb-win32-i386-2.2.7.zip

И подставляем необходимую нам версию mongo:

fastdl.mongodb.org/win32/mongodb-win32-i386-2.2.2.zip

C 2.2.2 прошло на «УРА».

И, да, со сторонней машины подключиться мне не удавалось, возможно, настройки базы тому виной, разбираться не стал, так как не было необходимости. Но даже с невозможностью удаленно подключиться к базе никто не мешает удаленно выполнить локальную команду на машине с сервером mongo.

На этом все, желаю удачи! Принимаю исправления/критику.

Unifi API
Уже после реализации всей затеи и приступив к статье я встретил упоминание о unifi api (видимо, в оригинальной статье, упомянутой вначале, именно на нем было реализовано), но ссылки и поиск на официальной вики информацию не раскрыли. Информация в репозитариях приоткрыла тайну некоторых методов.

Полагаю, что для изменения логина можно обратиться к $baseurl/api/cmd/stamgr и передать строку json={'cmd':'update-sta', 'mac':'${mac}', 'name':'$2', 'email':'$3'}.

Комментарии (2)


  1. lolmaus
    31.05.2015 15:53

    Как запустить UniFi Controller на EdgeRouter POE?


  1. max_rip
    31.05.2015 20:09

    А у кого-то получалось подключить facebook login (https://www.facebook.com/business/facebook-wifi)?