You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

9.4 KiB

uTun — защищённый VPN-туннель поверх UDP

uTun создаёт виртуальный TUN-интерфейс и маршрутизирует IP-трафик через зашифрованные UDP-каналы по протоколу ETCP (Extended TCP) — комбинация TCP-надёжности + QUIC-мультиплексирования + multi-link балансировки.

Возможности

Возможность Описание
Шифрование ECC (secp256r1) обмен ключами + AES-128-CCM с аутентификацией
Целостность CRC32 внутри зашифрованного payload
Multi-link Одно подключение через несколько UDP-каналов одновременно
Балансировка Выбор канала с минимальным inflight + round-robin при равенстве
Bandwidth shaping Ограничение полосы на каждом канале с автооценкой
Inflight control Динамическое ограничение байт в полёте для предотвращения перегрузки
Retransmission Адаптивный таймаут: RTT_avg × k₁ + jitter × k₂
Keepalive Двусторонний, с настраиваемым интервалом и таймаутом
Фрагментация/сборка Normalizer: упаковка мелких пакетов вместе, разбиение крупных
Маршрутизация Локальная (через TUN + системные маршруты) и распределённая (BGP-обмен)
NAT-детекция Определение типа NAT (open/restricted) через ping-пробы
Файрвол Белый список IP:port для трафика через туннель
Control server TCP-сервер для мониторинга метрик в реальном времени (GUI-клиент)
Горячая перезагрузка SIGHUP — выборочное обновление конфига (сравнение сокетов/клиентов/линков)
Авто-ключи При первом запуске генерирует ECC-пару и node_id, записывает в конфиг
Демонизация fork/setsid на Linux; foreground-режим -f для отладки
Кроссплатформенность Linux (epoll), Windows (wintun), FreeBSD
Эмуляция потерь loss_rate=N в конфиге сокета — для тестирования

Архитектура (кратко)

Приложение/ОС
  ↓ IP-пакеты
TUN interface (tun_if)
  ↓ queue
Routing (routing.c) — поиск маршрута
  ↓ (если удалённый)
Normalizer (pkt_normalizer.c) — фрагментация/упаковка
  ↓
ETCP (etcp.c) — seq/ack, retransmit, reassembly
  ↓
LoadBalancer (etcp_loadbalancer.c) — выбор канала
  ↓
Encrypt + UDP send (etcp_connections.c)
  ↓
Сеть (UDP)

Конфигурация (INI-формат)

CLI-запуск

utun -c utun.conf [-p /var/run/utun.pid] [-l utun.log] [-f] [-d "etcp:debug"]
  • -c — путь к конфигу (по умолчанию utun.conf)
  • -p — PID-файл
  • -l — лог-файл (по умолчанию utun.log)
  • -f — foreground (не демонизироваться)
  • -d — отладочный конфиг на лету, формат: "категория:уровень,..."

Секции конфига

[global] — основные параметры

Ключ Значение По умолчанию
my_node_name Имя узла (до 15 символов) —
my_node_id 64-битный ID узла (hex, 16 символов) авто
my_private_key Приватный ключ ECC (64 hex символа) авто
my_public_key Публичный ключ ECC (128 hex символов) авто
tun_ifname Имя TUN-интерфейса tun0
tun_ip IP-адрес TUN-интерфейса —
mtu MTU для всех подключений 1500
keepalive_timeout Таймаут keepalive (мс) 2000
keepalive_interval Интервал keepalive (мс) 200
log_file Путь к лог-файлу —
debug_level Уровень отладки: error, warn, info, debug, trace error
tun_test_mode 1 — не создавать реальный TUN (тесты) 0
enable_timestamp Метки времени в логах 1
enable_function_names Имена функций в логах 1
enable_file_lines Файл:строка в логах 0
enable_colors ANSI-цвета в терминале 0

[debug] — по-категорийные уровни (переопределяют debug_level)

Доступные категории: uasync, ll_queue, connection, etcp, crypto, memory, timing, config, tun, routing, timers, normalizer, bgp, socket, general, control, dump, traffic

Пример:

[debug]
etcp=info
routing=trace
bgp=trace
crypto=error

[server: ИМЯ] — локальные UDP-сокеты (обязательно хотя бы один)

Ключ Значение По умолчанию
addr IP:port для bind обязателен
type public, nat, private unknown
mtu MTU для этого сокета из [global]
loss_rate % потерь пакетов (0–100) 0
so_mark Linux SO_MARK для policy routing —
netif Привязка к интерфейсу (по имени) —
fib FreeBSD FIB (таблица маршрутизации) -1 (не задан)
only_local 1 — только локальные соединения, без forwarding 0

Пример:

[server: lan1]
addr=192.168.29.117:1333
type=public

[client: ИМЯ] — исходящие подключения к пиру

Ключ Значение По умолчанию
link сервер:удалённый_IP:порт (можно несколько) обязателен
peer_public_key Публичный ключ пира (128 hex) обязателен
keepalive 1 — включить keepalive 1

Пример:

[client: aeza]
link=lan1:85.192.42.96:1333
peer_public_key=04c1cae041a8e6bfba5245f6669c73f0793d7f9929300a2ba2e123ca55260d6e47...

Важно: в серверном конфиге секции [client] нет. В клиентском — есть свои ключи + peer_public_key каждого сервера в [client].

[routing] — маршруты

Ключ Значение
route_subnet Подсеть, доступная через этот TUN (добавляется в системную таблицу маршрутизации). Можно несколько
my_subnet Своя подсеть, анонсируемая через BGP

Пример:

[routing]
route_subnet=10.23.0.0/16
route_subnet=10.24.0.0/16
my_subnet=10.23.1.0/24

[firewall] — контроль доступа

Ключ Значение
allow all — разрешить всё. Или IP / IP:port (можно несколько)

По умолчанию: deny all (если нет allow=all).

Пример:

[firewall]
allow=192.168.1.100
allow=10.0.0.0/8:443

[control] — сервер мониторинга

Ключ Значение По умолчанию
control_ip IP для прослушивания 127.0.0.1
control_port Порт —
control_allow IP/mask (можно несколько) deny all

Пример:

[control]
control_ip=192.168.29.117
control_port=9090
control_allow=192.168.0.0/16

[allowed_keys] — белый список публичных ключей пиров

Ключ Значение По умолчанию
allow_all 1 — разрешить все ключи —
key Публичный ключ (128 hex, можно несколько) —

Поведение:

  • Секция отсутствует: разрешить все (совместимость)
  • allow_all=0 + нет ключей: запретить все
  • allow_all=0 + ключи: только перечисленные ключи

Пример:

[allowed_keys]
key=c6c8a8a9616ffa6cf44d4757e2bc9f7bd78a1d3cbbe75cffaf3cab8885ad48e7677b...
key=04c1cae041a8e6bfba5245f6669c73f0793d7f9929300a2ba2e123ca55260d6e4748...

Пример минимального конфига

[global]
tun_ip=10.23.1.1
my_node_name=vmL1
my_node_id=5f75c7445af88e1f
my_private_key=b0e8b68679db468979906894fe36239dbda910e06435361d696c7f5a8e2009c4
my_public_key=c6c8a8a9616ffa6cf44d4757e2bc9f7bd78a1d3cbbe75cffaf3cab8885ad48e7677b...

[server: lan1]
addr=192.168.29.117:1333
type=public

[routing]
route_subnet=10.23.0.0/16
my_subnet=10.23.1.0/24