// DevOps

Перенаправляем весь трафик контейнера через SOCKS-прокси с помощью tun2socks

Опубликовано 17.06.2025

Иногда возникает необходимость направлять весь исходящий трафик определённого контейнера через прокси-сервер. Это может быть полезно для обеспечения анонимности, обхода геоблокировок или для тестирования сетевых конфигураций. В этой статье мы рассмотрим, как настроить такую систему, используя утилиту tun2socks и правила iptables, а также как управлять этим процессом с помощью systemd.


Что такое tun2socks?

tun2socks – это мощный инструмент, который позволяет перенаправлять сетевой трафик, предназначенный для TUN-устройства, через SOCKS-прокси. Он создаёт виртуальный сетевой интерфейс (TUN-устройство), весь трафик которого заворачивается в SOCKS-соединение. Это особенно удобно, когда прямое проксирование на уровне приложения невозможно или нежелательно.


Установка tun2socks

Для начала нам нужно установить tun2socks. Мы будем использовать предварительно скомпилированные бинарные файлы с GitHub.

  1. Перейдите на страницу релизов tun2socks: https://github.com/xjasonlyu/tun2socks/releases

  2. Выберите последнюю стабильную версию и загрузите подходящий архив для вашей архитектуры (например, tun2socks-linux-amd64.tar.gz для 64-битных систем Linux).

  3. Распакуйте архив и переместите исполняемый файл в системный путь, например, /usr/local/bin/:

    # Пример для linux-amd64, замените версию на актуальную
    wget https://github.com/xjasonlyu/tun2socks/releases/download/v2.5.1/tun2socks-linux-amd64.tar.gz
    tar -xvf tun2socks-linux-amd64.tar.gz
    sudo mv tun2socks-linux-amd64/tun2socks /usr/local/bin/tun2socks
    sudo chmod +x /usr/local/bin/tun2socks
    

    Убедитесь, что путь к бинарнику в вашем скрипте совпадает с фактическим. В нашем примере это /usr/local/bin/tun2socks.


Скрипт перенаправления трафика

Теперь давайте рассмотрим скрипт, который автоматизирует процесс настройки TUN-устройства, iptables и запуска tun2socks.

Важное замечание: Для корректной работы с systemd, мы немного изменим скрипт, чтобы tun2socks запускался в фоновом режиме, и скрипт мог завершиться, а systemd уже управлял процессом tun2socks.

#!/bin/bash
set -euo pipefail

# Конфигурация
TUN_DEV="tun0" # Название TUN-устройства
TUN_ADDR="10.0.0.2/24" # IP-адрес для TUN-устройства
FWMARK="100" # Метка для трафика
ROUTE_TABLE="100" # Номер таблицы маршрутизации
CONTAINER_IP="172.29.172.2" # IP-адрес вашего контейнера, трафик которого нужно перенаправлять
SOCKS_PROXY="socks5://username:password@xxx.xxx.xxx.xx:yyyyy" # Адрес SOCKS5-прокси (с аутентификацией)
TUN2SOCKS_BIN="/usr/local/bin/tun2socks" # Путь к исполняемому файлу tun2socks

# Путь к PID-файлу, который будет использоваться systemd
PID_FILE="/var/run/tun2socks.pid"

# Функция для очистки правил
cleanup() {
    echo "[INFO] Очистка старых маршрутов и iptables..."
    # Удаляем правила в обратном порядке создания
    iptables -t nat -D POSTROUTING -o "$TUN_DEV" -j MASQUERADE 2>/dev/null || true
    iptables -t mangle -D PREROUTING -s "$CONTAINER_IP" -p tcp -j MARK --set-mark "$FWMARK" 2>/dev/null || true

    ip route flush table "$ROUTE_TABLE" 2>/dev/null || true
    ip rule del fwmark "$FWMARK" table "$ROUTE_TABLE" priority "$FWMARK" 2>/dev/null || true

    ip link set "$TUN_DEV" down 2>/dev/null || true
    ip tuntap del dev "$TUN_DEV" mode tun 2>/dev/null || true

    # Удаляем PID-файл
    rm -f "$PID_FILE" 2>/dev/null || true
}

# Проверяем аргументы командной строки
if [ "$#" -eq 1 ] && [ "$1" == "cleanup_only" ]; then
    cleanup
    echo "[INFO] Очистка завершена."
    exit 0
