Выбор self-hosted приложения для отслеживания локации
Сравнение Traccar, OwnTracks, Dawarich и Home Assistant для контроля перемещений. Узнайте, как настроить приватный сбор данных и избежать публикации API в открытый доступ.
Выбор приложения для отслеживания местоположения с self-hosted размещением
Выбор self-hosted решения для отслеживания местоположения зависит от одного вопроса: храните ли вы историю для себя или наблюдаете за перемещениями в реальном времени вместе с другими людьми? Dawarich отвечает на первый запрос. Это self-hosted замена для Google Maps Timeline, которая импортирует уже имеющуюся у вас историю. Traccar отвечает на второй. Он был создан для GPS-оборудования и автопарков, поэтому рассматривает телефон как еще один трекер. OwnTracks выступает в роли базового приложения для телефона и формата сообщений для обоих вариантов. Home Assistant уже знает, где находится ваш телефон, если вы его используете, но по умолчанию удаляет историю перемещений через 10 дней.
Выбирайте решение в зависимости от того, что вы хотите увидеть в следующем месяце:
- Карту всех мест, где вы были в прошлом марте, с указанием локаций и поездок: Dawarich.
- Карту нескольких устройств в реальном времени с геозонами и правилами событий: Traccar.
- Один телефон, отправляющий свои координаты в систему, которая у вас уже запущена: OwnTracks в режиме HTTP.
- Автоматизацию «дома/вне дома» без необходимости хранения истории: Home Assistant в чистом виде.
Ничего из этого не заработает, пока телефон не получит доступ к HTTPS-эндпоинту под вашим управлением, поэтому серверная часть вынесена в отдельный раздел ниже. Если вы все еще определяетесь с тем, что еще стоит разместить на сервере, более широкий список того, что стоит хостить самостоятельно в этом году показывает место трекера среди других сервисов.
Traccar: GPS-оборудование, автопарки и отслеживание в реальном времени
Traccar — это сервер для GPS-мониторинга. Он поддерживает протоколы, используемые специализированными GPS-трекерами; для каждого из них выделен отдельный порт (в текущем списке протоколов они нумеруются от 5001 до 5266). В официальных инструкциях Traccar для Docker рекомендуется открывать весь диапазон портов с 5000 по 5300 как для TCP, так и для UDP. Помимо этого, система предоставляет карту в реальном времени, геозоны, правила обработки событий и отчеты. Веб-интерфейс по умолчанию работает на порту 8082.
Для мобильных устройств доступно приложение Traccar Client (Android и iOS). Оно передает данные по протоколу OsmAnd, который по умолчанию использует порт 5055. Настройки приложения определяют расход заряда аккумулятора и количество записей в базе данных. Параметр Distance задает частоту обновления в метрах при движении. Параметр Interval включает передачу данных по времени, если дистанция равна 0. Параметр Angle инициирует обновление при изменении направления движения (в градусах). Параметр Stationary Heartbeat определяет поведение устройства, когда оно находится в состоянии покоя. В документации Traccar указано, что точный результат для этих параметров не гарантируется, так как решение принимает сама операционная система телефона.
Traccar поставляется со встроенной базой данных H2, что позволяет запустить систему без предварительной настройки, однако разработчики не рекомендуют использовать H2 в промышленной эксплуатации. В документации описан переход на MySQL, MariaDB или PostgreSQL. Для крупных инсталляций рекомендуется использовать TimescaleDB — базу данных временных рядов, построенную на базе PostgreSQL. Перенос базы данных следует выполнить до накопления истории, так как конвертация файла H2 вручную — сложная задача, для которой нет официальных инструментов.
В каких случаях Traccar подходит плохо: это консоль для наблюдения за объектами в текущий момент времени. Отчеты ориентированы на автопарки: поездки, остановки и сводки. Поэтому история ваших перемещений за год будет выглядеть как результат SQL-запроса, а не как хронологическая лента событий.
OwnTracks: мобильное приложение и эндпоинт, ничего лишнего
OwnTracks — это минималистичная классическая конфигурация. Приложение отправляет небольшой JSON-пакет каждый раз, когда определяет, что устройство переместилось. Передача данных возможна по протоколу MQTT (message queuing telemetry transport) или через обычный HTTP. В режиме HTTP эндпоинтом выступает URL вида http[s]://[user[:password]@]host[:port]/path, аутентификация выполняется через HTTP Basic, при этом проект настоятельно рекомендует использовать схему https://. Для работы с OwnTracks Recorder используется путь /pub.
Режим мониторинга важнее любых настроек сервера. Режим Quiet отправляет данные только по запросу. Manual добавляет мониторинг геозон и запрос местоположения с низким энергопотреблением. Significant — это стандартный автоматический режим. В iOS режим Move отправляет данные, как только устройство переместилось на locatorDisplacement метров или прошло locatorInterval секунд (в зависимости от того, что наступит раньше); значения по умолчанию составляют 100 метров и 300 секунд. В Android режим Move по умолчанию запрашивает координаты каждые 10 секунд. В документации OwnTracks указано, что режим Move расходует заряд аккумулятора на уровне навигационных приложений, поэтому его рекомендуется использовать во время поездок или при подключении к зарядке, а не в качестве повседневной настройки.
OwnTracks Recorder сохраняет поступающие данные и отображает простую карту. Многие пользователи не устанавливают его вовсе, так как формат данных идентичен независимо от того, куда направлено приложение: в Recorder, Dawarich или Home Assistant. Именно поэтому стоит начать с этого решения: приложение является стабильным и предсказуемым источником данных, а выбор потребителя можно изменить в любой момент.
Dawarich: self-hosted аналог Google Maps Timeline
Dawarich распространяется по лицензии AGPL-3.0 и запускается с помощью Docker Compose. Рабочая установка состоит из четырех контейнеров: приложения на Rails, воркера Sidekiq для фоновых задач, PostgreSQL и Redis. Приложение работает на порту 3000. Источники для импорта включают Google Maps Timeline, OwnTracks, Strava, Immich, файлы GPX и GeoJSON, а также EXIF-данные ваших фотографий. Именно этот список источников превращает систему в полноценную временную шкалу, а не просто в карту реального времени, так как она способна обрабатывать историю, накопленную до запуска сервера.
Прием данных осуществляется через HTTP-эндпоинт, который требует API-ключ со страницы вашего аккаунта. OwnTracks отправляет данные на /api/v1/owntracks/points?api_key=..., а Overland — на /api/v1/overland/batches?api_key=.... GPSLogger использует тот же эндпоинт, что и OwnTracks.
Обратите внимание на то, как передается этот ключ. Он находится в строке запроса, а стандартный формат логов Nginx записывает полную строку запроса. В результате ключ попадает в /var/log/nginx/access.log в открытом виде с каждой точкой данных. Считайте этот лог конфиденциальным, меняйте ключ при отправке логов в централизованные системы хранения и никогда не вставляйте рабочую ссылку в ветки обсуждения технической поддержки.
Что касается самого файла compose, томов и политики перезапуска, используйте механику работы с контейнерами для запуска compose на VPS. Данная страница ограничивается этапом принятия решения.
Home Assistant: эффективен для определения присутствия, но не подходит для истории
Если вы уже используете Home Assistant, у вас уже настроено отслеживание устройств. Сопутствующее приложение передает данные о местоположении, а интеграция OwnTracks предоставляет URL вебхука и ключ шифрования, которые нужно вставить в приложение. При настроенном MQTT эта интеграция ожидает сообщения MQTT вместо HTTP.
Ограничение заключается в хранении данных. Компонент recorder в Home Assistant по умолчанию использует purge_keep_days: 10, а автоматическая очистка запускается каждую ночь в 04:12 по местному времени, чтобы база данных не разрасталась бесконечно. Эти настройки подходят для базы данных домашней автоматизации, но не для архива перемещений. Home Assistant отвечает на вопрос «есть ли кто-то дома». Он не ответит на вопрос «где я был 14 марта», если вы не будете отправлять тот же поток данных в систему, которая сохраняет их.
Постоянное отслеживание или эпизодический обмен данными?
Постоянное отслеживание означает, что приложение публикует данные в течение всего дня, независимо от того, перемещаетесь вы или нет, а создаваемый архив является основной целью. Эпизодический обмен данными означает, что пользователи наблюдают друг за другом во время поездки, а архив является побочным эффектом, который никому не нужен. Одно и то же программное обеспечение обслуживает оба сценария с помощью различных настроек.
Для постоянного отслеживания отдавайте предпочтение передаче данных на основе перемещения, а не по короткому таймеру. Храните базу данных на носителе, который вы действительно резервируете, и определите политику хранения данных в первый же день, а не тогда, когда диск окажется заполнен. Для эпизодического обмена данными увеличивайте частоту передачи только на время необходимости, а затем возвращайте телефон в режим пониженного энергопотребления. В OwnTracks это реализовано как элемент управления в приложении, а в Traccar Client — через поля расстояния и интервала.
Если вам нужна ссылка для обмена данными на два часа для одной поездки, ознакомьтесь с примечаниями к выпуску (release notes) выбранного вами сервера перед началом использования. Эта функция чаще всего меняется между версиями и является самым слабым местом в каждом из представленных вариантов.
Нужен ли вам вообще MQTT-брокер?
Начните работу без него. HTTP-режим — это URL, пароль и TLS (transport layer security), которые поддерживает каждый упомянутый выше сервер. Брокер становится необходим, когда один и тот же поток данных требуется нескольким потребителям одновременно: например, если Home Assistant должен реагировать на смену зоны, пока система записи сохраняет историю, или если члены семьи должны видеть местоположение друг друга.
MQTT — это протокол публикации и подписки, а Mosquitto является стандартным брокером. Он ожидает подключений на порту 1883 для открытого текста и 8883 для TLS; вам следует использовать только 8883. Контроль доступа настраивается для каждого топика, поэтому одной учётной записи можно разрешить публикацию в owntracks/alice/phone и запретить чтение любых других данных. Это главный аргумент в пользу MQTT для семейной сети: брокер принудительно ограничивает видимость на уровне ниже приложения, поэтому ошибка в коде приложения не сможет расширить права доступа.
Цена этого решения — ещё один сервис со своим сертификатом, своим списком пользователей и своим сценарием отказа. Если брокер перестаёт принимать соединения, это выглядит так же, как телефон без сигнала сети, и ни один из них не сообщит вам о причине проблемы.
Сколько строк с данными о местоположении создаст один телефон?
Приведенные ниже цифры являются результатом арифметических вычислений, а не измерений. Они предполагают фиксированный интервал отправки отчетов, одну строку на отчет и отсутствие других факторов.
The data behind this chart
[
{
"label": "Every 30 seconds",
"points_30d": "86,400",
"points_365d": "1,051,200"
},
{
"label": "Every 60 seconds",
"points_30d": "43,200",
"points_365d": "525,600"
},
{
"label": "Every 5 minutes",
"points_30d": "8,640",
"points_365d": "105,120"
},
{
"label": "Every 15 minutes",
"points_30d": "2,880",
"points_365d": "35,040"
}
]Телефон, отправляющий отчеты раз в минуту, создает 43,200 строк в месяц и 525,600 строк в год. Если увеличить интервал до пятнадцати минут, то за год получится 35,040 строк. Реальные приложения работают иначе, так как они отправляют отчеты не только по времени, но и при перемещении, а также переходят в режим ожидания, когда телефон неподвижен. Поэтому воспринимайте верхнее значение как максимально возможный предел, а не как точный прогноз.
Полмиллиона строк в год — это незначительный объем для PostgreSQL. Проблема возникает при визуализации: браузер зависнет при попытке отрисовать годовой объем точек в полном разрешении задолго до того, как база данных почувствует нагрузку. Именно поэтому такие приложения агрегируют историю в виде поездок и посещенных мест. Измерьте реальное количество данных на своем сервере, вместо того чтобы доверять цифрам из статьи:
SELECT pg_size_pretty(pg_total_relation_size('tc_positions'));Это таблица positions в Traccar на базе PostgreSQL. Выполните аналогичный запрос для выбранного вами сервера после месяца обычной эксплуатации, а затем умножьте результат на двенадцать. Ни один из этих серверов не удаляет старые точки автоматически. Они хранят всё, что вы отправляете, пока вы не удалите данные вручную. Поэтому определите правила хранения (retention policy), пока таблица еще невелика, и убедитесь, что резервное копирование охватывает базу данных, а не только конфигурацию, так как историю перемещений невозможно восстановить из других источников.
Расход заряда аккумулятора зависит от настроек телефона, а не сервера
Это аспект, который self-hosting не меняет. Операционная система сама решает, когда активировать GPS, как долго фоновое приложение может работать и будет ли оно активно ночью. Система управления питанием в Android агрессивно приостанавливает фоновые процессы, а iOS передает данные о значительных изменениях местоположения вместо непрерывного потока. Ваш сервер не влияет на эти процессы, поэтому установка короткого интервала отправки данных в приложении — это лишь запрос, на который телефон отвечает по своему усмотрению.
Вы можете управлять настройками на самом телефоне: предоставьте разрешение на доступ к геолокации в фоновом режиме «всегда», исключите приложение для трекинга из списка оптимизации расхода заряда и выбирайте режим отправки данных в соответствии с текущими задачами. Использование режима Move mode в течение всей недели приведет к тому, что телефон разрядится к четырем часам дня.
На стороне сервера это проявляется в виде пакетов данных со старыми временными метками. И Traccar Client, и OwnTracks буферизуют точки при отсутствии сети и отправляют их после восстановления соединения, поэтому время записи и время фиксации координат различаются. Если на карте отображается прямая линия через весь город, это означает наличие разрыва в данных, а не реальный маршрут.
Серверная часть: TLS и путь аутентифицированного приема данных
Телефону требуется имя хоста, которое он может разрешить, и сертификат, которому он доверяет. Самоподписанный сертификат — самая частая причина, по которой свежая установка не получает никаких данных: приложение прерывает TLS-рукопожатие и прекращает попытки, а лог сервера остается пустым, так как запрос не был завершен. Пустой лог выглядит как проблема на стороне телефона, хотя это не так.
Существует два чистых пути решения. Завершить TLS в nginx с помощью настоящего сертификата, что описано в сертификате Let's Encrypt перед nginx, и открыть только 443 порт. Либо не открывать входящие порты вовсе, используя Cloudflare Tunnel, чтобы на публичном IP ничего не прослушивалось, что подходит для Dawarich и OwnTracks, так как их прием данных осуществляется по обычному HTTP.
Есть одно ограничение для варианта с туннелем. Протокол OsmAnd для Traccar — это HTTP, поэтому клиент на телефоне без проблем проходит через обратный прокси или туннель. Бинарные протоколы, которые используют специализированные GPS-устройства, работают через «сырой» TCP на собственных портах. Для них требуется действительно открытый порт, настроенный как в файрволе VPS, так и в отдельном сетевом файрволе вашего провайдера (это разные панели управления у большинства хостинг-провайдеров).
Как только сервер начнет отвечать, проверьте путь одним запросом, вместо того чтобы гадать по поведению приложения:
curl -si -u alice:secret -H 'Content-Type: application/json' \
-d '{"_type":"location","lat":51.5,"lon":-0.12,"tst":1788480000}' \
https://track.example.com/pub | head -1Рабочая конечная точка отвечает статусом 2xx. Статус 401 означает, что учетные данные неверны, но транспорт работает исправно. Ошибка curl до появления строки статуса указывает на проблемы с DNS или TLS, поэтому исправьте сертификат, прежде чем переходить к настройке приложения.
Открытая точка приема данных раскрывает ваше местоположение
URL-адрес для приема данных без аутентификации передает ваши координаты любому, кто его обнаружит, а их находят довольно часто.
- Любой, у кого есть этот URL, может записывать точки в вашу историю. Ложные данные трудно заметить и утомительно удалять.
- URL-адрес не является секретом. Он хранится в настройках приложения на телефоне, в access log вашего reverse proxy, в истории браузера, если вы когда-либо тестировали его в новой вкладке, и на любом скриншоте, который вы прикладываете при запросе помощи.
- Конечная точка, отвечающая на неавторизованные GET-запросы, выдаст ваше последнее местоположение любому сканеру, который угадал путь.
- Имя хоста публично, что бы вы ни делали. Новый сертификат появляется в логах certificate transparency в течение нескольких минут, поэтому адрес, который вы никогда не публиковали, все равно можно обнаружить.
Используйте HTTP Basic поверх TLS для OwnTracks, API-ключ для Dawarich и модель учетных записей Traccar с уникальным идентификатором устройства. Разместите интерфейс администратора за той же аутентификацией, что и путь приема данных, так как именно в интерфейсе доступен для чтения весь маршрут. Затем посмотрите, кто пытался подключиться спустя первую неделю:
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20IP-адреса мобильного оператора вашего телефона должны доминировать в этом списке. Любой другой адрес с большим количеством запросов заслуживает внимания, а настройка rate limit для пути приема данных в Nginx ничего не стоит.
Трекер также может незаметно выйти из строя. Контейнер останавливается, телефон продолжает накапливать данные в буфере, а вы узнаете об этом спустя недели, когда обнаружите отсутствие данных о поездке. Настройте health check контейнера или systemd OnFailure= на ваш собственный ntfy сервер, чтобы уведомление о сбое пришло на тот же телефон, который отправляет данные.
Кто еще может видеть историю перемещений и как это контролируется
Traccar управляет доступом с помощью прав пользователей и устройств: учетная запись видит только те устройства, к которым администратор предоставил доступ, а API использует сессии или токены. OwnTracks через MQTT реализует контроль на уровне брокера с помощью ACL для топиков. Это наиболее надежный метод, так как учетная запись без прав подписки на топик не сможет прочитать данные независимо от действий приложения. У OwnTracks через HTTP нет аналогичного уровня защиты, поэтому вся безопасность доступа зависит исключительно от того, что находится за конечной точкой. Dawarich спроектирован для просмотра истории одним пользователем, поэтому для отслеживания нескольких человек в реальном времени лучше подходят Traccar или брокер сообщений.
Семейное отслеживание — это не только технический, но и этический вопрос согласия. Каждый человек, чей телефон передает данные, должен знать об этом и понимать, как остановить передачу. Трекер, который невозможно отключить, не может считаться инструментом для семьи.
Что не решает self-hosting
- Операционная система телефона определяет, когда активируется GPS, поэтому разряд батареи и пропуски в треке — это преимущественно её работа, а не вашего сервера.
- Google изменила формат экспорта данных Timeline. Перед планированием миграции ознакомьтесь с актуальной документацией по импорту в Dawarich, так как файл, который Google предоставляет сегодня, отличается от того, который пользователи импортировали два года назад.
- Ваша конечная точка видит ваш мобильный IP-адрес при каждом запросе, как и любая сеть на пути следования. Self-hosting меняет лишь того, кто хранит эту запись. Он не удаляет саму запись.
- История местоположений незаменима. Создавайте резервные копии базы данных, восстановите её один раз, чтобы убедиться в работоспособности бэкапа, и храните копию в зашифрованном виде, так как это самый конфиденциальный файл на сервере.
FAQ
Какое self-hosted приложение заменяет Google Maps Timeline?
Dawarich. Оно создано как self-hosted альтернатива Google Timeline. Приложение импортирует данные из экспорта Google Maps Timeline, а также из OwnTracks, Strava, Immich, GPX, GeoJSON и EXIF-данных фотографий. История отображается в виде мест и поездок, а не в виде карты в реальном времени. Traccar может хранить те же точки, но его интерфейс предназначен для управления автопарком, а отчеты ориентированы на логистику. Перед планированием миграции изучите документацию Dawarich по импорту, чтобы узнать ожидаемый формат данных, так как формат экспорта Google изменился.
Можно ли использовать OwnTracks без MQTT-брокера?
Да. Переключите приложение в режим HTTP и укажите URL вида http[s]://[user[:password]@]host[:port]/path, который для OwnTracks Recorder выглядит как /pub. Приложение отправляет те же JSON-данные с аутентификацией через HTTP Basic. OwnTracks настоятельно рекомендует использовать схему https://. Брокер можно добавить позже, когда двум сервисам потребуется один и тот же поток данных одновременно или когда потребуется контроль доступа на уровне топиков, чтобы брокер определял, кто и что может видеть.
Сколько места занимает год истории перемещений?
Планируйте объем в строках, а не в гигабайтах. При отправке одного отчета в минуту получается 525,600 строк в год на один телефон, а при отправке раз в пятнадцать минут — 35,040. Для PostgreSQL это незначительный объем. Практическое ограничение заключается в способности браузера отрисовать годовой набор точек на одной карте, поэтому приложения используют агрегацию данных. Измерьте размер своей таблицы через месяц с помощью pg_total_relation_size и умножьте результат на двенадцать.
Почему в истории перемещений есть пропуски?
Операционная система телефона сама решает, когда активировать GPS и когда остановить фоновое приложение, поэтому большинство пропусков возникают именно по этой причине. Предоставьте приложению разрешение на доступ к геолокации в фоновом режиме «всегда», исключите его из оптимизации расхода заряда батареи и проверьте режим отправки данных. В OwnTracks на iOS режим Move отправляет данные каждые locatorDisplacement метров или locatorInterval секунд (по умолчанию 100 метров и 300 секунд), а на Android приложение по умолчанию запрашивает координаты каждые 10 секунд. В любом случае это расходует заряд батареи на уровне навигационного приложения. Если строки приходят с задержкой и содержат старые временные метки, значит, происходит выгрузка данных из офлайн-буфера: координаты были получены вовремя, но их отправка была отложена.
Достаточно ли секретного URL для защиты точки приема данных?
Нет. Неаутентифицированная точка приема позволяет любому, кто узнает URL, записывать ложные точки в вашу историю. URL не является секретом: он хранится в настройках приложения, в access log вашего reverse proxy, в истории браузера и на любом скриншоте, которым вы поделитесь. Имя хоста можно обнаружить, так как новый сертификат появляется в логах прозрачности сертификатов (certificate transparency logs) вскоре после выпуска. Используйте HTTP Basic поверх TLS или API-ключ, ограничьте частоту запросов (rate limit) для пути приема данных и защитите административный интерфейс тем же способом аутентификации.