Piero V.

FTTH TIM con OpenWrt e con Debian

Un mese fa, ho finalmente messo da parte il rame per la mia connessione a Internet per passare alla fibra ottica.

Come ad ogni passaggio, certe cose cambiano, altre rimangono le stesse.

La configurazione, grosso modo, è rimasta invariata. Fin dai tempi dell’ADSL Alice, TIM richiede l’uso del protocollo PPPoE, senza validare però username e password. Quelli che erano VPI 8 e VCI 35, sono diventati l’id VLAN 835 per FTTC e FTTH.

E proprio questo uso di VLAN rende un po’ più difficile la configurazione delle connessioni TIM.

Dopo la morte del mio secondo TD-W8970, ero passato ad un router generico con un modem in bridge connesso alla porta WAN. La VLAN veniva gestita dal modem, un Technicolor TG789vac v2 con firmware di iiNet.

Invece, con l’ONT fornitomi da TIM, un Sercomm FG1000R, la VLAN deve essere impostata nel router.

OpenWrt

Sul mio Cudy WR2100 mi è bastato modificare /etc/config/network in questo modo:

config interface 'wan'
	option device 'wan.835'
	option proto 'pppoe'
	option ipv6 '0'
	option peerdns '0'
	# Il DNS può essere impostato come meglio preferite
	list dns '127.0.0.1'
	option username 'timadsl'
	option password 'timadsl'

config device
	option type '8021q'
	option ifname 'wan'
	option vid '835'
	option name 'wan.835'

Per il resto, mi sono affidato alla configurazione standard di OpenWrt.

Debian

Il mio router purtroppo mi faceva da collo di bottiglia a causa della sua CPU.

Siccome a circa 2 metri c’è un computer con Debian che uso come NAS, ho deciso di usarlo anche come router, e di usare l’altro router come access point puro, come quando usavo La Fonera 😄️.

Su Debian ci sono diverse possibilità per la gestione della rete. Nei sistemi desktop, di default c’è Network Manager. Non è presente invece quando si sceglie un’installazione base, che di solito imposta ifupdown. Un’ulteriore alternativa è systemd-networkd.

È passato un po’ da quanto ho fatto queste configurazioni e non ho testato i vari passaggi che ho elencato su un sistema nuovo e non sono un esperto di questi argomenti, quindi potrebbero esserci degli errori.

PPPoE con ifupdown

Il primo passo è configurare la VLAN sull’interfaccia Ethernet collegata all’ONT, nel mio caso enp1s0. Ho cancellato ogni riga che la riguardasse da /etc/network/interfaces e poi ho aggiunto le seguenti:

allow-hotplug enp1s0
iface enp1s0 inet manual

auto vlan835
iface vlan835 inet manual
        vlan-raw-device enp1s0

Ho dovuto usare la notazione vlanN con l’impostazione vlan-raw-device, al posto di enp1s0.835, perché il punto non è ammesso nella configurazione di PPPoE. Ho trovato questo trucco su man 5 vlan-interfaces (ho letto il fottuto manuale 😄️).

Non sono sicurissimo sull’uso corretto di allow-hotplug e auto. Per il momento questa configurazione sembra resistere anche ai riavii, ma non ho provato a riavviare il NAS con l’ONT staccato.

Dopodiché, secondo il wiki di Debian si dovrebbe eseguire il comando pppoeconf vlan835 e seguire le istruzioni.

Quando l’avevo eseguito, non avevo ancora creato l’interfaccia per la VLAN, quindi non aveva funzionato correttamente, perciò non sono sicurissimo che nemmeno con la VLAN funga.

Il file più importante è /etc/ppp/peers/tim-ftth (che di default si chiamerebbe dsl-provider, ma io ho rinominato):