fi

# Вызываем cleanup при старте для гарантии чистоты, если не режим cleanup_only
cleanup

echo "[INFO] Создание $TUN_DEV..."
ip tuntap add dev "$TUN_DEV" mode tun
ip addr add "$TUN_ADDR" dev "$TUN_DEV"
ip link set "$TUN_DEV" up

echo "[INFO] Настройка ip rule и iptables..."
ip rule add fwmark "$FWMARK" table "$ROUTE_TABLE" priority "$FWMARK"
ip route replace default dev "$TUN_DEV" table "$ROUTE_TABLE"

iptables -t mangle -A PREROUTING -s "$CONTAINER_IP" -p tcp -j MARK --set-mark "$FWMARK"
iptables -t nat -A POSTROUTING -o "$TUN_DEV" -j MASQUERADE

echo "[INFO] Запуск tun2socks..."
"$TUN2SOCKS_BIN" \
  --device "$TUN_DEV" \
  --proxy "$SOCKS_PROXY" \
  --nohup \
  --log-level info &

# Сохраняем PID tun2socks для systemd
echo $! > "$PID_FILE"

echo "[INFO] Настройка завершена. tun2socks запущен."

Разбор скрипта

Давайте подробнее разберем, что делает каждая часть скрипта:

Конфигурация

В начале скрипта определяются ключевые переменные:

  • TUN_DEV: Имя виртуального сетевого интерфейса (например, tun0).
  • TUN_ADDR: IP-адрес и маска подсети, которые будут назначены TUN_DEV. Этот адрес будет использоваться как шлюз для контейнера.
  • FWMARK: Произвольная числовая метка, которая будет использоваться для маркировки пакетов, предназначенных для перенаправления.
  • ROUTE_TABLE: Номер пользовательской таблицы маршрутизации, куда будет направлен помеченный трафик.
  • CONTAINER_IP: Критически важный параметр! Это IP-адрес вашего контейнера, трафик которого вы хотите перенаправлять. Вам нужно будет узнать его.
  • SOCKS_PROXY: Полный адрес вашего SOCKS5-прокси, включая протокол, имя пользователя, пароль и порт.
  • PID_FILE: Путь к файлу, куда будет записан PID процесса tun2socks для отслеживания systemd.

Функция cleanup

Функция cleanup() отвечает за удаление всех ранее созданных правил iptables, маршрутов и самого TUN-устройства. Это важно для обеспечения “чистого” состояния перед каждой новой настройкой и при остановке сервиса. Она также удаляет PID-файл.

Логика запуска и очистки

Скрипт проверяет аргументы командной строки. Если он запущен с аргументом cleanup_only, то выполняет только функцию cleanup и завершает работу. В противном случае, он сначала очищает предыдущие настройки, а затем приступает к созданию новых.

Создание TUN-устройства

  • ip tuntap add dev "$TUN_DEV" mode tun: Создает новый TUN-интерфейс с указанным именем.
  • ip addr add "$TUN_ADDR" dev "$TUN_DEV": Назначает IP-адрес созданному TUN-интерфейсу.
  • ip link set "$TUN_DEV" up: Активирует TUN-интерфейс.

Настройка ip rule и iptables

Это сердце механизма перенаправления трафика:

  • ip rule add fwmark "$FWMARK" table "$ROUTE_TABLE" priority "$FWMARK": Создает правило маршрутизации, которое гласит: “любой пакет с меткой FWMARK должен быть обработан с использованием таблицы маршрутизации ROUTE_TABLE”. Приоритет FWMARK гарантирует, что это правило будет рассмотрено раньше других.

  • ip route replace default dev "$TUN_DEV" table "$ROUTE_TABLE": Внутри нашей специальной таблицы ROUTE_TABLE мы устанавливаем маршрут по умолчанию, который указывает на наше TUN-устройство. Это означает, что весь трафик, попадающий в эту таблицу, будет направлен через TUN_DEV.

  • iptables -t mangle -A PREROUTING -s "$CONTAINER_IP" -p tcp -j MARK --set-mark "$FWMARK": Это правило iptables в цепочке PREROUTING (которая обрабатывает пакеты до того, как они пройдут через маршрутизацию) в таблице mangle (которая используется для изменения пакетов). Оно говорит: “если TCP-пакет исходит от CONTAINER_IP, пометь его меткой FWMARK”. Это то, как мы идентифицируем трафик, который нужно перенаправить.

  • iptables -t nat -A POSTROUTING -o "$TUN_DEV" -j MASQUERADE: Это правило в таблице nat в цепочке POSTROUTING (которая обрабатывает пакеты непосредственно перед их отправкой). Оно выполняет маскарадинг (SNAT), то есть изменяет исходный IP-адрес исходящих пакетов, проходящих через TUN_DEV, на IP-адрес, ассоциированный с TUN_DEV. Это необходимо для корректной работы прокси.

