Контроль устройств в Wi-Fi сети

Все IP адреса и имена хостов являются вымышленными.
Любые совпадения с реальными – случайны.

Доброго дня, уважаемые читатели и единомышленники.
Сегодня я хочу рассказать о том, как выполняется мониторинг подключения клиентов к домашней Wi-Fi сети.

Решаемая задача:

Мониторинг подключения Wi-Fi клиентов в режиме реального времени. Информирование по электронной почте в случае подключения не зарегистрированного (не входящего в белый список) клиента.
Для решения задачи используется следующее оборудование:
1) Роутер с прошивкой на основе openwrt (Gargoyle) в моем случае (назовем его Роутер);
2) Компьютер под управлением Linux (в моем случае это нетбук с установленным Debian, назовем его Сервер);
3) Собственно клиентские устройства, подключающиеся к Wi-Fi.

Краткое описание принципа работы решения.

В предлагаемом решении логи аутентификации пользовательских устройств в сети Wi-Fi передаются с Роутера по syslog на Сервер. Настроенный на сервере syslog сервис записывает эти логи в файл, который потом читает SEC (Simple Event Correlator). Согласно настроенному в SEC правилу, при появлении лога аутентификации пользователя по Wi-FI, выполняется запуск скрипта на вход которому передается МАС адрес аутентифицированного устройства. Скрипт выполняет сверку МАС адреса со списком разрешенных и, в случае не нахождения совпадения, отправляет сообщение по электронной почте. Архитектура решения приведена на рисунке ниже.

Рисунок 1 — Архитектура решения

Далее разберем конфигурации систем в подробностях.

Подробности настройки

Настройка Роутера

Начнем с Роутера. Здесь все очень просто. Должна быть настроена передача логов аутентификации пользователей WiFi на удаленный хост (в нашем случае Сервер). В некоторых прошивках это можно сделать даже через графический веб-интерфейс. В моем случае необходимо отредактировать две строки в файле /etc/config/system:

        option log_remote '1'  # Включает функционал отправки сообщений по syslog
        option 'log_ip' '10.0.0.10' # Указывается адрес удаленного сервера

И перезапустить роутер (для верности).
После этого, на стороне Сервера видим трафик приходящий от Роутера по syslog:

tcpdump –i eth0 host 10.0.0.1 and port 514
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
22:42:49.739272 IP gateway.36808 > server.local.syslog: SYSLOG kernel.warning, length: 235
22:42:50.689308 IP gatewayw.36808 > server.local.syslog: SYSLOG kernel.warning, length: 264

На этом настройка Роутера закончена. Переходим к настройке Сервера.

Настройка Сервера

Настройка сервиса syslog

В качестве сервиса syslog на Сервере я использую syslog-ng. Конечно, можно использовать и другие службы обработки журналов, например, rsyslog, но в данной статье я опишу настройку syslog-ng.
Установка syslog-ng находится за рамками данной статьи, поэтому предполагается, что он уже установлен.
Для настройки приема добавляем в соответствующие разделы конфигурационного файла /etc/syslog-ng/syslog-ng.conf следующие строки:

source s_net { udp(); }; #создает сетевой приемник с именем s_net (источник лога)
destination sec_log { file("/var/log/sec.log"); }; #создает файл (точку назначения), в который будут записываться логи
filter wifi_auth { message(".*IEEE 802.11: authenticated"); }; #создает фильтр для записи в лог не всех подряд сообщений, а только касающихся аутентификации по Wi-Fi
log { source(s_net); filter(wifi_auth); destination(sec_log); }; #и, наконец, эта строка соединяет в себе, все созданные сущности – источник, фильтр и назначение

Далее необходимо перезапустить syslog-ng:

/etc/init.d/syslog-ng restart

И ждать появления новых сообщений в файле /var/log/sec.log

Настройка SEC (Simple Event Correlator)

Задача SEC, как уже описывал ранее, состоит в том, чтобы выполнять запуск скрипта при появлении события аутентификации пользователя Wi-Fi.
События аутентификации в моем случае имеют следующий вид:

Aug 13 22:24:25 10.0.0.1 hostapd: wlan1: STA 34:12:98:11:22:33 IEEE 802.11: authenticated

Таким образом, правило SEC получается следующее:

type=Single # простейшее правило, срабатывающее на единственное событие
ptype=RegExp # правило ищет соответствие регулярному выражению в событии
pattern=.*\s+STA\s+(\S+)\s+IEEE\s+802\.11\:\s+authenticated.* # шаблон регулярного выражения
desc=MAC $1 authenticated in wireless network # просто описание
action=shellcmd /usr /smarthome/wifi_device_check.sh $1 # действие, выполняемое правилом

Здесь необходимо немного пояснить работу SEC. Часть регулярного выражения, заключенную в скобки (в моем случае это как раз МАС адрес клиентского устройства – (\S+) ) SEC может передавать как параметр запускаемому скрипту. Обозначается как $1, $2 … $N. В зависимости от того, сколько параметров из сообщения нужно передать. Каждый параметр нужно выделять скобками. Счет идет слева направо.
Таким образом, при получении события аутентификации пользователя Wi-Fi происходит запуск скрипта. На вход скрипту передается МАС адрес подключившегося устройства в качестве параметра.

Скрипт проверки МАС адреса

Ниже приведен текст скрипта, выполняющего сверку МАС адреса со списком разрешенных. Список разрешенных МАС адресов можно заполнять вручную. А в моем случае, список берется из конфигурационного файла сервиса dnsmasq, выполняющего роль DHCP сервера. В том случае, если обнаруженный МАС не входит в список разрешенных, скрипт выпполняет запрос к ресурсу macvendors.com для выявления типа устройства по МАС и отправляет всю полученную информацию на заданный в теле скрипта e-mail.

#!/bin/bash
MAIL="/usr/local/smarthome/wifi_access/mail.txt"
NEW_MAC=$1
dt=`date`
MAC_FILE=/usr/local/smarthome/wifi_access/mac.txt
MAC_LIST=`grep dhcp-host /etc/dnsmasq.conf |grep -v "#"|awk -F '=' '{print $2}'|awk -F ',' '{print $1}'`
#echo $MAC_LIST
for MAC in $MAC_LIST
do
# echo "Checking MAC $MAC"
if [[ $MAC = $NEW_MAC ]]
then
# echo "MAC valid"
VALID=1
fi
done
if [[ $VALID = "1" ]]
then
exit 0
else
# echo "$MAC is Invalid"
wget https://api.macvendors.com/$NEW_MAC -O $MAC_FILE
sleep 3
printf "Subject: Unknown device authenticated in wireless network at $dt\n" > $MAIL
printf "MAC address: $NEW_MAC\n" >> $MAIL
# echo "found `cat $MAC_FILE` vendor"
printf "Device type: `cat $MAC_FILE`\n" >> $MAIL
/usr/sbin/ssmtp email@gmail.com < $MAIL
rm $MAC_FILE
rm $MAIL
fi
exit 0

Пример email сообщения:

Вот и все!
Спасибо за внимание! ))