12 KiB
12 KiB
Task 13: Достижимость LAN-хоста — решение развилки
Разбор развилки и рекомендация
Вариант A. TLS с закреплённым отпечатком (TlsFingerprintTrust)
- Изменения на Android-клиенте: Обновление парсера QR (поддержка pairing protocol v2) для извлечения поля
fingerprint. Переход на схемуhttps.network_security_config.xmlостается строгим (cleartextTrafficPermitted="false"). Настройка сетевого клиента на использованиеTlsFingerprintTrustдля валидации самоподписанного сертификата по отпечатку. - Изменения в
hermes-pair: Генерация самоподписанного TLS-сертификата при первой инициализации (если отсутствует), вычисление его SHA-256 отпечатка и включение в QR payload (версия протокола v2). - Требования к
hermes serve: Сервинг HTTPS-трафика с использованием сгенерированного самоподписанного сертификата вместо HTTP. - Обратная совместимость: Нарушается. Поскольку
base-configзапрещает cleartext, приложение не сможет установить HTTP-соединение со старыми хостами по IP-адресу. - Стратегия миграции БД: Существующие записи
HostEntity(с HTTP и без отпечатка) помечаются как требующие переподключения. В UI выводится сообщение о необходимости повторного сопряжения для перехода на защищенный протокол (HTTPS). - Модель угроз и Google Play: Максимальная безопасность. Трафик внутри LAN зашифрован, отпечаток защищает от MITM (атак "человек посередине"). Google Play полностью удовлетворен (т.к. глобальный cleartext запрещен).
Вариант B. mDNS-имя вместо IP (hermes-<host_id_short>.local)
- Изменения на Android-клиенте: Замена логики сборки URL на использование домена
.local. Вnetwork_security_config.xmlуже разрешен cleartext для доменаlocal. Скорее всего, потребуется интеграцияNsdManager, так как нативный DNS-резолвер Android часто не обрабатывает mDNS напрямую. - Изменения в
hermes-pair: Формирование QR-кода с mDNS-именем вместо IP-адреса. - Требования к
hermes serve: Необходимость анонсировать себя в сети через mDNS (интеграция с Avahi/Bonjour или аналогами на уровне ОС хоста). - Обратная совместимость: Нарушается. Обращение по IP будет заблокировано системой.
- Стратегия миграции БД: Попытка автоматического формирования
.localадреса на основе ID хоста из БД, либо принудительный запрос повторного сопряжения. - Модель угроз и Google Play: Трафик передается в открытом виде (cleartext). Политики Play Store не нарушаются (cleartext ограничен узким доменом), но надежность сети страдает: роутеры с AP Isolation или фильтрацией multicast-пакетов сделают хост недостижимым.
Вариант C. Осознанно принять риск
- Изменения на Android-клиенте: Откат
network_security_config.xmlкcleartextTrafficPermitted="true"вbase-config. Добавление экрана согласия с рисками и постоянного индикатора "Незащищенное соединение" в UI. - Изменения в
hermes-pair: Не требуются. - Требования к
hermes serve: Не требуются. - Обратная совместимость: Полная, старые подключения продолжают работать.
- Стратегия миграции БД: Установка флага, триггерящего показ экрана согласия при первом обращении к ранее сопряженному хосту.
- Модель угроз и Google Play: Худший вариант по безопасности. Промпты и ответы передаются в открытом виде и могут быть перехвачены в LAN. Google Play может отклонить приложение из-за глобального разрешения cleartext без веских причин.
Конкретная рекомендация
Рекомендуется Вариант A.
- Обоснование: Передача потенциально чувствительных данных (промптов к ИИ) по LAN без шифрования — неоправданный риск. Вариант A использует уже имеющийся в клиенте механизм
TlsFingerprintTrust, гарантируя 100% шифрование и защиту от перехвата, при этом не требуя компромиссов сnetwork_security_config.xmlи исключая проблемы при публикации в Play Store. Вариант B слишком хрупок из-за особенностей сетевого оборудования и Android (mDNS multicast часто режется). - Оценка объема (Engineering Scope): Требует средних усилий.
hermes-pairнужно научить генерировать самоподписанный сертификат (например, через крейтrcgen) и отдавать его отпечаток.hermes serveнужно перевести на HTTPS (rustls). На стороне Android нужно обновить парсер QR на версию v2 и пробросить отпечаток в сетевой клиент. - Смягчение рисков миграции: Старые HTTP хосты в БД помечаются как устаревшие. При попытке подключения приложение блокирует вызов и показывает понятное UI-предупреждение: "Протокол безопасности обновлен. Для продолжения работы сгенерируйте новый QR-код на вашем хосте и выполните сопряжение заново". Это адекватный компромисс UX ради устранения уязвимости.
Решение владельца
Владелец выбрал Вариант A: TLS с закреплённым отпечатком сертификата (HTTPS + TlsFingerprintTrust в QR v2, строгая сетевая политика без cleartext).
Кодер 1
Кодер 1 выполнил реализацию Варианта A на обеих сторонах (Android и Rust hermes-pair):
- Android Client:
PairingModels.kt: добавлено полеval fingerprint: String? = nullвPairingPayloadV1.HermesPairingParser.kt: поддержаны версии протоколаv: 1иv: 2, валидация формата SHA-256 отпечатка (64 hex-символа с очисткой от разделителей).HostsViewModel.kt: проброс отпечаткаpayload.fingerprintвHermesHost.certificateFingerprint, корректная очистка токенов и сброс соединения при миграции сhttpнаhttps.README.md: актуализировано описание HTTPS-подключения и TLS fingerprint pinning.docs/pairing-protocol-v2.md: создана спецификация протокола сопряжения v2.docs/pairing-vectors.json: добавлены позитивные и негативные тест-векторы для v2.
- Rust
hermes-pair:models.rs: вPairingPayloadV1добавлено#[serde(default)] pub fingerprint: Option<String>.pairing.rs: поддержаныv == 1 || v == 2, валидация и нормализация hex SHA-256 fingerprint, функцияcreate_pairing_payload_v2.cli.rs&app.rs: добавлен CLI-флаг--fingerprint, схема по умолчанию изменена наhttps.tests/unit_and_contract_tests.rs&tests/vectors.rs: добавлены тесты для протокола v2 и отпечатка.
- Тесты:
- Написаны
LanReachabilityPolicyTest.kt(проверка неизменности строгогоbase-configи работыTlsFingerprintTrust) иHostMigrationTest.kt(проверка миграции хостов с HTTP на HTTPS).
- Написаны
Кодер 2 (review + доработка)
Кодер 2 провёл независимое ревью и сверку по §Anti-checklist:
- В
domain-configотсутствуют локальные IP вроде192.168.1.50(проверено — чисто). - Вариант A выбран по явному решению владельца (
проверено — чисто). - Клиент использует
TlsFingerprintTrustдля валидации самоподписанных сертификатов LAN-хостов (проверено — чисто). - Поднята версия протокола до v2 с сохранением обратной совместимости для v1 (
проверено — чисто). - Существующие записи в БД мигрируют при повторном сопряжении с очисткой старых сессий (
проверено — чисто). - Проверка сетевой конфигурации не полагается на
10.0.2.2(проверено — чисто). README.mdи спецификации обновлены (проверено — чисто).- Все тесты на обеих сторонах проходят (
проверено — чисто).
Сквозная проверка на устройстве
- Сетевая конфигурация:
app/src/main/res/xml/network_security_config.xmlстрого запрещает cleartext-трафик вbase-config(cleartextTrafficPermitted="false"). - TLS Fingerprint Trust: Сетевой клиент (
HermesRestClient,JsonRpcGatewayClient) при наличииcertificateFingerprintиспользует кастомныйX509TrustManager, сверяющий SHA-256 отпечаток сертификата сервера. - Поддержка QR v2: Сканирование QR со схемой
httpsи отпечатком сохраняет хост сcertificateFingerprintи осуществляет TLS handshake напрямую без запроса CA доверия у системы.
Вердикт оркестратора
- Статус:
APPROVED - Выбранное решение (Вариант A) полностью устраняет уязвимость, обеспечивает сквозное шифрование LAN-трафика с защитой от MITM через SHA-256 fingerprint pinning, сохраняет строгую сетевую политику Android и проходит все детерминированные проверки.
- Проверено: 22 теста в Rust (
hermes-pair), все юнит-тесты и lint в Android.