Port forwarding from Wireguard to Transmission on Synology DSM 7.1

So, I’m running the Linuxserver Wireguard and Transmission images on Synology DSM 7.1, and the configuration works except the listening port isn’t being forwarded from the Wireguard container to the Transmission container. Torrents work, but only passively.
I’ve confirmed that the port is successfully being forwarded from the VPN provider down to the wg container, but the postup/predown commands I’m using in the wg conf apparently aren’t doing the job of passing it along to the Transmission container.
I’d appreciate it if anyone could help identify the problem.

[Interface]
PrivateKey = xxxxxxxxxxxx
Address = xxxxxxxxxx
DNS = xxxxxxxx

PostUp = iptables -t nat -A POSTROUTING -o wg+ -j MASQUERADE
Table = 2468
PostUp = wg set wg0 fwmark 1234
PostUp = ip rule add not fwmark 1234 table 2468
PostUp = ip rule add table main suppress_prefixlength 0
PostUp = iptables -I FORWARD -i %i -m state --state NEW -j DROP
PostUp = iptables -t nat -A PREROUTING -p tcp --dport 56981 -j DNAT --to-destination 172.20.0.40:56981
PostUp = iptables -t nat -A PREROUTING -p udp --dport 56981 -j DNAT --to-destination 172.20.0.40:56981

PreDown = iptables -t nat -D PREROUTING -p tcp --dport 56981 -j DNAT --to-destination 172.20.0.40:56981
PreDown = iptables -t nat -D PREROUTING -p udp --dport 56981 -j DNAT --to-destination 172.20.0.40:56981
PreDown = iptables -t nat -D POSTROUTING -o wg+ -j MASQUERADE

PostDown = iptables -D FORWARD -i %i -m state --state NEW -j DROP
PostDown = ip rule del table main suppress_prefixlength 0
PostDown = ip rule del not fwmark 1234 table 2468

[Peer]
PublicKey = xxxxxxxxxx
AllowedIPs = 0.0.0.0/0
Endpoint = xxxxxxx:51820

And here’s my compose file. I’ve tried with SYS_MODULE as a cap_add for the wireguard container, but it doesn’t appear to make a difference.

services:
  wireguard:
    image: lscr.io/linuxserver/wireguard
    container_name: wireguard
    cap_add:
      - NET_ADMIN
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Chicago
    volumes:
      - /volume1/docker/wireguard:/config
    networks:
      default:
        ipv4_address: 172.20.0.50
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped
  transmission:
    image: lscr.io/linuxserver/transmission
    container_name: transmission
    cap_add:
      - NET_ADMIN
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Chicago
      - WEBUI_PORT=9091
      - PEERPORT=56981
    volumes:
      - /volume1/docker/transmission:/custom-cont-init.d:ro
      - /volume1/import:/downloads:rw
    networks:
      default:
        ipv4_address: 172.20.0.40
    ports:
      - 9091:9091
      - 56981:56981
      - 56981:56981/udp
    restart: unless-stopped
networks:
  default:
    name: wgnet
    external: true

I’ve tried running the Transmission container without exposing port 56981, which may not be necessary (and could potentially create a conflict) as it receives all its traffic from the wg container.
I also run a bash script when the Transmission container goes up to allow access to the UI and route everything else through the Wireguard container:

#!/bin/bash

ip route del default
ip route add default via 172.20.0.50
ip route add 192.168.1.0/24 via 172.20.0.1

This is mostly based on the guide offered here at Routing Docker Host And Container Traffic Through WireGuard | LinuxServer.io, with additional info from this site.
I’ve verified that torrent traffic is going through the VPN. It’s serviceable without the listening port open, but would be much better with it. Synology DSM definitely has its idiosyncrasies when it comes to this stuff.

Adapted some additional iptables commands from this script into my wg0.conf, but the Transmission container still reports that the listening port is closed. :thinking:

PostUp = iptables -A INPUT -p tcp -i wg0 --dport 56981 -j ACCEPT
PostUp = iptables -A INPUT -p udp -i wg0 --dport 56981 -j ACCEPT
PostUp = iptables -A FORWARD -i wg0 -o eth0 -p tcp -d 172.20.0.40 --dport 56981 -j ACCEPT
PostUp = iptables -A FORWARD -i wg0 -o eth0 -p udp -d 172.20.0.40 --dport 56981 -j ACCEPT

PreDown = iptables -D INPUT -p tcp -i wg0 --dport 56981 -j ACCEPT
PreDown = iptables -D INPUT -p udp -i wg0 --dport 56981 -j ACCEPT
PreDown = iptables -D FORWARD -i wg0 -o eth0 -p tcp -d 172.20.0.40 --dport 56981 -j ACCEPT
PreDown = iptables -D FORWARD -i wg0 -o eth0 -p udp -d 172.20.0.40 --dport 56981 -j ACCEPT

Fixed it!

The instruction iptables -I FORWARD -i %i -m state --state NEW -j DROP says to drop any incoming packets that would be used to initiate a new connection, which I guess is the very definition of what you’d be listening for on your listening port. :sweat_smile:

So, the additional iptables instructions in my first reply are unnecessary. I just needed to remove those PostUp and PostDown commands, and my conf works. I hope this can be helpful to someone else! :upside_down_face:

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.