# PPP non deve cercare di indovinare un indirizzo IP da assegnarci
noipdefault
# Imposta questa connessione come gateway predefinito...
defaultroute
# ... in caso sostituendo l'instradamento predefinito già esistente
replacedefaultroute
# Non includere la password nei log (default e comunque a TIM non interessano le credenziali)
hide-password
# Non abbiamo bisogno che il peer si autentichi
noauth
# Riconnettiti se la connessione cade
persist
# Carica il plugin per PPPoE
plugin rp-pppoe.so
# Usa l'interfaccia vlan835 per il PPPoE. Questa è l'opzione che fallisce con la notazione enp1s0.835.
nic-vlan835
# Imposta l'utente timadsl. La password viene cercata /etc/ppp/pap-secrets o in /etc/ppp/chap-secrets, non sono sicuro
user "timadsl"

In aggiunta a questo file, bisogna specificare la password per il nostro utente. La procedura guidata per me ha aggiunto questa linea sia a /etc/ppp/pap-secrets, che a /etc/ppp/chap-secrets:

"timadsl" * "timadsl"

Infine, bisogna specificare il provider aggiungendo queste ulteriori linee a /etc/network/interfaces:

auto wan
iface wan inet ppp
        provider tim-ftth

Firewall con iptables-persistent

Arrivato a questo punto, il NAS poteva accedere a Internet, ma il resto della LAN no. Quindi ho impostato un NAT e qualche regola del firewall per rendere la nuova configurazione più sicura. Un passaggio simile è necessario indipendentemente dal sistema usato per il punto precedente, sia esso ifupdown, Network Manager o altro ancora.

Anche per il firewall ci sono diverse possibilità. Io ho usato i pacchetti iptables-persistent e netfilter-persistent, quindi mi è bastato aggiungere tutta una serie di regole a /etc/iptables/rules.v4:

*filter
# Di default, non accettiamo input e non inoltriamo niente tra le varie interfcce
:INPUT DROP
:FORWARD DROP
:OUTPUT ACCEPT
# Ma allentiamo queste regole per il loopback...
-A INPUT -i lo -j ACCEPT
# ...e per l'interfaccia privata.
-A INPUT -i enp2s0 -j ACCEPT
# Inoltre, accettiamo tutte le risposte alle connessioni che abbiamo creato noi
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# E in generale, abilitiamo il forward dall'interfaccia privata
-A FORWARD -i enp2s0 -j ACCEPT
# Esempio per servizi installati sul router (HTTP e HTTPS; opzionale)...
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
# ...e un esempio di port forwarding (anch'esso opzionale)
-A FORWARD -d 192.168.1.2/32 -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
COMMIT

*nat
:PREROUTING ACCEPT
:INPUT ACCEPT
:OUTPUT ACCEPT
:POSTROUTING ACCEPT
# Abilitiamo il NAT verso l'interfaccia PPPoE
-A POSTROUTING -o ppp0 -j MASQUERADE
# E aggiungiamo regole come questa se prima avevamo aggiunto dei port forwarding
-A PREROUTING -p tcp -m tcp --dport 22 -j DNAT --to-destination 192.168.1.2:22
COMMIT

Server DHCP e DNS con dnsmasq

Pur mantenendo il WR2100 nella mia rete, ho deciso di disattivargli dnsmasq e di configurarlo invece nel NAS, in modo da diminuire i sistemi che devono essere sempre attivi e rendere eventuali sostituzioni più facili.

Inoltre, ho deciso di non usare il DNS del provider, ma di inoltrare le varie richieste a un server DoH, tramite dnscrypt-proxy.

Potete mettere la configurazione in un file qualsiasi in /etc/dnsmasq.d. Questa è la mia, ed è il frutto di diversi tentativi e ritocchi, probabilmente non è perfetta, ma per il momento funziona:

# Ho impostato esplicitamente le interfacce perché avevo un conflitto con un'altra istanza di dnsmasq usata da LXC. Non sono sicuro sia necessario
interface=enp2s0
bind-interfaces
# Stessa cosa per i DNS
listen-address=::1,127.0.0.1,192.168.1.1
# Usa .lan come dominio per la rete (ereditato da OpenWrt 😄️)
domain=lan
local=/lan/
# Aggiungi il dominio agli host di /etc/hosts che non ne hanno nessuno
expand-hosts
# Cerca di adattare gli indirizzi IP all'interfaccia da cui arriva la richiesta
localise-queries
# Il range di indirizzi IP da assegnare e la durata del lease
dhcp-range=192.168.1.100,192.168.1.250,12h
# Default gateway
dhcp-option=3,192.168.1.1

