WireGuard и Docker Networking: сохранение реальных IP-адресов клиентов без NAT — сложная задача маршрутизации.

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

Введение

Здравствуйте,

Я работаю с настройкой Docker-Compose, которая запускает как WireGuard, так и CoreDNS, и моя цель заключается в том, чтобы CoreDNS записывал фактические IP-адреса клиентских пиров, отключив NAT. Эта часть достаточно проста и не является проблемой, но из-за сегментации сети все стало очень сложно. Поскольку я не специалист по сетям и знаю только основы, устранение этой проблемы оказалось весьма сложной задачей.


Настройка Docker-Compose

Вот мой текущий docker-compose.yml:

version: '3.3'

services:
  wireguard:
    image: lscr.io/linuxserver/wireguard:latest
    container_name: wireguard
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - SERVERURL=***
      - SERVERPORT=51820
      - PEERS=1
      - PEERDNS=172.29.0.3
      - INTERNAL_SUBNET=10.13.13.0
      - ALLOWEDIPS=0.0.0.0/0
      - LOG_CONFS=true
    ports:
      - "51820:51820/udp"
    volumes:
      - /root/volumes/wireguard/config:/config
    networks:
      vpn_net:
        ipv4_address: 172.28.0.2
      dns_net:
        ipv4_address: 172.29.0.2

  coredns:
    image: coredns:latest
    container_name: coredns
    volumes:
      - /root/volumes/coredns/Corefile:/Corefile
      - /etc/letsencrypt/live/***.com/fullchain.pem:/fullchain.pem:ro
      - /etc/letsencrypt/live/***.com/privkey.pem:/privkey.pem:ro
    cap_add:
      - NET_ADMIN
    networks:
      dns_net:
        ipv4_address: 172.29.0.3
    command: ["-conf", "Corefile"]

networks:
  vpn_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16
  dns_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.29.0.0/16

Docker-compose раскрывает архитектуру сети:

  • WireGuard: vpn_net, dns_net
  • CoreDNS: dns_net

Конфигурация WireGuard настраивается автоматически, и все работает как ожидалось. Контейнер CoreDNS доступен (ping 172.29.0.3).

На этом этапе активна стандартная сгенерированная конфигурация WireGuard, которая включает NAT. В этом случае CoreDNS легко доступен, и dig google.de @172.29.0.3 возвращает ответ.

Внутри VPN-туннеля я могу достичь CoreDNS, пока включен NAT.


Конфигурация без NAT

Однако, поскольку CoreDNS записывает IP контейнера вместо IP клиента, я хочу отключить NAT. Это можно легко сделать в конфигурации WireGuard. Директивы PostUp и PostDown устанавливают правильные правила iptables при запуске сервера:

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 ! -d 172.29.0.0/16 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 ! -d 172.29.0.0/16 -j MASQUERADE

Все кажется в порядке. Однако, когда я выполняю ping до CoreDNS изнутри VPN-туннеля (ping 172.29.0.3), я получаю тайм-аут. Интересно, что когда я запускаю dig google.de @172.29.0.3, CoreDNS регистрирует DNS-запрос с IP клиента 10.13.13.x … Это означает, что трафик успешно достигает контейнера CoreDNS, но не маршрутизируется обратно. В стандартной настройке WireGuard (где NAT активен) это работает идеально. Для меня совершенно неясно, почему это не работает.


Попытки устранения неполадок

Я пробовал множество решений более 20 часов, но безуспешно. Внутри контейнера CoreDNS я добавил следующий маршрут:

ip route add 10.13.13.0/24 via 172.29.0.2

Но это не работает.

Я могу запустить dig google.de @172.29.0.3, и CoreDNS регистрирует запрос, но я не получаю ответ.

Тот факт, что CoreDNS регистрирует запрос, указывает, что трафик успешно передается от WireGuard к CoreDNS. Однако кажется, что трафик не маршрутизируется обратно к WireGuard.


Запрос о помощи

Я действительно застрял на этом моменте. Может быть, какие-то эксперты по сетям смогут помочь мне понять топологию и определить, где, вероятно, застревает трафик.

Может быть, какие-то сетевые гики смогут углубиться в топологию и отследить, как движется трафик, чтобы выяснить, где он, вероятно, застревает.

Для меня это важный проект на основе увлечения, и я вкладываю все усилия в решение этой проблемы. Я должен найти решение, иного пути нет. Весь мой проект зависит от этого, и он много значит для меня.

Заранее спасибо, желаю вам всего наилучшего и хорошего дня!

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

Решение задачи маршрутизации при использовании WireGuard и Docker для сохранения реальных IP-адресов клиентов без применения NAT может показаться сложным из-за специфики сетевой настройки и маршрутизации пакетов между контейнерами Docker. Обратим внимание на ключевые элементы этой задачи и потенциальные методы её решения.

Теория

Сетевые технологии, такие как Docker и VPN, например, WireGuard, требуют понимания нескольких ключевых аспектов. Docker использует свои собственные сетевые драйверы для изоляции контейнеров и их взаимодействия. Ваша установка включает два таких моста – vpn_net и dns_net, каждый из которых имеет свою подсеть. Ваше стремление отключить NAT в конфигурации WireGuard обусловлено желанием, чтобы CoreDNS мог логировать реальные IP-адреса клиентов, а не IP-адреса контейнеров. Однако отключение NAT приводит к проблемам с маршрутизацией возвратного трафика.

Когда NAT включен, запросы от клиентов, проходя через WireGuard, получают замещённый источником IP-адрес, принадлежащий контейнеру WireGuard. Таким образом, все ответы от CoreDNS автоматически возвращаются в этот контейнер, и он перенаправляет их к клиентам, что не вызывает проблем с маршрутизацией. Без NAT запросы от клиентов сохраняют свои исходные IP-адреса, и если не продуманы правила маршрутизации для возвратных пакетов, CoreDNS не сможет направить их обратно к клиенту через WireGuard.

Пример

Вы столкнулись с ситуацией, когда CoreDNS получает DNS-запросы и логирует их с клиентскими адресами в диапазоне 10.13.13.x, но ответы не возвращаются к клиентам. Это классический пример асимметричной маршрутизации, где запрос достигает сервера, но ответ не может вернуться к отправителю. Подключение iptables в цепочке OUTPUT или POSTROUTING в CoreDNS для пометки пакетов маршрутной информацией — один из способов решения, но требует внимания к деталям конфигурации межсетевого экрана и маршрутизации пакетов.

Применение

Для решения вашей проблемы можно рассмотреть несколько шагов и подходов:

  1. Обновление конфигурации маршрутизации:

    • Удостоверьтесь, что в CoreDNS или соответствующем сетевом устройстве маршрутизация располагает информацией о сети клиента (10.13.13.0/24). Подключение маршрута через 172.29.0.2 — шаг в правильном направлении, но это может быть не единственное изменение, необходимое для надлежащей маршрутизации.
    • Проверьте общий путь маршрутизации в системе через команду traceroute и tcpdump, чтобы удостовериться, что возвратный маршрут до клиентского IP имеется и соблюдается.
  2. Использование политики маршрутизации:

    • Добавление политик маршрутизации (Policy-Based Routing) может помочь направить трафик из CoreDNS в VPN-клиенты, в частности, при указании в роутинговых таблицах направлений боле сложной логики маршрута.
  3. Правила iptables:

    • Измените правила iptables на сервере WireGuard и/или в контейнере CoreDNS. В частности, убедитесь, что все цепочки правил (FORWARD, OUTPUT и т.п.) разрешают нужный трафик. Можно также рассмотреть добавление SNAT правил.
  4. Обновление системной конфигурации контейнера:

    • В зависимости от конфигурации сети, настройка IP Forwarding (sysctl -w net.ipv4.ip_forward=1) может быть необходимой как в Docker-хосте, так и внутри контейнеров.
  5. Просмотр логов и диагностика:

    • Анализируйте логи Docker, WireGuard и CoreDNS для поиска вероятных ошибок конфигурации или сетевых проблем.

Комплексное понимание конфигурации сети Docker и ее ограничения, а также правильная установка маршрутизации, позволят устранить текущие проблемы и сохранить действительный клиентский IP. Это не быстрый процесс, но систематический подход позволит вам со временем прийти к оптимальному решению. Успехов!

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

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