INTRODUZIONE A
USER MODE LINUX


Ing. Michele Messori
http://weblab.ing.unimo.it/people/messori
                                            1
Overview di User Mode Linux




                              2
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/




                                                       3
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)                          4
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

                                             Proc.
                                                      Host
                                                     system
     Proc. Proc.               Proc. Proc.   UML

      Operating System           Operating System
           kernel                     kernel

          Hardware                  Hardware


                                                          5
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

                                                             6
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”
                                                                  7
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

                                                           8
Dettagli tecnici




                   9
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
   – ...                                                  10
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)

                                                               11
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
                                                             12
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




                                                              13
Altri usi della system call ptrace
• Controllo della memoria (ricerca di memory leak)
  – valgrind
• Debugging
  – GDB (The GNU Project Debugger)
• Monitoring di processi
  – strace




                                                     14
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, "177ELF11100000000030301000220U1"..., 512) = 512


                                                                                    15
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




                                                                                     16
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, "pippon", 6pippo
)          =6
munmap(0xb7d37000, 4096)                =0
exit_group(0)                  =?




                                                                       17
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                                    18
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




                                                      19
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                    Tracing
      “lato Host”                        Thread


  Codice e dati
 del kernel UML
                                                       20
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                Proc.      Tracing
                                                      thread
   – Scarsa protezione (spazio di
     indirizzamento condiviso tra                  4 2
                                                           3
                                            1
     processo e tracing thread)
   – Non completamente trasparente (un
     programma può capire se gira su           Host kernel
     UML)
   – Lento (4 context switch e 1 segnale)
                                                                21
UML in modalità Skas 3
• SKAS: Separate Kernel Address Space
• Versioe di riferimento SKAS 3



 Visione dei processi
      “lato UML”




 Visione dei processi                    Codice e dati
      “lato Host”                       del kernel UML

                                                         22
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             23
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!)                       24
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)

 Visione dei processi
      “lato UML”


 Visione dei processi
      “lato Host”
                                         Codice e dati
  Codice e dati                         del kernel UML
 del kernel UML
                                                         25
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
                                                               26
UML in azione




                27
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

                                                           28
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>
                                                                        29
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




                                                                          30
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
                                                             31
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




                                                                           32
Creazione di un filesystem (2)
• Ora devo creare le strutture dati del filesystem
  $ /sbin/mke2fs nuovofs.ext2
  mke2fs 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




                                                       33
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.
                                                                        34
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


                                                           35
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)                               36
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

                                                                 37
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
   ...


                                              38
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
                                                              39
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




                                                        40
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                          41
Funzionamento del meccanismo COW



   Read                     Write


             COW file



             Backing file




                                    42
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
                                                                   43
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
                                                              44
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                                                45
Prime esperienze con UML




                           46
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


                                                           47
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
                                          interfaccia di
• Autenticarsi                            rete: eth0 su
    User: root                            switch1
                                          (/tmp/uml.ctl)
    Password: root (se richiesta)                          48
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




                                                          49
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

                                                        50
Seconda esperienza
• Un solo nodo
  – come nel caso precedente ma con due partizioni che
    verranno montate sotto / e /usr


                                     /

                                      /usr/

• Obiettivo: far funzionare il nodo e vedere se funziona
  a dovere


                                                           51
Lanciare il sistemi virtuale
• Scaricare e scompattare i binari di UML e le immagini
  del sistema nella directory corrente

• Lanciare lo switch
  $ ./uml_switch
                                                  •2 dischi:
• Lanciare user mode linux                        • ubd0
  $ ./linux                                      • ubd1
  ubd0=root1.cow,root.ext2 ubd1=usr1.cow,usr.ext2 
  eth0=daemon,,unix,/tmp/uml.ctl
                                              interfaccia di
• Autenticarsi                                rete: eth0 su
  – User: root                                switch1
                                              (/tmp/uml.ctl)
  – Password: root
                                                               52
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




                                                     53