Запуск tun2socks

  • "$TUN2SOCKS_BIN" --device "$TUN_DEV" --proxy "$SOCKS_PROXY" --nohup --log-level info &: Запускает сам tun2socks. Он привязывается к созданному TUN_DEV и использует указанный SOCKS_PROXY для перенаправления всего трафика, который поступает на TUN_DEV. Флаг --nohup позволяет tun2socks продолжать работать даже после завершения родительского процесса (скрипта), а & запускает его в фоновом режиме. --log-level info полезен для отладки.

  • echo $! > "$PID_FILE": Сохраняет PID только что запущенного в фоне tun2socks в файл, чтобы systemd мог его отслеживать.


Как использовать (с systemd)

Теперь, когда скрипт готов, мы можем интегрировать его с systemd для удобного управления.

  1. Сохраните скрипт: Создайте файл, например, /usr/local/bin/tun2socks_redirect.sh, и вставьте в него содержимое измененного скрипта.

    sudo nano /usr/local/bin/tun2socks_redirect.sh
    
  2. Сделайте его исполняемым:

    sudo chmod +x /usr/local/bin/tun2socks_redirect.sh
    
  3. Определите IP-адрес контейнера: Если вы используете Docker, вы можете узнать IP-адрес контейнера, выполнив docker inspect <имя_контейнера> | grep "IPAddress".

  4. Обновите CONTAINER_IP и SOCKS_PROXY: Обязательно измените значения CONTAINER_IP и SOCKS_PROXY в скрипте /usr/local/bin/tun2socks_redirect.sh на ваши собственные.


Создание Systemd Unit-файла

Создадим файл unit-а systemd для нашего сервиса.

  1. Создайте файл /etc/systemd/system/tun2socks-redirect.service:

    sudo nano /etc/systemd/system/tun2socks-redirect.service
    
  2. Вставьте следующее содержимое:

    [Unit]
    Description=Tun2socks Traffic Redirection Service
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=forking
    # Используем Type=forking, так как наш скрипт запускает tun2socks в фоне
    # и завершается сам. tun2socks сам демонизируется (благодаря --nohup).
    # PIDFile используется для отслеживания PID tun2socks.
    PIDFile=/var/run/tun2socks.pid
    ExecStartPre=/usr/local/bin/tun2socks_redirect.sh
    # ExecStart - это команда, которую systemd будет отслеживать.
    # Так как наш скрипт запускает tun2socks в фоне, systemd сам будет следить за tun2socks по PIDFile.
    ExecStart=/bin/true
    # ExecStopPost выполняется после завершения сервиса, для очистки
    ExecStopPost=/usr/local/bin/tun2socks_redirect.sh cleanup_only
    # User=root - поскольку скрипт требует root-прав
    User=root
    Restart=on-failure
    RestartSec=5s
    
    [Install]
    WantedBy=multi-user.target
    

