Что внутри
Vertex — небольшой набор архитектурных решений, применённых последовательно. На этой странице — те же шесть опор, что на главной, но с подробностями по криптографии и настройкам.
Сквозное шифрование
Каждый пакет между вашим устройством и выходным узлом запечатан ChaCha20-Poly1305 на сессионном ключе, полученном из X25519 Diffie-Hellman при подключении. У вершины нет ключевого материала; даже если она сохранит каждый переданный байт — у неё останется только шифротекст. Сессионный ключ — свой на каждое устройство и каждое подключение, отсюда Perfect Forward Secrecy на уровне сессии.
- Эфемерная пара ключей X25519 на каждое подключение
- HKDF-SHA256 даёт 256-битный сессионный ключ
- ChaCha20-Poly1305 AEAD на каждом пакете
- 12-байтный nonce + 16-байтный auth tag (28 байт накладных)
- Никаких постоянных общих секретов между клиентом и выходным узлом
session_key = derive(client_pub || exit_pub)
ciphertext, auth_tag = seal(session_key, nonce, plaintext) Несколько независимых вершин
Vertex держит несколько независимых вершин у разных инфраструктурных провайдеров в разных регионах, без репликации и кластеризации между ними. Выходные узлы подключены ко всем вершинам; клиент хранит упорядоченный список и переходит к следующей доступной вершине при сбое. Переключение занимает порядка 100 мс — обычно этого достаточно, чтобы стрим или SSH-сессия не оборвались.
- Несколько независимых вершин у разных инфраструктурных провайдеров
- Между вершинами нет ни репликации, ни кластеризации — каждая полностью самостоятельна
- Список вершин клиент получает автоматически — всегда самый свежий
- Выходные узлы подключены ко всем вершинам; ответ идёт обратно по тому же пути
- Sticky reconnect: первой пробуется последняя рабочая вершина
vertices = [
v0, // основная
v1, // резервная
... // дополнительные независимые вершины
]
# упорядоченный failover, sticky к last-good Автоматический выбор выхода
При подключении клиент измеряет RTT до каждого доступного выходного узла и смотрит на его текущую нагрузку. Через тот, у кого минимальный RTT с поправкой на нагрузку, идёт трафик. Переоценка — раз в 5 минут; ручной выбор в интерфейсе имеет приоритет.
- Выходные узлы объявляют о себе короткими периодическими heartbeats
- Оценка балансирует измеренный RTT и текущую нагрузку (RTT доминирует)
- Переоценка раз в 5 минут
- Ручной выбор выходного узла отменяет автоматический
- Несколько боевых выходных узлов в независимых регионах
score(exit) = rtt + load_penalty
pick min(score) over reachable exits Идентичность устройства (TOFU)
Каждый клиент при первом запуске создаёт пару ключей X25519 и хранит приватную половину на устройстве (Keychain на Apple, EncryptedFile на Android, файл на Linux). Публичная половина уходит выходному узлу при handshake; узел запоминает её при первом подключении (Trust On First Use) и отказывает любому последующему подключению с тем же именем пользователя, но другим ключом идентичности. Только пароля для входа в сеть мало.
- Пара ключей X25519: 32 байта публичный + 32 байта приватный
- HMAC-SHA256 как доказательство, с фиксированной меткой идентичности устройства
- TOFU-пиннинг хранится на каждом выходном узле
- Сброс — по письму в поддержку, при переустановке или смене устройства
- Приватный ключ никогда не покидает устройство
shared = ECDH(identity_priv, exit_pub)
proof = HMAC-SHA256(shared, device_label) Split routing
Локальная таблица CIDR с российским сетевым пространством (8 585 подсетей) держит трафик до RU-адресов вне туннеля; через вершину уходят только зарубежные направления. В итоге: ниже задержка до отечественных сервисов и никаких ложных гео-блокировок на банкинге, платежах и госпорталах.
- 8 585 российских подсетей зашиты в каждый релиз
- iOS / macOS: NEPacketTunnelNetworkSettings excludedRoutes
- Android: VpnService.Builder excludeRoute (лимит 1 500 записей)
- Linux-шлюз: ipset
ru-nets+ iptables MARK - Тумблер в приложении: полный туннель ↔ split
# фрагмент таблицы RU CIDR
2.56.0.0/16, 31.13.144.0/21, 77.88.0.0/18, 87.250.224.0/19, 213.180.192.0/19, ... Транспорт, устойчивый к блокировкам
У Vertex нет характерной сетевой сигнатуры привычного VPN. Пассивному наблюдателю соединение видится как обычный зашифрованный веб-трафик — поэтому оно работает там, где специализированные VPN-протоколы фильтруются. Клиент сначала пробует основной путь и тихо уходит на резервный, если что-то по дороге отказывается пропускать пакеты.
- Ни выделенного VPN-порта, ни протокольной сигнатуры
- На сетевом уровне неотличимо от обычного зашифрованного веб-трафика
- Несколько транспортных путей, выбор — при подключении
- Автоматический переход на резервный путь, если основной заблокирован
- Регулярно пересматривается под новые методы фильтрации
transport: prefer → standard
fallback → web-stream
mode → adaptive