I would like to have a VPN service that relays traffic through Tor. I setup services via docker by using following images with little changes for Tor making listen it on external interface instead of localhost as it’s done by original image.
I defined a docker network that is shared among these containers (openvpn, tor). Then according to this tor manual I added
iptables rules to make traffic pass from OpenVPN
tun0 to Tor host (docker container). In original the
REDIRECT target is used to redirect to localhost. I replaced it with
DNAT to redirect to separate host.
So, Tor listens on
*:5353 for DNS and
*:9040 for TCP inside docker container having IP 172.19.0.2 for
eth0. OpenVPN host
eth0 IP address is 172.19.0.3. Inside
openvpn container iptables nat table looks like.
# iptables -t nat -vL Chain PREROUTING (policy ACCEPT 71 packets, 24535 bytes) pkts bytes target prot opt in out source destination 9116 547K DNAT tcp -- tun0 any 192.168.255.0/24 anywhere tcp flags:FIN,SYN,RST,ACK/SYN to:172.19.0.2:9040 145 9500 DNAT udp -- tun0 any 192.168.255.0/24 anywhere udp dpt:domain to:172.19.0.2:5353 Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 60 packets, 4212 bytes) pkts bytes target prot opt in out source destination 341 23987 DOCKER_OUTPUT all -- any any anywhere 127.0.0.11 Chain POSTROUTING (policy ACCEPT 120 packets, 8424 bytes) pkts bytes target prot opt in out source destination 341 23987 DOCKER_POSTROUTING all -- any any anywhere 127.0.0.11 18337 1238K MASQUERADE all -- any eth0 192.168.255.0/24 anywhere 0 0 MASQUERADE all -- any eth0 192.168.254.0/24 anywhere Chain DOCKER_OUTPUT (1 references) pkts bytes target prot opt in out source destination 0 0 DNAT tcp -- any any anywhere 127.0.0.11 tcp dpt:domain to:127.0.0.11:46653 341 23987 DNAT udp -- any any anywhere 127.0.0.11 udp dpt:domain to:127.0.0.11:44292 Chain DOCKER_POSTROUTING (1 references) pkts bytes target prot opt in out source destination 0 0 SNAT tcp -- any any 127.0.0.11 anywhere tcp spt:46653 to::53 0 0 SNAT udp -- any any 127.0.0.11 anywhere udp spt:44292 to::53
The only change I made is two first rules that I added to the
PREROUTING chain. Commands for these are:
iptables -t nat -A PREROUTING -i tun0 -p udp -s 192.168.255.0/24 --dport 53 -j DNAT --to-destination 172.19.0.2:5353 iptables -t nat -A PREROUTING -i tun0 -p tcp -s 192.168.255.0/24 --syn -j DNAT --to-destination 172.19.0.2:9040
After that DNS works fine. The issue is with TCP. The connection can be established, but there is no data response from remote side at all. The connection is just closed. E.g. the
wget http://check.torproject.org looks like this. The origin host (192.168.255.6) is my workstation connected to the OpenVPN I’m trying to setup.
filter table chains are empty and have
ACCEPT policy. Also I looked through similar posts on Server Fault and etc. (with the difference that they
REDIRECT to localhost) and still have no idea how to resolve this. It’s Alpine Linux. Connection tracking is enabled I see the connection via
conntrack tool, it’s closed immediately.
It looks like server reply packets where TCP flags (SYN, ACK etc.) are clear are not Un-DNATed that leads to source address (172.19.0.2) is not replaced with check.torproject.org’s actual IP (184.108.40.206) somehow.
Tor configuration is as follows
# cat /etc/torrc VirtualAddrNetworkIPv4 10.192.0.0/10 AutomapHostsOnResolve 1 TransPort 0.0.0.0:9040 DNSPort 0.0.0.0:5353
Routing table is
# route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface default 172.19.0.1 0.0.0.0 UG 0 0 0 eth0 172.19.0.0 * 255.255.0.0 U 0 0 0 eth0 192.168.254.0 192.168.255.2 255.255.255.0 UG 0 0 0 tun0 192.168.255.0 192.168.255.2 255.255.255.0 UG 0 0 0 tun0 192.168.255.2 * 255.255.255.255 UH 0 0 0 tun0
Where am I wrong?
And the minor question is I can’t realize how does Tor figure out what host to send packet to if original destination is replaced with it’s IP (172.19.0.2)? It would be great if someone cleared up this for me.