{"id":2088,"date":"2016-12-12T18:36:38","date_gmt":"2016-12-12T16:36:38","guid":{"rendered":"http:\/\/www.void.gr\/kargig\/blog\/?p=2088"},"modified":"2017-01-02T17:48:18","modified_gmt":"2017-01-02T15:48:18","slug":"firejail-with-tor-howto","status":"publish","type":"post","link":"https:\/\/www.void.gr\/kargig\/blog\/2016\/12\/12\/firejail-with-tor-howto\/","title":{"rendered":"Firejail with Tor HOWTO"},"content":{"rendered":"<p>A few years ago I created a set of scripts to start applications inside a linux namespace and automatically &#8220;Tor-ify&#8221; their network traffic. The main reason behind this effort was to provide some isolation and Tor support for applications that don&#8217;t have socks5 support, for example claws-mail. While this worked it was hard to keep adding sandboxing features like the ones <a href=\"https:\/\/firejail.wordpress.com\/\" target=\"_blank\">firejail<\/a> already provided. So I decided to take a look at how I could automatically send\/receive traffic from a firejail-ed application through Tor.<\/p>\n<p>This blog post is <strong>NOT<\/strong> meant to be used as copy\/paste commands but to explain why each step is needed and how to overcome the problems found in the path.<br \/>\nIf you have reasons to proxy all your traffic through Tor as securely as possible use Tails on a different machine, this guide is <strong>NOT<\/strong> for you.<\/p>\n<p><strong>A dedicated bridge<\/strong><br \/>\nFirst of all create a Linux bridge and assign an IP address to it. Use this bridge to attach the <a href=\"https:\/\/lwn.net\/Articles\/232688\/\" target=\"_blank\">veth<\/a> interfaces that firejail creates when using the <em>&#8216;net&#8217;<\/em> option. This option creates a new network namespace for each sandboxed application.<br \/>\n<pre><code2># brctl addbr tornet\n# ip link set dev tornet up\n# ip addr add 10.100.100.1\/24 dev tornet<\/code2><\/pre><\/p>\n<p><strong>NAT<\/strong><br \/>\nThen enable NAT from\/to your &#8220;external&#8221; interface (eno1 in my case) for tcp connections and udp port 53 (DNS) and enable IP(v4) forwarding, if you don&#8217;t already use it. Some rules about sane default policy for FORWARD chain are added here well, modify to your needs.<br \/>\n<pre><code2># sysctl -w net.ipv4.conf.all.forwarding=1\n# iptables -P FORWARD DROP\n# iptables -A INPUT -m state --state INVALID -j DROP\n# iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n# iptables -A FORWARD -i tornet -o eno1 -p tcp -j ACCEPT\n# iptables -A FORWARD -i tornet -o eno1 -p udp --dport=53 -j ACCEPT\n# iptables -t nat -A POSTROUTING -s 10.100.100.0\/24 -o eno1 -j MASQUERADE<\/code2><\/pre><\/p>\n<p>This configuration is enough to start a sandboxed application that will have it&#8217;s traffic NAT-ed from the Linux host.<br \/>\n<pre><code2>$ firejail --net=tornet \/bin\/bash\nParent pid 26730, child pid 26731\n\nInterface&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MAC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mask&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Status\nlo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;127.0.0.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;255.0.0.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UP&nbsp;&nbsp;&nbsp;&nbsp;\neth0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 72:cc:f6:d8:6a:09&nbsp;&nbsp;10.100.100.29&nbsp;&nbsp;&nbsp;&nbsp;255.255.255.0&nbsp;&nbsp;&nbsp;&nbsp;UP&nbsp;&nbsp;&nbsp;&nbsp;\nDefault gateway 10.100.100.1\n\n$ host www.debian.org\nwww.debian.org has address 5.153.231.4\nHost www.debian.org not found: 3(NXDOMAIN)\nHost www.debian.org not found: 4(NOTIMP)\n$ host whoami.akamai.net\nwhoami.akamai.net has address 83.235.72.202\n$ curl wtfismyip.com\/text\n3.4.5.6\n<\/code2><\/pre><br \/>\n(where 3.4.5.6 is your real IP and 83.235.72.202 should be the IP address of the final DNS recursive resolver requesting information from whois.akamai.net)<\/p>\n<p>So NAT works and the shell is sandboxed.<\/p>\n<p><strong>&#8220;Tor-ify&#8221; traffic<\/strong><br \/>\nEdit \/etc\/tor\/torrc and enable <em>TransPort<\/em> and <em>VirtualAddrNetwork<\/em> Tor features to transparently proxy to the Tor network connections landing on Tor daemon&#8217;s port 9040. <em>DNSPort<\/em> is used to resolve DNS queries through the Tor network. You don&#8217;t have to use <em>IsolateDestAddr<\/em> for your setup, but I like it.<br \/>\n<pre><code2>TransPort 9040\nVirtualAddrNetwork 172.30.0.0\/16\nDNSPort 5353 IsolateDestAddr\n<\/code2><\/pre><\/p>\n<p>Then use iptables to redirect traffic from tornet bridge to <em>TransPort<\/em> and <em>DNSPort<\/em> specified in torrc. You also need to ACCEPT that traffic in your INPUT chain if your policy is DROP (it is right ?)<br \/>\n<pre><code2># iptables -t nat -A PREROUTING -i tornet -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.1:5353\n# iptables -t nat -A PREROUTING -i tornet -p tcp -j DNAT --to-destination 127.0.0.1:9040\n# iptables -A INPUT -i tornet -p tcp --dport 9040 -j ACCEPT\n# iptables -A INPUT -i tornet -p udp --dport 5353 -j ACCEPT\n<\/code2><\/pre><\/p>\n<p>Run your sandbox again and try to access the same website:<br \/>\n<pre><code2>$ firejail --net=tornet \/bin\/bash\n$ curl wtfismyip.com\/text\ncurl: (7) Failed to connect to wtfismyip.com port 80: Connection timed out\n<\/code2><\/pre><br \/>\naaaand nothing happens. The problem is that you have tried to route traffic from a &#8220;normal&#8221; interface to loopback which is considered a &#8220;martian&#8221; and is not allowed by default by the Linux kernel.<\/p>\n<p><strong>sysctl magic<\/strong><br \/>\nTo enable loopback to be used for routing the <a href=\"https:\/\/www.kernel.org\/doc\/Documentation\/networking\/ip-sysctl.txt\" target=\"_blank\">route_localnet<\/a> sysctl setting must be set.<br \/>\n<code># sysctl -w net.ipv4.conf.tornet.route_localnet=1<\/code><\/p>\n<p>Try again:<br \/>\n<pre><code2>$ firejail --net=tornet \/bin\/bash\n$ host whoami.akamai.net\nwhoami.akamai.net has address 74.125.181.10\nHost whoami.akamai.net not found: 3(NXDOMAIN)\nHost whoami.akamai.net not found: 4(NOTIMP)\n$ curl wtfismyip.com\/text\n176.10.104.243\n$ host 176.10.104.243\n243.104.10.176.in-addr.arpa domain name pointer tor2e1.digitale-gesellschaft.ch.\n<\/code2><\/pre><\/p>\n<p>it works!<\/p>\n<p>You can actually run any program you want like that:<br \/>\n<code>$ firejail --net=tornet google-chrome<\/code><\/p>\n<p><strong>Accessing onion services<\/strong><br \/>\nThere&#8217;s one problem left though, accessing onion services.<br \/>\nIf you try and access www.debian.org onion service from your firejail+tor setup you will get an error.<br \/>\n<pre><code2>$ firejail --net=tornet \/bin\/bash\n$ curl http:\/\/sejnfjrq6szgca7v.onion\/\ncurl: (6) Could not resolve host: sejnfjrq6szgca7v.onion<\/code2><\/pre><\/p>\n<p>To fix that you need to modify \/etc\/tor\/torrc again and add <em>AutomapHostsOnResolve<\/em> option.<br \/>\n<code>AutomapHostsOnResolve 1<\/code><\/p>\n<p><pre><code2>$ firejail --net=tornet \/bin\/bash\n$ curl -I http:\/\/sejnfjrq6szgca7v.onion\/\nHTTP\/1.1 200 OK\nDate: Fri, 09 Dec 2016 12:05:56 GMT\nServer: Apache\nContent-Location: index.en.html\nVary: negotiate,accept-language,Accept-Encoding\nTCN: choice\nLast-Modified: Thu, 08 Dec 2016 15:42:34 GMT\nETag: &quot;3a40-543277c74dd5b&quot;\nAccept-Ranges: bytes\nContent-Length: 14912\nCache-Control: max-age=86400\nExpires: Sat, 10 Dec 2016 12:05:56 GMT\nX-Clacks-Overhead: GNU Terry Pratchett\nContent-Type: text\/html\nContent-Language: en\n<\/code2><\/pre><\/p>\n<p>Accessing onion services works as well now.<\/p>\n<p><strong>Applications supporting socks5<\/strong><br \/>\nIf you already have some of your applications proxying connections to tor using 127.0.0.1:9050 then you need to add another iptables rule to redirect the socks traffic from inside firejail&#8217;s namespace to Tor SocksPort.<br \/>\n<code># iptables -t nat -A PREROUTING -i tornet -p tcp -m tcp --dport 9050 -j DNAT --to-destination 127.0.0.1:9050<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few years ago I created a set of scripts to start applications inside a linux namespace and automatically &#8220;Tor-ify&#8221; their network traffic. The main reason behind this effort was to provide some isolation and Tor support for applications that don&#8217;t have socks5 support, for example claws-mail. While this worked it was hard to keep [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ep_exclude_from_search":false,"footnotes":""},"categories":[5,3,8,4],"tags":[33,620,328,595,599,87,474],"class_list":["post-2088","post","type-post","status-publish","format-standard","hentry","category-internet","category-linux","category-networking","category-privacy","tag-debian","tag-firejail","tag-iptables","tag-linux","tag-networking","tag-sandbox","tag-tor"],"aioseo_notices":[],"views":45654,"_links":{"self":[{"href":"https:\/\/www.void.gr\/kargig\/blog\/wp-json\/wp\/v2\/posts\/2088","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.void.gr\/kargig\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.void.gr\/kargig\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.void.gr\/kargig\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.void.gr\/kargig\/blog\/wp-json\/wp\/v2\/comments?post=2088"}],"version-history":[{"count":13,"href":"https:\/\/www.void.gr\/kargig\/blog\/wp-json\/wp\/v2\/posts\/2088\/revisions"}],"predecessor-version":[{"id":2103,"href":"https:\/\/www.void.gr\/kargig\/blog\/wp-json\/wp\/v2\/posts\/2088\/revisions\/2103"}],"wp:attachment":[{"href":"https:\/\/www.void.gr\/kargig\/blog\/wp-json\/wp\/v2\/media?parent=2088"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.void.gr\/kargig\/blog\/wp-json\/wp\/v2\/categories?post=2088"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.void.gr\/kargig\/blog\/wp-json\/wp\/v2\/tags?post=2088"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}