I kernel Unbit

Uno dei core-business di Unbit e' l'hacking del kernel di Linux. Dalle implementazioni per i sistemi embedded all'hardening per la sicurezza, lo staff Unbit ha accumulato negli anni una grande esperienza nel campo.

Ove possibile alcune modifiche o implementazioni sono stare rilasciate al pubblico e postate sulla LKML.

Hosting e Application Server

La maggior parte dei sistemi di virtual hosting sono INSICURI. C'e' poco da fare, il problema principale e' che un utente puo' facilmente dannegiarne un altro. E' uno dei motivi principali per cui nei contesti professionali e' preferibile l'utilizzo di un VPS o un server dedicato.

Amministrare pero' un server non e' un lavoro facile, soprattutto quando il proprio lavoro e' programmare e non si ha voglia di addentrarsi nel mondo dell'amministrazione di sistema.

Per questo motivo abbiamo deciso di implementare un sistema che ci piace chiamare Ultra Lightweight Virtualization (ULV).

Soluzioni come OpenVPS,Virtuozzo,Xen, le jail BSD e cosi' via, sono interessantissime ma poco pratiche in un contesto dove si vuole semplicemente eseguire il proprio framework o application server.

ULV si basa sul semplice concetto che Linux mette gia' a disposizione molti strumenti per limitare i singoli utenti del sistema. Basta semplicemente carrozzare questa struttura introducendo qualche nuova funzionalita'.

Il primo passo e' stato dotare ogni singolo processo di informazioni aggiuntive, attualmente (ottobre 2009) ogni processo utente ha le seguenti informazioni

control_uid: indica l'uid che ha il privilegio di collegamento a una porta di controllo TCP in modalita' application server 

max_as: address space massimo in megabytes

max_cpu: tempo massimo che la cpu puo' dedicare a un processo

ipv4_tcp_port: porta IPv4 locale su cui il processo puo' fare il binding

ipv4_tcp_control_port: porta IPv4 locale di controllo (dipende dall'applicazione) su cui il processo puo' fare il binding

ipv4_udp_port: 0 porta IPv4/UDP locale su cui il processo puo' fare il binding

ipv4_tcp_socket_protection: abilita il socket protection

ipv4_firewall_mask: maschera di bit per utilizzare il PerProcessFirewall

fs_readonly: abilita/disabilita il privilegio di scrittura su disco

cloned_vm: tipo di memoria usata dal processo. Se e' a 2 indica un thread

domain_id: id del dominio 

fcgi_id: inode del file fastcgi di avvio

scgi_id: inode del file scgi di avvio

wapp_id: id applicazione speciale (1 php5-cgi, 2 uwsgi, 3 urack)

apps_id: id application server

ssh_id: identifica un processo generato via ssh

cron_id: identifica un processo generato da cron

max_dom_proc: massimo numero di processi che un dominio puo' generare

max_apps_proc: massimo numero di processi che un application server puo' generare

max_apps_thread: massimo numero di thread che un application server puo' generare

max_ssh_proc: massimo numero di processi generabili via ssh

max_cron_proc: massimo numero di processi generabili ia cron

accept_cnt: numero di connessioni riceute (conta le chiamate alla syscall accept())

accept_last: timestamp unix dell'ultima chiamata ad accept()

listen_backlog: dimensione del backlog per listen(), indica quante connessioni possono essere accodate in attesa di un processo. Le connessioni successive vengono scartate.

fork_cnt: numero di fork() eseguite dal processo

fork_last: timestamp unix dell'ultima chiamata ad fork()

syscall: numero syscall attualmente in esecuzione

bio_read: numero di bytes letti da disco (non tiene conto della page cache, quindi puo' esserci anche il valore 0)

bio_write: numero di bytes scritti su disco dal processo

memory_errors: errori di allocazione di memoria, se > 0 e' molto probabile che l'address space sia in esaurimento

errors: numero di errori generati dalla chiamate a fork() e bind(), se > 0 e' molto probabile che il numero di processi non sia sufficiente

e' possibile visualizzare queste informazioni leggendo semplicemente il file /proc/<pid>/attr/current oppure inviando la syscall 357 con 2 argomenti. Il primo e' un area di memoria in cui il kernel copiera' la struttura dati del processo e il secondo e' il pid del processo a cui si e' interessati. Per gli utenti e' possibile usare solo il pid 0 che restituisce le informazioni sul processo corrente.

La struttura aggiuntiva di un processo unbit (restituita dalla syscall 357) e' la seguente:

struct uidsec_struct {
        /* network limits */
        unsigned short ipv4_tcp_port;
        unsigned short ipv4_udp_port;
        unsigned short ipv4_tcp_control_port;

        int ipv4_tcp_socket_protection;
        unsigned long long ipv4_firewall_mask;

        /* limits */
        int fs_readonly;

        /* process markers */
        int domain_id;
        int fcgi_id;
        int scgi_id;
        int apps_id;
        int wapp_id;
        int ssh_id;
        int cron_id;

        /* thread ?*/
        int cloned_vm;

        /* process limit */
        int max_dom_proc;
        int max_apps_proc;
        int max_apps_thread;
        int max_ssh_proc;
        int max_cron_proc;

        /* misc */
        int control_uid;
        int listen_backlog;
        int errors ;

        /* counters */
        int accept_cnt ;
        int accept_last;

        int fork_cnt ;
        int fork_last;

        unsigned long long bio_read;
        unsigned long long bio_write;

        int memory_errors;

};

Una volta che il kernel ha a disposizione queste informazioni e' bastato aggiungere una decina di syscall per effettuare i vari controlli sul numero di processi relativo ai vari ambienti (domini, application server, cron ed ssh).

Per quanto riguarda ssh e cron il controllo viene gestito da un modulo pam che imposta i limiti per questi 2 ambienti e che richiama le syscall necessarie.

Sicurezza

Una volta suddivisi i processi e limitate le loro risorse hardware bisogna lavorare su cosa ogni processo puo' fare e cosa no.

I moduli LSM uidsec e uidbind sono integrati in tutti i kernel unbit (da luglio 2007) e rilasciati al pubblico sotto licenza GPL2. Le versioni pubbliche hanno meno funzioni di quelle utilizzate sui nostri sistemi, tuttavia rilasciamo periodicamente le modifiche piu' interssanti per i contesti generici (Ovviamente la maggior parte delle nostre patch sono specifiche del nostro ambiente e non e' tecnicamente vantaggioso portarle altrove).

uWSGI/uRack/UFCGI/SuExecUnbit

Implementare nuove funzionalita' in un kernel e' inutile senza un supporto dello user space.

I nostri prodotti per il deploy di applicazioni web si integrano perfettamente con i nostri kernel, sfruttandone appieno le informazioni aggiuntive per permettere tecniche avanzate per migliorare l'affidabilita' delle proprie applicazioni.

Il controllo del comportamento delle proprie applicazioni web in produzione deve essere una pratica costante di un bravo sviluppatore nei primi periodi del deploy.

Tramite la sezione "Processi" del pannello di controllo potrai valutare lo stato degli applicativi e i loro consumi. Ogni qual volta hai un problema controlla lo stato dei Processi prima di contattare l'assistenza Unbit. Ci permetterai di guadagnare tempo e mantenere alta' la qualita' del servizio.

Tutti i processi generati via web e gli application server, reindirizzano lo STDERR nel file stderr_log (per alcuni ambienti e' possibile personalizzarne il path) della tua home. In caso di errori consulta lo stderr_log alla ricerca di informazioni utili.

UnbitKernel (l'ultima modifica รจ del 2009-10-31 13:27:03, fatta da RobertoDeIoris)