
Инструмент для обнаружения локальной сети с интерактивным терминальным пользовательским интерфейсом (TUI), написанный на Go. Обнаруживайте, исследуйте и понимайте свою LAN интуитивно. Тук-тук.. кто там? 🚪
# Whosthere
[](https://go.dev/doc/devel/release)
[](LICENSE)
[](https://github.com/ramonvermeulen/whosthere/releases)
[](https://github.com/ramonvermeulen/whosthere/releases)
[](https://github.com/ramonvermeulen/whosthere)
Инструмент обнаружения устройств в локальной сети с интерактивным терминальным интерфейсом (TUI), написанный на Go.
Исследуйте и изучайте свою локальную сеть интуитивно понятным способом.
Whosthere выполняет **непривилегированные параллельные сканирования**, используя сканеры [**mDNS**](https://en.wikipedia.org/wiki/Multicast_DNS)
и [**SSDP**](https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol). Кроме того, он сканирует
локальную подсеть, пытаясь установить TCP/UDP-соединения для запуска ARP-разрешения, а затем читает
[**ARP-кэш**](https://en.wikipedia.org/wiki/Address_Resolution_Protocol) для идентификации устройств в вашей локальной сети.
Эта техника заполняет ARP-кэш без необходимости в повышенных привилегиях. Все обнаруженные устройства дополняются
данными из [**OUI**](https://standards-oui.ieee.org/) для отображения производителей, когда это возможно.
Whosthere предоставляет удобный, интуитивный способ ответить на вопрос, который задаёт каждый сетевой администратор: «Кто там в моей сети?»

## Возможности
- **Интерактивный TUI:** Интуитивная навигация и исследование обнаруженных устройств.
- **Быстрый и параллельный:** Одновременно использует несколько методов обнаружения.
- **Не требует повышенных привилегий:** Работает полностью в пользовательском пространстве.
- **Обогащение данных об устройствах:** Использует поиск по [**OUI**](https://standards-oui.ieee.org/) для отображения производителей устройств.
- **Встроенный сканер портов:** Опциональное обнаружение сервисов на найденных хостах (сканируйте только устройства, на которые у вас есть разрешение!).
- **Режим демона с HTTP API:** Работа в фоне и интеграция с другими инструментами.
- **Темы и конфигурация:** Персонализация внешнего вида и поведения через конфигурацию YAML.
## Установка
Через [**Homebrew**](https://brew.sh/) с помощью `brew`:
```bash
brew install whosthere
```
В [**NixOS**](https://nixos.org/) с помощью `nix`:
```bash
nix profile install nixpkgs#whosthere
```
В [**Arch Linux**](https://archlinux.org/) с помощью `yay`:
```bash
yay -S whosthere-bin
```
Если вашего менеджера пакетов нет в списке, вы всегда можете установить с помощью [**Go**](https://go.dev/):
```bash
go install github.com/ramonvermeulen/whosthere@latest
```
Или **собрать из исходного кода**:
```bash
git clone https://github.com/ramonvermeulen/whosthere.git
cd whosthere
make build
```
Кроме того, вы можете скачать готовые бинарные файлы со
[**страницы релизов**](https://github.com/ramonvermeulen/whosthere/releases).
## Использование
Запустите TUI для интерактивного обнаружения:
```bash
whosthere
```
Запустите как CLI для однократного сканирования и вывода результатов:
```bash
whosthere scan -t 5
```
Вывод результатов в файл JSON:
```bash
whosthere scan -t 5 --json --pretty > devices.json
```
Запуск в режиме демона с HTTP API:
```bash
whosthere daemon --port=8080
```
Массовый импорт псевдонимов из файла или экспорт текущих:
```text
whosthere aliases import ./aliases.yaml
whosthere aliases export --stdout
```
Дополнительные параметры командной строки можно найти, выполнив:
```bash
whosthere --help
```
## Горячие клавиши (TUI)
| Клавиша | Действие |
| ------------------ | --------------------------------- |
| `/` | Начать поиск по регулярному выражению |
| `k` | Вверх |
| `j` | Вниз |
| `g` | Перейти к началу |
| `G` | Перейти к концу |
| `y` | Скопировать IP выбранного устройства |
| `Y` | Скопировать MAC выбранного устройства |
| `enter` | Показать сведения об устройстве |
| `CTRL+t` | Переключить выбор темы |
| `CTRL+i` | Переключить выбор интерфейса |
| `CTRL+c`/`q` | Остановить приложение |
| `ESC` | Очистить поиск / Вернуться назад |
| `p` (просмотр сведений) | Запустить сканирование портов на устройстве |
| `tab` (модальное окно) | Переключить выбор кнопки |
## Конфигурация
Whosthere поддерживает несколько способов конфигурации со следующим приоритетом (от высшего к низшему):
1. **Флаги командной строки** — Наивысший приоритет. См. `whosthere --help` для доступных флагов.
1. **Переменные окружения** — С префиксом `WHOSTHERE__`. См. [**Конфигурация через переменные окружения**](#configuration-via-environment-variables).
1. **Файл конфигурации** — Файл конфигурации YAML. См. [**Файл конфигурации**](#configuration-file).
1. **Значения по умолчанию** — Резервные значения по умолчанию. См. `DefaultConfig()` в [**config.go**](https://github.com/ramonvermeulen/whosthere/blob/main/internal/core/config/config.go).
### Файл конфигурации
Whosthere ищет файл конфигурации в следующем порядке, используя первый найденный:
1. Путь, указанный через флаг `--config` или переменную окружения `WHOSTHERE_CONFIG`
1. `$XDG_CONFIG_HOME/whosthere/config.yaml` (если `XDG_CONFIG_HOME` задана)
1. `~/.config/whosthere/config.yaml` (расположение по умолчанию)
**Пример конфигурации:**
```yaml
# Uncomment the next line to configure a specific network interface - uses OS default if not set
# network_interface: eth0
# When enabled, devices from all network interfaces are shown and persist when switching interfaces
# Note: if two interfaces share the same subnet (e.g. both use 192.168.1.x), devices may get merged
# since they are identified by IP address. Use with caution on overlapping subnets.
all_interfaces: false
# Optional IPv4 CIDR subnets to sweep. When set, the sweeper skips the auto-detected interface subnet unless it is listed here.
# target_subnets: ["10.0.0.0/24", "10.0.1.0/24"]
# WARNING: scanning subnets larger than /16 sends packets to 65535+ IPs per subnet. Enable only if you understand the traffic implications. Consider using smaller /24 subnets for targeted scanning.
# scan_large_subnets: false
# How often to run discovery scans
scan_interval: 20s
# Maximum timeout for each scan, recommended to be less than the scan interval
scan_timeout: 10s
scanners:
mdns:
enabled: true
ssdp:
enabled: true
arp:
enabled: true
sweeper:
enabled: true
interval: 5m
timeout: 20s
port_scanner:
timeout: 5s
# List of TCP ports to scan on discovered devices
tcp: [21, 22, 23, 25, 80, 110, 135, 139, 143, 389, 443, 445, 993, 995, 1433, 1521, 3306, 3389, 5432, 5900, 8080, 8443, 9000, 9090, 9200, 9300, 10000, 27017]
splash:
enabled: true
delay: 1s
theme:
# When disabled, the TUI will use the terminal it's default ANSI colors
# Also see the NO_COLOR environment variable to completely disable ANSI colors
enabled: true
# See the complete list of available themes at https://github.com/ramonvermeulen/whosthere/tree/main/internal/ui/theme/theme.go
# Set name to "custom" to use the custom colors below
# For any color that is not configured it will take the default theme value as fallback
name: default
# Disable ANSI colors completely, overrides theme.enabled
# Can also be set via NO_COLOR or WHOSTHERE__THEME__NO_COLOR environment variables
# no_color: false
# Custom theme colors (uncomment and set name: custom to use)
# primitive_background_color: "#000a1a"
# contrast_background_color: "#001a33"
# more_contrast_background_color: "#003366"
# border_color: "#0088ff"
# title_color: "#00ffff"
# graphics_color: "#00ffaa"
# primary_text_color: "#cceeff"
# secondary_text_color: "#6699ff"
# tertiary_text_color: "#ffaa00"
# inverse_text_color: "#000a1a"
# contrast_secondary_text_color: "#88ddff"
aliases:
# Uncomment to import aliases.yaml into the local database on startup (only when it changed)
# auto_import: false
# Override the aliases file path - defaults to the app config directory
# file: "/path/to/aliases.yaml"
```
## Переменные окружения
### Общие переменные окружения
| Переменная | Описание |
| ------------------ | ------------------------------------------------------------------------------- |
| `WHOSTHERE_CONFIG` | Путь к файлу конфигурации, чтобы переопределить расположение по умолчанию. |
| `WHOSTHERE_LOG` | Установить уровень логирования (например, `debug`, `info`, `warn`, `error`). По умолчанию `info`. |
| `NO_COLOR` | Отключить ANSI-цвета в TUI. |
### Конфигурация через переменные окружения
Любую опцию конфигурации, доступную в конфигурации YAML, можно задать через переменные окружения, используя
префикс `WHOSTHERE__` (обратите внимание на двойное подчёркивание). Вложенные ключи конфигурации разделяются двойными подчёркиваниями, а
ключи нечувствительны к регистру.
Примеры:
- `WHOSTHERE__SPLASH__ENABLED=false` — Отключить заставку, эквивалентно `splash.enabled: false` в конфигурации YAML
- `WHOSTHERE__SPLASH__DELAY=2s` — Установить задержку заставки в 2 секунды, эквивалентно `splash.delay: 2s` в конфигурации YAML
- `WHOSTHERE__SCAN_INTERVAL=30s` — Установить интервал сканирования в 30 секунд, эквивалентно `scan_interval: 30s` в конфигурации YAML
- `WHOSTHERE__TARGET_SUBNETS=10.0.0.0/24,10.0.1.0/24` — Установить целевые подсети, эквивалентно `target_subnets: ["10.0.0.0/24", "10.0.1.0/24"]` в конфигурации YAML
- `WHOSTHERE__SCANNERS__MDNS__ENABLED=false` — Отключить сканер mDNS, эквивалентно `scanners.mdns.enabled: false` в конфигурации YAML
- `WHOSTHERE__PORT_SCANNER__TCP=80,443,8080` — Установить пользовательские TCP-порты для сканирования, эквивалентно `port_scanner.tcp: [80, 443, 8080]` в конфигурации YAML
- `WHOSTHERE__THEME__NAME=cyberpunk` — Установить тему cyberpunk, эквивалентно `theme.name: cyberpunk` в конфигурации YAML
## Псевдонимы устройств
Псевдонимы хранятся в локальной базе данных [bbolt](https://github.com/etcd-io/bbolt) в каталоге состояния. Чтобы
задать сразу много, импортируйте их из файла YAML (`aliases.yaml` в каталоге конфигурации; переопределяется
ключом конфигурации `aliases.file` или аргументом пути).
Файл — это **патч, а не зеркало**, и он только читается: импорт выполняет upsert для содержащихся в нём MAC-адресов
и оставляет остальные нетронутыми, а изменения в TUI **никогда не записываются обратно в файл**. Используйте `export`, чтобы
пересоздать его.
```yaml
version: 1
aliases:
aa:bb:cc:dd:ee:ff: "Living Room TV"
de:ad:be:ef:00:01: "Office Printer"
```
- `version` — версия формата файла; используйте `1` (файлы без неё по умолчанию считаются версией 1).
- MAC-адреса принимаются в любом распространённом формате и нормализуются, поэтому `AA:BB:CC:DD:EE:FF`, `aa-bb-cc-dd-ee-ff`
и `aabbccddeeff` эквивалентны. Пустой псевдоним (`""`) удаляет его.
- Недопустимые MAC-адреса пропускаются и о них сообщается; остальная часть импорта всё равно выполняется.
```bash
whosthere aliases import # from the default location
whosthere aliases import ./aliases.yaml
whosthere aliases export # to the default location
whosthere aliases export --stdout # to stdout
```
Включите импорт при запуске с помощью `aliases.auto_import: true`. Файл проверяется по хешу и
повторно импортируется только при изменении, поэтому нетронутый файл никогда не затирает ваши изменения в TUI — но **изменённый
файл перезаписывает** псевдонимы для каждого содержащегося в нём MAC-адреса. Держите псевдонимы, созданные только в TUI, вне файла,
или выполняйте `export` после редактирования, чтобы синхронизировать его.
## HTTP API режима демона
При запуске Whosthere в режиме демона он предоставляет очень простой HTTP API со следующими эндпоинтами:
| Метод | Эндпоинт | Описание |
| ------ | -------------- | ---------------------------------- |
| GET | `/devices` | Получить список всех обнаруженных устройств |
| GET | `/device/{ip}` | Получить сведения о конкретном устройстве |
| GET | `/health` | Проверка работоспособности |
## Темы
Тему можно настроить через файл конфигурации или во время выполнения с помощью привязки клавиш `CTRL+t`.
Полный список доступных тем можно найти [**здесь**](https://github.com/ramonvermeulen/whosthere/blob/main/internal/ui/theme/theme.go), не стесняйтесь открыть PR, чтобы добавить свою тему!
Пример конфигурации темы:
```yaml
theme:
enabled: true
name: cyberpunk
```
Когда для `name` задано значение `custom`, можно использовать другие параметры цвета для создания собственной темы.
Когда для параметра `enabled` задано значение `false`, TUI будет использовать стандартные ANSI-цвета терминала.
Когда задана переменная окружения `NO_COLOR`, все ANSI-цвета будут отключены.
## Логирование
Логи записываются в каталог состояния приложения:
- `$XDG_STATE_HOME/whosthere/app.log` (если `XDG_STATE_HOME` задана)
- `~/.local/state/whosthere/app.log` (резервный вариант для Linux/MacOS)
- `%LOCALAPPDATA%/whosthere/app.log` (резервный вариант для Windows)
Когда приложение не работает в режиме TUI, логи также выводятся в консоль.
## Платформы
Whosthere поддерживается на следующих платформах:
- [x] Linux
- [x] macOS
- [x] Windows
## Известные проблемы
Для работы функции буфера обмена используется [**форк go-clipboard**](https://github.com/dece2183/go-clipboard).
Убедитесь, что у вас установлен соответствующий инструмент копирования для вашей ОС:
| ОС | Поддерживаемые инструменты копирования |
| -------------------------------------- | -------------------------------------------- |
| Darwin | `pbcopy` |
| Windows | `clip.exe` |
| Linux/FreeBSD/NetBSD/OpenBSD/Dragonfly | X11: `xsel`, `xclip` <br> Wayland: `wl-copy` |
## Отказ от ответственности
Whosthere предназначен для использования в сетях, где у вас есть разрешение на выполнение обнаружения и сканирования сети,
например, в вашей собственной домашней сети. Несанкционированное сканирование сетей может быть незаконным и неэтичным.
Всегда получайте надлежащее разрешение перед использованием этого инструмента в любой сети.
Этот инструмент был создан в первую очередь в образовательных целях и для исследования домашней сети. Хотя он функционален
и полезен, его не следует рассматривать как профессиональное решение для мониторинга сети. Результаты
основаны на непривилегированных методах сканирования и могут быть неполными. Для критического анализа сети
или оценки безопасности рассмотрите использование проверенных профессиональных инструментов с официальной поддержкой.
## Участие в разработке
Вклад и предложения, такие как запросы функций, отчёты об ошибках или улучшения, приветствуются!
Не стесняйтесь открывать issues или отправлять pull requests в репозитории GitHub.
Пожалуйста, обязательно обсудите любые значительные изменения в issue на GitHub перед их реализацией.