Das Böse Büro

Le etichette sono il contrario del pensiero.

E' possibile farsi una darknet “privata”?

Avendo fatto partire una diatriba tecnologica intorno alla vicenda di Autistici/Inventati, non dovrebbe stupirmi che, prima o poi, sia saltata fuori una domanda piuttosto strana. Sì, Tor va bene, ma ha un problema evidente: è fin troppo facile che qualcuno vi associ automaticamente a qualsiasi genere di attività sospetta solo perché lo usate. I2P è interessante, tecnicamente anche molto elegante, ma appena volete usarlo per costruire qualcosa di stabile la gestione dei tunnel può diventare un piccolo delirio operativo. Quindi la domanda è stata: come faccio ad avere una rete privata, sempre in piedi, destinata al mio piccolo gruppo, alla mia associazione o alla mia organizzazione? In pratica: come mi costruisco una mia piccola fetta di darknet?


Che ci crediate o meno, per un sysadmin minimamente decente non è un'operazione particolarmente difficile.

Benvenuti in una rete mesh chiamata Yggdrasil.

Yggdrasil è una rete mesh overlay IPv6 cifrata: ogni nodo riceve un proprio indirizzo IPv6 e può comunicare con gli altri nodi passando, quando serve, attraverso altri peer.

Non esiste un server centrale. Ogni macchina conosce uno o più peer Yggdrasil, e da questi collegamenti nasce automaticamente il grafo della rete e il relativo routing.

Se configurate soltanto i vostri peer, ottenete una mesh privata tra le vostre macchine. Se invece vi collegate anche a peer pubblici, entrate nella rete Yggdrasil pubblica.

Non è Tor: non nasce per anonimizzarvi, ma per creare connettività cifrata, distribuita e resiliente tra nodi.

Siccome non state commettendo crimini, ma volete semplicemente sottrarvi alla dipendenza dai registrar, dal DNS e dalle varie autorità che possono intervenire su quella catena, dovrebbe essere sufficiente. Se invece vi serve anche l'anonimato, allora dovrete guardare a qualcosa come I2P, che personalmente considero ormai molto più macchinoso di quanto valga. Tor, invece, io non lo userei nemmeno a morire se il problema fosse evitare qualcosa di simile a quanto accaduto ad Autistici/Inventati.

Non perché Tor “non funzioni”. Il problema è un altro.

L'onion routing nasce negli anni Novanta nei laboratori dello U.S. Naval Research Laboratory, cioè all'interno della Marina militare americana; Tor deriva direttamente da quella linea di ricerca. Questo non è complottismo: lo racconta tranquillamente lo stesso Tor Project nella propria storia ufficiale.

Successivamente Tor è diventato un progetto open source e il Tor Project un'organizzazione indipendente, ma il rapporto economico con il governo statunitense non è esattamente marginale. Nell'esercizio fiscale 2023-2024, per esempio, circa il 35% delle entrate del Tor Project proveniva dal governo degli Stati Uniti; nel 2021-2022 era addirittura il 53,5%. Il Tor Project stesso pubblica questi numeri e dichiara esplicitamente di voler ridurre nel tempo questa dipendenza.

E se il mio problema specifico fosse proprio costruire un'infrastruttura che non dipenda, politicamente o amministrativamente, dagli Stati Uniti, diciamo che questo sarebbe sufficiente a farmi cercare altrove.



Ma diciamo che vogliamo usare Yggdrasil. Allora ci servono alcuni amici smanettoni, o comunque dei sysadmin decenti, e diciamo tre VPC distribuite su cloud europei. Volendo possono anche essere tre macchine a casa: il punto è semplicemente avere tre nodi abbastanza stabili, possibilmente su reti diverse. Su ciascuno installiamo Linux e Yggdrasil. Diciamo che usiamo Debian. I comandi sono questi:

sudo apt-get update
sudo apt-get install -y dirmngr gnupg

sudo mkdir -p /usr/local/apt-keys

gpg --fetch-keys \
https://neilalexander.s3.dualstack.eu-west-2.amazonaws.com/deb/key.txt

