Sandbox and torify Signal messenger on Linux

Most of the popular Linux distributions don’t offer any sandboxing or anonymization capabilities and it can be quite difficult to find a good solution. In this post I’m going to describe how I manged to sandbox the messenger app Signal and tunnel all it’s traffic through the anonymization network Tor.

All the tool you need are already in the Archlinux repositories:
pacaur -S firejail tor signal
Firejail is a kind of wrapper around sandboxing capabilities of the Linux kernel. It ships with profiles for various applications, including a profile for Signal.

To launch Signal in a sandboxed environement, just prepend the command firejail like this:
firejail signal-desktop
If you try to share files with someone, you’ll notice that your local files aren’t available anymore to Signal. One of the few “shared” and real directories left is the Signal configuration directory in ~/.config/signal. All files in there will be preserved, even after you close the sandbox. As a lazy workaround I’ll temporarily move files into this directory if I want to share them via Signal.

To isolate the sandbox from your local network and tunnel all traffic through Tor is a bit more difficult. First of all, we have to create a virtual networking bridge with an own subnet:

Somehow assigning the IP with the systemd network profile was not successfull so I further used this service file to manually set the address:

Now start and enable the services to make these changes persistent:
systemctl start systemd-networkd bridge-set-addr
systemctl enable systemd-networkd bridge-set-addr

We also need to enable IP forwarding for the tornet network bridge:

In the Tor configuration, we have to enable the a local port to which we can route our internet traffic:

It is than useful to autostart Tor at boot time:
systemctl start tor
systemctl enable tor

Run following Iptable rules as root
iptables -P FORWARD DROP
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i tornet -o ${inet_interface} -p tcp -j ACCEPT
iptables -A FORWARD -i tornet -o ${inet_interface} -p udp --dport=53 -j ACCEPT
iptables -t nat -A POSTROUTING -s -o ${inet_interface} -j MASQUERADE
iptables -t nat -A PREROUTING -i tornet -p udp -m udp --dport 53 -j DNAT --to-destination
iptables -t nat -A PREROUTING -i tornet -p tcp -j DNAT --to-destination
iptables -A INPUT -i tornet -p tcp --dport 9040 -j ACCEPT
iptables -A INPUT -i tornet -p udp --dport 5353 -j ACCEPT

And save the routing table state to the main configuration file:
iptables-save > /etc/iptables/iptables.rules
systemctl start iptables
systemctl enable iptables

I also had to use the program ifplugd to prevent firejail from removing the IP address after closing the sandbox:
pacaur -S ifplugd
So ifplugd will always reassign an IP to the network bridge if you start the sandbox again:

Enable and start ifplugd:
systemctl start ifplugd@tornet
systemctl enable ifplugd@tornet

You can now run Signal sandboxed and in an isolated network where all traffic is going through Tor:
firejail --net=tornet signal-desktop
Signal won’t have any connection if the Tor daemon isn’t running or when Tor is blocked in your network. You can also use the program arm to check if all traffic is going through Tor.

I’m not entirely sure if DNS queries are also anonymized in this setup but according to the original how-to by kargig this should also be the case.

It is important to note that this setup just adds an extra layer of security and anonymity in using Signal. If you strongly rely on anonymity you should consider using Tails or SubgraphOS as pointed out by the security researcher x0rz. His blog post also explains how to register Signal with a fake mobile number to use it pseudonymously.

Leave a Reply

Your email address will not be published. Required fields are marked *

* Checkbox GDPR is required


I agree