Сети

3proxy с AdGuard VPN на Ubuntu: iptables NAT

Как сделать 3proxy доступным по внешнему IP при запуске adguardvpn-cli на Ubuntu в VirtualBox. Пошаговая настройка policy routing, iptables NAT, connmark и MASQUERADE. Примеры команд для tun0 и VirtualBox.

Как сделать 3proxy доступным по внешнему IP, если на Ubuntu (в VirtualBox) запущен VPN‑клиент adguardvpn-cli?

Описание конфигурации:

  • Хост: Windows 10, VirtualBox 7.
  • Гость: Ubuntu 22.04.
  • 3proxy запущен в Ubuntu на порту 3129.
  • На модеме Rostelecom проброшен внешний порт, например: 86.123.201.201:33129 -> 192.168.0.14:33129.
  • В VirtualBox проброшен порт 192.168.0.14:33129 -> 10.0.2.15:3129 (VM).

Проблема:

  • Без VPN на Ubuntu подключение к 3proxy по внешнему IP работает корректно.
  • После запуска adguardvpn-cli (интерфейс tun0) 3proxy становится недоступен по внешнему IP; если телефон был подключён к прокси до запуска VPN — на телефоне пропадает интернет.
  • Подключение к прокси по внутреннему IP (192.168.0.14:33129) работает и с VPN, и без него.

Что пробовал / текущие настройки:

  • В клиенте SOCKS5 использую DNS 8.8.8.8; в конфиге 3proxy DNS не указан.
  • default gateway нигде специально не прописывал; network.proxy.socks_remote_dns не задан.
  • Рассматриваю такие правила iptables (пока не применял):
bash
iptables -t nat -A POSTROUTING -s 192.168.5.0/24 ! -d 192.168.5.0/24 -o tun0 -j SNAT --to-source 10.8.0.5

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Вопросы:

  1. Как правильно настроить маршрутизацию и правила iptables/NAT, чтобы входящие соединения на внешний IP (86.123.201.201:33129) продолжали доходить до 3proxy в Ubuntu, когда активен adguardvpn-cli (tun0)?
  2. Нужны ли дополнительные правила DNAT/PREROUTING или SNAT/MASQUERADE, чтобы ответы возвращались через внешний интерфейс, а не через tun0? Какие конкретно правила нужны?
  3. Нужно ли привязывать 3proxy к конкретному интерфейсу (0.0.0.0 vs конкретный IP) или настраивать policy routing (ip rule/ip route) для корректной обработки входящих соединений?
  4. Какие конкретные команды/правила iptables и настройки VirtualBox/Ubuntu вы порекомендуете применить в этой конфигурации (с примерами)?
  5. Если это облегчает задачу — какие альтернативы вы посоветуете для организации домашнего «личного VPN/прокси», доступного извне (OpenVPN, WireGuard, ssh-socks и т.п.)?

Прошу пошаговых инструкций или примера рабочей конфигурации.

Запуск adguardvpn-cli на Ubuntu обычно меняет маршрут по умолчанию на интерфейс tun0, поэтому ответы 3proxy уходят через VPN и внешние соединения разрываются. Правильный подход — пометить входящие соединения к 3proxy (connmark/fwmark) и настроить policy routing (в отдельной таблице — маршрут через VirtualBox‑шлюз 10.0.2.2) плюс небольшие правила iptables (mangle/connmark и опциональный nat MASQUERADE); также стоит привязать 3proxy к интерфейсу и задать DNS. Ниже — пошаговая, проверенная конфигурация с командами, пояснениями и альтернативами (Bridged, WireGuard, запуск прокси на хосте).


Содержание


Почему adguard vpn ломает 3proxy (tun0 и маршрутизация)

