introduzione user mode linux
TRANSCRIPT
1
INTRODUZIONE A USER MODE LINUX
Ing. Michele Messorihttp://weblab.ing.unimo.it/people/messori
2
Overview di User Mode Linux
3
User Mode Linux
• Esegue il Kernel di Linux come se fosse un normale programma Linux
• Crea un ambiente
– Protetto
– Facilmente ispezionabile
– Facilmente controllabile
• Homepage
– http://user-mode-linux.sourceforge.net/
4
Storia di User Model Linux
• Febbraio 1999:
– Jeff Dike inizia a lavorare a User Mode Linux
– La prima versione si presenta come una patch per il kernel versione 2.0
• 1999-2002:
– Lo sviluppo di User Mode Linux procede in parallelo a quello del kernel
– User Mode Linux è sempre una patch esterna per i kernel versioni 2.0, 2.2, 2.4
• Settembre 2002:
– User Mode Linux è inserito nel kernel 2.5.34
• Oggi:
– User Mode Linux è parte del kernel 2.6
– Attenzione: ha dei problemi di compilazione se la libc usa NPTL (in teoria risolti dalla versione 2.6.17)
5
Come funziona (1)
• Di norma i processi si appoggiano sul kernel del sistema operativo che incapsula l'hardware
• User Mode Linux aggiunge un livello software
Hardware
Operating Systemkernel
Proc. Proc.
Hardware
Proc. Proc.
Proc.
UML
Hostsystem
Operating Systemkernel
6
Come funziona (2)
• User Mode Linux aggiunge uno strato software
– Per il kernel “Host” è un processo normale
– Per i processi che girano sulla macchina virtuale è un kernel
– Offre risorse virtuali (rete, dischi, CPU, ...)
• User mode Linux è un kernel full featured
– Nei sorgenti del kernel è una nuova architettura hardware (um)
– Modifiche di alcuni aspetti architecture dependent nel kernel (directory /arch/um nei sorgenti)
– Tutto il resto del kernel rimane invariato
7
A cosa serve User Mode Linux
• Debugging del kernel
– Se il kernel UML si pianta si può analizzare cosa è andato storto
• Sicurezza
– Un problema (o una compromissione) su UML non interessa il resto della macchina
– Jail system (bind, sendmail), Honeypot
• Testing dei sistemi
– Consente di creare reti virtuali
– Consente di provare diverse ditribuzioni
• Didattica
– Se gli studenti fanno qualche danno non compromettono le macchine “vere”
8
Programma su User Mode Linux
• Argomenti trattati:
– Meccanismo di funzionamento di User Mode Linux
– Gestione dei dischi
– Configurazione della rete
– Networking con uml_switch
– Management console
– Dischi partizionati, dischi raw, hostfs (tempo permettendo)
• Argomenti non trattati:
– Networking con tun/tap per accedere alla rete fisica
– X11
9
Dettagli tecnici
10
Il cuore del funzionamento di UML
• UML intercetta le interazioni tra sistema operativo e processi che girano nella macchina virtuale
• Tali interazioni (system call) vengono gestite dal kernel UML che fa da intermediario con il kernel “vero”
• Queste operazioni vengono realizzate sfruttando la system call ptrace
• Tale system call è usata principalmente dai debugger
• Consente ad un processo di monitorare e controllare l'esecuzione di una altro processo
– Osservare memoria
– Esecuzione step-by step
– ...
11
System call ptrace
• long ptrace(
– enum __ptrace_request request,
– pid_t pid,
– void *addr
– void * data);
• request
– PTRACE_TRACEME: il processo dice al padre di essere pronto ad essere “tracciato”
– PTRACE_ATTACH: un processo richiede di tracciare un altro processo (il parametro pid indica il bersaglio dell'operazione di tracing)
12
Tracciare processi
• Quando un processo viene tracciato:
– Il kernel blocca il processo tracciato ogni volta che questo riceve un segnale
– Il kernel informa il processo tracciante mediante un opportuno segnale
• Atri usi di ptrace: osservare/modificare lo spazio di indirizzamento di un processo
– PTRACE_PEEKTEXT, PTRACE_PEEKDATA, PTRACE_PEEKUSER
– PTRACE_POKETEXT, PTRACE_POKEDATA, PTRACE_POKEUSER
– Uso dei parametri *addr e *data per accedere alla memoria
13
L'uso di ptrace utile per UML
• Il campo request = PTRACE_SYSCALL
– Interrompe il processo tracciato ogni volta che questo esegue una system call
– Consente di intercettare e ridefinire il comportamento delle varie system call
• In pratica il kernel UML è un incrocio tra un kernel di un sistema operativo e un debugger
14
Altri usi della system call ptrace
• Controllo della memoria (ricerca di memory leak)
– valgrind
• Debugging
– GDB (The GNU Project Debugger)
• Monitoring di processi
– strace
15
Esperienza: uso di strace (1)
$ strace echo pippo
execve("/bin/echo", ["echo", "pippo"], [/* 30 vars */]) = 0
uname({sys="Linux", node="chrysophylax", ...}) = 0
brk(0) = 0x804d000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe9000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=57684, ...}) = 0
old_mmap(NULL, 57684, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fda000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/tls/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220U\1"..., 512) = 512
16
Esperienza: uso di strace (2)
fstat64(3, {st_mode=S_IFREG|0644, st_size=1153188, ...}) = 0
old_mmap(NULL, 1159068, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7ebf000
old_mmap(0xb7fd0000, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x111000) = 0xb7fd0000
old_mmap(0xb7fd8000, 8092, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fd8000
close(3) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7ebe000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7ebe6c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
munmap(0xb7fda000, 57684) = 0
17
Esperienza: uso di strace (3)
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=1593424, ...}) = 0
mmap2(NULL, 1593424, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7d38000
close(3) = 0
brk(0) = 0x804d000
brk(0x806e000) = 0x806e000
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d37000
write(1, "pippo\n", 6pippo
) = 6
munmap(0xb7d37000, 4096) = 0
exit_group(0) = ?
18
Esperienza: uso di strace (4)$ strace -c echo pippo
# -c = Count time, calls, and errors for each system call and report a summary on program exit.
pippo
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
43.12 0.000279 279 1 execve
26.89 0.000174 174 1 write
6.65 0.000043 14 3 open
6.65 0.000043 7 6 old_mmap
4.33 0.000028 14 2 munmap
2.78 0.000018 6 3 3 access
2.47 0.000016 4 4 fstat64
2.16 0.000014 7 2 mmap2
1.39 0.000009 3 3 brk
1.24 0.000008 3 3 close
1.08 0.000007 7 1 read
0.62 0.000004 4 1 uname
0.62 0.000004 4 1 set_thread_area
------ ----------- ----------- --------- --------- ----------------
100.00 0.000647 31 3 total
19
Dettagli implementativi di UML
• UML usa la system call ptrace per intercettare le system call
• Tre versioni:
– Modalità tracing thread
– Modalità SKAS 3
– Modalità SKAS 0
20
UML in modalità tracing thread
• Uso di uno speciale kernel thread chiamato tracing thread
• Ogni processo UML si mappa su un processo dell'host system.
Visione dei processi“lato UML”
Visione dei processi“lato Host”
Codice e datidel kernel UML
TracingThread
21
UML in modalità tracing thread
• Ogni system call viene mappata con un segnale Unix
• Non sono necessarie modifiche all'host kernel
– Usa funzioni già presenti nella system call ptrace
• Il meccanismo ricorda quello che nel microkernel Mach era chiamato trampoline
• Limiti del tracing thread
– Scarsa protezione (spazio di indirizzamento condiviso tra processo e tracing thread)
– Non completamente trasparente (un programma può capire se gira su UML)
– Lento (4 context switch e 1 segnale)
Proc.
Host kernel
Tracingthread
12 3
4
22
UML in modalità Skas 3
• SKAS: Separate Kernel Address Space
• Versioe di riferimento SKAS 3
Visione dei processi“lato UML”
Visione dei processi“lato Host”
Codice e datidel kernel UML
23
UML in modalità Skas 3
• Distinzione netta tra kernel space e user space anche in UML
• Un solo processo a livello host impersona di volta in volta un diverso processo UML
• Le system call e i context switch vengono eseguite modificando lo spazio di indirizzamento del processo
• Necessita di soluzioni particolari per la gestione della memoria (basata su segnali Unix)
• Necessita di ptrace modificata nell'host kernel
– PTRACE_SWITCH_MM
– PTRACE_FAULTINFO
– Si può vedere se il supporto SKAS è abilitato nell'host system guardando se esiste il file /proc/mm
24
UML in modalità Skas 3
• Approccio tipico di sistemi microkernel di nuova generazione (Mach 4.0, L4)
• Punti di forza di SKAS
– Protezione user space/kernel space
– Completamente trasparente (il processo non riesce a capire se esegue su linux nativo o su UML)
– Veloce (il numero di context switch è ridotto a 2)
• Svantaggio:
– Richiede la modifica dell'host kernel (mediante patch)
– SKAS 3 è definito “poco elegante” dal suo stesso autore
– SKAS 4 potrebbe essere parte dei nuovi kernel (ma è dal 2003 che lo aspettiamo!)
25
UML in modalità Skas 0
• SKAS: Separate Kernel Address Space
• SKAS 0: proposta di Paolo Giarrusso
• Molto usata specialmente su piattaforme HW diverse da i386 (E.g. S390, x86_64)
Codice e datidel kernel UML
Visione dei processi“lato UML”
Visione dei processi“lato Host”
Codice e datidel kernel UML
26
UML in modalità Skas 0
• Soluzione intermedia tra SKAS 3 e Tracing thread
• SKAS 3 richiede modifiche all'host kernel
– Gestione della paginazione della memoria
– Gestione di alcuni segnali
• SKAS 0 implementa queste funzioni in una serie di “stub” presenti nello spazio di indirizzamento dei processi
• Il codice presente e' minimo
– Solo alcuni signal handler vengono usati
– < 8K di codice
– Il kernel e I suoi dati rimangono in un altro spazio di indirizzamento
27
UML in azione
28
Come si presenta UML
• Eseguibili
– linux (il kernel)
– uml_moo, uml_mkcow (utility per la gestione dei dischi in modalità Copy On Write)
– uml_switch (gestione della rete virtuale)
– uml_mconsole (gestione delle macchine dall'esterno)
– altre utility...
• Richiede un immagine di un filesystem funzionante (un file organizzato come se fosse un disco fisso)
• NOTA: in questo corso ci si concentra su un sistema Debian GNU/Linux
29
Lanciare il kernel (1)
• Eseguibile linux
– linux [opzioni kernel] [opzioni init]
• Opzioni del kernel
– ubd<N> indica un disco virtuale (<N> è un numero) ubd<N>=[<cow_file>,]<image_file> <image_file> è il nome del file con l'immagine del filesystem <cow_file> è un file di appoggio per la modalità copy on write
– root=<nome_device> specifica la root partition, di solito non è necessaria messaggio di errore “I have no root and I want to scream”,
tratto da un racconto di H. Ellison
– mem=<quantità di memoria della macchina virtuale>
30
Lanciare il kernel (2)
• Opzioni del kernel
– eth<N>=daemon,,unix,<socket> Daemon indica che usiamo il sistema uml_switch per
simulare una rete virtuale Socket è il punto di ascolto di uml_switch Esistono altre modalità di gestione della rete ma richiedono
privilegi particolari per poter essere utilizzate (e.g. modalità tuntap)
– devfs=mount Abilita l'utilizzo del dev filesystem Usata con UML versione 2.4
31
Creazione di un filesystem (1)
• $ dd if=/dev/zero of=nuovofs.ext2 bs=1 count=1 seek=300M
entrati 1+0 record
usciti 1+0 record
1 bytes transferred in 0,113273 seconds (9 bytes/sec)
– dd= comando data dump, legge e scrive dati in modo raw
– Leggo da /dev/zero
– Scrivo su nuovofs.ext2
– La dimensione dei blocchi da scrivere è 1 byte
– Leggo e scrivo 1 blocco (di 1 byte)
– Lo scrivo sul file a partire dalla posizione 300Mb rispetto all'inizio del file
32
Creazione di un filesystem (2)
• Ho creato uno scattered file
– Ho un file lungo 300M di cui solo 1 byte è scritto il resto non viene allocato sul disco
– $ ls -lh mostra la dimensione del file (-h=human readable)
-rw-r--r-- 1 riccardo riccardo 301M 2005-05-05 11:52 nuovofs.ext2
– $ls -lhs mostra l'occupazione del file su disco (parametro -s)
12K -rw-r--r-- 1 riccardo riccardo 301M 2005-05-05 11:52 nuovofs.ext2
33
Creazione di un filesystem (2)
• Ora devo creare le strutture dati del filesystem
$ /sbin/mke2fs nuovofs.ext2mke2fs 1.37 (21-Mar-2005)
./nuovofs.ext2 non è un device speciale a blocchi.
Procedere comunque? (y,n) s
Etichetta del filesystem=
Tipo SO: Linux
Dimensione blocco=1024 (log=0)
Dimensione frammento=1024 (log=0)
76912 inode, 307200 blocchi
15360 blocchi (5.00%) riservati per l'utente root
34
Creazione di un filesystem (3)
Primo blocco dati=1
38 gruppi di blocchi
8192 blocchi per gruppo, 8192 frammenti per gruppo
2024 inode per gruppo
Backup del superblocco salvati nei blocchi:
8193, 24577, 40961, 57345, 73729, 204801, 221185
Scrittura delle tavole degli inode: fatto
Scrittura delle informazioni dei superblocchi e dell'accounting del filesystem: fatto
Questo filesystem verrà automaticamente controllato ogni 21 mount, o
180 giorni, a seconda di quale venga prima. Usare tune2fs -c o -i per cambiare.
35
Creare il sistema di base
• Serve creare un filesystem con struttura unix-like
• Occorrono alcuni programmi di base per il funzionamento del sistema
• Distribuzione Debian o Ubuntu: debootstrap
– Scarica e installa i pacchetti “base”
• Montare il filesystem in una directory accessibile all'host system
– Questa operazione è possibile solo con privilegi di superutente
– # mount nuovofs.ext2 /mnt -o loop
36
Uso di Debootstrap
• Uso:
– debootstrap --include=<pkt1>,<pkt2>,... --arch <arch> <version> <directory> <repository>
• Parametri:
– include: lista di pacchetti aggiuntivi da aggiungere
– arch: archittetura hardware (e.g., i386, alpha, ....)
– version: versione (e.g., sarge, etch, breezy)
– directory: la directory in cui creare il fs (nel nostro caso /mnt)
– repository: l'origine dei pacchetti (e.g., http://ftp.us.debian.org/debian)
37
Configurazioni finali
• File /etc/hostname
– Contiene il nome del nodo
• File /etc/fstab:
– Contiene la struttura del filesystem
• File /etc/securetty
– Terminali virtuali da cui il superutente puo' entrare nel sistema
– A noi serve aggiungere il terminale tty0
• File /etc/inittab
– File di configurazione del demone init
– A noi serve impostare la console virtuale su tty0
38
Risultato
• File /etc/hostname
uml1
• File /etc/fstab:
/dev/ubd0 / ext3 defaults 0 1
proc /proc proc defaults 0 0
• File /etc/securetty
...
tty0
ttys/0
...
39
Risultato
• File /etc/inittab
...
1:2345:respawn:/sbin/getty 38400 tty0
... • Processo (/sbin/getty 38400 tty0 attende il login sul terminale tty0)• Azione (respawn vuol dire che una volta terminati i processi, questi ripartono)• Runlevels
• 1 halt• 2 default• 3,4,5 custom• 6 reboot
• ID
40
File copy on write
• COW=copy on write
• Dalle parole di Jeff Dyke:
– Come fare a disegnare i baffi alla gioconda senza andare in prigione?
– Semplice: mettiamo un telo di plastica davanti al dipinto
41
File copy on write
• Consente di non sovrascrivere le immagini di dischi originali
– L'immagine originale (backing file) viene usata in modalità read-only
• il file .cow contiene le differenze con il file originale
– Una stessa immagine originale può essere condivisa tra tanti sistemi virtuali
– Ciascuno di questi sistemi scriverà le sue differenze sul suo file COW
– Questo consente di risparmiare spazio perchè i file .cow sono scattered file
– Attenzione al timestamp dei file: il file originale DEVE essere più vecchio del file .cow
42
Funzionamento del meccanismo COW
Backing file
COW file
Read Write
43
Utility per gestire file Copy On Write
• Le immagini cow sono gestite direttamente dal kernel
• Due comandi aggiuntivi sono disponibili
• uml_mkcow
– Crea un'immagine cow
– Questa operazione viene fatta in modo trasparente dal kernel UML
• uml_moo
– Da un'immagine cow e dalla corrispondente immagine originale crea una nuova immagine
– Integra e sincronizza le differenze
– Uso: uml_moo <file.cow> <nuova_immainge.ext2>
– Non serve immagine di partenza: l'informazione sta nel file .cow
44
Rete virtule
• Comando uml_switch
• Software che emula un dispositivo di rete. Due possibili modalità di funzionamento:
– switch
– hub
• Parametri
– -hub mette uml_switch in modalità hub, il default è la modalità switch
– -unix specifica la socket unix che verrà usata come comunicazione tra la macchina virtuale UML e lo switch, il valore di questo parametro è usato come quarto parametro nelle interfacce di rete di UML
45
Networking con tun/tap
• tun/tap serve per interfacciare UML con il sottosistema di networking dell'host system.
• Uso di un dispositivo di rete fittizio tap
– Si crea una scheda di rete fittizia sull'host system che viene mappata su una scheda di rete UML
– In alternativa il dispositivo tap viene collegato a UML_switch
– L'host system diventa un gateway per il resto del mondo
• Richiede privilegi particolari per creare l'interfaccia tap
– Nell'ambito di questo corso non useremo il networking con tun/tap
46
Prime esperienze con UML
47
Prima esperienza
• Un solo nodo
– con una sola partizione montata sotto /
– connesso ad uno switch
• Obiettivo: far funzionare il nodo e vedere se funziona a dovere
/
48
Lanciare il sistemi virtuale
• Scaricare e scompattare i binari di UML e le immagini del sistema nella directory corrente
– NOTA: in laboratorio si lavora sempre nella directory /tmp, mai in $HOME
• Lanciare lo switch (in un console separata)$ ./uml_switch
• Lanciare user mode linux$ ./linux \
ubd0=installato.cow,installato.ext2 \
eth0=daemon,,unix,/tmp/uml.ctl
• AutenticarsiUser: root
Password: root (se richiesta)
interfaccia direte: eth0 suswitch1 (/tmp/uml.ctl)
49
Due parole su come si scompatta un archivio
• tar (TApe aRchive)
• Opzioni
– -v (verbose operation)
– comando -x scompatta, -t mostra contenuto
– algoritmo di compressione -Z compress, -z gzip, -j bzip2
– -f file
50
Errori comuni
• Mettere lo spazio tra i sottoparametri del kernel
– NO: ubd0=file.cow, file.ext2
– SI: ubd0=file.cow,file.ext2
• Sbagliare a scrivere i nomi dei parametri
– NO: udb
– SI: ubd
– NO: demon o damon
– SI: daemon
• Terminare in modo sporco i processi UML
– MAI chiudere le finestre di UML, dare il comando shutdown dalla linea di comando del sistema UML
51
Seconda esperienza
• Un solo nodo
– come nel caso precedente ma con due partizioni che verranno montate sotto / e /usr
• Obiettivo: far funzionare il nodo e vedere se funziona a dovere
/
/usr/
52
Lanciare il sistemi virtuale
• Scaricare e scompattare i binari di UML e le immagini del sistema nella directory corrente
• Lanciare lo switch$ ./uml_switch
• Lanciare user mode linux$ ./linux \
ubd0=root1.cow,root.ext2 ubd1=usr1.cow,usr.ext2 \
eth0=daemon,,unix,/tmp/uml.ctl
• Autenticarsi– User: root
– Password: root
•2 dischi:• ubd0• ubd1
interfaccia direte: eth0 suswitch1 (/tmp/uml.ctl)
53
Osservazioni
• Come fa il sistema a montare correttamente i due dischi?
• Verifica nel file /etc/fstab
# /etc/fstab: static file system information.
/dev/ubd0 / ext3 defaults 0 1
/dev/ubd1 /usr ext3 defaults 0 0
proc /proc proc defaults 0 0