sindro.me

feeling bold
on the internet

info 🇬🇧🇮🇹

L’app Verisure fa schifo. Lì, l’ho detto.

Non che l’allarme funzioni male — il pannello SDVECU è solido, i sensori sono affidabili, l’installazione è professionale. Ma l’app. Dio santo, l’app.

Il problema

Apri l’app per controllare lo stato dell’allarme e ti accoglie una pubblicità di Verisure stessa. Io pago fior di quattrini per il servizio e loro mi piazzano le ads dentro l’app. È il 2026 e un’azienda di sicurezza mi fa vedere banner pubblicitari quando provo a verificare se casa mia è protetta.

Ma le ads sono il meno. I veri problemi sono:

  • Routine cieche. Sì, l’app ha le “routine” — attiva a mezzanotte, disattiva alle 7. Ma non sanno dove sei. Mezzanotte e sei ancora in giardino? L’allarme si attiva e i sensori scattano. Finestra aperta? Il pannello annuncia che non riesce ad attivare, ma se non lo senti l’allarme resta spento. Vai in vacanza e dimentichi di disabilitare la routine di disattivazione mattutina? Allarme spento con la casa vuota. E le modifiche alle routine impiegano 20 minuti a propagarsi — “o il giorno dopo”. Nel 2026.
  • Zero presenza. L’app non sa dove sei. Non sa chi è in casa. Non sa se la donna delle pulizie è andata via. Nessuna automazione basata sulla posizione.
  • Una telecamera alla volta. Vuoi vedere tutte le camere? Tocca, aspetta, torna indietro, tocca la prossima, aspetta. Nessuna vista d’insieme. Nessun “cattura tutto”.
  • Lentezza biblica. Richiedi un’immagine, aspetti, aspetti, forse arriva. A volte ricarichi l’app e riprovi. Nel 2026.
  • Nessuno storage permanente. Le immagini catturate spariscono. Non c’è uno storico consultabile.
  • Nessun timestamp sulle immagini. Catturi una foto e non sai quando è stata scattata né da quale camera. Devi ricordartelo tu. Per un sistema di sicurezza è imbarazzante.
  • Notifiche generiche. Una notifica uguale per tutti. Niente notifiche actionable, niente notifiche critiche che bypassano il “Non Disturbare”.

Quello che volevo: il mio allarme, integrato nella mia domotica, con automazioni intelligenti, notifiche per tutti i residenti, e una dashboard che mostra tutto in un colpo d’occhio. Senza pubblicità.

Tutto è cominciato con il rilevamento presenza WiFi. Avevo costruito un sistema che traccia in quale stanza si trova ognuno scrapando l’RSSI dai miei AP OpenWrt. Funzionava – ma le assegnazioni delle stanze continuavano a sfarfallare. Cucina. Ufficio. Cucina. Ufficio. Tre volte in dieci secondi. La macchina a stati era a posto. Il WiFi no.

La mia rete domestica ha sei AP OpenWrt su tre piani, due SSID – Mercury su 5 GHz, Saturn su 2,4 GHz – tutti con 802.11r per il roaming veloce. Vista da fuori, sembra una mesh fatta bene. Vista da dentro, un telefono rimbalzava tra access point 129 volte in 24 ore.

Non lo sapevo finché non ho costruito lo strumento per vederlo.

Timeline di roaming — 24 ore

Ogni riga è un client WiFi, il colore mostra a quale AP è connesso. I client sani mostrano barre lunghe e piene. Quelli malati sembrano pali da barbiere. Vedi sara-iphone? Quella striscia arcobaleno sono 129 connessioni in 24 ore – il telefono cammina in una zona di overlap tra due AP dove entrambi hanno un segnale circa uguale (e orrendo).

Il problema che non puoi vedere

Il roaming WiFi è invisibile. Il tuo telefono mostra tutte le tacche, Netflix bufferizza un attimo, e tu dai la colpa alla connessione internet. Ma quello che è successo davvero è che il tuo telefono si è disconnesso da un AP, ha scansionato le alternative, ne ha scelto un altro con un segnale marginalmente diverso, si è associato, autenticato, e ha ricominciato lo streaming – tutto in meno di un secondo se 802.11r funziona, diversi secondi se non funziona.

Avevo due problemi con il rilevamento presenza di Home Assistant.

Il primo: il GPS ti dice se qualcuno è a casa, ma non dove in casa si trova. La mia casa ha sei access point OpenWrt distribuiti su tre piani. Sanno già esattamente quale telefono è connesso a quale AP in ogni momento – sono dati di presenza a livello di stanza, lì nello stack WiFi, che urlano per essere usati. Sapere chi è in quale stanza apre un’intera classe di automazioni che il GPS non può toccare: luci che ti seguono, climatizzazione per stanza occupata, una dashboard che mostra la situazione della casa a colpo d’occhio.