gpg --export 1C5162E133015D81A811239D1840CDAC6011C5EA \
| sudo tee /usr/local/apt-keys/yggdrasil-keyring.gpg >/dev/null

echo 'deb [signed-by=/usr/local/apt-keys/yggdrasil-keyring.gpg] https://neilalexander.s3.dualstack.eu-west-2.amazonaws.com/deb/ debian yggdrasil' \
| sudo tee /etc/apt/sources.list.d/yggdrasil.list

sudo apt-get update
sudo apt-get install -y yggdrasil

sudo systemctl enable --now yggdrasil

A questo punto Yggdrasil ha già creato la sua configurazione in:

/etc/yggdrasil.conf

e il demone è attivo. Potete verificarlo con:

systemctl status yggdrasil

e vedere l'indirizzo IPv6 Yggdrasil assegnato alla macchina con:

ip addr

Da qui in poi comincia la parte interessante: fare in modo che i tre nodi si conoscano fra loro e diventino l'ossatura della nostra piccola rete.




Il vostro indirizzo IPv6 Yggdrasil viene derivato dalla vostra chiave pubblica crittografica. Finché conservate la stessa coppia di chiavi, quindi, conserverete anche lo stesso indirizzo. La probabilità che due normali indirizzi Yggdrasil /128 collidano accidentalmente è talmente bassa da poterla, per i nostri scopi, considerare irrilevante. Adesso però ricordate una cosa: Yggdrasil cifra il traffico, ma non è un firewall. Se una porta è aperta sull'interfaccia Yggdrasil, chi può raggiungere il vostro nodo può tentare di collegarcisi. La documentazione stessa raccomanda quindi esplicitamente di usare un firewall IPv6. Diciamo che l'interfaccia si chiami ygg0 e che, per il momento, vogliamo accettare soltanto SSH sulla porta 22.

Con nftables possiamo fare, per esempio:

sudo nft add table inet yggdrasil
sudo nft 'add chain inet yggdrasil input { type filter hook input priority 0; policy accept; }'

sudo nft add rule inet yggdrasil input iifname "ygg0" ct state established,related accept
sudo nft add rule inet yggdrasil input iifname "ygg0" tcp dport 22 accept
sudo nft add rule inet yggdrasil input iifname "ygg0" drop

A questo punto, dall'interfaccia Yggdrasil entra soltanto SSH e il traffico appartenente a connessioni già stabilite. Il resto viene buttato via.




Forse la vostra interfaccia avrà un altro nome: dipende dalla versione, dal packaging e dalla configurazione. Controllate con ip addr e usate il nome effettivo. Adesso dovete entrare nella mesh, o almeno cominciare a costruirne una. Per farlo avete bisogno degli indirizzi IP “normali” dei vostri amici — cioè gli IPv4 o IPv6 con cui le loro macchine sono raggiungibili su Internet — e della porta TCP o TLS sulla quale Yggdrasil ascolta. Poi li inserite nel file di configurazione, /etc/yggdrasil.conf, nella sezione Peers. Per esempio:

Peers:
  - tls://203.0.113.10:443
  - tls://198.51.100.27:443

Naturalmente quegli indirizzi sono solo esempi. E chiaramente, la porta deve essere aperta e deve girarci Yggdrasil.

Volendo potreste usare anche degli hostname al posto degli indirizzi IP. Ma, se il motivo per cui state facendo tutto questo è proprio sottrarvi alla dipendenza da DNS, registrar e hostname revocabili, sarebbe abbastanza buffo reintrodurre il problema dalla finestra dopo averlo cacciato dalla porta.

Quindi, per questa configurazione, usiamo direttamente gli IP.

A questo punto il vostro nodo proverà a collegarsi direttamente a quei peer. E se anche loro hanno configurato almeno uno degli altri nodi, comincia a formarsi la mesh.

Non serve che ogni macchina conosca tutte le altre: basta che il grafo rimanga connesso.


