Files
utun2/utun.md
T

219 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`
Пример:
```ini
[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` |
Пример:
```ini
[server: lan1]
addr=192.168.29.117:1333
type=public
```
#### `[client: ИМЯ]` — исходящие подключения к пиру
| Ключ | Значение | По умолчанию |
|---|---|---|
| `link` | `сервер:удалённый_IP:порт` (можно несколько) | **обязателен** |
| `peer_public_key` | Публичный ключ пира (128 hex) | **обязателен** |
| `keepalive` | 1 — включить keepalive | `1` |
Пример:
```ini
[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 |
Пример:
```ini
[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).
Пример:
```ini
[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 |
Пример:
```ini
[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` + ключи: только перечисленные ключи
Пример:
```ini
[allowed_keys]
key=c6c8a8a9616ffa6cf44d4757e2bc9f7bd78a1d3cbbe75cffaf3cab8885ad48e7677b...
key=04c1cae041a8e6bfba5245f6669c73f0793d7f9929300a2ba2e123ca55260d6e4748...
```
### Пример минимального конфига
```ini
[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
```