Sandboxing sicuro più semplice possibile (risorse limitate necessarie)


15

Sto lavorando a un progetto che implementa simulazioni distribuite: il codice arbitrario viene eseguito su più nodi e i risultati vengono successivamente raccolti e aggregati.

Ogni nodo è un'istanza di una macchina virtuale Ubuntu Linux ed esegue un processo principale che si occupa di inoltrare il codice da eseguire a un numero di processi di lavoro (1 per ogni core).

Questa domanda riguarda come assicurarsi che ciascun lavoratore operi in un ambiente sandbox senza ricorrere all'uso di un'istanza di macchina virtuale per ognuno di essi. I requisiti esatti per i lavoratori sono:

  • fs : nessuna autorizzazione di scrittura, autorizzazione di sola lettura limitata a una singola directory (e sottocartelle)
  • net : sono consentite solo comunicazioni locali (IPC, TCP, qualunque cosa ...)
  • mem : limite sull'utilizzo della memoria (nessuna memoria di scambio) uccide se supera il limite mem
  • cpu : solo 1 core consentito, uccidi se oltre il limite di tempo

Non dovrebbero essere imposte altre limitazioni: il lavoratore dovrebbe essere in grado di caricare librerie dinamiche (dalla cartella di sola lettura), generare nuovi thread o processi, chiamare la funzione di sistema, ecc ecc ma i limiti devono essere ereditati dalle entità generate / caricate e dovrebbe applicarsi in modo sommario (ad esempio non possiamo avere un lavoratore che genera due thread che usano 800 MB ciascuno, il limite di memoria per tale lavoratore è 1 GB).

Va da sé che il lavoratore non dovrebbe avere modo di aumentare i propri diritti.

Ho trascorso molto tempo a recensire le alternative disponibili (SELinux, AppArmor, cgroups, ulimit, namespace Linux, LXC, Docker, ...) per la soluzione più semplice che soddisfa i miei requisiti ma la mia esperienza sul campo è limitata.

Comprensione attuale: LXC e Docker sono un po 'difficili per il mio caso d'uso e non sono completamente sicuri 1 . AppArmor preferibile a SELinux a causa della configurazione più semplice, usalo per restrizioni fs e net; i cgroup preferibili a ulimit (che opera su un singolo processo), lo hanno usato per le restrizioni mem e cpu.

È questo il modo più semplice per raggiungere il mio obiettivo? Posso usare esclusivamente AppArmor o cgroups? C'è qualche ovvio buco nella sicurezza nel mio modello? La linea guida dovrebbe essere "il lavoratore può abbattere se stesso ma nient'altro" .


2
Se il limite delle risorse [ing] è il tuo obiettivo, potresti fare molto meglio di un guest Ubuntu (o davvero qualsiasi derivato Debian per quella materia) . In ogni caso, probabilmente vuoi linux in modalità utente e / o (con kernel recenti) lo spazio dei nomi utente
mikeserv

2
LXC sembra esattamente ciò di cui hai bisogno. Perché pensi che sia pesante e insicuro? (Certo, ha avuto dei bug, ma ha anche tutto ciò che potresti usare.)
Gilles 'SO- smetti di essere malvagio' il

La presentazione collegata (certamente dal 2011) e la sezione Sicurezza della documentazione Ubuntu LXC che parla di "perdite di spazi dei nomi" non sono molto rassicuranti. Sembra che LXC, basato principalmente su spazi dei nomi e cgroups, potrebbe essere l'opzione migliore in questo momento comunque. Ho anche trovato Linux-Sandboxing , lettura interessante
StephQ

Potrebbe richiedere un po 'di riattrezzaggio, ma hai mai pensato di correre su jail BSD?
Ryder,

Mentre LXC potrebbe essere "pesante" in quanto è come un gruppo di macchine virtuali, è davvero semplice realizzarle. Alcune di queste soluzioni, mentre "più leggere" potrebbero richiedere molta configurazione. Con LXC, potrebbe non essere necessario configurare elementi come la scrittura, poiché l'unica app avrebbe l'intero contenitore.
MikeP,