Il secondo: la nostra donna delle pulizie sta a casa nostra un paio di giorni a settimana. Non voglio configurarle un account HA completo, installarle l’app companion sul telefono, o avere a che fare con i permessi GPS. Ma devo sapere se è a casa – perché la mia automazione dell’allarme ha bisogno di sapere se la casa è davvero vuota prima di attivarsi. Il suo telefono si connette al WiFi. Mi basta questo.

Così ho scritto openwrt-ha-presence: una macchina a stati che scrapa le metriche RSSI direttamente dai tuoi AP OpenWrt, capisce in quale stanza si trova ogni persona in base alla potenza del segnale, e pubblica lo stato casa/fuori per ogni persona su Home Assistant via MQTT Discovery. Niente cloud, niente beacon, niente parsing di log, niente database time-series. Python, async, ~600 righe di logica effettiva.

Storico tracking stanze di Home Assistant

Un paio di mesi fa, la fibra è andata giù. Come da primo corollario di Murphy, è successo nel momento peggiore in assoluto: subito prima di una riunione cruciale con un’azienda partner. Mi sono ritrovato a saltare freneticamente tra l’AP di un vicino lontano e l’hotspot del telefono, ma entrambi facevano schifo. Parliamo di 200ms di RTT e 15% di packet loss. Mi stavo scusando a profusione mentre il mio feed video si trasformava in uno slideshow del 1998; nessuno capiva una parola di quello che dicevo. Ho finito per spegnere il video e stare zitto. Opportunità persa. Mai. Più.

Così sono andato in modalità paranoica totale e ho costruito un setup di backup 5G serio.

L’hardware

Il segnale 5G qui è inesistente, quindi ho dovuto usare l’artiglieria pesante. La Poynting è una bestia. 11 dBi di guadagno, vero MIMO 4x4, cross-polarizzata, stagna. Puntala verso la torre più vicina e all’improvviso il SINR salta da “meh” a “porco dio!”.

Ma puntare un’antenna direzionale senza feedback visivo è doloroso. In pratica giri in tondo, aggiorni una web UI, bestemmi guardando il cielo.

Il software

Ho scritto un set di strumenti per risolvere il problema: quectel-5g-tools.

5g-info scarica tutto quello che il tuo modem sa in un formato leggibile:

output di 5g-info

5g-monitor è una TUI ncurses che si aggiorna in tempo reale e – qui viene il bello – emette beep in base al SINR. Qualità del segnale più alta = più beep. Punta l’antenna, ascolta i beep, stringi i bulloni. Fatto.

Siamo nel 2026, e stiamo ancora lottando con l’arroganza assoluta di Docker riguardo al networking Linux.

Ecco lo scenario: faccio girare un host ibrido. Da un lato, ho una macchina virtuale KVM che fa girare Home Assistant (perché ho bisogno del controllo completo del SO e della cifratura del disco). Dall’altro, ho la solita lista di container Docker – NUT per monitorare il mio UPS Lakeview (Vultech) di merda e Technitium per DNS e DHCP – in esecuzione direttamente sull’host.

Sembra semplice. Dovrebbe essere semplice.

Ma nel momento in cui ho installato Docker, la comunicazione con la mia VM Home Assistant è morta. Semplicemente cessata di esistere.

Il problema: Docker è un dittatore

Docker, per default, tratta le tue regole iptables come se fossero semplici suggerimenti. Quando il demone si avvia, sostanzialmente sovrascrive la chain FORWARD, inserisce la sua logica, e imposta policy che isolano efficacemente qualsiasi cosa non sia un container gestito da Docker stesso.

Se hai un’interfaccia bridge per una VM (come br0 o virbr0), le regole di Docker spesso finiscono per droppare i pacchetti destinati a quella VM perché non corrispondono alla sua logica interna per il traffico dei container.

La soluzione ingenua (e perché fallisce)

La mia prima reazione – come qualsiasi sysadmin che fa questo lavoro dai primi anni 2000 – è stata sistemare le regole a mano e poi eseguire:

iptables-save > /etc/iptables/rules.v4

Questa è una trappola!

Trap GIF

Se usi iptables-persistent (o netfilter-persistent) con Docker, stai entrando in un mondo di dolore per due motivi:

LUKS remoto? Pfft. Ecco come sbloccare via SSH una root ZFS cifrata su FreeBSD (nel modo difficile)

Se usi FreeBSD come me, su un server remoto con cifratura completa del disco (ZFS su GELI), conosci il panico del riavvio. Sei sempre alla mercé di un KVM-over-IP o di una connessione VNC dal browser, per inserire la password del filesystem root al prompt del kernel.