Naturalmente quegli indirizzi sono soltanto esempi. E, altrettanto naturalmente, sui nodi remoti quella porta deve essere raggiungibile attraverso il firewall e Yggdrasil deve essere configurato per ascoltarvi. Mettere tls://203.0.113.10:443 dentro Peers non fa comparire magicamente un peer dall'altra parte: su 203.0.113.10:443 deve esserci davvero un'istanza Yggdrasil in ascolto.


Se abbiamo tre macchine:

A = 11.12.13.14
B = 21.22.23.24
C = 31.32.33.34

sulla macchina A possiamo avere, dentro /etc/yggdrasil.conf :

Peers: [
  tls://21.22.23.24:443
  tls://31.32.33.34:443
]

Listen: [
  tls://[::]:443
]

sulla macchina B:

Peers: [
  tls://11.12.13.14:443
  tls://31.32.33.34:443
]

Listen: [
  tls://[::]:443
]

e sulla C:

Peers: [
  tls://11.12.13.14:443
  tls://21.22.23.24:443
]

Listen: [
  tls://[::]:443
]

Ovviamente la 443 dovrebbe essere esposta su internet.



Adesso le vostre macchine creeranno una mesh. E se mettete una configurazione compatibile su altre macchine Linux con Yggdrasil installato, queste potranno collegarsi alla stessa rete.

A quel punto emerge un problema molto terra-terra: gli indirizzi IPv6 Yggdrasil non sono esattamente il genere di cosa che volete ricordare a memoria.

Vi serve un DNS.

Quindi voi tre compari che avete dato inizio alla cosa potete anche mettere in piedi tre server DNS autoritativi interni alla mesh.

Diciamo che decidiate di usare:

.narnia

.narnia, al momento, non è un TLD delegato nella root pubblica. Quindi, dentro la vostra rete, potete tranquillamente comportarvi come se foste gli dei del namespace.

Avete tre nodi Yggdrasil, diciamo con questi indirizzi IPv6:

200:1111:2222:3333:4444:5555:6666:7777
200:8888:9999:aaaa:bbbb:cccc:dddd:eeee
200:1234:5678:9abc:def0:1234:5678:9abc

Su tutti e tre installate BIND.

Uno sarà il primary della zona narnia, gli altri due saranno secondary.

Non serve multicast: BIND possiede già il suo sistema per mantenere sincronizzate le zone, attraverso NOTIFY e trasferimenti IXFR o AXFR.

Sul primary, dentro la configurazione di named, avrete qualcosa del genere:

zone "narnia" {
    type primary;
    file "/etc/bind/db.narnia";

    allow-transfer {
        200:8888:9999:aaaa:bbbb:cccc:dddd:eeee;
        200:1234:5678:9abc:def0:1234:5678:9abc;
    };

    also-notify {
        200:8888:9999:aaaa:bbbb:cccc:dddd:eeee;
        200:1234:5678:9abc:def0:1234:5678:9abc;
    };
};

Sugli altri due:

zone "narnia" {
    type secondary;

    primaries {
        200:1111:2222:3333:4444:5555:6666:7777;
    };

    file "/var/cache/bind/db.narnia";
};

Quando cambiate la zona sul primary e aumentate il seriale del record SOA, il primary avvisa i secondary e questi si aggiornano automaticamente.

In pratica avete appena costruito il vostro piccolo DNS interno, che vive interamente dentro Yggdrasil e non ha bisogno né di registrar né del DNS pubblico.




Domanda avanzata: per sincronizzare i DNS dovrei usare anche TSIG?

No. In questo caso sarebbe sostanzialmente ridondante.

Gli indirizzi Yggdrasil derivano già dall'identità crittografica dei nodi, e le comunicazioni tra quei nodi sono già autenticate e cifrate dalla rete stessa. Se state permettendo i trasferimenti di zona soltanto verso gli indirizzi Yggdrasil dei vostri secondary, avete già un'identità crittografica sottostante sulla quale basare l'ACL.

Aggiungere TSIG significherebbe sovrapporre un secondo meccanismo di autenticazione a uno che, per questo specifico threat model, avete già.

Non aggiungereste sostanzialmente niente, se non altre chiavi da distribuire e gestire.





