How configure nftables to make Tor working?

Hi,

I’ve a pretty tight nftables ruleset that block almost everything (good :slight_smile: )

unfortunately I can’t make Tor connect.

in my hook input I have

ct state established,related accept		

in my hook output I have

tcp dport { 9001, 9010} accept
ct state established,related accept

but this doesn’t help…

I have Tor output traffic that is still blocked

Dropped: IN= OUT=eth0 SRC=aMyIP DST=aIP LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=12288 DF PROTO=TCP SPT=51784 DPT=25565 WINDOW=64240 RES=0x00 SYN URGP=0

any ideas or documentation to make Tor works with a tight nftables ?

Thanks.

Use output rules based on user Tor is executed by. Since relays/bridges can use any port numbers for binding, it is insufficient to open few specific ports for output for being able to connect to any relay/bridge.

For example on Debian like OSes the user of the main Tor instance is debian-tor.
The following rules will allow outgoing traffic to any IP address/port combo, but only for this main instance of Tor (one for IPv4 and one for IPv6):

nft insert rule ip  filter OUTPUT ip protocol tcp skuid debian-tor counter accept
nft insert rule ip6 filter OUTPUT ip protocol tcp skuid debian-tor counter accept

Then use this debian-tor user only to execute Tor and for nothing else.
Each Tor instance should be run by its own separate user.

If you have more than one Tor instance running, the following command will add such rules for each running instance:

sh -c 'for uid in $(ps -o uid -q $(pidof tor -d,) --no-headers); do nft insert rule ip filter OUTPUT ip protocol tcp skuid $uid counter accept; nft insert rule ip6 filter OUTPUT ip protocol tcp skuid $uid counter accept; done'

You can verify that the rule(s) work(s) by observing the output of:

nft list chain ip  filter OUTPUT
nft list chain ip6 filter OUTPUT

Where you should see something like

... packets 1297 bytes 1680166 ...

which are the number of packets and bytes caught by your rule. So the rule works.

For input the rules can be as follows:

nft insert rule ip  filter INPUT tcp dport <PORT> skuid debian-tor counter accept
nft insert rule ip6 filter INPUT tcp dport <PORT> skuid debian-tor counter accept

or for multiple ports:

nft insert rule ip  filter INPUT tcp dport { <PORT>,<PORT>,<PORT>} skuid debian-tor counter accept
nft insert rule ip6 filter INPUT tcp dport { <PORT>,<PORT>,<PORT>} skuid debian-tor counter accept

Replace <PORT> with the port number(s) you specified in your torrc.

To verify the rules are working, observe the output of:

nft list chain ip  filter INPUT
nft list chain ip6 filter INPUT
1 Like

You could either use webtunne bridges or set the FascistFirewall to 1. Then tor only uses Ports 80/443. I guess those are already allowed in your nftables ruleset.

1 Like

Thank you very much @excurso !

I didn’t know about skuid in nftables !

Then use this debian-tor user only to execute Tor and for nothing else.

is runuser -u debian-tor -- tor works flawlessly with TOR ?


.

Replace <PORT> with the port number(s) you specified in your torrc.

if the torrc is In its original state(meaning nothing has been ~uncommented )
then just 9050 ?

It depends on how you are using tor.

If you use tor as client, then you need only the output rules.
If your setup is a relay or bridge, you need both the output and the input rules.
Since you didn’t change torrc, I assume you are using tor as client.

Yes, this or this one should do it:

sudo -u debian-tor tor

But if you installed tor from the Debian/Ubuntu or Tor Project’s repositories,
it’s better to let systemd start tor.

systemctl enable tor --now

This will ensure tor will start automatically on system start up.

As already mentioned the user of the default instance of tor is debian-tor in this case and you don’t need to change anything related to user.

You can check the user of all running tor instances by running this command:

sh -c 'ps -o pid,uid,uname -q $(pidof tor -d,)'

The process ID, the user ID and the user name will be shown.

If you want to see, what command started a tor process, use this:

sh -c 'ps -o pid,cmd -q $(pidof tor -d,)'

To see what ports tor processes are listening on:

sudo netstat -tulpn | grep tor | tr -s ' ' | cut -s -d' ' -f4,6,7

You’ll get something like this as output:

127.0.0.1:9150 LISTEN 2685/tor
127.0.0.1:9151 LISTEN 2685/tor
127.0.0.1:9050 LISTEN 1385/tor
127.0.0.1:9051 LISTEN 1385/tor

If tor is listening on loopback addresses only (127.0.0.0/8), you don’t need any input rules that allow connections from outside.

Thanks again @excurso , for your detailed answer :+1:

If you use tor as client, then you need only the output rules.
If your setup is a relay or bridge, you need both the output and the input rules.

To get a deepen knowledge of tor, I assume that HiddenService (aka Onion service) do not require to open income port ?

Thanks for your systemd example, but

I switched back to SystemVinit

systemd is an abomination regarding the GNU philosophy.
There are tons of articles about it. (on lemmy you might found more neutral or real debate about it)

For those that use SystemVinit, some Linux distribution have in their repository a sysvinit script that come when you install tor (thanks to them) .

Note that tor’s systemd config limits access to the file system.
It allows tor only to access few directories on the file system.

Extract from the tor@.service file:

# Hardening
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectHome=yes
ProtectSystem=full
ReadOnlyDirectories=/
# We would really like to restrict the next item to [..]/%i but we can't,
# as systemd does not support that yet.  See also #781730.
ReadWriteDirectories=-/var/lib/tor-instances
ReadWriteDirectories=-/run
CapabilityBoundingSet=CAP_SETUID CAP_SETGID CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH

I doubt SysV init is doing this. So using the old SysV stuff might be more insecure.
Since you care about security, as I see here, you shouldn’t use SysV.

Once again, thank you very much for your inputs @excurso.

Since you care about security, as I see here, you shouldn’t use SysV.

SysVinit is not at all insecure ! quite the opposite btw.
It’s just that Tor dev choose to support systemd exclusively… :confused:

SysVinit Vs systemd

systemd has also been criticized for its complexity and the large attack surface it presents. Some security experts argue that simpler init systems like sysvinit may be more secure, as they have fewer lines of code and therefore fewer potential vulnerabilities.

However, sysvinit lacks some of the advanced security features that systemd provides, such as support for encrypted filesystems and network connections.

The choice between sysvinit and systemd should be based on the specific needs and constraints of the system, rather than on security considerations alone.

For me, like systemd seem to spread all over the system, I choose back sysvinit.

QED

So now my nftables is not blocking anymore Tor
I let run Tor run for about 15min. and the only output i got in the terminal was

[notice] Read configuration file “/usr/share/tor/tor-service-defaults-torrc-edited”.
[notice] Read configuration file “/etc/tor/torrc”.
[notice] Opening Socks listener on /run/tor/socks
[notice] Opened Socks listener connection (ready) on /run/tor/socks
[notice] Opening Socks listener on 127.0.0.1:9050
[notice] Opened Socks listener connection (ready) on 127.0.0.1:9050
[notice] Opening Control listener on /run/tor/control
[notice] Opened Control listener connection (ready) on /run/tor/control

I’ve look into /var/log/tor/notices.log and I see a lot of

[debug] circuit_remove_handled_ports(): Port 443 is already being handled; removing

I’ve followed the connections trough netstat -natp and three TCP where connected all-along the process.

Any idea what prevent my to connect ?
(btw I can connect to Tor network with another windows :frowning: computer with tor-browser on the same LAN, without any problems)


just to be sure:

I assume that HiddenService (aka Onion service) do not require to open income port ?

No problem.

That’s what I mean. systemd can place a process into an isolated environment, where the process only gets access to what it requires.
How would you achieve this using a SysVInit script? That’s where SysVInit is insecure.

First you write

then you ask, what prevents it from connecting? :face_with_monocle:

Try to connect to the SOCKS port with torsocks in combination with wget and to fetch some website:

torsocks -a 127.0.0.1 -P 9050 wget -qO- https://torproject.org/

Do you read the docs?
https://community.torproject.org/onion-services/setup/

The HiddenServicePort line specifies a virtual port (that is, the port that people visiting your Onion Service will be using), and in the above case it says that any traffic incoming to port 80 of your Onion Service should be redirected to 127.0.0.1:80 (which is where the web server from step 1 is listening).

Tor acts as proxy here. I don’t have a hidden service, so didn’t test it, but the port will have to be reachable from outside. How else should people connect to your service?

Btw, if not already done, you’ll have to allow outgoing UDP traffic to port 53, else domain name resolution won’t work.

erratum:

You were right @excurso, I was indeed well connect the to Tor network

I was following the debug level of the log… and I didn’t saw pass the Bootstrapped 100% :shushing_face:

Tor acts as proxy here. I don’t have a hidden service, so didn’t test it, but the port will have to be reachable from outside. How else should people connect to your service?

FYI: I’ve read the opposite

you do not need to open a specific port to the outside world, as the traffic is encrypted and anonymized within the Tor network itself.

I will try anyway :slight_smile: and let you know.

This doesn’t make sense, because TCP is not encrypted. All above TCP is encrypted. You will have to allow incoming connections to your onion service port for the onion service to be reachable by exit routers.

any traffic incoming to port 80 of your Onion Service should be redirected to 127.0.0.1:80

How Onion Services Work

This means that connections from the client to the server never leave the Tor network. In contrast to running a Tor relay, running a Tor Onion Service does not result in your IP address being publicly listed anywhere, nor does your service relay other Tor traffic.

Ah, Ok, it seems to connect itself to somewhere. But then the question is why a port is being specified explicitly.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.