Обещание «мы ничего не отправляем» проверяется с вашей стороны и без доступа к исходному коду. Приложение может скрыть от вас что угодно внутри себя, но не может скрыть сетевое соединение: пакет либо ушёл с вашей машины, либо нет.
Этот гайд нужен, когда вы устанавливаете новый инструмент, работающий с чувствительными данными, или когда вендор утверждает что-то про приватность и вам этого недостаточно. Он не нужен, если приложение и так очевидно облачное — там вопрос не «отправляет ли», а «что именно».
#Что понадобится
- Права администратора на своей машине — часть команд без них не покажет владельца соединения.
- Полчаса на первый заход. Повторная проверка занимает пять минут.
- Перехватывающий прокси для второго уровня проверки:
mitmproxy— бесплатный и работает на всех трёх системах. - Готовность к тому, что результат будет неоднозначным. Часть соединений вы не опознаете сразу, и это нормально.
#Шаг 1. Найдите идентификатор процесса
Все дальнейшие команды фильтруют соединения по процессу — иначе вы утонете в трафике браузера и системных служб.
Windows, PowerShell:
Get-Process | Where-Object { $_.ProcessName -like "*python*" } | Select-Object Id, ProcessName, Path
macOS и Linux:
ps aux | grep -i persona
Запишите идентификатор процесса. Если приложение состоит из нескольких процессов — фонового агента, веб-сервера, воркера, — записывайте все: они ходят в сеть независимо.
#Шаг 2. Снимите список соединений
Windows, PowerShell:
Get-NetTCPConnection -State Established |
Where-Object { $_.OwningProcess -eq 12345 } |
Select-Object RemoteAddress, RemotePort, State
macOS:
sudo lsof -nP -iTCP -sTCP:ESTABLISHED -p 12345
Linux:
sudo ss -tunp state established | grep 12345
Адреса в выводе будут числовыми. Превратить их в понятные имена:
Resolve-DnsName 93.184.216.34 -Type PTR
dig -x 93.184.216.34 +short
Обратная запись есть не всегда; если её нет, смотрите принадлежность адреса через whois.
#Шаг 3. Три замера, которые дают ответ
Один снимок ничего не доказывает. Нужны три, и в этом порядке.
Замер А: холостой ход. Запустите приложение и не трогайте его десять минут. Всё, что появилось в списке, — это внешние зависимости и телеметрия. Запросов к модели здесь быть не должно: вы ничего не спрашивали.
Замер Б: один запрос. Задайте ассистенту один вопрос и снимите список снова. Разница между Б и А — это получатели вашего запроса. Их должно быть ровно столько, сколько вы ожидаете: при локальной модели — ни одного нового внешнего, при облачной — один домен провайдера.
Замер В: час работы. Оставьте утилиту соединений писать в файл на час обычной работы. Так ловятся периодические отправки: проверка обновлений, накопленная статистика, синхронизация. Их не видно на коротком замере, и именно они чаще всего оказываются сюрпризом.
На Windows непрерывный сбор делается циклом с записью в файл:
while ($true) {
Get-NetTCPConnection -State Established |
Where-Object { $_.OwningProcess -eq 12345 } |
Select-Object @{n='t';e={Get-Date}}, RemoteAddress, RemotePort |
Export-Csv -Append -NoTypeInformation -Path conn.csv
Start-Sleep -Seconds 10
}
На macOS и Linux — тем же способом через watch или цикл в оболочке.
#Шаг 4. Тест отключением сети
Самая быстрая и самая убедительная проверка для локального режима. Отключите сеть целиком — не только Wi-Fi, а все интерфейсы — и задайте ассистенту вопрос.
- Ответил — обработка идёт на вашей машине, отправлять было нечего.
- Ошибка соединения — запрос уходит наружу, и дальше вопрос только в том, кому.
Оговорка, которая делает тест честным: он проверяет обработку запроса, а не отсутствие любой отправки. Приложение может работать офлайн и накапливать данные для отправки при появлении сети — это ловится замером В, а не этим тестом. Как собрать конфигурацию, которая проходит этот тест, — в гайде по подключению Ollama к Persona.
#Шаг 5. Перехватывающий прокси, если нужно содержимое
Шаги выше показывают, куда ушло соединение. Чтобы увидеть, что внутри, нужен прокси, который расшифровывает трафик, подставляя собственный сертификат.
Порядок:
- Установите
mitmproxyи запустите его на выбранном порту:
mitmproxy --mode regular --listen-port 8080
- Откройте в браузере, настроенном на этот прокси, служебный адрес
mitm.itи установите корневой сертификат в системное хранилище доверенных. - Направьте трафик приложения через прокси — системными настройками прокси либо переменными окружения:
export HTTPS_PROXY=http://127.0.0.1:8080
export SSL_CERT_FILE=~/.mitmproxy/mitmproxy-ca-cert.pem
- Повторите замеры А и Б. Теперь в окне прокси видны адреса, заголовки и тела запросов.
- Удалите сертификат из системы, когда закончите. Оставленный корневой сертификат — это постоянная возможность расшифровывать ваш трафик для того, кто получит доступ к его закрытому ключу.
Два ограничения, о которых надо знать заранее. Приложения с закреплением сертификата (certificate pinning) откажутся работать через прокси — это не признак злого умысла, а обычная мера защиты. И приложения, использующие собственное хранилище сертификатов вместо системного, потребуют отдельной настройки переменных окружения.
#Проверка результата
Проверка удалась, если вы можете письменно ответить на четыре вопроса:
- Список доменов на холостом ходу — конкретный, а не «вроде ничего».
- Что добавляется после одного запроса — и совпадает ли это с вашим ожиданием.
- Что появляется за час работы — периодические соединения, которых не было в первых двух замерах.
- Проходит ли приложение тест отключением сети в том режиме, в котором вы собираетесь им пользоваться.
Если на любой из вопросов ответ «не знаю» — проверка не закончена.
#Что может пойти не так
Проверяли не тот процесс. У приложений с фоновым агентом и веб-частью процессов несколько, и в сеть ходят разные. Проверьте все, что нашли на шаге 1.
Забыли про DNS. Даже если соединение не установилось, запрос на разрешение имени уже ушёл вашему провайдеру DNS и сообщил ему, к какому домену вы обращались. Это отдельный канал утечки метаданных, и утилиты соединений его не показывают.
Приняли собственный сервер приложения за телеметрию. Обращение к домену, который вы сами вписали в настройки, — это работа продукта.
Сертификат прокси остался в системе. Самая опасная ошибка гайда. Удаляйте его сразу после проверки.
Сделали вывод из одного замера. Периодические отправки видны только на длинном наблюдении. Замер В обязателен.
Проверяли в браузере с блокировщиком. Расширение вырезало часть запросов, и картина оказалась чище реальной. Веб-часть проверяйте в чистом профиле; полная методика — в гайде про телеметрию в ИИ-приложениях.
#Частые вопросы
#Что проверять первым, если времени мало?
Тест отключением сети. Он занимает минуту и отвечает на главный вопрос для локального режима: обрабатывается запрос на месте или уезжает. Всё остальное — уточнения.
#Как отличить телеметрию от нужного соединения?
По моменту возникновения и по домену. Нужное соединение появляется в ответ на ваше действие и идёт туда, куда вы ожидаете: ваш сервер, выбранный провайдер модели. Телеметрия возникает без действия и идёт к третьей стороне. Разбор классов соединений — там же, в гайде про телеметрию.
#Можно ли проверить, что именно ушло в облачную модель?
Да, перехватывающим прокси: тело запроса видно целиком, включая системную инструкцию и подмешанные фрагменты памяти, которые в интерфейсе не показываются. Обычно это самая отрезвляющая часть проверки — состав запроса разобран в статье про то, что уходит в облако при работе с языковой моделью.
#Работает ли эта методика для веб-интерфейса?
Частично: панель разработчика браузера показывает все запросы страницы, включая сторонние домены и их тела, и это проще прокси. Но она не видит того, что делает серверная часть от вашего имени — например, обращение сервера к провайдеру модели. Для этого нужен доступ к серверу.
#Проверяли ли вы этим способом Persona?
Да, и результат опубликован — вместе с находкой, которую нам было бы удобнее не публиковать: публичные страницы подключают шрифты со стороннего домена до и независимо от баннера согласия. Отдельно про счётчик — в статье про Яндекс.Метрику и вебвизор.
#Зачем вы даёте инструмент, которым можно проверить вас же?
Потому что альтернативы у нас нет. Репозиторий Persona закрыт, публичной лицензии нет, и аргумент «прочитайте код» нам недоступен. Единственное, что мы можем предложить вместо него, — методику внешней проверки и готовность к её результату. Что локальность при этом не защищает — отдельно разобрано в модели угроз локального ИИ, а общая рамка — в статье про приватный ИИ и локальное хранение.
#Вывод
Если вы проверяете один инструмент — начните с теста отключением сети и списка доменов на холостом ходу: две операции, десять минут, ответ на главный вопрос. Если решение важное и данные чувствительные — доведите проверку до конца: три замера, час наблюдения, перехватывающий прокси и удалённый после этого сертификат. И применяйте это к любому вендору одинаково, включая нас: продукт, который боится такой проверки, вы отличите по результату, а не по формулировкам на его сайте.