# How to create a Tor router?

**URL:** https://forum.torproject.org/t/how-to-create-a-tor-router/21573
**Category:** Core Tor
**Created:** [May 11, 2026, 1:36pm UTC](https://forum.torproject.org/t/how-to-create-a-tor-router/21573 "2026-05-11T13:36:49Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Netwarrior](https://forum.torproject.org/letter_avatar_proxy/v4/letter/n/49beb7/32.png) [@Netwarrior](https://forum.torproject.org/u/Netwarrior)
#### Post date: [May 11, 2026, 1:36pm UTC](https://forum.torproject.org/t/how-to-create-a-tor-router/21573/1 "2026-05-11T13:36:49Z")

</div>

Hello,  
I want to set up a Linux gateway that routes traffic over Tor so that anyone who enters the Linux IP address can access the internet via Tor.  
I changed the Tor configuration file as follows:

```auto
TransPort 9040
DNSPort 53
VirtualAddrNetwork 10.192.0.0/10
AutomapHostsOnResolve 1

```

The iptables rules are as follows:

```auto
#!/bin/bash

# Clear existing rules
iptables -F
iptables -t nat -F
iptables -t mangle -F

# Enable forwarding and network settings
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.rp_filter=0
sysctl -w net.ipv4.conf.enp0s3.rp_filter=0
sysctl -w net.ipv4.conf.all.route_localnet=1

# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

# Allow loopback interface
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# SSH ACCEPT RULES
# Allow established SSH connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow new SSH connections on port 22 from anywhere
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# FORWARD RULES for gateway functionality
# Allow forwarding between interfaces
iptables -A FORWARD -i enp0s3 -o enp0s3 -j ACCEPT

# Allow established connections in FORWARD chain
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow DNS responses back from Google DNS
iptables -A FORWARD -p udp --sport 53 -j ACCEPT

# Allow Tor traffic to forward
iptables -A FORWARD -p tcp --dport 9040 -j ACCEPT
iptables -A FORWARD -p tcp --sport 9040 -j ACCEPT

# OUTPUT RULES
# Allow Tor to send responses
iptables -A OUTPUT -p tcp --dport 9040 -j ACCEPT
iptables -A INPUT -p tcp --sport 9040 -j ACCEPT

# NAT RULES - Traffic redirection for ALL IPs (no restrictions)
# DNS: Forward all DNS queries to Google DNS (not through Tor)
iptables -t nat -A PREROUTING -i enp0s3 -p udp --dport 53 -j DNAT --to-destination 8.8.8.8:53

# TCP: Redirect all other TCP traffic to Tor
iptables -t nat -A PREROUTING -i enp0s3 -p tcp -j REDIRECT --to-port 9040

# Optional: Allow ICMP (ping) for debugging
iptables -A INPUT -p icmp -j ACCEPT

# Log dropped packets for debugging (optional)
iptables -A INPUT -j LOG --log-prefix "INPUT_DROP: " --log-level 4

```

But I can’t browse anything. My Linux server can see the traffic:

```auto
# tcpdump -i enp0s3 -v src host 172.21.50.77
tcpdump: listening on enp0s3, link-type EN10MB (Ethernet), snapshot length 262144 bytes
06:48:26.177486 IP (tos 0x0, ttl 128, id 29909, offset 0, flags [none], proto UDP (17), length 56)
    172.21.50.77.54664 > 172.21.50.52.domain: 35298+ A? zone94.com. (28)
06:48:26.177546 IP (tos 0x0, ttl 127, id 29909, offset 0, flags [none], proto UDP (17), length 56)
    172.21.50.77.54664 > dns.google.domain: 35298+ A? zone94.com. (28)
06:48:27.079925 IP (tos 0x0, ttl 128, id 29910, offset 0, flags [none], proto UDP (17), length 76)
    172.21.50.77.50283 > 172.21.50.52.domain: 37312+ A? self.events.data.microsoft.com. (48)
06:48:27.080035 IP (tos 0x0, ttl 127, id 29910, offset 0, flags [none], proto UDP (17), length 76)
    172.21.50.77.50283 > dns.google.domain: 37312+ A? self.events.data.microsoft.com. (48)
06:48:27.180032 IP (tos 0x0, ttl 128, id 29911, offset 0, flags [none], proto UDP (17), length 56)
    172.21.50.77.54664 > 172.21.50.52.domain: 35298+ A? zone94.com. (28)
06:48:27.180077 IP (tos 0x0, ttl 127, id 29911, offset 0, flags [none], proto UDP (17), length 56)
    172.21.50.77.54664 > dns.google.domain: 35298+ A? zone94.com. (28)
06:48:28.187805 IP (tos 0x0, ttl 128, id 29912, offset 0, flags [none], proto UDP (17), length 56)
    172.21.50.77.54664 > 172.21.50.52.domain: 35298+ A? zone94.com. (28)
06:48:28.187856 IP (tos 0x0, ttl 127, id 29912, offset 0, flags [none], proto UDP (17), length 56)
    172.21.50.77.54664 > dns.google.domain: 35298+ A? zone94.com. (28)

```

What is wrong?

Thank you.

---

<div class="post-metadata">

### Author: ![lars-skuggi](https://forum.torproject.org/letter_avatar_proxy/v4/letter/l/8baadc/32.png) [@lars-skuggi](https://forum.torproject.org/u/lars-skuggi)
#### Post date: [May 12, 2026, 9:09am UTC](https://forum.torproject.org/t/how-to-create-a-tor-router/21573/2 "2026-05-12T09:09:28Z")

</div>

This won’t work as a general “route all traffic through Tor” gateway.

Tor’s `TransPort` can transparently handle TCP, but Tor is not a normal IP/VPN gateway. Tor transports TCP streams, not arbitrary IP packets like UDP, ICMP, QUIC, etc.

A Tor transparent gateway is possible, but only with carefully redirected TCP plus DNS-to-Tor for a controlled LAN/subnet. For most cases, a SOCKS proxy is simpler and safer.

---

<div class="post-metadata">

### Author: ![Netwarrior](https://forum.torproject.org/letter_avatar_proxy/v4/letter/n/49beb7/32.png) [@Netwarrior](https://forum.torproject.org/u/Netwarrior)
#### Post date: [May 12, 2026, 12:10pm UTC](https://forum.torproject.org/t/how-to-create-a-tor-router/21573/3 "2026-05-12T12:10:56Z")

</div>

I installed and ran nipe. I also changed the Tor configuration as follows:

```auto
SocksPort 127.0.0.1:9050
TransPort 127.0.0.1:9040
DNSPort 127.0.0.1:5353
AutomapHostsOnResolve 1
VirtualAddrNetworkIPv4 10.192.0.0/10

```

I configured dnsmasq as follows:

```auto
# Listen on your gateway IP
listen-address=127.0.0.1,172.21.50.52

# Bind to interface
bind-interfaces

# Forward DNS queries to Tor's DNSPort
server=127.0.0.1#5353

# Don't forward reverse lookups for local networks
no-negcache

# Log queries for debugging
log-queries

# Don't read /etc/resolv.conf
no-resolv

# Cache size
cache-size=1000

# Log queries for debugging
log-queries
log-facility=/var/log/dnsmasq.log

```

The resolv.conf file is as follows:

```auto
nameserver 127.0.0.1
options edns0

```

On Debian:

```auto
# nslookup google.com 172.21.50.52
Server: 172.21.50.52
Address:	172.21.50.52#53

Non-authoritative answer:
Name:	google.com
Address: 142.251.39.142
Name:	google.com
Address: 2a00:1450:400e:809::200e

```

But, from my client:

```auto
# tcpdump -i enp0s3 -n host 172.21.50.77 and port 53
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), snapshot length 262144 bytes
03:51:43.999793 IP 172.21.50.77.63645 > 172.21.50.52.53: 34385+ A? api.intelsa.intel.com. (39)
03:51:44.522355 IP 172.21.50.77.63646 > 172.21.50.52.53: 1+ PTR? 52.50.21.172.in-addr.arpa. (43)
03:51:46.530926 IP 172.21.50.77.63647 > 172.21.50.52.53: 2+ A? google.com.mydomain.com. (41)
03:51:48.532525 IP 172.21.50.77.63648 > 172.21.50.52.53: 3+ AAAA? google.com.mydomain.com. (41)
03:51:50.536529 IP 172.21.50.77.63649 > 172.21.50.52.53: 4+ A? google.com. (28)
03:51:52.542196 IP 172.21.50.77.63650 > 172.21.50.52.53: 5+ AAAA? google.com. (28)

```

Why?

---

<div class="post-metadata">

### Author: ![Netwarrior](https://forum.torproject.org/letter_avatar_proxy/v4/letter/n/49beb7/32.png) [@Netwarrior](https://forum.torproject.org/u/Netwarrior)
#### Post date: [May 12, 2026, 12:11pm UTC](https://forum.torproject.org/t/how-to-create-a-tor-router/21573/4 "2026-05-12T12:11:26Z")

</div>

Hello,

Do you understand my point? I want to use Linux as a Default Gateway but have traffic routed over the Tor network. Do you know of an article that teaches this?

---

<div class="post-metadata">

### Author: ![Protium\_serratum](https://forum.torproject.org/letter_avatar_proxy/v4/letter/p/eb8c5e/32.png) [@Protium\_serratum](https://forum.torproject.org/u/Protium_serratum)
#### Post date: [May 14, 2026, 1:00pm UTC](https://forum.torproject.org/t/how-to-create-a-tor-router/21573/5 "2026-05-14T13:00:23Z")

</div>

You can add two default routes in different routing tables, then configure the OS to use `uidrange` or something else to match the tor processes.

> **[ip-rule(8) — iproute2 — Debian trixie — Debian Manpages](https://manpages.debian.org/trixie/iproute2/ip-rule.8.en.html)**

> **uidrange** _NUMBER-NUMBER_  
> select the **uid** value to match.

---

<div class="post-metadata">

### Author: ![Netwarrior](https://forum.torproject.org/letter_avatar_proxy/v4/letter/n/49beb7/32.png) [@Netwarrior](https://forum.torproject.org/u/Netwarrior)
#### Post date: [May 18, 2026, 1:02pm UTC](https://forum.torproject.org/t/how-to-create-a-tor-router/21573/6 "2026-05-18T13:02:21Z")

</div>

Hello,

The `/etc/tor/torrc` is:

```auto
SocksPort 127.0.0.1:9050
TransPort 127.0.0.1:9040
DNSPort 127.0.0.1:5300
AutomapHostsOnResolve 1
VirtualAddrNetworkIPv4 10.192.0.0/10
TransListenAddress 0.0.0.0
DNSPort 0.0.0.0:5353

```

And I asked AI to modify the iptables rules to use `uidrange`:

```auto
#!/bin/bash

# =============================================
# FIXED TOR GATEWAY FOR YOUR SETUP
# =============================================

# Your actual interface (only one interface visible)
_OUT_IF="enp0s3" # Your only interface (WAN + LAN combined)

# Get the actual gateway
_MAIN_GW=$(ip route show default | awk '/default/ {print $3}')

# Get your LAN subnet (assuming 192.168.1.0/24 based on your iptables)
_LAN_NET="192.168.1.0/24"

# Tor settings
_TOR_UID=$(id -u debian-tor)
_TRANS_PORT="9040"
_DNS_PORT="5353"
_VIRT_ADDR="10.192.0.0/10"

echo "=== FIXING TOR GATEWAY SETUP ==="
echo "Main gateway: $_MAIN_GW"
echo "Tor UID: $_TOR_UID"
echo "Output interface: $_OUT_IF"

# =============================================
# 1. FIX POLICY ROUTING
# =============================================

# Remove existing rules
ip rule del uidrange $_TOR_UID-$_TOR_UID lookup tor_bypass 2>/dev/null
ip rule del priority 1000 2>/dev/null

# Flush routing tables
ip route flush table tor_bypass 2>/dev/null
ip route flush table tor_direct 2>/dev/null

# Recreate tor_bypass table (for Tor's own direct connections)
ip route add default via $_MAIN_GW dev $_OUT_IF table tor_bypass
ip route add $_LAN_NET dev $_OUT_IF table tor_bypass

# tor_direct table (for traffic going through Tor proxy)
ip route add default dev lo table tor_direct

# CRITICAL FIX: Allow Tor's own traffic to bypass Tor (use tor_bypass)
ip rule add uidrange $_TOR_UID-$_TOR_UID lookup tor_bypass priority 100

# All other traffic uses main table (which we'll redirect to Tor)
# Don't add extra rules that conflict

echo "Fixed routing rules:"
ip rule show
echo ""
echo "tor_bypass table:"
ip route show table tor_bypass
echo ""
echo "tor_direct table:"
ip route show table tor_direct

# =============================================
# 2. FIX IPTABLES - ADD MISSING NAT RULES
# =============================================

# Flush everything
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X

# Default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# =============================================
# NAT TABLE (THIS WAS MISSING!)
# =============================================

# Redirect DNS to Tor
iptables -t nat -A OUTPUT -d 127.0.0.1 -p udp --dport 53 -j REDIRECT --to-ports $_DNS_PORT

# Redirect virtual address range to Tor
iptables -t nat -A OUTPUT -d $_VIRT_ADDR -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports $_TRANS_PORT

# IMPORTANT: Don't redirect Tor's own traffic (using routing table, not iptables owner)
iptables -t nat -A OUTPUT -o lo -j RETURN

# Don't redirect LAN traffic
iptables -t nat -A OUTPUT -d $_LAN_NET -j RETURN

# Redirect all other TCP to Tor
iptables -t nat -A OUTPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports $_TRANS_PORT

# For Windows client (forwarded traffic)
iptables -t nat -A PREROUTING -i $_OUT_IF -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports $_TRANS_PORT
iptables -t nat -A PREROUTING -i $_OUT_IF -p udp --dport 53 -j REDIRECT --to-ports $_DNS_PORT

# =============================================
# FILTER TABLE - INPUT
# =============================================

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -s $_LAN_NET -p udp --dport $_DNS_PORT -j ACCEPT

# =============================================
# FILTER TABLE - FORWARD (for Windows client)
# =============================================

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $_OUT_IF -o $_OUT_IF -j ACCEPT

# =============================================
# FILTER TABLE - OUTPUT
# =============================================

iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT

# Allow Tor user to make direct connections (this works with policy routing)
iptables -A OUTPUT -o $_OUT_IF -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j ACCEPT

# Allow connections to Tor's proxy ports
iptables -A OUTPUT -d 127.0.0.1 -p tcp --dport $_TRANS_PORT -j ACCEPT
iptables -A OUTPUT -d 127.0.0.1 -p udp --dport $_DNS_PORT -j ACCEPT

# Allow SSH
iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

echo ""
echo "=== NAT TABLE RULES (now added) ==="
iptables -t nat -S

echo ""
echo "=== VERIFICATION ==="

# Test if Tor is working
if systemctl is-active --quiet tor; then
    echo "✓ Tor is running"
else
    echo "✗ Tor is NOT running - start with: systemctl start tor"
fi

# Test DNS through Tor
echo "Testing DNS through Tor..."
timeout 2 dig @127.0.0.1 -p $_DNS_PORT google.com +short

echo ""
echo "=== FIX COMPLETE ==="
echo "To test Tor: sudo -u debian-tor curl --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip"

```

I got the same result.

Can you tell me which part is wrong?

---

<div class="post-metadata">

### Author: ![Protium\_serratum](https://forum.torproject.org/letter_avatar_proxy/v4/letter/p/eb8c5e/32.png) [@Protium\_serratum](https://forum.torproject.org/u/Protium_serratum)
#### Post date: [June 1, 2026, 5:41pm UTC](https://forum.torproject.org/t/how-to-create-a-tor-router/21573/7 "2026-06-01T17:41:45Z")

</div>

Use LLMs to generate code which you can’t understand is very dangerous, please don’t do this.
