Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

On a Linux system, is there a way to block all in and outbound traffic unless it passes through the Tor network. This includes any form of IP communication, not just TCP connections. For example I want UDP to be completely blocked since it cannot pass through Tor. I want this systems Internet usage to be entirely anonymous, and I don't want any applications leaking.

I realize this might be complicated because Tor itself needs to communicate with relay nodes somehow.

share|improve this question
I was just about to ask a similar question :) –  amyassin Oct 2 '12 at 11:55
For those of you casting close votes, I would like to remind you that there are valid business use cases for Tor. –  Michael Hampton Oct 8 '12 at 3:17
add comment

1 Answer

up vote 23 down vote accepted

Easy enough with iptables. It can have rules which match specific users, and you should have already set up tor to run under its own user ID; deb and rpm packages provided by major Linux distributions and the Tor Project set up a user for Tor already.

Complete sample, usable iptables and Tor configurations follow. This firewall can be loaded with the iptables-restore command. The end result of this configuration will transparently route all traffic originating from, or being forwarded through, the host to Tor, without needing to configure proxies. This configuration should be leak-proof; though you should of course test it thoroughly.

Note that the uid for the tor user (here, 998) is stored in numeric form by iptables. Substitute the correct uid for your tor user in each place that it appears here.

Note also that the IP address of the host needs to be given in the first rule to support incoming clearnet and LAN traffic addressed directly to the host (here shown as If you have multiple IP addresses, repeat the rule for each address.

-A PREROUTING -p udp -m udp --dport 53 -j REDIRECT --to-ports 53
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports 49151
-A OUTPUT -m owner --uid-owner 998 -j RETURN
-A OUTPUT -p udp -m udp --dport 53 -j REDIRECT --to-ports 53
-A OUTPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports 49151
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m conntrack --ctstate NEW -m tcp -d --dport 22 -j ACCEPT
-A INPUT -j LOG --log-prefix "IPv4 REJECT INPUT: "
-A FORWARD -j LOG --log-prefix "IPv4 REJECT FORWARD: "
-A OUTPUT -d -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -d -p tcp -m tcp --dport 49151 -j ACCEPT
-A OUTPUT -m owner --uid-owner 998 -m conntrack --ctstate NEW -j ACCEPT
-A OUTPUT -j LOG --log-prefix "IPv4 REJECT OUTPUT: "

The ssh INPUT rule only allows connections if they arrive via the local host, i.e. a Tor hidden service. If you also want to permit incoming ssh connections via clearnet, remove -d

The corresponding torrc file is:

User toranon
SOCKSPort 9050
DNSPort 53
TransPort 49151
AutomapHostsOnResolve 1

This configuration requires that the host have a static IP address. For the expected use cases, it's likely that you have already planned for it to have a static IP address.

And finally, the output!

[root@unknown ~]# curl ifconfig.me
[root@unknown ~]# host domain name pointer cronix.sk.
[root@unknown ~]# curl ifconfig.me
[root@unknown ~]# host domain name pointer marcuse-1.nos-oignons.net.
share|improve this answer
add comment

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.