Risposte:


1

Sì, puoi usare cgroups e SELinux / AppArmor esclusivamente per monitorare e controllare il codice arbitrario che eseguirai.

Con i cgroup, puoi fare quanto segue:

  1. Limitare l'utilizzo del core della CPU a 1 CPU con il cpusetsottosistema
  2. Imposta i limiti di utilizzo della memoria con il memorysottosistema, monitorando anche le forcelle. Vedi https://github.com/gsauthof/cgmemtime per un esempio.
  3. Impedisci l'accesso alla rete a tutto ciò che non è attivo locon il net_priosottosistema.

E con SELinux / AppArmor, è possibile limitare l'accesso in lettura / scrittura al processo.

Nota: non ho familiarità con AppArmor, ma è un sistema di controllo dell'accesso obbligatorio (MAC), il che significa che proteggere la scrittura e la lettura è il suo lavoro.

L'uso di questi sistemi è una questione di scrittura delle configurazioni appropriate. Naturalmente, tutto ciò è molto più facile a dirsi che a farsi. Quindi, ecco alcuni link di riferimento per iniziare:

In bocca al lupo!


1

Scarterei SELinux per AppArmor solo se usassi Ubuntu . (davvero piuttosto difficile)

LXC non è sicuro da solo Se hai bisogno di sicurezza devi usarli tramite libvirt (basato su SELinux MLS ).

Il tuo problema è infinito, quindi non cercare di trovare una soluzione dallo scaffale e senza un tempo infinito, ricorda che anche kernel.org è stato sfruttato e molto recentemente l' FBI ha dichiarato che qualcuno ha usato i loro sistemi per anni senza essere scoperto fino ad ora.

Andrò con LXC / libvirt per una sicurezza abbastanza buona o proverò i "nuovi" contenitori Intel Clear , che usano una VM molto leggera per il tuo contenitore con un uso chiaro di DAX / KSM (non li ho testati ma sembrano molto davvero promettente).

Se sei preoccupato per lo sfruttamento del kernel, grsecurity è la tua soluzione ma dovresti integrarla con la tua soluzione container (sicuramente mal di testa).

Quindi non è un compito facile, LXC / libvirt sono davvero ordinati, ma forse i contenitori trasparenti sono la strada da percorrere.

Docker? Non ho / non userò docker per più di test locali quando non c'erano box vagabondi disponibili, hanno bisogno di molto più lavoro e di una comunità migliore.

Naturalmente anche i contenitori systemd sono belli, ma presumo che non ti piacciano / li desiderino perché non li hai nemmeno menzionati e non sono una soluzione agnostica del fornitore.

Se vuoi qualcosa di "più semplice" e più amatoriale potresti dare un'occhiata a Firejail , lo sto usando per alcune "app" desktop e fa il lavoro (è abbastanza facile creare il modello per la tua app personalizzata, usa "privato" si monta in cima alle directory e limita la rete solo per uso locale, i processi generati ereditano per parent e continua ...).

Saluti e divertiti senza impazzire. ;)


0

seccomp-bpf è un'altra opzione che funziona bene con OpenSSH, vsftpd e Chromium ha solo exit (), sigreturn (), read () usa anche write () sebbene permetta di filtrare le chiamate di sistema usando le regole configurabili del filtro pacchetti di Berkeley. Potrebbe anche essere usato in combinazione con cgroups per memoria, CPU ecc ...

https://wiki.mozilla.org/Security/Sandbox/Seccomp


0

Potresti voler esaminare i sistemi di grid computing. In particolare, BOINC ( http://boinc.berkeley.edu ) controlla quasi tutte le tue caselle.

Credo che funzioni sui tuoi parametri in quanto tale:

fs: può leggere / scrivere nella propria directory, da nessun'altra parte

net: può essere configurato per consentire l'accesso alla rete solo al server BOINC, ma non è predefinito IIRC

mem: sì, limiti di memoria separati per macchine inattive e non inattive

cpu: sì, può persino dire "non eseguire se il computer non è inattivo"

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.