2018 Spring Term
February 27 2018
Virtualità
Virtualizzare qualcosa significa fornire un oggetto che possa essere usato (stessa interfaccia) efficacemente al posto dell'altro. Se si usa una scarpa per piantare un chiodo, la scarpa è un "martello virtuale".
Memoria virtuale
- Interfaccia della memoria principale: load(indirizzo), store(indirizzo, oggetto).
- Semantica: se eseguo store(i, a) seguito da load(i), la seconda operazione ritornerà a.
La memoria secondaria può essere usata per implementare l'interfaccia di quella primaria. Anche l'hardware di un calcolatore può essere visto come un'entità astratta che parla il linguaggio ISA del processore di cui fa uso. Se virtualizziamo l'hardware tramite un programma che ne implementa la stessa interfaccia otteniamo una macchina virtuale.
Possibilità di virtualizzare il tempo.
Significato di virtualsquare
Una piazza dove i vari tipi di virtualià coesistono, un laboratorio internazionale sulla virtualità.
Concetto di VIEW
I processi "vedono" l'ambiente di esecuzione. Se non stanno eseguendo istruzioni di calcolo, i processi si interfacciano ("vedono") al sistema (accedono a memoria, fanno routing) usando system calls. ogni processo può vedere un file diverso allo stesso path name
umview vecchia macchina parziale virtuale
L'Hypervisor agisce parzialmente come un debugger: intercetta le system calls ed intraprende azioni.
Virtual Distributed Ethernet (VDE)
VDE è una rete Ethernet virtuale che può essere distribuita su diverse macchine fisiche presenti in rete. Usare concetti reali nello "Standard" ethernet e vitualizzarli. ad esmpio uno switch con il vitual switch, più avanti nelle versioni sono stati creati dei "tasselli" che si posso interfacciare con vari altri tasselli per formare una rete virtuale personalizzata
Tip: "Trovate il nome giusto da dare a tutte le cose che pensate"
PeDaNTe S.P.A. (Physical, Data link, Network, Transport, Session, Presentation, Application)
Internet of Threads
Dare un indirizzo IP non alla macchina, ma direttamente al processo, questo ti pemette di migrare i processi da una macchina ad un'altra senza che il client deve riconfigurare l'IP della chiamata a quel processo (IPV6 è praticamente obbligatorio per rendere Internet of Threads utillizzabile, perchè IPV4 ha troppi pochi indirizzi) Se abbiamo due web servers virtuali sulla stessa macchina fisica vogliamo che abbiano comunque diversi indirizzi ip.
March 01 2018
INFO
Le comunicazioni e lo scambio di idee avverranno nel gruppo Telegram.
Per iscriversi/scrivere nel wiki occorre il numero magico usato già per il corso di Sistemi Operativi.
Vecchio materiale Virtual System Design
Altre risorse su GitHub
Nickname del docente
- rd235 (derivato dai documenti RFC es. RFC 1166)
- iz4dje
Tipi di virtualizzazione
finnix è un sistema operativo live da usare "quando si è nei guai", non ha interfaccia grafica e permette di provare i sistemi virtuali; la versione 1.0 è quella che funziona bene.
Il sistema operativo in cui viene eseguita la macchina virtuale, viene detto host (ospitante) mentre la macchina virtuale è chiamata guest (ospite).
Emulazione
Scrivendo un emulatore di una macchina emulo i passi di esecuzione dell'hardware: convertire le istruzioni dal linguaggio del processore che vuole essere emulato ad istruzioni per la macchina host.
QEMU è un esempio: traduce il codice macchina guest in codice macchina host (traduzione dinamica). QEMU contiene i sorgenti con le istruzioni del vari assembler (sottoforma di funzioni) che vengono messi in un vettore; fa uso di cache come fanno i browser: il codice non viene tradotto di continuo ma viene eseguito quello "in cache" e questo lo fa risultare 15/20 volte più veloce.
(NOTA: rimane in sospeso slirp, lo vedremo nel dettaglio in futuro)
Busybox è un piccolo eseguibile che combina diverse applicazioni standard Unix, in pratica le utility Unix non sono altro che un alias di busybox; si può scaricare e compilare i binari di busybox per mips (arm), se attivo il servizio binfmt-support il sistema utilizzerà QEMU per eseguire i binari mips, mentre disattivando il servizio sarà possibile utilizzare KVM.
Esempi di emulazione
qemu-system-* (wildcard) è il comando per lanciare un'architettura:
qemu-system-x86_64 -cdrom finnix-110.iso -m 512M
dove -m 512M è la quantità di ram che gli rendiamo disponibile.
Con QEMU possiamo eseguire finnix-armhf-111.iso su macchina x86_64 seguendo le istruzioni, per avere successo bisogna montare l'immagine iso ed estrarre il contenuto (initrd.xz, linux e vexpress-v2p-ca9.dtb) della directory /boot/armhf/ nella cartella da cui si lancia QEMU.
Virtualizzazione parziale
KVM, acronimo di Kernel-based Virtual Machine (utilizza VT per Intel e AMD-V per AMD), ha un comportamento a "trigger" il processore si comporta come la routine normale, soltanto quando vengono lanciate determinate call viene cambiata la routine da quella nativa a quella apposita per simulare altri processori. Questo permette di avere macchine virtuali molto più veloci, visto che girano direttamente sul processore escluse le varie eccezione rende una correlazione praticamente 1 a 1.
Si può abilitare la modalità KVM in QEMU usando l'opzione -enable-kvm che ovviamente richiede che i moduli siano stati caricati.
Virtualizzazione totale
VirtualBox è un esempio di virtualizzazione totale.
User-Mode Linux è una macchina virtuale i cui sorgenti sono presenti nel kernel linux; usa lo stesso supporto del comando strace (utile per vedere le system call di un comando); User-Mode Linux è molto vicino a umview (che appunto sta per User-Mode View); in quanto a velocità sta in mezzo tra qemu e kvm.
Differenze
QEMU virtualizzazione a livello di processo (PVM), KVM a livello di sistema (SVM), VirtualBox a livello di system call (SCVM). Vedere pag. 36 e a seguire.
qemu-system-* é formato dal processore di traduzioni dinamiche qemu_(arm, mips...) e dalle periferiche.
kvm invece non fa uso di qemu ma al posto suo usa l'accellerazione del processore (oltre alle periferiche).
qemu funziona come processo utente e non ha bisogno di permessi eccezionali; kvm invece risulta vincolato al processore (egrep '^flags.*(vmx|svm)' /proc/cpuinfo) e occorre anche il modulo kernel (lsmod | grep kvm).
VirtualBox non può convivere con KVM.
Macchine virtuali in rete
È possibile creare una propria macchina virtuale online usando le credenziali unibo okeanos grnet
Tip: molly-guard protects machines from accidental shutdowns/reboots (via ssh); è un software che se si tenta un reboot/poweroff chiede di digitare il nome della macchina, in questo modo si evita di spegnere una macchina virtuale non voluta tra le varie finestre aperte.
March 06 2018
I requisiti di virtualizzazione
I requisiti di virtualizzazione di Popek e Goldberg sono delle condizioni sufficienti per un'architettura per supportare la virtualizzazione (in modo efficiente):
- Equivalenza / Fedeltà - Un programma virtualizzato dovrebbe esibire un comportamento essenzialmente identico a quello dimostrato quando viene eseguito su una macchina equivalente direttamente.
- Controllo delle risorse / Sicurezza - L'hypervisor deve avere il completo controllo delle risorse virtualizzate.
- Efficienza / Performance
Davoli: "Il livello di sicurezza richiesto dipende dall'applicazione"
Popek e Goldberg descrivono anche le caratteristiche che l'ISA della macchina ospite deve possedere per essere in grado di far girare un hypervisor che goda dei tre requisiti precedenti.
Teoremi di virtualizzazione
Le istruzioni di un'ISA sono classificate in tre gruppi:
- Istruzioni privilegiate - le istruzioni che generano una trap se il processore è in user mode e non generano una trap se il processore è in kernel mode (e.g. divisione per zero, system call, accesso ad indirizzo di memoria non mappato).
- Istruzioni control sensitive - le istruzioni che cercano di cambiare la configurazione delle risorse del sistema (e.g. assegnare memoria, acquisire una risorsa).
- Istruzioni behavior sensitive - istruzioni che hanno comportamenti diversi a seconda della configurazione delle risorse (e.g. istruzioni che dipendono dal valore del registro di rilocazione o dalla modalità di esecuzione del processore).
Teorema relativo alle istruzioni privilegiate
Si può creare una VM effettiva se e solo se le istruzioni privilegiate sono un sovrainsieme dell'unione delle istruzioni degli altri due tipi; in altre parole tutte le istruzioni "sensitive" generano una trap se eseguite in user mode.
Le istruzioni sensitive sono quelle che possono influenzare il corretto funzionamento dell'hypervisor. Queste istruzioni devono essere tutte privilegiate.
Le istruzioni control sensitive devono essere privilegiate perché il processo virtualizzato non deve essere in grado di allocare nuove risorse a sè stesso.
Le istruzioni behavior sensitive devono essere privilegiate perché il processo virtualizzato deve vedere ...
(IBM Introduce le maccine virtuali per introdurre sistemi operativi multitasking su macchine monotask)
Negli anni 90 si producono processori senza considerare il teorema di Popek e Goldberg. L'ISA di questi processori non soddisfaceva le condizioni del teorema.
Vengono aggiunte istruzioni di virtualizzazione (da usare in ambienti virtuali) che non sono altro che le corrispettive istruzioni privilegiate delle istruzioni sensitive non privilegiate.
(Robert P. Goldberg: Architectural Principles for Virtual Computer Systems)
È difficile fare virtualizzazione tramite l'emulazione (problemi di efficienza).
L'emulazione consiste nell'emulare ogni singola funzione del sistema operativo e lo traduce per il livello sottostante.
La simulazione consiste nel convertire il codice assembler per un certo processore in codice macchina del processore di base.
Simulatore: apparenza (Simulatore di volo)
Emulatore: funzione effettiva e veritiera al 100% ma per questa molto più lenta (Ali di cera del racconto greco)
Qemu può funzionare in due modalità:
- Macchina virtuale: virtualità al livello di sistema (qemu-system-*).
- Virtualizzare solo il processore: tutte le system call sono gestite dal sistema operativo reale (qemu-*).
Esperimento: Prendere busybox per architettura arm ed eseguirlo anche se siamo su un intel
Busybox: eseguibile che fa da contenitore per molti comandi. Permette di risparmiare RAM e disco.
Sistemi embedded: spesso fatti con kernel + busybox + applicazione per cui è nato il sistema.
Finnix arm
Per far partire Finnix su Arm occorre prendere dall'immagine del file system dei file che servono all'esterno.
Per far partire un sistema occorre sicuramente il kernel e poi in molti casi (non tutti) il file system.
Il kernel viene caricato dal boot loader.
qemu-system-arm -display none -machine vexpress-a9 -m 256 \
-kernel linux -initrd initrd.xz -dtb vexpress-v2p-ca9.dtb \
-append "console=ttyAMA0,115200" -serial stdio \
-drive file=finnix-armhf.iso,id=cd0,format=raw \
-device virtio-blk-device,drive=cd0
kernel linux --> cerca nella directory corrente un file "linux" contenente il kernel
initrd è un file di configurazione che contiene i moduli kernel usato per l'inizializzazione.
Perché nasce initrd?
Il kernel quando fa boot ha bisogno dei driver per tutti i device che servono per caricare il kernel.
Se vogliamo progettare un kernel che possa fare boot da vari dischi inserire tutti i device driver di questi dischi all'interno del kernel non è una scelta saggia.
Possiamo studiare un modo per caricare solo i "moduli" che ci servono --> initrd
Quando il kernel è partito possiamo caricare i moduli che ci servono.
initrd ha al suo interno un file system (banale, di sola lettura, ad allocazione contigua) che contiene un'altra copia dei moduli kernel (.ko).
In questo modo si ha un piccolo spreco di memoria: i moduli compaiono sia in initrd che in /sys/. Ad oggi anche nei sistemi embedded si preferisce accettare questo piccolo spreco di memoria flash.
DTB (Device Tree Binary)
Descrive la configurazione del sistem on chip alla partenza.
sistem on chip: integratore contenente processore ed altre cose. Lo stesso integrato può essere configurato per fare un sacco di cose diverse. Si possono scegliere le interfacce dei device da attivare.
Quando il kernel parte, il kernel deve sapere quali device ha a disposizione, quindi la configurazione del sistem on chip va fatta prima che il kernel parta.
Il vero file contenente le informazioni (in forma testuale) è il device tree, ma dato che queste informazioni devono essere usate in tempi rapidi al boot, questo file viene compilato e si ottiene il DTB.
Possiamo ottenere i tre file di cui abbiamo bisogno montando l'immagine ISO:
mount -o ro finnix-armhf.iso /mnt
ed andando nella cartella /mnt/boot/armhf/ possiamo trovare i file copiarli e smontare l'immagine. Possiamo far partire la macchina virtuale.
Paravirtualizzazione
Il prefisso para significa simile, affine a.
La paravirtualizzazione è un'ottimizzazione del processo di virtualizzazione perché non il processore non viene emulato.
Il punto è che l'implementazione di una virtualizzazione completa talvolta non è efficiente.
E.g. Algoritmi di minimizzazione delle seek su dischi virtuali sono inutili.
Il kernel del guest deve essere informato di stare girando su un device virtuale, questo viola i principi di Popek e Goldber.
Meglio emulare perfettamente i sistemi reali o fare device ottimizzati per il mondo virtuale?
Dipende.
La virtualizzazione si può realizzare su vari livelli ed in varie modalità
Uno dei modi è quello di catturare le system call (system call interposition) o quello di catturare le chiamate ad una libreria.
Catturare le system call
ptrace è una system call che si può usare per virtualizzare le system call.
Catturare le chiamate a libreria
Funziona con le librerie dinamiche. Le librerie dinamiche sono linkate all'eseguibile solamente in fase di esecuzione. Un eseguibile non contiene le librerie, ma solamente le dipendenze alle librerie. Per vedere quali sono si può usare il comando ldd executablename.
Esempio:
La system call open non è altro che una funzione che solleva una trap tramite il comando syscall.
Potremmo trovare un modo per sovrascrivere la open della libreria standard (libc) in modo che la nuova open sia chiamata al posto dell'altra.
purelibc è una libreria che prende gran parte delle system call e le ridefinisce.
Autovirtualizzazione
Il processo stesso virtualizza le sue chiamate. L'hypervisor è una libreria.
Sicuro NO, utile SI.
In ViewOS questo meccanismo viene usato in varie occasioni. Permette di utilizzare le librerie oltre il loro scopo originale; e.g. se abbiamo una libreria che agisce su dei file e siamo interessati esclusivamente alla logica possiamo fare in modo che le system call relative ai file siano virtualizzate in modo tale da fornire i dati in altro modo.
Libreria --> purelibc purelibc libreria di autovirtualizzazione
UserModeLinux e ViewOS virtualizzano entrambi tramite system call interposition.
User mode linux virtualizza tutte le chiamate, ViewOS no.
Namespaces: implementano la virtualizzazione parziale (come ViewOS) ma all'interno del kernel. Sono più efficienti ma complicano il kernel.
Xen
L'idea su cui Xen si basa è quella di fondere insieme kernel ed hypervisor.
Siccome scrivere un intero kernel sarebbe un compito troppo impegnativo, Xen si ispira all'architettura a microkernel.
Xen implementa uno strato, che si trova direttamente sull'hardware, che usa paravirtualizzazione e che contiene solo le funzioni necessarie a gestire le macchine virtuali.
In Xen "tutte le macchine sono uguali, ma una è più uguale delle altre".
Di per sè Xen non supporta direttamente l'hardware della macchina reale, infatti non contiene i device driver, ma sfrutta quelli della prima macchina virtuale (domain0). Se non configurato diversamente tutti i device vengono gestiti dal domain0. Tutto ciò che arriva dall'hardware viene inoltrato al domain0. Domain0 vede quindi device virtuali che sono rappresentazioni esatte dei device fisici.
KVM ha dimostrato di avere ormai le stesse prestazioni di Xen. Quindi potrebbe essere una buona idea quella di usare un Linux minimale con KVM al posto di Xen.
March 08 2018
ptrace è una system call che permette ad un processo di controllare un altro processo. Inizialmente si usavano i segnali stop and continue. Nelle prime versioni era proibito usare i segnali stop e continue se il processo era tracciato. Nelle ultime versioni c'è un nuovo modo di collegarsi ad un processo: PTRACE_SEIZE.
(VUos usa virtualizzazione parziale)
3 tipologie di viste per un unico sistema
Nei panni degli utenti
L'idea di VUos è di fornire ad un processo un ambiente diverso; VUos usa il concetto di modulo (come nel kernel) ovvero abilita delle funzionalità; abbiamo moduli e sottomoduli (usati per specifiche implementazioni delle funzionalità dei moduli): http://wiki.v2.cs.unibo.it/wiki/index.php?title=Main_Page
Moduli:
- UM-Fuse (versione vecchia) --> VUfuse (versione nuova) modulo per la virtualizzare file system.
- Compatibile con Fuse; modulo del kernel di Linux con lo stesso scopo.
- Fuse si trova nel kernel, i sottomoduli no.
- Se si compilano gli stessi sorgenti per Fuse linkando la libreria di UM-Fuse lo stesso sorgente funziona con UM Fuse.
- (Tip: meglio non riscoprire l'acqua calda ed uniformare le interfacce ed usarlo)
- Sottomoduli:
- umfuseext2 (fuseext2) (monta anche ext3 ed ext4)
- umfusefat (libfat)
- umfuseiso
- umfusessh
- umfusecrypt
- UM Net --> VUnet
- Consente di avere una visione virtualizzata della rete.
- Sottomoduli:
- umnetlwipv6 (lwipv6)
- UM Dev
- Sottomoduli:
- umdevmbr - Master Boot Record
Esempio UM Dev:
Possiamo montare l'immagine di un disco con UM Dev e montare la prima partizione con umfuseext2 (se la partizione è ext2).
Immagine di un disco = tabella partizioni (MBR o GPT) + partizioni (file system all'interno delle partizioni).
mount
ed il file system sono i punti cardine dell'architettura Unix; Unix da nome alle cose tramite il file system.
Esempio fatto dal prof:
truncate -s 1G mydisk # creiamo l'immagine del disco
umview xterm # facciamo partire la macchina virtuale parziale su un terminale xterm
#nel terminale xterm
um_add_service umdev umfuse # aggiungiamo i moduli
ls /dev/hda
mount -t umdevmbr mydisk /dev/hda # umdevmbr è il tipo di montaggio
#Il disco montato sarà visibile solamente nel terminale della macchina virtuale (e nei suoi figli).
#ViewOS si accerta che esista un modulo che faccia match con la prima parte del nome (umdev) e dà la chiamata in gestione al modulo.
#A quel punto la libreria (umdevmbr.so) viene caricata in memoria.
locate umdevmbr.so
ls -l /dev/hda # verifichiamo il montaggio
/sbin/fdisk /dev/hda # creaiamo la tabella delle partizioni come in un disco reale
# Il file mydisk è l'immagine di un disco in formato raw.
# Se facessimo cat di mydisk e ridirezionassimo l'output in un disco da 1G, l'hard disk si partizionerebbe e conterrebbe esattamente il contenuto del file.
# in alternativa a cat si usa dd perchè è ottimizzato per file di grandi dimensioni (usa grandi cache)
ls /dev/hda1
/sbin/mkfs.ext2 /dev/hda1 # make file system ext 2
/sbin/fsck.ext2 -f /dev/hda1 # file system check
ls /mnt
mount -o rw+ -t umfuseext2 /dev/hda1 /mnt # montiamo il disco ('''nidifichiamo la virtualizzazione''')
# ora tutte le chiamate verso /mnt saranno catturate e virtualizzate
ls /mnt # dovrebbe comparire solo lost+found
# echo "ciao" > /mnt/ciao
Nidificazione della virtualizzazione
Se creiamo un file il nostro processo fa una open
al pathname: la system call viene intercettata da ViewOS in quanto stiamo accedendo ad un path virtualizzato.
L'hypervisor si accorgerà che il file system è virtualizzato da umfuseext2
, che sa come fare la open sul file system virtuale (generando una write
ad un certo offset nell'immagine della partizione).
Anche la partizione però è virtualizzata: la chiamata dovrà essere intercettata dal modulo umdevmbr
(che virtualizza le partizioni); questa chiamata tuttavia è generata dall'hypervisor.
Com'è possibile che l'hypervisor catturi la sua stessa chiamata e la virtualizzi nuovamente? --> purelibc
/etc/fstab
contiene la tabella dei filesystem
Un file system non deve essere mai montato da più macchine; vale anche per i file dei filesystem virtuali.
Tramite i comandi standard siamo in grado, con i permessi di utente, di fare operazioni che potrebbero essere svolte solo da root.
Queste operazioni si potrebbero fare anche senza virtualizzazione, ma servirebbero i permessi di amministratore e avremmo molti limiti.
loop device dispositivo a blocchi asssociato dinamicamente ad un file e che serve per vedere il file come una memoria di massa.
ViewFS
ViewFS è un modulo che virtualizza la struttura dei file system.
um_add_service viewfs
mkdir /tmp/newroot
viewsu
mount -t viewfs -o mincow,except=/tmp,vstat /tmp/newroot /
mincow
ed except
sono opzioni di ViewFS
COW
COW (Copy On Write): Si accede un file in sola lettura ed ogni volta che lo si modifica ne si fa una copia.
I risultati saranno visibili solamente a noi.
mincow: ogni volta il sistema proverà ad accedere in scrittura al file e se non ce la fa lo farà in modalità cow.
Si possono installare pacchetti debian virtualmente usando metodo copy on write (possiamo testare l'installazione di nuovi pacchetti).
qcow
Formato usato da qemu per le immagini dei dischi. Usa COW al livello dei blocchi di disco.
Se si modifica il file originale del cow si possono attuare varie politiche. Qemu non dà alcuna garanzia. ViewOS non permette la modifica.
umview è disponibile nei repository di debian o (aggiornato) su SourceForce.
unreal
Modulo di test: fa vedere l'intero file system come se fosse in /unreal
ed anche dentro /unreal/unreal
.
Si possono fare vari esperimenti, e.g. andare dentro /unreal
e lanciare comandi come make
.
Se make
si comporta nello stesso modo la virtualizzazione sta funzionando.
Tip: principio chiave del debugging - separare le responsabilità.
umview --> umvu
umbinfmt
KMVIEW
Fratello di UMVIEW. Molto veloce perché usava un modulo kernel sperimentale che però non entrerà a far parte nel kernel. Permetteva, al livello del kernel, di distinguere i file descriptor reali da quelli virtuali. La virtualizzazione costava solo 4%.
Berkeley socket
L'interfaccia Berkeley socket deve essere aggiornata nei tempi in quanto possiede intrinsecamente l'idea di view globale (global view assuption).
I parametri della chiamata socket sono tre:
- famiglia (domain, ipv4)
- servizio (type)
- protocollo
Se vogliamo un socket AF_INET (ipv4), di tipo SOCK_STREAM, con protocollo di 0 (di default, TCP) non abbiamo modo di scegliere lo stack di rete.
Se potessimo avere a disposizione d'uso diversi stack di protocolli di rete potremmo avere nuovi tipi di applicazioni ed avere soluzioni più semplici a problemi noti.
In virtual square l'API dei Berkeley sockets è stata estesa con un API chiamata msockets: - permette l'utilizzo di più stack di rete allo stesso tempo. - il file system viene usato per dare nome agli stack di rete (molto Unix consistent). - è compatibile con il passato.
Gli stack di rete appaiono quindi nel file system come file speciali. Si può fare mount dello stack. Vedere libro di Virtual square per maggiori informazioni.
umattach
Si può virtualizzare qualche processo che sta già eseguendo. Se la view di un processo cambia improvvisamente potrebbero generarsi delle incoerenze.
Nei panni degli sviluppatori
purelibc
purelibc è una libreria che a differenza di libc prevede l'esclusione delle systemcall in modo da lasciare la libertà di usare le systemcall che si preferisce.
libc = libreria c + libreria di system call (la libc è una libreria c ibrida)
Una vera libreria c quando avviene una printf deve svolgere i calcoli e chiamare la write. Non possiamo usare la libc ridefinendo le system call perché quando la printf chiama la write essendo una libreria unica il linker ha già risolto la chiamata. Per fare ciò abbiamo bisogno di una libreria pura, che non implementi le system call al suo interno. L'hypervisor di ViewOS usa purelibc. Attualmente la purelibc è complessa ed usa il meccanismo del dynamic linker preload per virtualizzare (vedere la documentazione di purelibc).
La purelibc al momento è implementata come layer al di sopra della libc. Questo è scomodo. Se qualche system call fosse aggiunta dovremmo aggiungerne un'altra anche in purelibc.
execs --> progetto praticamente concluso
cado
cado: sudo con le capability (privilegio).
Le capability permettono di separare le prerogative di root e di poterle assegnare in maniera separata, possono essere assegnate a processi o a file.
man capabilities
Un processo può avere 4 classi di capability. Le possiamo vedere in /proc/id_processo/status
cat /proc/$$/status
Capabilities
- Permitted - che possono essere attivate dal thread.
- Inheritable - che possono essere ereditate.
- Effective - attive. Sono sempre un sottoinsieme dei permitted.
- Ambient - sono mantenute a patto che il file non sia privilegiato.
Bound - maschera non modificabile che indica quali capabilities il sistema è in grado di gestire.
Capabilities dei file
Capabilities ambient: sono mantenute a patto che il file non sia privilegiato. Se si ha una capability ambient essa è considerata come permitted e come effective.
Come cambiano le capabilities quando si chiama una exec?
/etc/sudoers
--> file di configurazione di sudo (anche cado ha un file di configurazione)
namespace
Si possono dare ai processi visioni diverse sulle risorse.
man namespaces
Rete, IPC, PID.
I namespaces sono stati implementati male: funzionano ma sono molto pesanti da utilizzare e vengono usati dai processi senza che l'utente non ne abbia visibilità ( Chromium per creare dei sandbox usa i namespaces ).
I namespace si possono creare in 3 modi diversi:
- clone: crea un nuovo processo con namespace associato.
- setns: permette ad un processo di unirsi ad un namespace esistente.
- unshare: il processo chiamante si collega ad un namespace nuovo.
Nei panni degli sviluppatori core
March 13 2018
Quando si trasmette una lista di interfacce in protocollo netlink
prevede il pacchetto "done" come sentinella finale. In alternativa si può usare busybox ip addr
in quanto ip addr
di busybox non fa nessun controllo sul pacchetto done.
#Facciamo partire una macchina virtuale in un terminale.
umview xterm
#Vediamo le vere interfacce di rete.
ip addr
#Carichiamo il supporto per le reti virtuali.
um_add_service umnet
#vde vuole indirizzi simili agli url.
#???????? vedere meglio nella documentazione ???????????????
mount -t umnetlwipv6 -o vde0=vxvde:// none /dev/net/mynet
#Osserviamo di nuovo le interfacce di rete.
ip link
#Vediamo le interfacce precedenti in quanto la nuova rete non è montata come rete di default.
#Possiamo avere tanti stack diversi ognuno con le sue interfacce.
#mstack --> multiple stack; comando di umview usare lo stack selezionato.
mstack /dev/net/mynet ip link
#Se volessi far partire un browser su quello stack dovrei fare
mstack /dev/net/mynet firefox
#Se volessi far partire una connessione ssh
mstack /dev/net/mynet ssh
#Se volessimo avviare un terminale che vive nella rete nuova potremmo fare
mstack /dev/net/mynet bash
ip addr add 10.0.0.1/24 dev vd0
ip link set vd0 up
Se adesso su un'altra macchina della rete locale facessi le stesse operazioni con un indirizzo ip diverso, le macchine avrebbero la possibilità di mettersi in contatto.
Per completezza dell'esempio realizziamo l'altro stack con vdens (namespace di vde).
Parte dell'esempio fatto dal prof; qui viene usato in entrambi i terminali vdens, mentre il prof a lezione ha usato per uno umnet e vdens per l'altro. Sono necessari vdens ,vdeplug4 ( e forse anche vxvdex).
Per entrambe le sessioni del terminale setto una variabile d'ambiente in modo che mi cerchi la libvdeplug.so.4 in /usr/local/lib.
export LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib
Terminale 1
vdens vxvde://
ip link set vde0 up
ip addr add 10.0.0.1/24 dev vde0
ping 10.0.0.2
nc 10.0.0.2 2222
#scrivendo dei messaggi nel terminale 1 compariranno nel 2 e viceversa
Terminale 2
vdens vxvde://
ip link set vde0 up
ip addr add 10.0.0.1/24 dev vde0
#ora nel terminale 1 posso eseguire ping 10.0.0.2
nc -l 2222
#ora nel terminale 1 posso eseguire nc 10.0.0.2 2222
Stack TCP/IP: o implementato a livello utente come libreria o implementato nel kernel.
umview
--> prima opzione.
vdens
--> chiede al kernel di costruire un altro stack TCP/IP per questo utente (sfrutta i namespace).
nc
(alias netcat
) coltellino svizzero per esperimenti su rete.
#Connessione TCP alla porta 22 di maddalena
nc mad.cs.unibo.it 22
#Connessione alla porta 80
nc 130.136.1.110 80
nc permette di collegarsi tramite TCP e di scrivere HTTP manualmente
#Faccio un server TCP in ascolto su porta 2222
nc -l 2222
#Mi connetto alla porta 2222 dell'indirizzo 10.0.0.2
nc 10.0.0.2 2222
Un utente può creare tutti gli stack di rete che vuole ed averne vari a disposizione con configurazioni diverse.
Esempio: possiamo lanciare un browser facendo in modo che il browser non sia logicamente dove siamo ma usi un ip di un'altra area geografica.
- Così facendo inganneremmo where si my ip
- Comodo per testare la neutralità della rete. Stessa pagina acceduta con ip di aree geografiche diverse appare nello stesso modo.
Se volessimo implementare un VPN per sicurezza aziendale normalmente dovremmo spostare tutta la macchina dentro il VPN, con questo metodo possiamo avere un solo stack connesso al VPN.
I supporti di rete, file system e device, portandoli fuori dal kernel in user mode ricordano il concetto di microkernel.
ViewOS serve anche per poter fare una transizione dolce dai kernel monolitici ai microkernel; è come avere un microkernel configurabile a runtime.
- Possiamo decidere di tenere parti del kernel (moduli) in spazio utente tramite moduli di ViewOS. è meno efficiente ma più sicuro e si usa solo all'occorrenza.
- Se dovessimo gestire un tipo di file system appena inventato (di cui non abbiamo il supporto nel kernel) per inserire il supporto del kernel dovremmo ricompilare tutto; Se usiamo un modulo a livello utente no.
ViewOS è una specifica; per ora è stato implementato tramite system call interposition (ptrace), ma può essere implementato in altri modi.
Potremmo implementare il tutto attraverso i namespace, nel kernel (e.g. vdens). Creare diversi visioni dell'ambiente.
March 15 2018
Lezione sospesa causa lauree.
March 20 2018
March 22 2018
March 27 2018
Registrazione 27/03/18 pt1 pt2
Esempio su veth
Terminale 1
sudo bash
ip link add type veth
ip link
# solo per avere una panoramica del comando
ip netns help
ip netns add renzonet
ip netns list
#trasferiamo veth1 nel namespace appena creato renzonet
ip link set veth1 netns renzonet
ip netns exec renzonet ip addr
ip addr add 10.1.1.1/24 dev veth0
ip link set veth0 up
Terminale 2
sudo bash
ip netns exec renzonet bash
ip addr add 10.1.1.2/24 dev veth1
ip link set veth1 up
ping 10.1.1.1
# per riportare le cose allo stato precedente
#il comando si prende la libertà di eliminare anche veth0 e veth1 create con 'ip link add type veth'
ip netns delete renzonet
April 05 2018
Esempio fatto alla fine riguardo la gestione dei file in umvu
umvu xterm
Terminale xterm 1
#step 1
xterm &
vu_insmod mountreal
#step 3
ps -ax | grep less #leggo il pid di less /unreal/etc/services
cd /proc/pid/fd # pid è quello letto poco prima
ls -l | grep .vu
Terminale xterm 2
#step 2
less /unreal/etc/services #less mostra il file e lo mantiene aperto
April 10 2018
April 12 2018
April 17 2018
Registrazione del 17/04 pt1 pt2