SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Выбор 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 в чистом виде.

Для передачи данных по HTTP телефон должен иметь доступ к HTTPS-эндпоинту под вашим управлением, поэтому серверная часть вынесена в отдельный раздел ниже. Если вы все еще определяетесь с тем, что еще стоит разместить на сервере, обширный список того, что стоит хостить самостоятельно в этом году показывает место трекера среди других сервисов.

Traccar: GPS-оборудование, автопарки и отслеживание в реальном времени

Traccar — это сервер для GPS-мониторинга. Он поддерживает протоколы, используемые специализированными GPS-трекерами; каждый протокол работает на собственном порту. В текущем списке протоколов номера портов варьируются от 5001 до 5267. Официальные инструкции Traccar для Docker рекомендуют открывать весь диапазон портов с 5000 по 5300 как для TCP, так и для UDP. Те же инструкции предупреждают, что каждый опубликованный порт запускает отдельный процесс docker-proxy, что потребляет значительный объем оперативной памяти. Поэтому более экономным решением будет публикация только тех портов, которые фактически используются вашими устройствами, либо отключение пользовательского прокси Docker (userland proxy), чтобы система использовала NAT через iptables. Помимо этого, Traccar предоставляет карту в реальном времени, геозоны, правила обработки событий и отчеты. Веб-интерфейс по умолчанию работает на порту 8082.

Для мобильных телефонов доступно приложение Traccar Client для Android и iOS. Оно передает данные по протоколу OsmAnd, который по умолчанию использует порт 5055. Настройки приложения определяют время автономной работы устройства и количество записей в базе данных. Distance задает обновление координат через каждые N метров при движении. Interval включает передачу данных по времени, если дистанция равна 0 (работает только на Android) или если установлена максимальная точность. Angle инициирует обновление при изменении направления движения на заданное количество градусов (требуется максимальная точность). Stationary Heartbeat определяет поведение устройства, когда оно находится в состоянии покоя. Согласно документации Traccar, точный результат для этих параметров не гарантируется, так как решение принимает операционная система телефона.

Traccar поставляется со встроенной базой данных H2, что позволяет запустить систему без дополнительной настройки, однако проект не рекомендует использовать H2 в промышленной эксплуатации. Документация описывает переход на MySQL, MariaDB и PostgreSQL, а для крупных инсталляций рекомендуется TimescaleDB — база данных временных рядов на основе PostgreSQL. Перенесите базу данных до того, как накопится история перемещений, так как перенос накопленных данных в новую СУБД потребует выполнения миграции.

В чем Traccar менее эффективен: это консоль для наблюдения за объектами в текущий момент времени. Отчеты ориентированы на автопарки, поездки, остановки и сводные данные, поэтому история ваших перемещений за год будет выглядеть как результат SQL-запроса, а не как хронологическая лента событий.

OwnTracks: мобильное приложение, Recorder и Frontend

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 сохраняет поступающие данные и предоставляет простую карту, а отдельный OwnTracks Frontend добавляет полноценный веб-интерфейс с тепловой картой, фильтрацией по датам и отображением истории в виде точек или линий. Многие пользователи вообще не устанавливают 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 в открытом виде с каждой точкой данных. Относитесь к этому логу как к конфиденциальным данным, меняйте ключ, если вы отправляете логи в централизованное хранилище, и никогда не публикуйте рабочие URL в ветках поддержки.

Информацию о файле compose, томах и политике перезапуска см. в разделе механика работы с контейнерами при запуске compose на VPS. Данная страница завершается на этапе принятия решения.

Home Assistant: эффективен для определения присутствия, но не подходит для истории

Если вы уже используете Home Assistant, у вас уже есть функции отслеживания устройств. Сопутствующее приложение передает данные о местоположении, а интеграция OwnTracks предоставляет URL вебхука и ключ шифрования, которые нужно вставить в приложение. При настроенном MQTT эта интеграция ожидает сообщения MQTT вместо HTTP.

Ограничение заключается в хранении данных. По умолчанию в recorder для Home Assistant установлено значение purge_keep_days: 10, а автоматическая очистка запускается каждую ночь в 04:12 по местному времени, чтобы база данных не разрасталась бесконечно. Это значение по умолчанию подходит для базы данных домашней автоматизации, но не для архива перемещений. Home Assistant отвечает на вопрос «есть ли кто-нибудь дома». Чтобы ответить на вопрос «где я был 14 марта», сохраняйте историю до того, как она будет удалена: увеличьте purge_keep_days, отключите auto_purge или отправляйте тот же поток данных в систему, которая их сохраняет. Хранение большего объема истории увеличивает базу данных recorder; если вы отключите auto_purge, документация рекомендует самостоятельно планировать периодические вызовы recorder.purge.

