Homelable: живая карта всей домашней сети

Давно хотел видеть всю инфраструктуру одним взглядом: две площадки, роутеры в разных концах города, туннели между ними, контейнеры на двух внутренних сетях, кто за каким NAT сидит и кто сейчас лежит. Не «список устройств в Wi-Fi», а именно схему — чтобы по ней сразу читалось, что через что ходит.
Рассказываю, как выбирал инструмент, что в итоге поставил и как оживил карту статусами туннелей.
Муки выбора
Сначала казалось, что задача простая — «нарисовать сеть», а инструментов вон сколько. Перебрал пять кандидатов, и у всех нашлось одно общее ограничение: это discovery-инструменты. Они сканируют один сегмент (обычно LAN) и рисуют «что болтается в broadcast domain». А моя топология — инфраструктурная: связи между площадками, туннели поверх интернета, контейнеры за NAT. Сканер за свой broadcast domain не заглянет в принципе.
NetAlertX (~7k звёзд). Один контейнер, лёгкий, красивые карточки устройств, online/offline, порты. Но карта древовидная: родитель → дети. Туннели рисует неидеально, VLAN — подписью на ребре. Вердикт: отличный «кто висит в домашней сети», но схема лабы — нет.
NetPulse (1 звезда, 8 коммитов). PHP + SQLite, ICMP/TCP/SNMP, ручное рисование связей, пунктиры, цвета. По духу — то, что надо, но проект сырой, наружу такое не выставишь. Вердикт: «рисовалка с пингами», которую за вечер напишешь сам.
Scanopy (~5.7k звёзд). L2/L3, VLAN, порты, контейнеры, живая карта. Но три контейнера + PostgreSQL + привилегированный сканер. Для домашней лабы тяжело и привилегированно, и снова L2-центричен — межсайтовые туннели не покажет.
MikroTik-NetMap (0 звёзд, но живой). Веб-альтернатива The Dude: сам находит соседей роутеров по MNDP/LLDP, dotted-линии для VPN, анимация трафика. Но рисует только то, что роутеры видят в L2. Мои контейнеры и туннели между площадками автоматически не покажет.
Homelable (3179⭐, MIT, обновляется чуть ли не ежедневно). – Импорт Proxmox VE — сам вытаскивает контейнеры и VM – Свободный канвас: зоны-сети, вложенность (хост → контейнеры внутри), ручные линки любого типа – Живые статусы нод: ping/TCP/HTTP – Экспорт PNG/SVG, read-only Live View, MCP-сервер для ИИ-ассистентов – Docker-образ или bare-metal скрипт — влезает в обычный LXC
Вердикт: единственный, кто закрывает именно мою задачу — произвольная схема + живые статусы + импорт уже существующей инфраструктуры.
Почему Homelable
- Моя топология — граф: 2 площадки, полтора десятка контейнеров, 2 внутренних сети, 3 типа туннелей между роутерами. Нужен свободный канвас с ручными связями, а не авто-дерево.
- Импорт Proxmox даёт 80% наполнения бесплатно — не надо вбивать контейнеры руками.
- Живые статусы — схема одновременно работает мониторингом.
- Лёгкий: frontend + backend, живёт в LXC рядом с остальными сервисами.
- Экспорт PNG — картинку можно вставить в статью.
Точный путь установки
Шаг 1. Контейнер
Свежий LXC на Proxmox (ubuntu, unprivileged, nesting=1 — docker внутри требует):
pct create 116 local:vztmpl/ubuntu-26.04-standard_26.04-1_amd64.tar.zst \
--hostname homelable --memory 2048 --cores 2 --swap 512 \
--rootfs m_storage_vm:8 \
--net0 name=eth0,bridge=vmbr1,gw=198.51.100.1,ip=198.51.100.24/24,type=veth \
--nameserver 203.0.113.53 \
--ostype ubuntu --unprivileged 1 --features nesting=1 --onboot 1
pct start 116
Грабли: сначала взял 198.51.100.22 — а он уже занят другим сервисом. Симптом: HTTP 000 флапает (ARP-конфликт — пакеты уходят то туда, то сюда). Перед выдачей IP — проверять занятость pct list + pct config <id> | grep net0.
Шаг 2. Docker
pct exec 116 -- bash -c "apt-get update && apt-get install -y curl ca-certificates; curl -fsSL https://get.docker.com | sh"
Шаг 3. Homelable (prebuilt-образы, без сборки)
cd /opt
curl -fsSLO https://raw.githubusercontent.com/Pouzor/homelable/main/docker-compose.prebuilt.yml
curl -fsSL https://raw.githubusercontent.com/Pouzor/homelable/main/.env.example -o .env
# SECRET_KEY = secrets.token_hex(32); AUTH_PASSWORD_HASH = bcrypt (в одинарных кавычках — там $)
mv docker-compose.prebuilt.yml docker-compose.yml
docker compose up -d
# frontend :3000, backend :8000, mcp :8001
Шаг 4. Read-only токен Proxmox для импорта
pveum user token add root@pam homelable --privsep 1
pveum acl modify / -token root@pam!homelable -roles PVEAuditor
Тонкость PVE 9.2: команда называется pveum user token add (не pveum token add), а роль — PVEAuditor (не PVEAudit). Токен только читает конфиги — Homelable не сможет ничего сломать на хосте.
Шаг 5. Импорт топологии
Импорт ходит в API Proxmox и возвращает готовые ноды и связи — остаётся разложить по канвасу и сохранить:
curl -H "Authorization: Bearer $AT" -H "Content-Type: application/json" \
-d '{"host":"192.0.2.10","port":8006,"token_id":"root@pam!homelable","token_secret":"...","verify_tls":false}' \
http://198.51.100.24:3000/api/v1/proxmox/import
# раскладка + POST /api/v1/canvas/save {nodes:[...], edges:[...]}
Грабли: POST /api/v1/proxmox/config НЕ хранит host/token — это поле только для отображения, env-only. Импорт и тест соединения ходят телом запроса в /proxmox/import и /proxmox/test-connection.
Шаг 6. Доступ
Внутренний адрес + публикация через Caddy за admin_acl (как остальные админки — только свои IP):
homelable.example {
header {
-Server
}
import admin_acl 198.51.100.24:3000
log { output file /var/log/caddy/access.log }
}
Раскладка: сетевая, а не импортная
Первый вариант карты вышел «PVE-центричным» — так его отдал импорт: хост по центру, все контейнеры вокруг, сверху интернет. Владелец лабы глянул и сказал: «ты не прав, у нас всё за Caddy». И ведь верно — импорт дал физику, а не логику трафика.