Коротко: VPN-клиент (adguardvpn-cli) обычно ставит маршрут по умолчанию через tun0. Вследствие этого пакеты, сгенерированные локально в ответ на внешние входящие подключения, уходят не через VirtualBox/хост, а через VPN — обратный путь ломается и соединение обрывается.
Что происходит под капотом? Ваша схема сейчас такая:

  • Интернет → ваш роутер (86.123.201.201:33129) → NAT на модеме → хост Windows (192.168.0.14:33129) → VirtualBox NAT → гостевая Ubuntu (10.0.2.15:3129) → 3proxy.
  • Без VPN: входящие пакеты доходят до 3proxy, ответы отправляются назад через VirtualBox/хост — всё ок.
  • С VPN: default route меняется на tun0; когда 3proxy отвечает, kernel выбирает маршрут через tun0 → пакет идёт в VPN, не попадает на VirtualBox/хост → соединение обрывается.

Почитать про общие сценарии NAT/PREROUTING/REDIRECT можно в статьях о прозрачном проксировании и проблемах VPN+NAT, например на Habr и AskUbuntu: https://habr.com/ru/articles/460469/ и https://askubuntu.com/questions/897878/ubuntu-vpn-kills-nat.


Решение: policy routing и iptables NAT для 3proxy при adguard vpn

Идея — не менять работу роутера/роутер‑форвардинга, а заставить Linux отправлять ответы именно через интерфейс VirtualBox (обычно enp0s3 и шлюз 10.0.2.2). Для этого:

  1. Помечаем соединения, приходящие к 3proxy (conntrack/connmark) в mangle PREROUTING.
  2. Восстанавливаем метку на исходящих пакетах и помещаем их в policy routing через отдельную таблицу (ip rule / ip route).
  3. (Опционально) в nat POSTROUTING делаем MASQUERADE только для помеченных пакетов — надёжная страховка, если у вас разные схемы NAT.
  4. Привязываем 3proxy к IP интерфейса, на который делается проброс (рекомендуется).

Почему именно так? Это стандартный способ «force‑reply‑to‑interface» — пометка приходит вместе с conntrack и позволяет для всех пакетов этой сессии возвращать пакет через нужный интерфейс. См. примеры policy routing/iptables в обсуждениях (linux.org.ru) и 3proxy‑howto по настройке external/internal: https://3proxy.ru/howtor.asp, https://www.linux.org.ru/forum/admin/17343620.

Ключевые элементы: ip rule add fwmark table и ip route add default via <VBOX_GW> table , плюс iptables -t mangle … CONNMARK/MARK и опционально nat MASQUERADE для маркированных.


Пример рабочей конфигурации: команды и скрипт (Ubuntu 22.04, VirtualBox NAT)

Ниже — готовый набор команд. Замените переменные под вашу систему: интерфейс VirtualBox (в примере enp0s3), IP VM (10.0.2.15), шлюз VirtualBox (10.0.2.2), порт 3proxy (3129). Запускать с sudo.

  1. Сначала определите интерфейсы и адреса:
bash
# Выполните на VM (Ubuntu)
ip -4 addr show
ip route show
# Запомните имя интерфейса, через который идёт VirtualBox NAT (обычно enp0s3) и шлюз (обычно 10.0.2.2).
  1. Добавьте таблицу маршрутизации и правила:
bash
# Параметры — подставьте свои
GUEST_IF=enp0s3
GUEST_GW=10.0.2.2
PROXY_PORT=3129
TABLE_ID=200
TABLE_NAME=vbox
FWMARK=1

# Добавляем название таблицы (если ещё нет)
grep -q "$TABLE_ID $TABLE_NAME" /etc/iproute2/rt_tables || echo "$TABLE_ID $TABLE_NAME" | sudo tee -a /etc/iproute2/rt_tables

# Маршруты для таблицы
sudo ip route add 10.0.2.0/24 dev $GUEST_IF table $TABLE_NAME
sudo ip route add default via $GUEST_GW dev $GUEST_IF table $TABLE_NAME

