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:

Kind=bridge

[Match]
Name=tornet

[Network]
Address=10.100.100.1/24

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

[Service]
Type=oneshot
ExecStart=/bin/ip addr replace 10.100.100.1/24 dev tornet

[Install]
WantedBy=sys-subsystem-net-devices-tornet.device

Now start and enable the services to make these changes persistent:

systemctl enable --now systemd-networkd bridge-set-addr

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

net.ipv4.conf.all.forwarding=1
net.ipv4.conf.tornet.route_localnet=1

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

Log notice file /var/log/tor/notices.log
#AutomapHostsSuffixes .onion,.exit
#AutomapHostsOnResolve 1
TransPort 9040
VirtualAddrNetworkIPv4 172.30.0.0/16
DNSPort 5353 IsolateDestAddr
ControlPort 9051
DataDirectory /var/lib/tor

It is than useful to autostart Tor at boot time:

systemctl enable --now tor

Run following Iptable rules as root

inet_interface=wlp3s0
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 10.100.100.0/24 -o ${inet_interface} -j MASQUERADE
iptables -t nat -A PREROUTING -i tornet -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.1:5353
iptables -t nat -A PREROUTING -i tornet -p tcp -j DNAT --to-destination 127.0.0.1:9040
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 enable --now 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:

INTERFACES="tornet"
ARGS="--no-beep -fwI -u0 -d0"
#!/bin/sh
ifname="$1"
action="$2"

case "$action.$ifname" in
up.tornet)
	ip addr replace 10.100.100.1/24 dev tornet
	;;
down.tornet)
	ip addr replace 10.100.100.1/24 dev tornet
	;;
esac

Enable and start ifplugd:

systemctl enable --now 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.

No Comments

Leave a Reply

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

* Checkbox GDPR is required

*

I agree

Software
Virtual 3D online exhibition with MapBox GL JS

For my last semester in university (summer semester 2018) at the KIT, I was part of a project to create an “online art exhibition”. We planned to produce different media formats in smaller groups. One for video, another for text and promotion and one for the online presence. I’ve figured …

Software
Host your own Mapbox GL JS vector tiles map

I’ve done some research recently on how I could host my own online map viewer with a MapBox GL JS instance, an excellent and modern open-source alternative for Google Maps. The server should also serve own preprocessed map data from OpenStreetmap planet extracts. No external or third-party service will be …

Software
1
Easily setup Signal 2FA on Nextcloud 14

Two-factor authentication (short 2FA) is an important security concept to secure unauthorized access to your web applications. Popular online services like Google Mail, Instagram or Facebook already provide this mechanism to secure user accounts with an additional one-time token. Considering someone is able to obtain your username and password combination, …