Перерисовал правильно, как трафик реально ходит:
- сервисы сидят во внутренней сети за Caddy (шлюз + NAT);
- Caddy соединён с роутером площадки «дача» WireGuard-туннелем (публикация наружу идёт через него);
- R1 (дача) ⇄ R2 (дом) — четыре туннеля: L2TP, WG, reverse-L2TP (аварийный) и eBGP поверх;
- у каждого роутера свои WAN-аплинки — у дачи один (PPPoE), у дома два (основной + резервный провайдер), и это разные рёбра;
- у роутеров есть и свои внешние BGP-сессии с антифильтр-провайдерами (тянут префиксы для обхода блокировок) — тоже отдельные узлы и рёбра.
Живые статусы
Из коробки Homelable умеет проверять ноды (ping/TCP/HTTP раз в 60 секунд) — но рёбра-туннели статичные. Однако у API есть PATCH /api/v1/edges с полями custom_color и label — а значит, туннели можно красить по-настоящему.
Написал опросчик (cron, раз в минуту): ходит по SSH на оба MikroTik, снимает:
- WG — свежесть
last-handshake(меньше 3 минут = живой); - L2TP — флаг running у клиента;
- BGP — established у сессий;
- WAN — PPPoE running / DHCP bound.
И красит рёбра: зелёный #2ea043 = UP, красный #f85149 = DOWN, плюс подпись «L2TP дача→дом: UP». PATCH летит только при смене статуса, чтобы не дёргать API впустую.
Пара граблей из этой обвязки:
- RouterOS print — колоночный, и это не detail. Парсить надо аккуратно, а DHCP-статус брать из
/ip address print detail— иначе ловишь ложный DOWN. - WG last-handshake старше минуты RouterOS показывает как
1m2s, а не62s. Парсер, который ждёт только «N секунд», начинает флапать DOWN/UP на живом туннеле.
Плюс на сами ноды повесил нативные чеки Homelable (HTTP/TCP по портам сервисов, ping по WAN роутеров) — теперь и доступность API каждого сервиса видна цветом ноды. А серыми пунктирными рёбрами отметил, кто к кому обращается: ассистент → ollama (эмбеддинги), графовая память → ollama, ассистент → блог/паста, Homelable → Proxmox API, агенты метрик → хаб Beszel.
Итог
22 ноды, 33 ребра, всё живое: туннели красятся опросчиком раз в минуту, ноды — штатным scheduler'ом. Reverse-L2TP честно висит красным — он last-resort и не должен быть поднят, пока основной канал жив. Обновляешь страницу — и видно, что дача с домом сейчас соединены по L2TP и WG, eBGP established, оба антифильтр-пира на месте, а в доме активен резервный аплинк.
Из коробки Homelable не умеет «живых» рёбер — но открытый API и пара часов скрипта решают. Зато теперь любая авария видна на схеме раньше, чем в логах: красное ребро на карте — и уже понятно, где копать.
Бонус: скрипт опроса роутеров
Полный обфусцированный скрипт (SSH к роутерам, парсинг статусов RouterOS, PATCH рёбер Homelable, systemd-timer на минуту) — можно забрать и адаптировать под себя:
https://paste.clr58.ru/mikrotik-tunnel-status.py
В шапке файла — конфигурация: ключ SSH, адреса роутеров (в примере — документационные 203.0.113.x), URL Homelable и словарь рёбер с именами ваших интерфейсов RouterOS.