Skip to content

Security: necronicle/z2k

Security

SECURITY.md

Безопасность z2k

Как сообщить о проблеме

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

Ответ по существу в течение нескольких дней. Проект ведёт один человек — это не отговорка, а факт, который стоит учитывать в ожиданиях.


Что z2k собой представляет с точки зрения угроз

z2k ставится на домашний роутер, работает от root и регулярно скачивает и исполняет код с GitHub. Это значит, что цена компрометации канала доставки равна цене компрометации роутера целиком. Ниже честно перечислено, что защищено, а что нет.

Что защищено

Целостность доставляемых файлов. UPDATES.json несёт карту files_sha256 для каждого поставляемого файла. Каждый хоп цепочки зеркал сверяется с ней; не совпало — источник отвергается вместе с закешированным ETag, идём к следующему. Это закрывает протухший или подменённый ответ зеркала, включая jsdelivr и gh-proxy, которые терминируют TLS у себя.

Автообновление не запускает непроверенный код. Скрипт установки, запускаемый от root в ходе автообновления, сверяется с той же картой до запуска. Не совпало — обновление не применяется.

Стороннему реверс-прокси не доверяется то, что нечем сверить. gh-proxy.com участвует только там, где известен ожидаемый дайджест.

Ввод из вебпанели не превращается в команду. Конфиг исполняется как скрипт, поэтому значения экранируются, а строки стратегий отвергаются при наличии ", `, $ и управляющих символов.

Панель не отвечает на чужой адрес. Проверяется Host, Origin и Sec-Fetch-Site; адрес привязки не может сам себя внести в список разрешённых, если он не приватный.

Что НЕ защищено — и это осознанно

Первая установка — доверие при первом контакте. Установка идёт командой curl … | sh из README. На этом шаге доверие целиком опирается на TLS и на то, что репозиторий не захвачен. Проверять здесь нечем: инструмент проверки и есть то, что скачивается.

Манифест подписан Ed25519 (с r-75). Карта files_sha256 защищает от подмены на зеркале, а подпись — от того, кто получил доступ к самому репозиторию: приватный ключ там не лежит, и подписать обновление захвативший репозиторий не может. После первой принятой подписи роутер защёлкивает храповик и с этого момента требует её всегда (lib/auto_update.sh, au_manifest_verify / au_trust_pinned); смена ключа требует явного подтверждения человеком. Подробности и отпечаток ключа — в README, раздел «Подпись обновлений».

Оговорка про Realtek Lexra: под неё не собирается наш проверяльщик, поэтому проверка ложится на системный openssl. Если он есть и умеет Ed25519 — всё работает как обычно; если нет, а храповик ещё не защёлкнут, манифест принимается без подписи.

Панель по умолчанию без аутентификации, но пароль можно включить (с r-75.14). Раньше здесь стояло «панель не имеет аутентификации» — это устарело. Вход по паролю есть, включается в меню и в самой панели, флаг Z2K_PANEL_AUTH; выключен по умолчанию, потому что панель рассчитана на доверенную локальную сеть. Отсюда границы:

  • пока пароль не включён, заражённое устройство в вашей же локальной сети может управлять z2k — проверки происхождения запроса защищают от вредоносного сайта в браузере, но не от прямого HTTP-клиента;
  • не публикуйте панель наружу — и включённый пароль этого не меняет. В частности, не публикуйте её через KeenDNS: аутентификация в этом механизме по умолчанию выключена, и панель окажется доступна из интернета всякому, кто знает имя, — а имена перечислимы через публичные логи сертификатов.

Даже с включённым паролем это не равно родному веб-интерфейсу Keenetic: блокировки после неудачных попыток у нас нет. Утверждать «тот же уровень доверия» было бы неточно.

Общий секрет туннеля не является секретом. Он вшит в бинарники, которые лежат в открытом репозитории, и достаётся тривиально. Настоящая аутентификация туннеля — персональная пара Ed25519, которая чеканится на устройстве и не покидает его; общий секрет остаётся лишь купоном на регистрацию. Релей ограничен диапазонами Telegram, поэтому открытым прокси не является.

Учётные данные вспомогательного прокси не являются секретом по той же причине — он лежит в открытом репозитории. Защищает его не пароль, а область: он пропускает только один адрес назначения.

Телеметрия включена по умолчанию и сейчас идёт без TLS. Состав, адрес и способ отключения описаны в README.


Модель угроз: от кого защищаемся и от кого нет

Кто Защита
Провайдер, DPI, наблюдатель на пути Да для целостности обновлений. Нет для факта использования z2k
Подменённое или протухшее зеркало Да — карта хешей
Вредоносный сайт в браузере пользователя Да — проверки происхождения запроса
Заражённое устройство в той же LAN Только если включён пароль панели — по умолчанию выключен, граница принята
Захват репозитория или учётной записи GitHub Да — подпись манифеста Ed25519, ключ вне репозитория
Кто-то, знающий имя вашего KeenDNS Нет, если вы опубликовали панель — не делайте этого

Что делать, если считаете, что вас скомпрометировали

  1. Выключите z2k из меню — это не удаляет настройки.
  2. Сохраните /opt/var/log/z2k-auto-update.log и вывод z2k diag до любых действий: переустановка их перепишет.
  3. Проверьте, не опубликована ли панель наружу (ip http proxy в CLI роутера).
  4. Переустановите с нуля командой из README.

Если находка выглядит как проблема самого z2k — заведите issue с этими данными, они сокращают разбор на порядок.

There aren't any published security advisories