# Lease statici
dhcp-host=aa:bb:cc:11:22:33,192.168.1.101,host-01,1w
dhcp-host=00:11:22:ab:cd:ef,192.168.1.102,host-02,1w

# Server DNS a cui inoltrare le richieste (nel mio caso, dnscrypt-proxy)
server=::1#53000
server=127.0.0.1#53000
# Ignora /etc/resolv.conf, usa solo i server specificati in questo file.
# resolv.conf comunque dovrebbe avere solo 127.0.0.1 come server, in modo che il router stesso usi dnsmasq
no-resolv

# Record DNS aggiuntivi, e.g., per dispositivi configurati con indirizzo IP statico
host-record=wr2100,wr2100.lan,192.168.1.2

Potete trovare tutta la documentazione sulla pagina man di dnsmasq. I parametri da linea di comando possono essere specificati nel file di configurazione rimuovendo il prefisso --.

DNS over HTTPS con dnscrypt-proxy

Il DoH non è stato facilissimo da attivare.

Il primo problema è che dnscrypt-proxy non è stato incluso in bookworm, a causa di una dipendenza che non compilava.

Ci sono diverse soluzioni al problema, come installare da sorgenti, oppure installare il deb da oldstable o fare pinning con testing. Al momento della scrittura dell’articolo, testing e oldstable hanno la stessa versione, quindi oldstable dovrebbe essere una soluzione migliore, per evitare FrankenDebian.

Il secondo problema è che le distribuzioni configurano dnscrypt-proxy in modo che sia attivato da systemd sockets, che però non è supportato dal progetto upstream. Quindi, seguendo le varie guide, sia del progetto che del wiki di Arch, sono arrivato a questo /etc/systemd/system/dnscrypt-proxy.service, molto simile a quello di default (/lib/systemd/system/dnscrypt-proxy.service):

[Unit]
Description=Encrypted/authenticated DNS proxy
ConditionFileIsExecutable=/usr/sbin/dnscrypt-proxy

[Service]
StartLimitInterval=5
StartLimitBurst=10
ExecStart=/usr/sbin/dnscrypt-proxy -config /etc/dnscrypt-proxy/dnscrypt-proxy.toml
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelModules=yes
Restart=always
RestartSec=120
DynamicUser=yes
User=_dnscrypt-proxy

[Install]
WantedBy=multi-user.target

Ho poi configurato systemd di consequenza:

systemctl disable dnscrypt-proxy.socket
systemctl enable dnscrypt-proxy.service

Infine, il mio file di configurazione /etc/dnscrypt-proxy/dnscrypt-proxy.toml è questo:

# Porta 53000 perché sulla 53 c'è già dnsmasq
listen_addresses = ['127.0.0.1:53000']
# Per una configurazione più semplice, potete inserire i vostri servizi preferiti, presi da public-resolvers.md.
# Questo però assume vi fidiate della lista redatta da DNSCrypt.
# Si possono specificare più servizi. dnscrypt-proxy dovrebbe bilanciare il carico su tutti.
# Questa strategia potrebbe essere controproducente (un attacco DNS leak potrebbe elencarli tutti e rivelare una configurazione univoca).
server_names = ['provider-preferito']
# TIM non supporta IPv6, quindi evitiamo di risolvere AAAA
block_ipv6 = true

# Lista di servizi DoH/DoT pubblici.
# Se non vi fidate potete creare un vostro elecno con una sezione [static].
[sources]
  [sources.'public-resolvers']
  url = 'https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md'
  cache_file = '/var/cache/dnscrypt-proxy/public-resolvers.md'
  minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
  refresh_delay = 72
  prefix = ''