Inoltre, se (come me) fai girare un sistema con kern.securelevel > 0, allora installare una nuova libc significa riavviare in single user e installare gli aggiornamenti tramite la suddetta connessione KVM o VNC, che non è ergonomica per usare un eufemismo.

La soluzione standard è di solito un ambiente SSH pre-boot. Su Linux, dropbear-initramfs rende la cosa banale. Su FreeBSD? Devi costruirti un mfsroot (memory file system) custom da zero.

La maggior parte delle guide suggerisce di usare un semplice shell script come init. Funziona, ma è misero. Perdi il job control (niente Ctrl+C), non hai un TTY decente, e in bocca al lupo se devi fare debug dei problemi di rete in modo interattivo.

Non volevo un hack raffazzonato. Volevo un ambiente vero. Volevo init, getty, login, autenticazione PAM, e un chroot ZFS per la manutenzione – per installare aggiornamenti.

Ecco come ho costruito un unlocker remoto robusto per FreeBSD.

Il problema con /bin/sh come Init

L’approccio ingenuo è compilare un ramdisk minuscolo, ficcarci dentro un binario sh statico, e dire al loader di eseguirlo come PID 1.

# Questo crea incubi
cat > /sbin/init <<EOF
#!/bin/sh
/sbin/dropbear
exec /bin/sh
EOF

Perché fallisce?

Premessa

Quindi ho cominciato a far girare Home Assistant a casa su un Raspberry PI 5 e ho semplicemente installato HAOS su una SD. Poi ho iniziato a sentirmi sempre più a disagio nel salvare credenziali nel filesystem di HA in chiaro (qualsiasi offuscamento non è sufficiente).

Considerando che configurare una root cifrata con HAOS è semplicemente impossibile senza forkarlo, e considerando anche che dedicare un intero RPI5 a HAOS è uno spreco di risorse, ho deciso di aggiungere un SSD al Pi, avviarlo con Raspbian e poi far girare HAOS dentro una VM.

In questo modo, posso avere una root cifrata sull’host principale, cifrando così l’intera VM HAOS.

Inoltre posso ora fare snapshot dell’intera VM HAOS e ho molta più flessibilità nella gestione. Ultimo ma non meno importante, posso anche usare la CPU e la RAM rimanenti del RPI per qualcos’altro.

Ringraziamenti

Prima di tutto, un grande grazie a questo post che mi ha dato le indicazioni iniziali su come fare il setup. Ma quel post del 2021 è ora leggermente datato, e molti passaggi non sono più necessari.

Secondo, un grande grazie a Eric Fjøsne per aver usato questa guida e averla corretta dato che l’avevo scritta perlopiù a posteriori :-).

Requisiti

  • Un RPI5 con Debian 13 (trixie) o successivo
  • Una chiavetta USB decente e affidabile che può essere completamente cancellata
  • Una tastiera e un monitor collegati direttamente al RPI

Panoramica

L’idea di fondo è:

  • Prepariamo un initrd che contiene i seguenti strumenti:
    • resize2fs per ridurre e ingrandire filesystem ext4
    • cryptsetup per gestire la cifratura delle partizioni
  • Configuriamo il sistema per avviarsi da una root cifrata che non esiste ancora, forzando così il sistema a cadere nell’initrd.
  • Nell’initrd, riduciamo il filesystem root alla dimensione minima possibile
  • Copiamo il filesystem root dalla partizione in chiaro sulla chiavetta USB
  • Creiamo la partizione cifrata usando LUKS
  • Copiamo il filesystem root dalla chiavetta USB sulla partizione cifrata
  • Estendiamo il filesystem root alla dimensione massima
  • Configuriamo SSH nell’initrd così da poterlo sbloccare anche dopo aver piazzato il Raspberry Pi in un posto senza tastiera o schermo.

Pronti? Via!

Ho presentato un talk ad All Systems Go 2025, la conferenza fondamentale sullo userspace Linux. La conferenza è organizzata principalmente dal team di systemd, ed è un punto d’incontro annuale per tutti quelli che lavorano su software di sistema Linux.

Il tema di quest’anno è stato prevalentemente “container, container, container”, con molte nuove funzionalità in systemd per supportare la containerizzazione e anche esperienze pratiche da persone che lavorano sul campo su come usano systemd e software collaterali per costruire infrastrutture a container.

Io e Serge sul palco

Ho presentato insieme al mio collega Serge Dubrouski il nostro lavoro nella costruzione di un sistema operativo alla scala di Meta. Gestiamo un sistema operativo basato su immagini, ma l’azienda viene da due decenni di aggiornamenti del SO online, quindi abbiamo dovuto progettare una strategia di migrazione adeguata e gettare le fondamenta per il futuro.

