Вы никогда не задумывались, а куда вообще коннектится все то что у вас дома в сети ? Все эти Windows, MacOS, iOS и прочие проприетарные и умные утюги ? А это не сложно посмотреть. Сегодня в нашем кружке 'Оч.умелые ручки' мы будем следить за теми, кто следит за нами.

Наша цель - построить карту и графики того куда коннектится все то что сидит в сети дома. И не по трафику, понятно что какая-то там условная Амедиатека будет в топе, а именно про то, куда устанавливаются соединения. Готовить будем на Mikrotik, Grafana и Victoria Logs. В результаты мы получим что-то вроде вот этого:

Для изготовления 'блюда' нам понадобится всего 4 ингредиента:

  1. Mikrotik

  2. Linux или MacOS

  3. Docker (вместе с его другом, composerом)

  4. Немного умения консольных команд

1. Mikrotik это просто

Для начала зальём в mikrotik вот примерно такой конфиг, который будет следить за всеми новыми коннектами и вероломно сливать их нам по UDP syslog протоколу в victoria logs. Не забываем заменить x.x.x.x на адрес машины где будет поднята victoria logs, а y.y.y.y на внутренний адрес роутера

Скрытый текст
/system logging action set 3 remote=x.x.x.x remote-port=5514 src-address=y.y.y.y syslog-facility=local0
/system logging add action=remote prefix=:Firewall topics=firewall
/ip firewall filter add action=passthrough chain=forward comment="all new connections" connection-state=new log=yes log-prefix=new-connection

2. Готовим микросервисы

Дальше все еще проще

  1. Ставим на машину git, docker и docker compose если у вас Linux и git, orbstack и docker compose если у вас MacOS

  2. Клонируем себе заранее приготовленную репку https://github.com/sergeygalkin/habr.git

  3. Виртуозно исполняем всего пару команд

cd habr/mikrotik-victorialogs-mapip
docker compose up -d

В результате которых должно:

  1. Cтартануть 3 сервиса

  2. Появится два docker volume (для графаны и victoria logs)

  3. Собраться один имидж тупенького сервиса на питоне, который по запросу графаны лезет в victoria logs, запрашивает статистику за последний день, конвертит адреса в города, страны и координаты и отдает в виде json

  4. Запустится графана с одной дашбордой IP Map и datasource настроенный на сервис из пункта 3

3. Как пользоваться этой шнягой

Если вы все настроили правильно то должно произойти следующее

1. На адресе http://127.0.0.1:9428/select/vmui у вас должен появится вот такой симпатишный UI, который можно использовать для поиска всякого по ip адресам и портам

2. Команда`curl 'http://10.115.0.50:5555/city_data?ip=*&time=1h'` должна отдавать что-то такоe:

Скрытый текст

[{"city":"Moscow","count":19},{"city":"Paris","count":3},{"city":"Falkenstein","count":2},{"city":"Engel's","count":6},{"city":"Frankfurt am Main","count":32},{"city":"Dublin","count":19},{"city":"San Jose","count":1},{"city":"Stockholm","count":19},{"city":"Victoria","count":1},{"city":"Khasavyurt","count":1},{"city":"Boardman","count":3},{"city":"Helsinki","count":6},{"city":"Amsterdam","count":7},{"city":"Los Angeles","count":2},{"city":"M\u00fcnchwilen","count":1},{"city":"San Francisco","count":6},{"city":"Marseille","count":1},{"city":"Hangzhou","count":1},{"city":"London","count":2},{"city":"Newark","count":1},{"city":"Kansas City","count":7},{"city":"Perm","count":1},{"city":"Ashburn","count":32},{"city":"Kista","count":6},{"city":"Warsaw","count":7},{"city":"Sassenburg","count":1},{"city":"Bucharest","count":6},{"city":"Mountain View","count":1},{"city":"Tokyo","count":3},{"city":"Phoenix","count":1},{"city":"D\u00fcsseldorf","count":3},{"city":"Montreal","count":2},{"city":"Edison","count":1},{"city":"Groningen","count":2},{"city":"Boydton","count":5},{"city":"Lappeenranta","count":3},{"city":"B\u00f6nen","count":1},{"city":"Chicago","count":1}]

4. На урле http://127.0.0.1:3000/d/geiop/ после ввода логина и пароля admin/SuperSecret должна появится дашборда как на первом скриншоте

Особенности 'блюда'

  1. Секурность у описанного сетапа близка к нулю, пароль только на графане, http вместо https, порты торчат наружу, так что не надо это разворачивать на виртуалке в интернете, но для дома вполне сойдет.

  2. Самописный сервис на питоне не зря пишет при старте `WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead` он именно такой, исключительно для домашней нагрузки

  3. Надо понимать что запись в логе микротика new-connection говорит о том что что-то внутри пыталось установить соединение, но это не значит что это сделать удалось

  4. ICMP не учитывается

  5. Название поля ip (в отличие от time) номинально, ничего не мешает туда вписать номер порта вместо ip

