Внешний TUN через dev_attach
Режим для Keenetic OpkgTun и других контроллеров, которые сами создают интерфейс, назначают адрес, устанавливают маршруты и управляют его жизненным циклом.
Qeli передаёт пакеты, внешний контроллер владеет интерфейсом
С dev_attach=true Linux-клиент открывает уже существующий именованный TUN/TAP и подключает его к зашифрованному каналу. Обычная автоматическая настройка L3 и маршрутов в этом режиме не запускается.
| Операция | Qeli | Внешний владелец |
|---|---|---|
| Создать и удалить интерфейс | — | ✓ |
| MTU, link up, адрес и префикс | — | ✓ |
| Маршруты, full/split policy, NAT/firewall | — | ✓ |
| Шифрование и передача пакетов | ✓ | — |
| Сообщить выданный сервером IPv4 | ✓ | Читает файл |
Минимальная конфигурация Linux-клиента
dev = ext0
device_type = tun
dev_attach = true
gateway = false
dns = off
dev должен точно совпасть с именем созданного интерфейса; device_type — с его типом TUN/TAP. dns=off рекомендуется, если внешний менеджер владеет также DNS-политикой.
sudo ip tuntap add dev ext0 mode tun user qeli
sudo ip link set dev ext0 mtu 1200 up
QELI_PLATFORM_TUN_FD. dev_attach — пользовательский режим Linux CLI для существующего интерфейса по имени. Platform TUN FD — внутренний контракт transport-core с мобильными/платформенными адаптерами и не является ключом client.conf.Интерфейс должен существовать раньше клиента Qeli
| # | Исполнитель | Действие |
|---|---|---|
| 1 | Внешний владелец | Создаёт ext0, задаёт тип и MTU, поднимает link |
| 2 | Qeli | Подключается к серверу и открывает существующий интерфейс через TUNSETIFF |
| 3 | Qeli | После аутентификации атомарно записывает выданный IPv4 в QELI_TUNIP_FILE |
| 4 | Внешний владелец | Читает IP, применяет известный ему префикс, маршруты и firewall |
| 5 | Внешний владелец | После остановки Qeli сам удаляет интерфейс и свою сетевую политику |
Qeli заимствует file descriptor: при штатной остановке он закрывает его, но не удаляет интерфейс, адреса или маршруты внешнего владельца.
Передача назначенного адреса контроллеру
Путь задаётся переменной окружения процесса Qeli, а не ключом INI. После AUTH файл содержит только IPv4-адрес без длины префикса. Префикс внешний контроллер должен знать из согласованной серверной конфигурации.
Environment=QELI_TUNIP_FILE=/run/qeli/ext0.ip
TUN_IP=$(cat /run/qeli/ext0.ip)
TUN_PREFIX=24 # должно совпадать с префиксом tunnel pool на сервере
sudo ip addr replace "$TUN_IP/$TUN_PREFIX" dev ext0
QELI_TUNIP_FILE не содержит маску, поэтому контроллер обязан получить фактический префикс из своей конфигурации.Штатный сценарий интеграции в релизе
На Keenetic интерфейс создаёт ndm, init-скрипт запускает Qeli и экспортирует путь к файлу адреса, а hook wan.d применяет L3 и маршруты. Конфигурация клиента остаётся split-tunnel, потому что политикой управляет роутер.
dev = opkgtun0
dev_attach = true
gateway = false
dns = off
export QELI_TUNIP_FILE="$OPKGTUN_TUNIP"
Частые ошибки dev_attach
| Симптом | Что проверить |
|---|---|
| «interface … does not exist yet» | Порядок запуска и точное имя dev; reconnect повторит attach |
| Permission denied на /dev/net/tun | Пользователя, CAP_NET_ADMIN и права устройства |
| Attach завершается ошибкой | Тип TUN/TAP, совместимость владельца и multi-queue/занятый интерфейс |
| could not write tun IP | Каталог существует и доступен процессу Qeli, путь не read-only |
| Подключено, но трафика нет | Адрес с правильным префиксом, link up, маршруты, forwarding и firewall владельца |
| Qeli меняет DNS | Установить dns=off, если DNS должен контролироваться извне |
ip -details link show dev ext0тип, состояние и MTU интерфейсаip address show dev ext0адрес и фактический префиксip route showмаршруты, созданные внешним владельцемjournalctl -u qeli-client -bожидайте Attached …; L3 left to its ownerВладелец TUN видит пакеты до шифрования
Внешний менеджер контролирует интерфейс и имеет доступ к необработанным IP-пакетам до их передачи в Qeli. Запускайте его с минимальными правами и защищайте файл назначенного адреса. Qeli использует CLOEXEC-дубликаты, чтобы не передавать TUN descriptor дочерним hooks, но это не ограничивает самого владельца интерфейса.