Descriviamo come prepariamo le release CentOS dall’upstream, gli strumenti OSS che abbiamo costruito per creare le immagini del SO, e la tecnologia interna (MetalOS) che abbiamo ideato per costruire un SO che gira su milioni di server Linux.

Puoi anche scaricare il video per la visione offline.

Domande? Commenti? Sfogate qui sotto! 🤣

TL;DR

FreeBSD: come bloccare i port scanner dall’enumerare le porte aperte sul tuo server, usando fail2ban e una rappresentazione ASCII dei log di pf.

Premessa

Uso fail2ban per tenere alla larga attaccanti e bot che tentano di scansionare i miei siti web o di forzare le mie caselle di posta. Fail2ban funziona scansionando i file di log alla ricerca di pattern specifici e mantenendo un conteggio delle corrispondenze per IP, e permette all’amministratore di sistema di definire cosa fare quando quel conteggio supera una soglia definita.

I pattern sono indicativi di attività malevola, come il tentativo di indovinare la password di una casella di posta, o il tentativo di scansionare lo spazio di un sito web alla ricerca di vulnerabilità.

L’azione da eseguire nella maggior parte dei casi è bloccare l’indirizzo IP incriminato tramite il firewall della macchina, ma fail2ban supporta qualsiasi meccanismo che tu possa concepire, purché possa essere attuato da un comando UNIX.

PF e i suoi log

Sul mio server FreeBSD uso l’eccellente pf, il packet filter, per gestire il traffico in entrata e per eseguire la normalizzazione del traffico.

Il meccanismo di logging di PF è molto UNIX-iano: fornisce un’interfaccia di rete virtuale (pflog0) sulla quale vengono inoltrati i primi byte dei pacchetti bloccati da una regola con lo specificatore log, così che i log dei blocchi in tempo reale possano essere ispezionati con un semplice:

# tcpdump -eni pflog0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes
01:48:13.748353 rule 1/0(match): block in on vtnet0: 121.224.77.46.41854 > 46.38.233.77.6379: Flags [S], seq 1929621329, win 29200, options [mss 1460,sackOK,TS val 840989709 ecr 0,nop,wscale 7], length 0
01:48:15.726215 rule 1/0(match): block in on vtnet0: 192.241.235.20.37422 > 46.38.233.77.5632: UDP, length 3
01:48:17.993439 rule 1/0(match): block in on vtnet0: 145.239.244.34.54154 > 46.38.233.77.1024: Flags [S], seq 3365362952, win 1024, length 0
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel

Questi log possono essere salvati da pflogd in un file formato pcap in /var/log/pflog, che può essere usato per troubleshooting e ispezione asincrona, sempre con tcpdump o qualsiasi cosa che sappia leggere file pcap (come Wireshark).

Root cifrata su ZFS con FreeBSD

- 6 min di lettura

Premessa

Nel 2023, gestisco ancora il mio mailserver. Sì, perché mi piace avere il controllo (almeno in parte) della mia vita digitale, e mi piace avere diversi nomi di dominio su cui tenere le mie cose. Tuttavia, stavo pagando 30€/mese ad AWS per avere in cambio 2 core, 2GiB di RAM e 40G di disco, appena sufficienti per far girare IMAP+SMTP+MySQL+Clamd, figurarsi qualsiasi forma di protezione antispam o ricerca full-text nel corpo delle email.

Insomma, stavo pagando un botto di soldi per far girare un servizio merdoso, e avevo persino pensato di chiudere tutto e spostare la posta e i siti web su qualche servizio completamente managed.

Però voglio ancora farlo

Beh, per ospitare quattro domini con solo qualche redirect email più i siti web che gestisco, avrei speso di più di quanto stavo già pagando, incatenandomi per di più a qualche fornitore di servizi e alle sue politiche.

Quindi, volevo usare FreeBSD e ho cominciato a cercare nella pagina degli ISP fino a decidere di valutare Hetzner e netcup, che offrono entrambi prezzi aggressivi e un buon vecchio VPS senza fronzoli.

Scelta del provider

Alla fine, ho scelto un netcup VPS 1000 che mi dà, a 1/3 del prezzo che pagavo ad AWS, 4 volte le risorse: 6 core, 8GiB di RAM, 160GiB di SSD RAID10 e un’installazione FreeBSD completamente libera e senza limitazioni.

Tuttavia, l’immagine base fornita da Netcup ha alcune limitazioni:

  • Gira su UFS
  • Non ha una partizione di swap
  • Non ha cifratura

Fare un piano

Dato che ero già in fase di configurazione e non volevo ricominciare da zero (questo è un server vecchio stile, gestito a mano, zero automazione) ho deciso di: