Measuring a Tor Hidden Service's idle Traffic

A month ago, I wondered myself how much traffic an idle hidden service would consume just to keep the necessary circuits open. To answer this question, I set up a Tor node and some iptables rules on my raspberry pi and waited for 30 days. Here are the results.

Introduction

A Tor Hidden Service is a TCP network service which is only reachable from within the Tor network using the correct public key (the v3 onion address assigned to the Hidden Service). Since the tor node running the service connects to the Tor network through its circuits, a HS can be used to connect to servers behind firewalls, NATs or no public facing IP address.

I asked myself if I could use the Tor network as a poor man's VPN replacement to make one of my servers accessible without a centralized VPN server. My situation would require runing the HS off a mobile connection (3G or 4G), so I was curious how much traffic keeping a HS alive was needed.

Setup

I used a raspberry pi running at home and compiled tor from source, after creating a dedicated tor user.

The default configuration was used, except for SOCKSPort 0 and the path adjustments for the log file or hidden service related files:

tor@raspberrypi:~/time-log $ cat ~/etc/tor/torrc | grep -Pv '^#' | awk 'NF'
SOCKSPort 0 # Default: Bind to localhost:9050 for local connections.
Log notice file /home/tor/var/log/tor/notices.log
RunAsDaemon 1
DataDirectory /home/tor/var/lib/tor
ControlPort 9051
CookieAuthentication 1
HiddenServiceDir /home/tor/var/lib/tor/ssh_service/
HiddenServicePort 22 127.0.0.1:22 

Before I launched the tor daemon, I configured my iptables firewall to log the network traffic as well. Just two rules are needed to achieve that in a rudimentary manner:

*filter
:INPUT DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i eth0 -m connmark --mark 0x539
-A OUTPUT -o eth0 -m owner --uid-owner 1002 -j CONNMARK --set-xmark 0x539/0xffffffff 

We use the owner module to match all outgoing traffic for our tor user (uid = 1002) and mark those packets with 1337 in the OUTPUT chain. The firstmost rule in the INPUT chain matches incoming packets which were marked with 1337 and are therefore related to the outgoing connection.

Using a simple loop and a grep for the 0x539 mark in the output of iptables -L -vn, we log the traffic into files every single minute.

Finally, we start the tor daemon and wait 30 days. We never initiate a connection to the Hidden Service. We simply let tor keep the circuits alive to measure the minimum required traffic. Please also note that this tor node is not configured to be a relay or exit node.

Results

Lucky for us, the tor process is so kind to tell us about its traffic usage every 6 hours:

Nov 17 15:43:30.000 [notice] Heartbeat: Tor's uptime is 30 days 0:00 hours, with 9 circuits open. I've sent 292.22 MB and received 302.72 MB.
Nov 17 15:43:30.000 [notice] While bootstrapping, fetched this many bytes:
Nov 17 15:43:30.000 [notice]     622032 (consensus network-status fetch)
Nov 17 15:43:30.000 [notice]     13117 (authority cert fetch)
Nov 17 15:43:30.000 [notice]     2647704 (microdescriptor fetch)
Nov 17 15:43:30.000 [notice] While not bootstrapping, fetched this many bytes:
Nov 17 15:43:30.000 [notice]     25158221 (consensus network-status fetch)
Nov 17 15:43:30.000 [notice]     2025 (authority cert fetch)
Nov 17 15:43:30.000 [notice]     3345814 (microdescriptor fetch)
Nov 17 15:43:30.000 [notice] Our onion service received 0 v2 and 0 v3 INTRODUCE2 cells and attempted to launch 0 rendezvous circuits.    

As we can see, its traffic sums up to 594.94 MB.

Iptables reports different numbers, though:

tor@raspberrypi:~/time-log $ cat 2020-11-17\ 15-44.traffic.log 
 847K  362M            all  --  eth0   *       0.0.0.0/0            0.0.0.0/0            connmark match  0x539
 857K  352M CONNMARK   all  --  *      eth0    0.0.0.0/0            0.0.0.0/0            owner UID match 1002 CONNMARK set 0x539

The first column is packets counted and the second the traffic amount. We can see that iptables sums up to 714M bytes. Even if we assume a difference in SI (1 MB = 1000^2 = 1,000,000 bytes) vs. binary (1 MB = 1024^2 = 1,048,576 bytes) notation, the numbers do not come close at all.

Here are a few theories why that could be:

  • Tor only counts data (i.e. packet's payload), but iptables counts the whole packet.
  • Tor only counts circuit related data, but iptables also captures other traffic, i.e. DNS requests.
  • Something else? Let me know and I'm happy to update the post

Maybe it would have been a good idea to run tcpdump and capture the marked packets and calculate the traffic amount from the pcap. As I didn't think of that, this is left to the reader to replicate and report :-)

Nonetheless, to answer the initial question: A good estimate of operating an idle Tor Hidden Service is around 600 - 700 MB of traffic per month.

-=-