Introduzione User Mode Linux

  • 1.
    INTRODUZIONE A USER MODELINUX Ing. Michele Messori http://weblab.ing.unimo.it/people/messori 1
  • 2.
    Overview di UserMode Linux 2
  • 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/ 3
  • 4.
    Storia di UserModel 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) 4
  • 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 Proc. Host system Proc. Proc. Proc. Proc. UML Operating System Operating System kernel kernel Hardware Hardware 5
  • 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 6
  • 7.
    A cosa serveUser 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” 7
  • 8.
    Programma su UserMode 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 8
  • 9.
  • 10.
    Il cuore delfunzionamento 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 – ... 10
  • 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) 11
  • 12.
    Tracciare processi • Quandoun 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 12
  • 13.
    L'uso di ptraceutile 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 13
  • 14.
    Altri usi dellasystem call ptrace • Controllo della memoria (ricerca di memory leak) – valgrind • Debugging – GDB (The GNU Project Debugger) • Monitoring di processi – strace 14
  • 15.
    Esperienza: uso distrace (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, "177ELF11100000000030301000220U1"..., 512) = 512 15
  • 16.
    Esperienza: uso distrace (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 16
  • 17.
    Esperienza: uso distrace (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, "pippon", 6pippo ) =6 munmap(0xb7d37000, 4096) =0 exit_group(0) =? 17
  • 18.
    Esperienza: uso distrace (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 18
  • 19.
    Dettagli implementativi diUML • UML usa la system call ptrace per intercettare le system call • Tre versioni: – Modalità tracing thread – Modalità SKAS 3 – Modalità SKAS 0 19
  • 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 Tracing “lato Host” Thread Codice e dati del kernel UML 20
  • 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 Proc. Tracing thread – Scarsa protezione (spazio di indirizzamento condiviso tra 4 2 3 1 processo e tracing thread) – Non completamente trasparente (un programma può capire se gira su Host kernel UML) – Lento (4 context switch e 1 segnale) 21
  • 22.
    UML in modalitàSkas 3 • SKAS: Separate Kernel Address Space • Versioe di riferimento SKAS 3 Visione dei processi “lato UML” Visione dei processi Codice e dati “lato Host” del kernel UML 22
  • 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 23
  • 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!) 24
  • 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) Visione dei processi “lato UML” Visione dei processi “lato Host” Codice e dati Codice e dati del kernel UML del kernel UML 25
  • 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 26
  • 27.
  • 28.
    Come si presentaUML • 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 28
  • 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> 29
  • 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 30
  • 31.
    Creazione di unfilesystem (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 31
  • 32.
    Creazione di unfilesystem (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 32
  • 33.
    Creazione di unfilesystem (2) • Ora devo creare le strutture dati del filesystem $ /sbin/mke2fs nuovofs.ext2 mke2fs 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 33
  • 34.
    Creazione di unfilesystem (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. 34
  • 35.
    Creare il sistemadi 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 35
  • 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) 36
  • 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 37
  • 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 ... 38
  • 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 39
  • 40.
    File copy onwrite • 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 40
  • 41.
    File copy onwrite • 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 41
  • 42.
    Funzionamento del meccanismoCOW Read Write COW file Backing file 42
  • 43.
    Utility per gestirefile 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 43
  • 44.
    Rete virtule • Comandouml_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 44
  • 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 45
  • 46.
  • 47.
    Prima esperienza • Unsolo nodo – con una sola partizione montata sotto / – connesso ad uno switch / • Obiettivo: far funzionare il nodo e vedere se funziona a dovere 47
  • 48.
    Lanciare il sistemivirtuale • 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 interfaccia di • Autenticarsi rete: eth0 su User: root switch1 (/tmp/uml.ctl) Password: root (se richiesta) 48
  • 49.
    Due parole sucome 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 49
  • 50.
    Errori comuni • Metterelo 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 50
  • 51.
    Seconda esperienza • Unsolo nodo – come nel caso precedente ma con due partizioni che verranno montate sotto / e /usr / /usr/ • Obiettivo: far funzionare il nodo e vedere se funziona a dovere 51
  • 52.
    Lanciare il sistemivirtuale • Scaricare e scompattare i binari di UML e le immagini del sistema nella directory corrente • Lanciare lo switch $ ./uml_switch •2 dischi: • Lanciare user mode linux • ubd0 $ ./linux • ubd1 ubd0=root1.cow,root.ext2 ubd1=usr1.cow,usr.ext2 eth0=daemon,,unix,/tmp/uml.ctl interfaccia di • Autenticarsi rete: eth0 su – User: root switch1 (/tmp/uml.ctl) – Password: root 52
  • 53.
    Osservazioni • Come fail 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 53