Questo e' un post rivolto a chi ha fatto il sysadmin o l'architetto di sistemi ed ha cercato di costruirsi un sistema sicuro a casa. Avete mai avuto l'impressione che , ogni volta che stavate per chiudere le mura della vostra "fortezza", il software fosse fatto in modo da, guarda caso, lasciare aperto uno spiraglio almeno in OGNI configurazione? Sicuramente avrete avuto questo senso di "l'intero mondo complotta contro di me". Ma l'avrete cestinata come paranoia. Vi capisco. Ma adesso qualcuno e' stato abbastanza autorevole da dire che non e' una paranoia.
Questo signore qui ha l'autorevolezza e la levatura per dire le stesse cose senza essere tacciato di paranoia. E ha illustrato il modo in cui, lentamente, molto lentamente, NSA ha letteralmente rovinato moltissimo codice OpenSource in diversi modi.
vi consiglio di scaricarne una copia, non so per quanto tempo reggera'. Adesso penserete che una rondine non faccia primavera, MA non e' una singola rondine. Eccone una seconda:
Cosi', adesso possiamo sederci, e dire. Ok, ok. Non sono io ad essere paranoico. Non sono io il solo a pensare che il software opensource sia stato volutamente infiltrato e peggiorato al preciso scopo di impedire che risultasse IMpossibile costruire soluzioni davvero sicure.
Sarete ancora scettici. Direte che di certo il mondo non si preoccupa del vostro piccolo server di posta elettronica. Ed e' esattamente cosi'. Ma e' anche vero il contrario.
Cosi' mi sono messo a pensare: come e' possibile che da un lato la mia precisa volonta' personale di costruire un cloud domestico sicuro sia il bersaglio, e che contemporaneamente non sia IO in persona il bersaglio?
La logica ha una risposta: quando le affermazioni sono sia vere che false, o avete di fronte un paradosso e la teoria e' sbagliata (ma stiamo assumendo che sia vera per via della levatura e dell'autorevolezza delle fonti) , oppure abbiamo a che fare con fenomeni stocastici che hanno una forte componente gaussiana.
Se il nostro avversario sta usando metodi statistici per colpire quante piu' soluzioni possibile, allora saremo un bersaglio perche' siamo nel calderone. Ma non saremo esplicitamente e personalmente il bersaglio. In questo modo, abbiamo chiuso il cerchio.
diciamo che qualcuno raccolga statistiche dei metodi e degli strumenti di sicurezza piu' utilizzati. E diciamo che decida di colpire entro tre sigma. Ovvero di coprire tutti i software che sono, in una distribuzione normale (assumo che sia normale, ma il concetto si applica con qualsiasi distribuzione statistica) , con un andamento del genere:
68,3% = P{ μ - σ < X < μ + σ }
95,0% = P{ μ - 1,96 σ < X < μ + 1,96 σ }
95,5% = P{ μ - 2 σ < X < μ + 2 σ }
99,0% = P{ μ - 2,58 σ < X < μ + 2,58 σ }
99,7% = P{ μ - 3 σ < X < μ + 3 σ }
in pratica, cioe', calcolo quanto diffusi siano i vari software (usando uno scanner di rete sulle varie porte) e decido di coprire tre sigma, ovvero il 99.7% delle installazioni di software opensource operanti in rete.
Usando i metodi descritti sopra, nel filmato, diciamo che sono riuscito a rovinare i software in questione, per impedire che facciano quel che voglio. In fondo, quando nel mondo OSS si parla di office si parla SOLO di openoffice, quando si parla di SSL si parla di openssl, se parliamo di mail quasi sempre sono sendmail, postfix ed exim, e cosi' via.
Fatto questo, con il 99.7% dei software inquinati e difficilmente utilizzabili, cui sono state soppresse, guarda caso, quelle tre features che INSIEME(1) lo renderebbero a prova di bomba, se usate le soluzioni mainstream vi troverete a impazzire: state cercando di costruire una fortezza, ma c'e' SEMPRE un blocco che manca per chiudere l'anello.
Quindi, se usate una soluzione proprietaria mainstream, e' americana. Se usate qualcos'altro, usa software opensource. Ed e' ancora inquinata dagli americani.
Quindi, se usate una soluzione proprietaria mainstream, e' americana. Se usate qualcos'altro, usa software opensource. Ed e' ancora inquinata dagli americani.
Allora adesso mi starete chiedendo "ma allora e' impossibile essere sicuri?". La risposta e' no: ma sicuramente se dovete fare questo dovrete usare qualcosa , una combinazione di software, che ha MENO dello 0.3% di probabilita' di apparire, o che e' usata MENO del 0.3% delle volte..
Per esempio, la soluzione che ho a casa consiste in una serie di macchine virtuali, che girano su un Domani-0 che NON possiede indirizzi IP. Allora, se vado ad elencare i singoli sottosistemi:
- SMTP: Opensmtpd (key feature: criptazione delle code sul disco, relay da SMTP a LMTP, relay con autenticazione con regole di uscita programmabili, forza TLS in ingresso sulla porta 25)
- IMAP: Dovecot (key feature: riceve con LMTP su IP e va su imaps).
- VPN: OpenVpn (Key feature: esiste il client su android, PolarSSL)
- DNS: Pdnsd: (Key Feature: cache+hosts, scelta casuale dei forwarder, TTL negativo configurabile)
- DDNS: no-ip.org (key feature: si aggiorna facilmente con curl + ssl).
- File Sharing: Syncthing. (Key feature: codice facilissimo da leggere, bello, chiaro )
- OS1: FreeBsd (Key feature: ZFS, fingerprint piccolo)
- OS2: OpenBSD (Key feature: Packet filter e process domain deterministico).
- OS3: Linux: (Key feature: XEN, XFS , per il dump del filesystem a macchine virtuali in funzione)
- Firewall: PF (NAT semplice e poche righe di configurazions, IP fingerprint, load balancing, stateful)
- Firewall2: IPFW (Key Features: dummynet e bridge firewall)
- Firewall3: Iptables. (Key features: IP_CLUSTER)
- Wifi: hostapd + chiavetta con monitor.
- IDS: snort. (https://www.snort.org/)
- Network Sandbox: RaspBerry con FreebSD per Armv6. (key feature: il codice per ARM non gira su AMD x64).
allora voi direte: ehi, ma tutta questa complessita' fa bene? Dipende da quanto bene avete disegnato il sistema. In realta' e' una rete virtuale, un VIP/load balancer, due minuscoli server smtp, due minuscoli server imap,e se lavorate da abbastanza tempo, non e' nemmeno una configurazione tanto difficile.
E si, chiudono "abbastanza bene" ogni lato della fortezza.
Ma il punto e' che se cercate una configurazione simile, siete SOTTO lo 0.03% delle installazioni. Quindi probabilmente nessuno si e' mai posto il problema di impedire che una simile configurazione possa esistere.
Qui e' il punto: per come funziona il tutto, potete sperare di ottenere sicurezza SOLO usando configurazioni "poco mainstream", e combinazioni di software e di tecnologie "poco mainstream". Tecnologie che poi dovrete saper gestire con una certa confidenza il che restringe ancora il campo.
Ma adesso andiamo ad un altro punto: le librerie. Perche' si apre un altro fronte completo, se pensiamo alle librerie.
Volevo parlare di una libreria di crittazione, NaCl, detta "salt". ( http://nacl.cr.yp.to )
Si tratta di librerie per la crittazione, che vi servono se volete programmare software che usino comunicazioni crittate.
Ora, quanto e' facile?
Lo leggete qui:
http://nacl.cr.yp.to/box.html
Questo e' quello che dovete fare per criptare un testo con NaCl:
Questo e' quello che dovete fare per criptare un testo con NaCl:
#include "crypto_box.h"
std::string pk;
std::string sk;
std::string n;
std::string m;
std::string c;
c = crypto_box(m,n,pk,sk);
tre righe per generare le chiavi, non piu' di sette righe per criptare il payload. Un software scritto cosi' e' FACILE da debuggare, da capire, e se c'e' un baco e' semplice da trovare.
Volete un confronto?
Ecco qui , cosa dovete fare per fare lo stesso con OpenSSL:
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <stdio.h>
int
padding = RSA_PKCS1_PADDING;
RSA * createRSA(unsigned
char
* key,
int
public
)
{
RSA *rsa= NULL;
BIO *keybio ;
keybio = BIO_new_mem_buf(key, -1);
if
(keybio==NULL)
{
printf
(
"Failed to create key BIO"
);
return
0;
}
if
(
public
)
{
rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);
}
else
{
rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);
}
if
(rsa == NULL)
{
printf
(
"Failed to create RSA"
);
}
return
rsa;
}
int
public_encrypt(unsigned
char
* data,
int
data_len,unsigned
char
* key, unsigned
char
*encrypted)
{
RSA * rsa = createRSA(key,1);
int
result = RSA_public_encrypt(data_len,data,encrypted,rsa,padding);
return
result;
}
int
private_decrypt(unsigned
char
* enc_data,
int
data_len,unsigned
char
* key, unsigned
char
*decrypted)
{
RSA * rsa = createRSA(key,0);
int
result = RSA_private_decrypt(data_len,enc_data,decrypted,rsa,padding);
return
result;
}
int
private_encrypt(unsigned
char
* data,
int
data_len,unsigned
char
* key, unsigned
char
*encrypted)
{
RSA * rsa = createRSA(key,0);
int
result = RSA_private_encrypt(data_len,data,encrypted,rsa,padding);
return
result;
}
int
public_decrypt(unsigned
char
* enc_data,
int
data_len,unsigned
char
* key, unsigned
char
*decrypted)
{
RSA * rsa = createRSA(key,1);
int
result = RSA_public_decrypt(data_len,enc_data,decrypted,rsa,padding);
return
result;
}
void
printLastError(
char
*msg)
{
char
* err =
malloc
(130);;
ERR_load_crypto_strings();
ERR_error_string(ERR_get_error(), err);
printf
(
"%s ERROR: %s\n"
,msg, err);
free
(err);
}
no, non e' uno scherzo.
E' merda. Merda allo stato puro. Cosi' merda che ci crescono sopra solo piante di cesso. In che modo una persona possa vedere "a colpo d'occhio" un errore plateale quando per criptare un singolo coso devo invocare, descrivere, inizializzare, creare , e poi finalmente criptare, e' semplicemente controintuitivo, ovvero SOGGETTO AD ERRORI.
Allora voi mi chiederete se il codice di NaCl sia sicuro, o ben scritto. Andate a chiederlo all' autore. E' FAMOSO per come risponde a questa domanda, sin dai tempi di qmail. In ogni caso l'algoritmo e' noto, l'autore e' un matematico, e la codifica e' chiara. NaCl e' una specie di libro sulla crittografia, a leggere il codice.
Comunque si: il codice e' leggibile. Facile da capire. Bello. E' DIFFICILE SBAGLIARE.
Ma adesso cercate in giro blogs che parlino di NaCl, i classici blog che vi danno gli esempi: lo sviluppatore Merdiano che lavora di copia-incolla vive di questi blog. Se riempite un blog di esempi su come fare crittazione con NaCl, potete stare CERTI che entro qualche mese il 50% del nuovo codice opensource che richiede crittazione conterranno pezzi dei vostri esempi. Inquinare e' semplice.
Ed e' cosi' che hanno infettato molto OSS.
Ed e' cosi' che hanno infettato molto OSS.
Scrivere codice difficile da capire, per creare nel programmatore merdiano il bisogno di esempi, che sono poi stati forniti da provvidenziali blog , e hanno infettato meta' dei programmi opensource.
E' una cosa che probabilmente tutti abbiamo sospettato quando, volendo scrivere un nostro codice per la crittazione, ci siamo scontrati con le "CHIARISSIME" primitive di OpenPGP , o GNUPG, esportate per C e C++. Merda illeggibile, immanutenibile, scritta per rendere le cose PIU' DIFFICILI DEL NECESSARIO. Per indurre il programmatore in errore. Per aumentare il numero di errori. Per avere almeno un buco in ogni software.
E qui torniamo alla mia configurazione di cui sopra: non ho usato tre OS per sfizio. Ne ho usati tre perche' ce ne vogliono tre coi buchi per farne uno senza buchi, cioe' per avere nella stessa scatola TUTTE le funzionalita'che vi servono.
Ripeto: fino a qualche anno fa, era una paranoia. La pensavo come IgnorantGuru , a riguardo: paranoie mie, dicevo. Si, succedevano cose strane, certo arrivavano degli scanner molto sofisticati appena mettevo su alcune configurazioni, ma avevo sempre dato la colpa alla mia paranoia.
Ho sempre pensato che fossero gli sviluppatori di OSS che , casualmente, non riuscivano a condensare in UN SOLO software tutte le feature che servono. Pensare il contrario sarebbe stato paranoia.
Ma adesso molti "vecchi" dell'informatica stanno iniziando ad uscire allo scoperto,e a dire che la mia paranoia era anche la loro, che anche loro hanno ricevuto lo stesso trattamento, avute le stesse impressioni, ricevuto attenzioni quando dicevano alcune cose e non altre.
Adesso, se siete "paranoici", credo sia tempo di fare outing.
(1) Significa che a voi servono X,Y,Z, ma il software A fa solo X e Y, il software B fa solo Z e Y, e cosi' via. Ma nessuno le fa TUTTE.