A questo punto, sui client della vostra rete, dovete dire al resolver di usare i tre DNS della mesh. In un sistema che usa direttamente /etc/resolv.conf, avrete qualcosa del genere:

nameserver 200:1111:2222:3333:4444:5555:6666:7777 nameserver 200:8888:9999:aaaa:bbbb:cccc:dddd:eeee nameserver 200:1234:5678:9abc:def0:1234:5678:9abc

Da quel momento, quando chiedete per esempio:

git.narnia chat.narnia files.narnia

la risoluzione avviene usando i DNS che vivono dentro la vostra rete Yggdrasil.

Se non volete vivere solo dentro Narnia, allora dovete fare una cosa piu' lunga:

Lasciare /etc/resolv.conf per i fatti suoi e se usate systemd-resolved, potete fare una cosa molto più elegante: dire al sistema che soltanto il dominio .narnia deve essere risolto attraverso i DNS Yggdrasil.

Supponiamo che l'interfaccia si chiami ygg0:

sudo resolvectl dns ygg0 \
  200:1111:2222:3333:4444:5555:6666:7777 \
  200:8888:9999:aaaa:bbbb:cccc:dddd:eeee \
  200:1234:5678:9abc:def0:1234:5678:9abc

sudo resolvectl domain ygg0 '~narnia'

Quel ~narnia significa: tutte le query per .narnia devono passare da questa interfaccia.

Il resto del DNS continua invece a funzionare normalmente attraverso la vostra connessione Internet ordinaria.

Quindi:

git.narnia
chat.narnia
files.narnia

andranno ai DNS della mesh, mentre:

debian.org
wikipedia.org
kernel.org

continueranno a essere risolti attraverso i DNS normali.

Questo è esattamente lo split-DNS che ci serve.




Una volta fatto questo, avete una rete , diciamo “organization-wise”.

Cosa potete fare? Potete decidere che esiste chat.narnia , e assegnarlo all' IP di un server (magari un raspberry o un odroid da due lire, che fanno girare irc a casa di qualcuno), oppure decidere che avete smtp.narnia , per inviare posta, o imap4.narnia per scaricarla.

Siete voi tre i regnanti di .narnia, e quindi potete, se vi fidate di qualcuno, assegnare quel che volete a chi volte.

Vi servono certificati? No. non davvero. Il traffico e' gia' criptato, gli indirizzi IPv6 che usate sono gia' validati per via crittografica. Potete liberarvi di questa ridondanza.

Voi direte adesso:

si, ma non e' che milioni di persone adesso si mettono una debian e poi installano tutta la baracca: anche senza i DNS da gestire, per l'utente medio e' davvero troppo.

Vero. Infatti io parlavo di una rete molto privata e molto “organization-wise”. Significa che se vi cacciano fuori dalla internet regolare, almeno gli amministratori dei vari sistemi (forum, mailing list, eccetera) potrebbero pur sempre parlare sul forum.narnia o usare la posta sui server smtp/imap di Narnia. Almeno per decidere sul da farsi.

Potreste sempre continuare ad inviare messaggi sulla mailing list: se il sistema che fa da mailing list sta su una macchina che serve sia internet che yggdrasil, la posta in uscita dovrebbe venire consegnata normalmente.

E quindi potreste avvisare i vostri utenti.




Ma non esiste proprio un modo per far accedere il pubblico a .narnia?

Non del tutto.

Nel senso che un membro di .narnia, qualcuno di cui vi fidate, potrebbe mettere in piedi un proxy su una macchina che abbia contemporaneamente accesso a Internet normale e alla rete Yggdrasil.

Per esempio, uno Squid su un piccolo computer sempre acceso.

Quella macchina avrebbe quindi due gambe:

Internet normale
       |
       |
     Squid
       |
       |
   Yggdrasil
       |
       |
    .narnia

Squid può essere configurato per usare resolver DNS specifici. Quindi il proxy può sapere come risolvere forum.narnia, chat.narnia, files.narnia e gli altri nomi interni, anche se il computer dell'utente che lo sta usando non sa assolutamente nulla di Yggdrasil. In pratica avete costruito un gateway applicativo.