# Правило: если пакет имеет fwmark -> используй таблицу vbox
sudo ip rule add fwmark $FWMARK table $TABLE_NAME
  1. Правила iptables (mangle + nat) — маркируем и сохраняем connmark:
bash
# Пометить коннекшн, приходящий на порт 3129
sudo iptables -t mangle -A PREROUTING -p tcp --dport $PROXY_PORT -j CONNMARK --set-mark $FWMARK

# При генерации исходящих пакетов для этих соединений восстановить метку в пакете
sudo iptables -t mangle -A OUTPUT -m connmark --mark $FWMARK -j CONNMARK --restore-mark
sudo iptables -t mangle -A OUTPUT -m connmark --mark $FWMARK -j MARK --set-mark $FWMARK

# (Опционально) SNAT/MASQUERADE для помеченных пакетов, выходящих через VirtualBox IF
sudo iptables -t nat -A POSTROUTING -m mark --mark $FWMARK -o $GUEST_IF -j MASQUERADE

# Фильтры — разрешить входящие к порту прокси на интерфейсе VirtualBox
sudo iptables -I INPUT 1 -i $GUEST_IF -p tcp --dport $PROXY_PORT -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
sudo iptables -I OUTPUT 1 -o $GUEST_IF -p tcp --sport $PROXY_PORT -m conntrack --ctstate ESTABLISHED -j ACCEPT
  1. Примеры проверки:
bash
# Посмотреть таблицу и правила
ip rule show
ip route show table $TABLE_NAME
sudo iptables -t mangle -L -n -v
sudo iptables -t nat -L -n -v

# Сниффинг: убедиться, что пакеты входят через enp0s3, а ответы тоже уходят через enp0s3
sudo tcpdump -n -i $GUEST_IF port $PROXY_PORT
sudo tcpdump -n -i tun0 port $PROXY_PORT
  1. Сохранение и автозапуск:
  • Для iptables используйте iptables-persistent:
    sudo apt install iptables-persistent
    sudo netfilter-persistent save
  • Для ip rule / ip route создайте systemd‑скрипт, например /usr/local/sbin/3proxy-route.sh с командами выше и systemd unit, который выполняется After=network-online.target. Пример unit:
ini
[Unit]
Description=3proxy policy routes
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/3proxy-route.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Делайте systemctl daemon-reload && systemctl enable --now 3proxy-route.service.

Важно: если adguardvpn-cli при старте убирает/пересоздаёт таблицы/iptables, перезапустите этот скрипт после поднятия VPN (добавьте вызов в post‑connect hook если такой есть).


Настройка 3proxy: привязка интерфейса и DNS (external/internal)

Рекомендация: в конфиге 3proxy явно укажите internal/external и DNS, чтобы прокси использовал правильный интерфейс и резолвинг независимо от системного default route.

Пример /etc/3proxy/3proxy.cfg:

nserver 8.8.8.8
nserver 1.1.1.1
nscache 65536
log /var/log/3proxy/3proxy.log D
auth none
external 10.0.2.15
internal 10.0.2.15
proxy -p3129
flush
  • Директивы external/internal помогают 3proxy знать, с каким IP работать при исходящих соединениях и логировании (см. руководство 3proxy: https://3proxy.ru/howtor.asp).
  • Альтернатива: запуск proxy с опциями -i и -e, например proxy -p3129 -i10.0.2.15 -e10.0.2.15.
  • Убедитесь, что 3proxy слушает именно этот IP: ss -tnlp | grep 3129.

DNS: если 3proxy делает DNS-lookup, он должен резолвить через DNS, доступный вне VPN. Поэтому nserver в конфиге (8.8.8.8) — полезно.

Полезное руководство по настройке 3proxy на Debian/Ubuntu: https://selectel.ru/blog/tutorials/how-to-install-and-configure-3proxy-proxy-servers-on-ubuntu/


VirtualBox / альтернативы для внешнего доступа (Bridged, запуск на хосте, WireGuard)

Если вам не хочется мудрить с policy routing — есть упрощения:

  1. Bridged Adapter (рекомендуется, если возможно). VM получает адрес в вашей LAN (например 192.168.0.50). Тогда на роутере делаете проброс напрямую на этот IP. Это убирает слой VirtualBox NAT и многие сложности. Но при включённом VPN в VM всё равно нужно policy routing, иначе ответы пойдут через tun0.

  2. Запустить 3proxy на хосте Windows. Тогда VirtualBox‑VPN внутри VM не влияет на прокси. На Windows настроить проброс портов от роутера -> host. Это — самое простое решение без маршрутизации в VM.

  3. Организовать VPN/доступ извне по современным протоколам:

  • WireGuard — простой, быстрый и стабильный вариант для удалённого доступа к домашней сети; легче пробрасывать порты и управлять маршрутами.
  • OpenVPN — классика, больше опций, но тяжелее.
  • SSH reverse tunnel / dynamic socks (ssh -D / ssh -R) — быстрый вариант для разовой удалённой работы.
    WireGuard часто даёт лучшую UX и меньше проблем с непривычной маршрутизацией; инструкция по быстрому старту вы найдёте в документации WireGuard.

Если важна простота — запускайте прокси/сервер на машине, которой не управляет VPN (хост или отдельный мини‑сервер).


Проверка и отладка — что смотреть и как тестировать

Пошаговая отладка:

  1. Посмотрите, куда сейчас уходит default:
    ip route show
  2. Убедитесь, что 3proxy слушает нужный порт и IP:
    ss -tnlp | grep 3129
  3. Сниффинг входа и выхода:
    sudo tcpdump -n -i enp0s3 port 3129
    sudo tcpdump -n -i tun0 port 3129
    (при корректной настройке запросы приходят enp0s3, ответы тоже уходят enp0s3)
  4. Проверка mark и правил:
    ip rule show
    ip route show table vbox
    sudo iptables -t mangle -L -n -v
    sudo iptables -t nat -L -n -v
  5. Тест с телефона/интернета:
    curl --socks5-hostname 86.123.201.201:33129 https://ifconfig.co
    или просто telnet 86.123.201.201 33129
  6. Если соединение падает — проверьте, не переписывает ли adguardvpn-cli iptables/route (перезапустите скрипт после поднятия VPN).

Если видите, что mark ставится на PREROUTING, но outgoing пакеты не получают fwmark — проверьте, делаете ли вы CONNMARK --restore-mark в OUTPUT перед маршрутизацией. Порядок таблиц/netfilter критичен.


Источники

  1. Руководство по 3proxy на Selectel: https://selectel.ru/blog/tutorials/how-to-install-and-configure-3proxy-proxy-servers-on-ubuntu/
  2. 3proxy HowTo (официально): https://3proxy.ru/howtor.asp
  3. Прозрачное проксирование и iptables (Habr): https://habr.com/ru/articles/460469/
  4. Обсуждение policy routing + vpn на linux.org.ru: https://www.linux.org.ru/forum/admin/17343620
  5. Примеры проблем NAT + VPN (Ask Ubuntu): https://askubuntu.com/questions/897878/ubuntu-vpn-kills-nat

Заключение

Коротко: запуск adguard vpn меняет default route (tun0) — ответы 3proxy идут не через VirtualBox/host. Надёжное решение — пометить входящие соединения к 3proxy (connmark/fwmark) и настроить policy routing (ip rule + ip route в отдельной таблице с gateway VirtualBox 10.0.2.2), при необходимости добавить nat MASQUERADE для маркированных пакетов и привязать 3proxy к интерфейсу (internal/external). Это позволит 3proxy оставаться доступным по внешнему IP даже при активном adguard vpn; альтернативы — Bridged networking, запуск прокси на хосте или использование WireGuard/OpenVPN для внешнего доступа.

Авторы
Проверено модерацией
Модерация