Tor client image for Synology DSM with transparent WireGuard path support
234
Tor client image for Synology DSM with transparent WireGuard path support.
This image is meant for Synology DSM setups where exactly one selected WireGuard peer should go out through Tor.
Typical use case:
This image is intended to provide an explicit Tor path through a Synology DSM system.
In the published example, this Tor path is carried through an existing WireGuard container setup.
This is the recommended setup if you want the same selected Tor path from both internal and external clients.
This image itself is not limited to DS2422+.
This is not a full VPN appliance.
This is not a ready-made all-in-one stack for every environment.
This image expects runtime configuration.
You must adapt the example values to your own setup.
services:
tor-client:
image: friseer/synology-tor-client:latest
container_name: tor-client
restart: unless-stopped
network_mode: "container:wg-easy"
cap_add:
- NET_ADMIN
volumes:
- ./torrc:/etc/tor/torrc:ro
- ./entrypoint.sh:/usr/local/bin/entrypoint.sh:ro
ClientOnly 1
SocksPort 0
TransPort 10.8.0.1:9040
DNSPort 10.8.0.1:9053
AutomapHostsOnResolve 1
VirtualAddrNetworkIPv4 10.192.0.0/10
Log notice stdout
#!/bin/sh
set -eu
SRC_IP="10.8.0.4/32"
WG_IF="wg0"
WG_ADDR="10.8.0.1"
TOR_TRANS_PORT="9040"
TOR_DNS_PORT="9053"
IPT="iptables"
if command -v iptables-legacy >/dev/null 2>&1; then
IPT="iptables-legacy"
fi
nat_add() {
chain="$1"
shift
if ! $IPT -t nat -C "$chain" "$@" 2>/dev/null; then
$IPT -t nat -A "$chain" "$@"
fi
}
nat_del() {
chain="$1"
shift
if $IPT -t nat -C "$chain" "$@" 2>/dev/null; then
$IPT -t nat -D "$chain" "$@"
fi
}
flt_add() {
chain="$1"
shift
if ! $IPT -C "$chain" "$@" 2>/dev/null; then
$IPT -A "$chain" "$@"
fi
}
flt_del() {
chain="$1"
shift
if $IPT -C "$chain" "$@" 2>/dev/null; then
$IPT -D "$chain" "$@"
fi
}
cleanup() {
nat_del PREROUTING -i "$WG_IF" -s "$SRC_IP" -p tcp --syn -j REDIRECT --to-ports "$TOR_TRANS_PORT"
nat_del PREROUTING -i "$WG_IF" -s "$SRC_IP" -p udp --dport 53 -j REDIRECT --to-ports "$TOR_DNS_PORT"
flt_del INPUT -i "$WG_IF" -s 10.8.0.4/32 -p tcp -d "$WG_ADDR" --dport "$TOR_TRANS_PORT" -j ACCEPT
flt_del INPUT -i "$WG_IF" -s 10.8.0.4/32 -p udp -d "$WG_ADDR" --dport "$TOR_DNS_PORT" -j ACCEPT
flt_del INPUT -i "$WG_IF" -p tcp -d "$WG_ADDR" --dport "$TOR_TRANS_PORT" -j DROP
flt_del INPUT -i "$WG_IF" -p udp -d "$WG_ADDR" --dport "$TOR_DNS_PORT" -j DROP
flt_del FORWARD -i "$WG_IF" -s "$SRC_IP" -p udp -j DROP
flt_del FORWARD -i "$WG_IF" -s "$SRC_IP" -j DROP
}
trap 'cleanup' EXIT INT TERM
i=0
while [ "$i" -lt 30 ]; do
if ip -4 addr show dev "$WG_IF" 2>/dev/null | grep -q "$WG_ADDR/"; then
break
fi
i=$((i + 1))
sleep 1
done
if ! ip -4 addr show dev "$WG_IF" 2>/dev/null | grep -q "$WG_ADDR/"; then
echo "wg0 with $WG_ADDR not ready"
exit 1
fi
tor -f /etc/tor/torrc &
TOR_PID="$!"
i=0
while [ "$i" -lt 30 ]; do
if ss -ltn 2>/dev/null | grep -q "${WG_ADDR}:${TOR_TRANS_PORT}" \
&& ss -lun 2>/dev/null | grep -q "${WG_ADDR}:${TOR_DNS_PORT}"; then
break
fi
i=$((i + 1))
sleep 1
done
flt_add INPUT -i "$WG_IF" -s 10.8.0.4/32 -p tcp -d "$WG_ADDR" --dport "$TOR_TRANS_PORT" -j ACCEPT
flt_add INPUT -i "$WG_IF" -s 10.8.0.4/32 -p udp -d "$WG_ADDR" --dport "$TOR_DNS_PORT" -j ACCEPT
flt_add INPUT -i "$WG_IF" -p tcp -d "$WG_ADDR" --dport "$TOR_TRANS_PORT" -j DROP
flt_add INPUT -i "$WG_IF" -p udp -d "$WG_ADDR" --dport "$TOR_DNS_PORT" -j DROP
nat_add PREROUTING -i "$WG_IF" -s "$SRC_IP" -p tcp --syn -j REDIRECT --to-ports "$TOR_TRANS_PORT"
nat_add PREROUTING -i "$WG_IF" -s "$SRC_IP" -p udp --dport 53 -j REDIRECT --to-ports "$TOR_DNS_PORT"
flt_add FORWARD -i "$WG_IF" -s "$SRC_IP" -p udp -j DROP
flt_add FORWARD -i "$WG_IF" -s "$SRC_IP" -j DROP
wait "$TOR_PID"
In torrc:
10.8.0.1 with the WireGuard interface address inside your WireGuard containerIn entrypoint.sh:
SRC_IP="10.8.0.4/32" with the selected peer IP that should go through TorWG_ADDR="10.8.0.1" with the WireGuard interface address inside the containerwg0, also change WG_IF="wg0"In compose.yaml:
wg-easy, change:
network_mode: "container:wg-easy"WireGuard is not the purpose of this image.
WireGuard is the transport layer used in the published example so that selected clients can be routed through the same explicit Tor path via the Synology NAS.
The example uses:
wg-easywg0Install or recover WireGuard first on DS2422+ / v1000, then add this image on top.
docker compose up -d
From the selected WireGuard client path:
curl -4 https://check.torproject.org/api/ip
Expected result:
"IsTor": true
Content type
Image
Digest
sha256:d849ddfd7…
Size
36 MB
Last updated
6 months ago
docker pull friseer/synology-tor-client