4 febbraio 2025
Il principale collo di bottiglia nei relay Tor è spesso la velocità di clock del processore, e siccome Tor non supporta il multithreading, solitamente la soluzione migliore è eseguire un’istanza di Tor per ogni core (o thread). Dato il costo dell’elettricità, stiamo cercando hardware che consumi e costi poco, ma che sia comunque in grado di saturare la banda. Gli apu2, sebbene non più in produzione, restano ottime macchine, usate da anni e con supporto stabile a coreboot. Il modello che stiamo testando ha queste specifiche:
Vogliamo individuare la configurazione che ottimizza al meglio le risorse, avendo a disposizione un’intera subnet IPv4 e 2.5 Gbit di banda in upload.
E’ disponibile un insieme di script molto pratico per gestire più processi Tor nello stesso sistema.
Prima di tutto, bisogna disabilitare il servizio Tor di default:
systemctl disable tor
systemctl stop tor
Creiamo quindi l’istanza desiderata:
tor-instance-create <name of the instance>
Tutte le configurazioni si trovano in /etc/tor/instances
e possono essere gestite come servizi di sistema separati.
systemctl start tor@<name of the instance>
systemctl enable tor@<name of the instance>
Abbiamo provato con 4 processi (uno per ogni core), ma a causa della poca RAM a disposizione, le singole istanze non superavano i 4 MB/s: il minimo di memoria necessaria per ciascuno sembra essere intorno a 400-500M. Abbiamo quindi cambiato configurazione e applicato alcune ottimizzazioni:
/etc/resolv.conf
In questo modo siamo riusciti ad abbassare l’utilizzo di memoria del sistema di base e a lasciare circa 1.6 GB di RAM liberi per le istanze Tor.
Su un’interfaccia di rete abbiamo assegnato 3 indirizzi IPv4 e 3 indirizzi IPv6 perché ne abbiamo disponibilità, ma spesso si usa lo stesso IP e si scelgono porte diverse (c’è tuttavia un limite imposto dalle directory authority sul numero di nodi che possono avere lo stesso IPv4, attualmente 8).
Abbiamo quindi la seguente interfaccia di rete:
5: enp2s0.835@enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:0d:b9:4a:bf:71 brd ff:ff:ff:ff:ff:ff
inet 64.190.76.2/24 brd 64.190.76.255 scope global enp2s0.835
valid_lft forever preferred_lft forever
inet 64.190.76.3/24 brd 64.190.76.255 scope global secondary enp2s0.835
valid_lft forever preferred_lft forever
inet 64.190.76.4/24 brd 64.190.76.255 scope global secondary enp2s0.835
valid_lft forever preferred_lft forever
inet6 2001:67c:e28:1::4/64 scope global
valid_lft forever preferred_lft forever
inet6 2001:67c:e28:1::3/64 scope global
valid_lft forever preferred_lft forever
inet6 2001:67c:e28:1::2/64 scope global
valid_lft forever preferred_lft forever
Tuttavia, dopo qualche settimana, ci contatta il Network Health Team perché hanno rilevato che i relays, pur avendo indirizzi IPv4 diversi, risultavano uscire tutti sullo stesso.
Nota: è fondamentale fornire informazioni di contatto accurate quando si gestiscono nodi Tor, proprio per questo motivo. Non è la prima volta che riceviamo avvisi o suggerimenti su come migliorare la nostra gestione.
Per cambiare l’IP sorgente di un processo Linux ci sono diverse soluzioni, tra cui:
iptables
systemd
iptables
Abbiamo scelto la terza opzione con shorewall per comodità. La configurazione si trova in /etc/shorewall
.
I file per configurare la mappatura dei processi rispetto agli indirizzi IP di uscita sono:
/etc/shorewall/mangle
: per marcare i pacchetti in uscita di uno UID/etc/shorewall/snat
: per mascherare i pacchetti marcati con gli indirizzi IP sceltiEcco un esempio di configurazione con cui i pacchetti dello UID tor-bludicapra
vengono marcati (2
) e viene effettuato il source NAT sull’interfaccia di uscita enp2s0.835
con IP 64.190.76.2
.
/etc/shorewall/mangle
#ACTION SOURCE DEST PROTO DPORT SPORT USER
MARK(2) $FW 0.0.0.0/0 - - - _tor-bludicapra
/etc/shorewall/snat
#ACTION SOURCE DEST PROTO DPORT SPORT IPSEC MARK
SNAT(64.190.76.2) - enp2s0.835 - - - - 2
Il prerequisito è che gli indirizzi di uscita siano configurati sull’interfaccia WAN (es. via /etc/network/interfaces
).
Altri file significativi di shorewall, che non richiedono modifiche per questa configurazione, sono, in ordine di elaborazione del filtro:
/etc/shorewall/interfaces
: per la configurazione delle interfacce filtrate/etc/shorewall/rules
: per le regole del firewall/etc/shorewall/policy
: per le policy globaliDopo ogni modifica si può verificare la configurazione e applicarla:
shorewall check
shorewall reload
Da questa esperienza è nata una piccola famiglia di formaggi italiani: