Gluetun не может найти устройство TUN в Docker.

Вопрос или проблема

Это работало вчера, но после перезагрузки базового оборудования перестало работать.
Мой docker-compose.yml;

version: '3.8'

services:
  gluetun:
    image: qmcgaw/gluetun
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    environment:
      - VPN_SERVICE_PROVIDER=pia
      - VPN_TYPE=openvpn
      - OPENVPN_USER=user
      - OPENVPN_PASSWORD=pass
      - SERVER_REGIONS="Netherlands"
      - TZ=Europe/London
    restart: unless-stopped

При запуске с docker-compose up -d, я получаю ошибку:
ERROR checking TUN device: TUN device is not available: open /dev/net/tun: no such device.

Я пытался воссоздать устройство tun;

mkdir -p /dev/net 
mknod /dev/net/tun c 10 200 
chmod 666 /dev/net/tun

но это не помогло.

Запуск нового контейнера для проверки доступа к устройству работает, как ожидалось:

docker run --rm --privileged alpine ls /dev/net/tun
>>> /dev/net/tun

Добавление флага privileged: true в docker-compose.yml также не помогло.

Я также пытался заново скачать образ gluetun, перезапустить Docker и перезагрузить само оборудование.

Оборудование — это Synology NAS с установленной DSM6 (DSM7 не поддерживается). Версия Docker 20.10.3.

Если кто-то еще столкнется с этим, мне удалось исправить это следующим образом.

  1. Удалите ранее созданное устройство tun:
rm -rf /dev/net
  1. Загрузите устройство tun с помощью:
insmod /lib/modules/tun.ko
  1. Проверьте, что устройство туннеля отображается:
lsmod | grep tun
>>> tun                    18856  2
  1. При перезагрузке модуль не загружается автоматически (по-видимому, в DSM7 это происходит автоматически, но не в DSM6), поэтому я сделал это постоянным при перезагрузках, добавив скрипт запуска в /usr/local/etc/rc.d/:
vi /usr/local/etc/rc.d/tun.sh
#!/bin/sh
case "$1" in
    start)
        insmod /lib/modules/tun.ko
        ;;
    stop)
        rmmod tun
        ;;
esac
exit 0

Затем сделайте скрипт исполняемым:

chmod +x /usr/local/etc/rc.d/tun.sh 

Ответ или решение

В описанной ситуации, проблема с невозможностью найти TUN-устройство в docker-контейнере Gluetun после перезагрузки оборудования связана с особенностями конфигурации Synology NAS на базе DSM6. Рассмотрим подробно причины проблемы, шаги её решения и дальнейшие рекомендации для предотвращения подобных ситуаций в будущем.

Теория (Theory)

При использовании VPN внутри Docker-контейнера обычно требуется доступ к устройству туннелирования TUN, которое является виртуальным сетевым интерфейсом. Оно позволяет пакетам данных перемещаться между узлами через защищённое соединение. Docker предоставляет гибкие возможности управления устройствами, которые могут быть подключены к контейнерам, однако это может потребовать дополнительной настройки со стороны операционной системы хоста.

Основные шаги, необходимые для успешного создания и использования TUN-устройства в контейнере включают:

  • Подключение устройства к контейнеру с помощью docker-compose.
  • Корректное управление модулями ядра, которые отвечают за функциональность TUN-устройства.

Пример (Example)

В рассмотренном случае ошибка указывает на отсутствие устройства /dev/net/tun, несмотря на то, что оно было явно указано в конфигурации docker-compose.yml. Варианты устранения, такие как ручное создание устройства с помощью mknod, не привели к успеху, так как основная проблема заключалась в том, что модуль ядра для TUN-устройства не был загружен. Это характерное поведение для DSM6, где ручная загрузка модулей в ядро не выполняется при старте системы, в отличие от более новых версий, таких как DSM7.

Применение (Application)

  1. Удаление ранее созданного TUN-устройства:
    Для начала необходимо удалить любые ранее созданные устройства, чтобы избежать конфликтов. Это выполняется командой:

    rm -rf /dev/net
  2. Загрузка модуля ядра TUN:
    Загрузка модуля ядра является ключевым шагом. Это делается с помощью команды:

    insmod /lib/modules/tun.ko

    После успешной загрузки модуля необходимо проверить, что он действительно загружен:

    lsmod | grep tun
  3. Автоматизация загрузки модуля:
    Поскольку DSM6 не поддерживает автоматическую повторную загрузку модуля после перезагрузки, создание скрипта для автоматической загрузки модуля при старте системы позволяет исключить необходимость ручных действий в будущем. Скрипт создается в директории /usr/local/etc/rc.d/:

    • Создание скрипта:

      vi /usr/local/etc/rc.d/tun.sh
    • Содержание скрипта должно включать в себя команды для загрузки и выгрузки модуля:

      #!/bin/sh
      case "$1" in
       start)
           insmod /lib/modules/tun.ko
           ;;
       stop)
           rmmod tun
           ;;
      esac
      exit 0
    • Сделать скрипт исполняемым:

      chmod +x /usr/local/etc/rc.d/tun.sh

Заключение

Подводя итоги, важно помнить, что эффективная работа контейнеров Docker с устройствами уровня ядра может требовать дополнительной настройки конфигурации системы. В данном случае это включало манипуляции с модулями ядра для обеспечения работы TUN-устройства. Предпринимая шаги для автоматизации этих действий, вы можете значительно снизить количество ручных операций при последующих перезапусках системы, что сделает ваше решение более стабильным и надежным.

Также рекомендуется регулярно проверять обновления DSM и связанных пакетов, так как новые версии могут предложить улучшения в управлении сетью и поддержке контейнеров, упрощая решение подобных задач.

Оцените материал
Добавить комментарий

Капча загружается...