Постоянное отслеживание или эпизодический обмен данными?

Постоянное отслеживание означает, что приложение публикует данные в течение всего дня, независимо от того, перемещаетесь вы или нет, а создаваемый архив является основной целью. Эпизодический обмен данными означает, что пользователи наблюдают друг за другом во время поездки, а архив является побочным эффектом, который никому не нужен. Одно и то же программное обеспечение подходит для обоих сценариев при использовании разных настроек.

Для постоянного отслеживания отдавайте предпочтение передаче данных на основе перемещения, а не по короткому таймеру, храните базу данных на носителе, который вы действительно резервируете, и определите политику хранения данных в первый же день, а не тогда, когда диск окажется переполнен. Для эпизодического обмена данными увеличивайте частоту передачи только на время необходимости, а затем возвращайте телефон в режим низкого энергопотребления. В OwnTracks это реализовано как элемент управления в приложении, а в Traccar Client — через поля дистанции и интервала.

Если вам нужна ссылка для обмена данными на два часа для одной поездки, ознакомьтесь с примечаниями к релизу выбранного вами сервера перед началом использования. Traccar предоставляет временные ссылки для общего доступа к устройству, а Dawarich предоставляет ссылки для обмена данными о местоположении в реальном времени с возможностью установки пароля, даты истечения срока действия и немедленного отзыва доступа.

Нужен ли вам вообще MQTT-брокер?

Начните работу без него. HTTP-режим — это URL, пароль и TLS (transport layer security), и каждый из перечисленных выше серверов поддерживает его. Брокер становится необходим, когда один и тот же поток данных требуется нескольким потребителям одновременно, например, когда Home Assistant реагирует на смену зоны, в то время как регистратор записывает историю, или когда члены семьи отслеживают местоположение друг друга.

MQTT — это протокол публикации и подписки, а Mosquitto является стандартным брокером. Его слушатель по умолчанию использует порт 1883 для передачи данных в открытом виде; настройте TLS-слушатель на порту 8883 и сделайте доступным только его. Контроль доступа осуществляется на уровне топиков, поэтому одной учетной записи можно разрешить публикацию в owntracks/alice/phone и запретить чтение любых других данных. Это основной аргумент в пользу использования MQTT в семейной среде: брокер принудительно ограничивает видимость на уровне ниже приложения, поэтому ошибка в коде приложения не приведет к расширению прав доступа.

Цена этого решения — еще один сервис со своим сертификатом, своим списком пользователей и своим режимом отказа. Если брокер перестает принимать соединения, это выглядит так же, как телефон без сигнала сети, и ни в одном из этих случаев вы не получите уведомление о причине.

Сколько строк с координатами создаст один телефон?

Приведенные ниже цифры являются арифметическим расчетом, а не результатами измерений. Они предполагают фиксированный интервал отправки отчетов, одну строку на отчет и отсутствие других факторов.