L'utente normale non entra realmente nella mesh e non possiede un indirizzo Yggdrasil. Dice semplicemente al proprio browser:

usa questo proxy

e sarà il proxy, dall'altra parte, a raggiungere i servizi .narnia.

Quindi uno Squid con un piede su Internet e uno su Yggdrasil può fare da ponte tra il pubblico e quella parte della vostra infrastruttura che avete deciso di rendere accessibile. E lato utente la cosa può essere resa abbastanza semplice. Esistono molte estensioni per browser che permettono di scegliere automaticamente un proxy in base al dominio richiesto. Per esempio FoxyProxy, SwitchyOmega o estensioni analoghe basate su regole per dominio. In pratica potete dire:

*.narnia  -> usa il proxy
tutto il resto -> connessione normale

Quindi l'utente continua a navigare normalmente su Internet, ma quando apre:

forum.narnia
files.narnia
wiki.narnia

il browser manda automaticamente quelle richieste attraverso il proxy Squid. Non deve configurare Yggdrasil, non deve conoscere gli IPv6 della mesh e non deve modificare il proprio DNS di sistema.

Per lui .narnia diventa semplicemente un'altra porzione del Web, raggiungibile attraverso quel proxy.



Se volete, potete anche distribuire direttamente un file .pac, cioè un Proxy Auto-Configuration file, evitando persino di chiedere agli utenti di installare un'estensione.

Per esempio:

function FindProxyForURL(url, host) {
    if (host == "narnia" || shExpMatch(host, "*.narnia")) {
        return "PROXY 11.12.13.14:3128";
    }

    return "DIRECT";
}

La regola significa semplicemente:

*.narnia  -> proxy 11.12.13.14:3128
tutto il resto -> Internet normale

E ho usato direttamente l'indirizzo IP del proxy per una ragione abbastanza ovvia: se stiamo costruendo tutto questo proprio per sopravvivere alla perdita di domini e registrar, sarebbe piuttosto stupido distribuire un PAC contenente:

PROXY proxy.qualcosa.org:3128

e ritrovarci nuovamente dipendenti dal DNS pubblico quando gli americani ti droppano qualcosa.org

Il file .pac può essere distribuito agli utenti e configurato nei browser o nel sistema operativo come configurazione automatica del proxy. A quel punto l'utente digita:

https://forum.narnia/

e il browser manda quella connessione a Squid.

Squid, che conosce i DNS di .narnia e possiede anche un'interfaccia Yggdrasil, risolve forum.narnia e raggiunge il server attraverso la mesh.

Per tutto il resto, il browser continua tranquillamente a usare Internet come prima.




Direte: e' sempre troppo complicato per un utente bestia.

Vero. Ma dovete capire una cosa.

Se volete una cosa sicura e robusta, l'utente bestia e' esattamente la parte piu' pericolosa. Tutti gli attacchi sul layer 8 passano, infatti, dall'utente bestia.

L'utente bestia e' quello che clicca sui link di phishing. L'utente bestia e' quello che da' le credenziali del suo home banking al primo che telefona. L'utente bestia e' quello che da' i suoi risparmi da gestire a Wanna Marchi.

L'utente bestia e' quello che risponde al Principe Nigeriano cui serve solo il vostro conto corrente per poggarci 800.000 euro.

L'utente bestia e' pericoloso. Quindi, se non riesce nemmeno a configurare un proxy nel browser, teletelo fuori.

Questa rete privata e' per gli amministratori della rete mesh, per chi vuole aggiungervi i servizi , per chi vuole gestire dei servizi che stanno dentro.

Il pubblico li leggera' tramite internet, ma gli amministratori, in caso di attacco, potranno pur sempre incontrarsi telematicamente e parlare. E decidere come reagire.


Uriel Fanelli

--
Written using Blogfrei: https://git.keinpfusch.net/loweel/blogfrei
Fedi: @uriel@bbs.keinpfusch.net
XMPP: uriel@keinpfusch.net
vecchio blog: https://blog.keinpfusch.net
email: blog@keinpfusch.net