[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

How to Run High Capacity Tor Relays



After talking to Moritz and Olaf privately and asking them about their
nodes, and after running some experiments with some high capacity
relays, I've begun to realize that running a fast Tor relay is a
pretty black art, with a lot of ad-hoc practice. Only a few people
know how to do it, and if you just use Linux and Tor out of the box,
your relay will likely underperform on 100Mbit links and above.

In the interest of trying to help grow and distribute the network, my
ultimate plan is to try to collect all of this lore, use Science to
divine out what actually matters, and then write a more succinct blog
post about it.

However, that is a lot of work. It's also not totally necessary to do
all this work, when you can get a pretty good setup with a rough
superset of all of the ad-hoc voodoo. This post is thus about that
voodoo.

Hopefully others will spring forth from the darkness to dump their own
voodoo in this thread, as I suspect there is one hell of a lot of it
out there, some (much?) of which I don't yet know. Likewise, if any
blasphemous heretic wishes to apply Science to this voodoo, they
should yell out, "Stand Back, I'm Doing Science!" (at home please, not
on this list) and run some experiments to try to eliminate options
that are useless to Tor performance. Or cite academic research papers.
(But that's not Science, that's computerscience - which is a religion
like voodoo, but with cathedrals).

Anyway, on with the draft:


== Machine Specs ==

First, you want to run your OS in x64 mode because openssl should do
crypto faster in 64bit.  

Tor is currently not fully multithreaded, and tends not to benefit
beyond 2 cores per process. Even then, the benefit is still marginal
beyond just 1 core. 64bit Tor nodes require about one 2Ghz Xeon/Core2
core per 100Mbit of capacity.

Thus, to fill an 800Mbit link, you need at least a dual socket, quad
core cpu config.  You may be able to squeeze a full gigabit out of one
of these machines. As far as I know, no one has ever done this with
Tor, on any one machine.

The i7's also just came out in this form factor, and can do
hyperthreading (previous models may list 'ht' in cpuinfo, but actually
don't support it). This should give you a decent bonus if you set
NumCPUs to 2, since ht tends to work better with pure integer math
(like crypto). We have not benchmarked this config yet though, but I
suspect it should fill a gigabit link fairly easily, possibly
approaching 2Gbit.

At full capacity, exit node Tor processes running at this rate consume
about 500M of ram. You want to ensure your ram speed is sufficient,
but most newish hardware is good. Using on this chart:
https://secure.wikimedia.org/wikipedia/en/wiki/List_of_device_bandwidths#Memory_Interconnect.2FRAM_buses
you can do the math and see that with a dozen memcpys in each
direction, you come out needing DDR2 to be able to push 1Gbit full
duplex.

As far as ethernet cards, the Intel e1000e *should* be theoretically
good, but they seem to fail at properly irq balancing across multiple
CPUs on recent kernels, which can cause you to bottleneck at 100% CPU
on one core. At least that has been Moritz's experience. In our
experiments, the RTL-8169 works fine (once tweaked, see below).


== System Tweakscript Wibbles and Config Splatters ==

First, you want to ensure that you run no more than 2 Tor instances
per IP. Any more than this and clients will ignore them.

Next, paste the following smattering into the shell (or just read it
and make your own script):

# Set the hard limit of open file descriptors really high.
# Tor will also potentially run out of ports.
ulimit -SHn 65000

# Set the txqueuelen high, to prevent premature drops
ifconfig eth0 txqueuelen 20000

# Tell our ethernet card (interrupt found from /proc/interrupts)
# to balance its IRQs across one whole CPU socket (4 cpus, mask 0f).
# You only want one socket for optimal ISR and buffer caching.
#
# Note that e1000e does NOT seem to obey this, but RTL-8169 will.
echo 0f > /proc/irq/17/smp_affinity

# Make sure you have auxiliary nameservers. I've seen many ISP
# nameservers fall over under load from fast tor nodes, both on our
# nodes and from scans. Or run caching named and closely monitor it.
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
echo "nameserver 4.2.2.2" >> /etc/resolv.conf

# Load an amalgam of gigabit-tuning sysctls from:
# http://datatag.web.cern.ch/datatag/howto/tcp.html
# http://fasterdata.es.net/TCP-tuning/linux.html
# http://www.acc.umu.se/~maswan/linux-netperf.txt
# http://www.psc.edu/networking/projects/tcptune/#Linux
# and elsewhere...
# We have no idea which of these are needed yet for our actual use
# case, but they do help (especially the nf-contrack ones):
sysctl -p << EOF
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.netdev_max_backlog = 2500
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_moderate_rcvbuf = 1
net.core.rmem_max = 1048575
net.core.wmem_max = 1048575
net.ipv4.ip_local_port_range = 1025 61000
net.ipv4.tcp_synack_retries = 3
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_max_syn_backlog = 10240
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.netfilter.nf_conntrack_tcp_timeout_established=7200
net.netfilter.nf_conntrack_checksum=0
net.netfilter.nf_conntrack_max=131072
net.netfilter.nf_conntrack_tcp_timeout_syn_sent=15
net.ipv4.tcp_keepalive_time=60
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.ip_local_port_range = 1025 65530
net.core.netdev_max_backlog=300000
net.core.somaxconn=20480
net.ipv4.tcp_max_tw_buckets=2000000
net.ipv4.tcp_timestamps=0
vm.min_free_kbytes = 65536
net.ipv4.ip_forward=1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 2
net.ipv4.conf.default.forwarding=1
net.ipv4.conf.default.proxy_arp = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.send_redirects = 1
net.ipv4.conf.all.send_redirects = 0
EOF

# XXX: ethtool wibbles 

# You may also have to tweak some parameters with ethtool, possibly
# also enabling some checksum offloading or irq coalescing options to
# spare CPU, but for us this hasn't been needed yet.


== Setting up the Torrc ==

Basically you can just read through the stock example torrc, but there
are some as-yet undocumented magic options, and options that need new
defaults.

# NumCPUs doesn't provide any benefit beyond 2, and setting it higher
# may cause cache misses.
NumCPUs 2

# These options have archaic maximums of 2-5Mbyte
BandwidthRate 100 MB
BandwidthBurst 200 MB


== Waiting for the Bootstrap and Measurement Process ==

Perhaps the most frustrating part of this setup is how long it takes
for you to acquire traffic. If you are starting new at an ISP, I would
consider only 200-400Mbit for your first month. Hitting that by the
end of the month may be a challenge, mostly because their may be dips
and total setbacks along the way.

The slow rampup is primarily due to limitations in Tor's ability to
rapidly publish descriptor updates, and to measure relays.

It ends up taking about 2-3 days to hit an observed bandwidth of
2Mbyte/sec per relay, but it can take well over a week or more (Moritz, do
you have a better number?) to reach 8-9Mbyte/relay. This is for an
Exit node. A middle node will likely gather traffic slower. Also once
you crash, you lose it. This bug is about that issue:
https://trac.torproject.org/projects/tor/ticket/1863

There is also a potential dip when you get the Guard flag, as our load
balancing formulas try to avoid you, but no clients have chosen you
yet. Changes to the authority voting on Guards in Tor 0.2.2.15 should
make this less drastic. It is also possible that your observed
bandwidth will be greater than without it. However, it will still take
up to 2 months for clients to choose you as their new Guard. 


== Running temporary auxiliary nodes ==

One way to shortcut this process and avoid paying for bandwidth you
don't use is to spin up a bunch of temporary nodes to utilize the CPU
and quickly gather that easy first 2MB/sec of observed bandwidth.

But you need the spare IPs to do this.


== Monitoring ==

Personally, I prefer console-based options like nload, top, and
Damian's arm (http://www.atagar.com/arm/) because I don't like the
idea of running extra services to publish my monitoring data to the
world.

Other people have web-based monitoring using things like munin and
mrtg. It would be nice to get a script/howto for that too.


== Current 1-Box Capacity Record == 

Our setup has topped at 450Mbit, but averages between 300-400Mbit. We
are currently having uptime issues due to heat (melting, poorly
ventilated harddrives). It is likely that once we resolve this, we
will continually increase to our CPU ceiling.

I believe Moritz and Olaf also push this much capacity, possibly a bit
more, but with less nodes (4 as opposed to our 8). I hear Jake is also
ramping up some Guard nodes (or maybe I didn't? Did I just betray you
again Jake?)


== Did I leave anything out? ==

Well, did I?


-- 
Mike Perry
Mad Computer Scientist
fscked.org evil labs

Attachment: pgpTC6ZqKBX5Z.pgp
Description: PGP signature