ГрафикPosition rows per phone at a fixed reporting interval (arithmetic)
Данные, на которых построен график
[
  {
    "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. Выполните аналогичный запрос для выбранного вами сервера после месяца обычной эксплуатации, а затем умножьте результат на двенадцать. Home Assistant по умолчанию автоматически удаляет старую историю. Выберите правило хранения данных, пока таблица еще невелика, и убедитесь, что резервное копирование охватывает базу данных, а не только конфигурационные файлы, так как историю перемещений невозможно восстановить из других источников.

Расход заряда аккумулятора зависит от телефона, а не от вашего сервера

Это тот аспект, который self-hosting не меняет. Операционная система решает, когда активировать GPS, как долго может работать фоновое приложение и будет ли оно работать ночью. Система управления питанием Android агрессивно приостанавливает фоновые процессы, а iOS предоставляет данные о значительных изменениях местоположения вместо непрерывного потока. Ваш сервер не влияет на эти процессы, поэтому установка короткого интервала отправки данных в приложении — это лишь запрос, на который телефон отвечает по своему усмотрению.

Вы управляете настройками на самом телефоне: предоставьте разрешение на доступ к местоположению в фоновом режиме на постоянной основе, исключите приложение для отслеживания из списка оптимизации аккумулятора и выбирайте режим отправки данных в соответствии с текущими задачами. Режим перемещения (Move mode) на протяжении всей недели приведет к тому, что телефон разрядится к четырем часам дня.

Симптомом на стороне сервера является пакетная запись строк с устаревшими метками времени. OwnTracks и Traccar Client (при включенной функции буферизации в автономном режиме) сохраняют точки при отсутствии сети и отправляют их после восстановления соединения, поэтому время записи и время фиксации координат различаются. Если на вашей карте отображается прямая линия через весь город, это означает наличие разрыва в данных о местоположении, а не реальный маршрут.

Серверная часть: TLS и путь для аутентифицированного приема данных

Телефону требуется имя хоста, которое он может разрешить, и сертификат, которому он доверяет. Самоподписанный сертификат — самая частая причина, по которой свежая установка не получает никаких данных: приложение прерывает TLS-рукопожатие и прекращает попытки, а лог сервера остается пустым, так как запрос не был завершен. Пустой лог выглядит как проблема на стороне телефона, но это не так.

Существует два чистых пути решения. Завершите TLS в nginx с помощью настоящего сертификата, используя сертификат Let's Encrypt перед nginx, и откройте порты 80 и 443. Порт 80 должен оставаться доступным, так как плагин certbot для nginx подтверждает владение доменом с помощью проверки HTTP-01, которую Let's Encrypt выполняет только на 80 порту, поэтому настройте редирект на HTTPS вместо закрытия порта. Только переход на проверку DNS-01 или TLS-ALPN-01 позволит работать только с 443 портом. Либо не открывайте входящие порты вообще, используя Cloudflare Tunnel, чтобы на публичном IP ничего не прослушивалось, что подходит для Dawarich и OwnTracks, так как их прием данных работает по обычному HTTP.

Есть одно ограничение для варианта с туннелем. Протокол OsmAnd в Traccar использует HTTP, поэтому клиент на телефоне проходит через обратный прокси или туннель без проблем. Бинарные протоколы, которые используют специализированные GPS-трекеры, работают по «сырым» TCP или UDP на своих портах, и для них требуется реально открытый порт, настроенный как в файрволе 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, может записывать точки в вашу историю. Ложные точки сложно заметить, а их удаление требует много времени.
  • URL не является секретом. Он хранится в настройках приложения на телефоне, в access log вашего reverse proxy, в истории браузера, если вы когда-либо тестировали его в новой вкладке, и на любом скриншоте, который вы приложите, когда будете просить о помощи.
  • Незащищенный API для чтения, такой как /api/0/last в OwnTracks Recorder, передает ваше последнее местоположение любому, кто отправит запрос.
  • Имя хоста остается публичным, что бы вы ни делали. Недавно выпущенный сертификат появляется в логах certificate transparency в течение нескольких минут, поэтому адрес, который вы никогда не публиковали, все равно можно обнаружить.

Используйте HTTP Basic поверх TLS для OwnTracks, API-ключ для Dawarich и модель учетных записей Traccar с уникальным идентификатором устройства. Разместите интерфейс администратора за той же аутентификацией, что и путь приема данных, так как именно в интерфейсе доступна для чтения вся история перемещений. Затем посмотрите, кто проявлял активность после первой недели:

sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

IP-адреса мобильной сети вашего телефона должны преобладать в этом списке. Любой другой адрес с большим количеством запросов заслуживает внимания, а ограничение частоты запросов (rate limit) для пути приема данных в Nginx не требует никаких затрат.

Трекер также может перестать работать незаметно. Контейнер останавливается, телефон продолжает накапливать данные в буфере, и вы узнаете об этом спустя недели, когда обнаружите отсутствие данных о поездке. Настройте health check контейнера или systemd OnFailure= на ваш собственный ntfy сервер, чтобы уведомления о сбоях приходили на тот же телефон, который отправляет данные.

Кто еще может видеть трек и как это обеспечивается

Traccar ограничивает доступ с помощью прав пользователей и устройств: учетная запись видит только те устройства, к которым администратор предоставил доступ, а API использует сессию или токен. OwnTracks через MQTT обеспечивает безопасность на уровне брокера с помощью ACL для топиков. Это наиболее надежный метод, так как учетная запись, не имеющая прав на подписку к топику, не сможет прочитать его независимо от действий приложения. OwnTracks через HTTP не имеет аналогичного уровня защиты, поэтому вся система контроля доступа ограничивается тем, что находится за конечной точкой. Dawarich также поддерживает функцию совместного использования местоположения в реальном времени для членов семьи, при этом каждый участник самостоятельно управляет доступом к своим данным.

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

Что не решает 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) для пути приема данных и защитите административный интерфейс тем же способом аутентификации.

Была ли эта статья полезной?

#self-hosting#privacy#traccar#owntracks#dawarich#gps