Бон аппетит.

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


  1. chaynick
    15.02.2025 07:42

    Прелестно, просто прелестно! Не расскажите только как может тот же 8.8.8.8 находится в США если RTT из Москвы до него 5-10 мс - можете сами посчитать что оказывается США от Москвы находится в 1500 км теоретического предела - и это без учета не прямой прокладки линий, задержки на оборудовании и меньшей скорости света в волокне. Может не стоит уже использовать geoip в век CDN и bgp anycast?


    1. sergeygals Автор
      15.02.2025 07:42

      мне кажется 8.8.8.8 не очень удачный пример, на запросы в него давно отвечают провайдеры, а не cам 8.8.8.8. Такие сервисы надо заворачивать куда нужно и тогда пинг становится ~80 ms. ну и в целом надо понимать что geoip да еще на статичной базе на диске далека от 100% точности


      1. lantonov
        15.02.2025 07:42

        Если бы bgp не было такого быть не может так как каждая. Область имеет владельца и ели что через Россию очень много транзита идёт


        1. sergeygals Автор
          15.02.2025 07:42

          Ну я примерно представляю что такое bgp и протоколы маршрутизации, как и роутинг, но мысли все равно не понял :) какая разница как идёт трафик если составители базы знают (или утверждают что знают) что вот это конечный ip живёт в такой то стране ?


    1. lantonov
      15.02.2025 07:42

      Иза количества пирингов Гугла между провайдерами как и cloudflare так время задержки сокрящяетя так работает протокол bgp


  1. DikSoft
    15.02.2025 07:42

    del


  1. DikSoft
    15.02.2025 07:42

    Порядок запуска в WSL2: Сработает в  Windows 11 version 22H2 и выше
    1) в каталоге HOMEPATH (обычно это C:\Users\user_name\ )создаем или правим файл .wslconfig чтобы он содержал строку:

    [wsl2]
    networkingMode=mirrored

    2) В Windows Firewall создаем два правила , одно для UDP 5514 , второе для TCP 3000 , 5555 , 9428

    3) В запущенном WSL:

    sudo passwd root
    # вводим новый пароль для root
    su -
    ip a # - запоминаем IPv4 адрес для Mikrotik
    apt install git docker docker-compose
    git clone https://github.com/sergeygalkin/habr.git
    cd habr/mikrotik-victorialogs-mapip
    docker-compose up -d

    Дальше по тексту.

    PS Можно завернуть входящий трафик в WSL ещё несколькими способами, но этот самый простой, хотя и менее безопасный.


    1. DikSoft
      15.02.2025 07:42

      PS2 В таком варианте подключиться к WEB морде можно будет :
      1) С соседнего компьютера по IP машинки с WSL2
      и/или
      2) С того же самого компьютера с браузера, установленного в WSL2:

      apt install chromium
      3) Запускаем браузер: Linux GUI App in WIndows 11 Start menu


  1. GomelKiev
    15.02.2025 07:42

    Можно ли микротик заменить на асус с мерлин фирмваре?


    1. sergeygals Автор
      15.02.2025 07:42

      думаю что без проблем, алгоритм примерно такой

      1. Настраивем на асусе отправку логов в victroia logs. Как это на той прошивке делать не знаю, в чистых линухах по идее будет как то так. Добавляем примерно такое правило логирования 'iptables -A FORWARD -m conntrack --ctstate NEW -j LOG --log-prefix "firewall-new: " --log-level 4', потом в rsyslog перенаправляем это в викторию. Я с прошивкой мерлина не сталкивался, поэтому точно не подскажу как аналогичное там натыкивать.

      2. Потом нам надо переделать переменную API_QUERY_COMMON, даже не всю ее а вот эту часть `!NAT !ICMP | extract ', proto <proto>, <src_ip>:<src_port>-><dst_ip>:<dst_port>, len' from _msg `

      3. Для этого идем в  http://127.0.0.1:9428/select/vmui  и начинаем строит запросы, добиваясь что бы src_ip и dst_ip прилетали в данных, кажется что для linux будет примерно так `extract ' SRC=<src_ip> DST=<dst_ip> ' from _msg` в результате запроса должно получиться как то так, при просмотре в json формате должны появится поля src-ip и dst-ip (порты могут и не появляться, они никак счас не используются)

      1. если все ок, добавляем в конец запроса суммирование '| stats by (dst-ip) count() dst-ip-count | sort (dst-ip-count) desc limit 1000', проверяем что все выглядит примерно так

      1. вставляем полученную строку в переменную API_QUERY_COMMON

      2. перезапускаем все через `docker compose build && docker compose up -d`