WireGuard & Docker Networking: Preserving Real Client IPs Without NAT – A Tricky Routing Challenge


Introduction

Hello everyone,

I’m working with a Docker-Compose setup that runs both WireGuard and CoreDNS, and my goal is to have CoreDNS log the actual client peer IPs by disabling NAT. That part is simple enough and not the issue, but due to my network segmentation, things have become very complicated. Since I’m not a networking geek and only know the basics, troubleshooting this has been quite a challenge.


Docker-Compose Setup

Here is my current 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

The docker-compose reveals the network architecture:

  • WireGuard: vpn_net, dns_net
  • CoreDNS: dns_net

The WireGuard configuration is set up automatically, and everything works as expected. The CoreDNS container is reachable (ping 172.29.0.3).

At this point the standard auto-generated WireGuard configuration is active. This comes with NAT. In this scenario, CoreDNS is easily accessible and dig google.de @172.29.0.3 returns a response.

Inside the VPN tunnel, I can reach CoreDNS, as long as NAT is active.


Without NAT Configuration

However, since CoreDNS logs the container IP instead of the client peer IPs, I want to disable NAT. This can be done easily in the WireGuard configuration. The PostUp and PostDown directives set the right iptables rules when the server starts:

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

Everything seems fine. However, when I ping CoreDNS from within the VPN tunnel (ping 172.29.0.3), I get a timeout. Interestingly, when I run dig google.de @172.29.0.3, CoreDNS logs the DNS request with the client IP 10.13.13.x … This means the traffic successfully reaches the CoreDNS container but is not routed back. With the default WireGuard setup (where NAT is active), this works perfectly. It makes absolutely no sense to me why this doesn’t work.


Troubleshooting Attempts

I have tried numerous solutions for over 20 hours now without success. Inside the CoreDNS container, I added the following route:

ip route add 10.13.13.0/24 via 172.29.0.2

But this does not work.

I can run dig google.de @172.29.0.3, and CoreDNS logs the request, but I do not receive a response.

The fact that CoreDNS logs the request indicates that the traffic is successfully forwarded from WireGuard to CoreDNS. However, it seems that the traffic is not routed back to WireGuard.


Request for Assistance

I am really stuck at this point. Maybe some networking experts can help me understand the topology and identify where the traffic is likely getting stuck.

Maybe some networking geeks can dive deep into the topology and trace how the traffic flows to pinpoint where it is likely getting stuck.

This is an important passion project for me, and I am putting all my effort into solving this issue. I have to find the solution—there is no other way. My entire project depends on it, and it means a lot to me.

Thank you in advance, and I wish you all the best and a great day!

1 Like