Пояснения к Unit-файлу:

  • [Unit]:
    • Description: Краткое описание сервиса.
    • After=network-online.target: Сервис будет запущен после того, как сеть будет полностью настроена.
    • Wants=network-online.target: Указывает на желаемую зависимость от сети.
  • [Service]:
    • Type=forking: Указывает systemd, что основной процесс сервиса будет “форкать” дочерний процесс (наш tun2socks), и родительский процесс (скрипт) завершится. systemd будет использовать PIDFile для отслеживания истинного процесса сервиса.
    • PIDFile=/var/run/tun2socks.pid: Путь к файлу, в котором наш скрипт сохраняет PID запущенного tun2socks. Это критично для Type=forking.
    • ExecStartPre=/usr/local/bin/tun2socks_redirect.sh: Команда, которая выполняется перед основным запуском сервиса. Здесь наш скрипт настраивает TUN-устройство и правила iptables, а также запускает tun2socks в фоновом режиме.
    • ExecStart=/bin/true: Поскольку tun2socks уже запущен нашим ExecStartPre скриптом и systemd отслеживает его по PIDFile, нам не нужно запускать что-либо ещё в ExecStart. /bin/true просто возвращает успешный код выхода.
    • ExecStopPost=/usr/local/bin/tun2socks_redirect.sh cleanup_only: Команда, которая выполняется после остановки сервиса. При вызове с аргументом cleanup_only скрипт только очищает правила.
    • User=root: Сервис должен запускаться от имени root, так как он изменяет сетевые настройки и правила iptables.
    • Restart=on-failure: Если сервис завершится с ошибкой, systemd попытается перезапустить его.
    • RestartSec=5s: Задержка перед попыткой перезапуска.
  • [Install]:
    • WantedBy=multi-user.target: Сервис будет запущен при загрузке системы в многопользовательском режиме.

Включение и запуск сервиса Systemd

После создания Unit-файла и доработки скрипта:

  1. Перезагрузите systemd daemon:

    sudo systemctl daemon-reload
    
  2. Включите сервис для автоматического запуска при загрузке:

    sudo systemctl enable tun2socks-redirect.service
    
  3. Запустите сервис:

    sudo systemctl start tun2socks-redirect.service
    
  4. Проверьте статус сервиса:

    sudo systemctl status tun2socks-redirect.service
    

    Вы должны увидеть, что сервис активен (active (running)).

  5. Проверьте логи:

    journalctl -u tun2socks-redirect.service -f
    

    Это поможет вам отслеживать вывод скрипта и tun2socks.

Теперь ваш сервис будет автоматически запускаться при загрузке системы и пытаться поддерживать работу tun2socks и правил маршрутизации. Для остановки сервиса используйте sudo systemctl stop tun2socks-redirect.service, и он автоматически очистит правила. Для перезапуска - sudo systemctl restart tun2socks-redirect.service.


Заключение

Таким образом, мы настроили систему, которая перенаправляет весь TCP-трафик от указанного контейнера через SOCKS-прокси-сервер. Этот метод обеспечивает гибкость и контроль над сетевым трафиком, позволяя вам легко управлять его маршрутизацией через внешние прокси-сервисы, а интеграция с systemd значительно повышает надёжность и удобство управления.

Надеюсь, эта статья была полезной! Если у вас есть вопросы или предложения, не стесняйтесь оставлять комментарии.

// Reviews

Отзывы по теме

Опыт сотрудничества оставил максимально позитивное впечатление, в первую очередь профессионализмом и подходом к решению возникающих проблем.

Опыт сотрудничества оставил максимально позитивное впечатление, в первую очередь профессионализмом и подходом к решению возникающих проблем.

mendarinno384

Jitsi meet: персональный zoom, настройка jitsi meet в docker и на VPS

11.11.2025 · ★ 5/5

Была задача наладить работу n8n, redis и базы данных. Заказывал раньше у другого исполнителя, постоянно все ломалось. Заказал у Михаила, на следующий же день все стало работать быстро, как часы!

Была задача наладить работу n8n, redis и базы данных. Заказывал раньше у другого исполнителя, постоянно все ломалось. Заказал у Михаила, на следующий же день все стало работать быстро, как часы!

christ_media

N8n установка на ваш vps сервер. Настройка n8n, docker, ai, telegram

24.09.2025 · ★ 5/5

Опытный покупатель

ladohinpy

N8n установка на ваш vps сервер. Настройка n8n, docker, ai, telegram

25.08.2025 · ★ 5/5

Михаил выполнил настройку очередного VPS. Быстро, профессионально обходя определенные ограничение хостинг провайдеров.

Михаил выполнил настройку очередного VPS. Быстро, профессионально обходя определенные ограничение хостинг провайдеров.

NadoBy

NadoBy

N8n установка на ваш vps сервер. Настройка n8n, docker, ai, telegram

12.08.2025 · ★ 5/5

Освоившийся покупатель

// Contact

Нужна помощь?

Свяжись со мной и я помогу решить проблему