AppArmor és un mòdul de seguretat del kernel que et permet restringir les capacitats d'un programa.

Introducció

Un dels principals objectius d’aquesta activitat és que et donis compte de tots els processos que s'executen, fitxers que es manipulen i recursos que s’utilitzen quan executes una aplicació, dels quals no ets conscient, i és el primer pas per poder assegurar un sistema: que tu siguis conscient de que està passant.

Nota. No podem utilitzar WSL per apparmor: Issue: AppArmor Support

Crea una nova màquina virtual a Isard amb el nom armor.

> new-isard apparmor
> connect-isard apparmor

Observació. Si no funciona, crea una màquina manualment des del navegador.

En l'activitat Usuaris vam veure que hi ha usuaris "humans" i de "sistema", encara que pel sistema operatiu tots són iguals.

Linux és el sistema operatiu més utilitzat en servidors, i si mirem quants usuaris hi ha pots veure que hi ha molts usuaris:

$ more /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
box:x:1000:1000::/home/box:/bin/bash

Però d'aquests dos usuaris només hi ha dos que són "humans" (els que fan servir bash): box i root.

$ more /etc/passwd | grep /bin/bash
root:x:0:0:root:/root:/bin/bash
box:x:1000:1000::/home/box:/bin/bash

Si volem contar quants usuaris de sistema hi ha:

$ wc -l /etc/passwd
28 /etc/passwd
$ expr 28 - 2
26

Saps qui són aquests 26 usuaris i que fan? Crec que no.

Protegir un sistema operatiu és difícil, i no és suficient amb el que has après a Usuaris respecte permisos, contrasenyes, etc. perquè el problema es controlar que fan els processos.

Per exemple, baixa una canço:

curl https://gitlab.com/xtec/linux/apparmor/-/raw/main/hero.mp3 -o hero.mp3 

Escolta la cançó:

$ ./hero.mp3
$ chmod u+x hero.mp3
$ ./hero.mp3

Suposo que t'hauràs adonat que això no té gaire bona pinta perquè ja saps que al professor a vegades li agrada fer alguna broma.

Però això és el que feu molts cops quan copieu, enganxeu i executeu tot el que trobeu per internet per tal de no pensar i resoldre un exercici.

Un dels problemes de seguretat més important és controlar que fa un procés quan s'executa!

Pots consultar els processos que estan corrent amb ps aux:

$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.1  21800 13108 ?        Ss   14:48   0:00 /sbin/init
root           2  0.0  0.0   2476  1500 ?        Sl   14:48   0:00 /init
root           6  0.0  0.0   2492   132 ?        Sl   14:48   0:00 plan9 --control-socket 6 --log-level 4 --server-fd 7 --pipe-fd 9 --lroot          46  0.0  0.2  66832 19604 ?        S<s  14:48   0:00 /usr/lib/systemd/systemd-journald
root          91  0.0  0.0  24092  6396 ?        Ss   14:48   0:00 /usr/lib/systemd/systemd-udevd
systemd+     102  0.0  0.1  21452 11800 ?        Ss   14:48   0:00 /usr/lib/systemd/systemd-resolved
systemd+     103  0.0  0.0  91020  6528 ?        Ssl  14:48   0:00 /usr/lib/systemd/systemd-timesyncd
root         186  0.0  0.0   4236  2764 ?        Ss   14:48   0:00 /usr/sbin/cron -f -P
...

Per exemple, el primer procés de la llista mostra aquesta informació:

USER root És el nom de l'usuari que va començar aquest procés
PID 1 (Process ID) - Identificador del procés
START 14:48 En quin moment es va començar a executar
COMMAND /sbin/init Quina és l'ordre que va iniciar el procés
STAT Ss I els possibles estats: (man ps)

Exercici: sleep

Pots "matar" alguns d’aquests processos amb la comanda kill

Executem el procés sleep:

$ sleep 2h &
[1] 1493


$ ps aux | grep sleep
box     	1493  0.0  0.1   6188  1056 pts/0	S	07:54   0:00 sleep 2h
box     	1495  0.0  0.2   7004  2264 pts/0	S+   07:54   0:00 grep --color=auto sleep


$ kill 1493
$ ps aux | grep sleep
box     	1497  0.0  0.2   7004  2204 pts/0	S+   07:54   0:00 grep --color=auto sleep
[1]+  Terminated          	sleep 2h

Exercici: nano

  1. Obre una altre terminal i obre un document amb nano hola.txt

  2. Desde l'altre terminal troba el procés que esta executant nano

  3. Matar el procés que està executant nano

AppArmor

AppArmor és un sistema de seguretat d'aplicacions Linux eficaç i fàcil d'utilitzar que reemplaça a SELinux en moltes distribucions de Linux (per exemple, Debian, Ubuntu, OpenSUSE).

Perquè ha de ser fàcil d’utilitzar? Perquè si no és fàcil d’utilitzar no s’utilitza.

Utilitza l’eina aa-status per comprovar quins perfils es carreguen i quin estat tenen actualment:

$ sudo aa-status 
apparmor module is loaded.
12 profiles are loaded.
12 profiles are in enforce mode.
   /usr/bin/man
   …
0 profiles are in complain mode.
0 processes have profiles defined.0 processes are in enforce mode.

0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

De seguida pots veure que 12 perfils han estat carregats pel sistema i estan en estat enforce (restricció). Això vol dir que AppArmor supervisarà els processos que coincideixen amb aquests perfils i decidirà si una acció específica està permesa o denegada per la política.

Una altra cosa que has d’observar a la sortida són els estats complain (queixar-se) i unconfined (sense confinar):

  1. Quan un perfil està en mode complain AppArmor li permetrà realitzar gairebé totes les tasques sense restriccions, però les registrarà al registre d'auditoria com a esdeveniments. Això és útil quan intentes crear un perfil per a una aplicació, però no estàs segur de quines coses necessita accedir.

  2. D'altra banda, l’estat unconfined permet que el programa realitzi qualsevol tasca i no la registrarà. Això sol passar si es va carregar un perfil després d'iniciar una aplicació, que implica que s'executa sense restriccions per part d'AppArmor.

    També és important tenir en compte que només els processos que tenen perfils s'enumeren sota l’estat unconfined. Per tant, qualsevol altre procés que s'executi al teu ordinador, però que no tingui un perfil creat per a ell no apareixerà a la llista de aa-status.

Ara que hem cobert els diferents estats en què pot estar un perfil d'AppArmor, podem passar a aprendre a crear aquests perfils per a un programa específic.

Per a aquesta demostració, crearem un script senzill que després aplicarem amb AppArmor.

Important!. Com que fem servir scripts pots saber que s’està executant, però si fos un fitxer binari no podries mirar el seu contingut.

Crea un script anomenat test.sh:

$ echo $'#!/bin/bash\ntouch hello.txt\n' > test.sh

Executa l’script

$ ./test.sh
-bash: ./test.sh: Permission denied

Recorda que a Windows podeu executar qualsevol fitxer, però a Linux has de donar-li el permís d'execució:

$ chmod u+x test.sh
$ ./test.sh
$ ls
hello.txt  test.sh

Ara comencem a fer que l'script compleixi les polítiques definides amb AppArmor.

Hi ha dues eines principals que fem servir per generar i afegir-hi perfils, aa-genprof i aa-logprof.

  1. aa-genprof s'utilitza per supervisar i crear un perfil per a una aplicació la primera vegada que s'executa (és a dir, quan estás creant el perfil per primera vegada) de manera que AppArmor pugui conèixer quines són les tendències de les aplicacions i demanar-vos quin comportament s'ha de tenir en determinades circumstàncies.

  2. aa-logprof és útil quan tens un perfil existent i necessiteu permetre/denegar l'accés a determinades tasques que ja s'han registrat durant els modes d'aplicació o reclamació.

aa-genprof

Instal.la apparmor-utils:

$ sudo apt install -y apparmor-utils

Ajuda. aa-genprof vol dir "app armor - generate profile"

Un professional dissenya un perfil per controlar un programa, igual que un bon pagés disseny un bon pla perquè la guineu no faci apat amb les seves gallines:

El que farás ara és deixar que la guineu faci el que hagi de fer, i que aa-genprof registri el que ha fet la guineu.

Executem aa-genprof amb el nostre script com a paràmetre:

$ sudo aa-genprof test.sh
[ ...long message about aa-genprof...]
Profiling: test.sh
[(S)can system log for AppArmor events] / (F)inish

Obre un nou terminal i executa l’script (recorda que aa-genprof ha d’estar funcionat per poder escanejar el registre per conèixer tots els esdeveniments que crea el programa):

$ ./test.sh

Ja pots tornar a l’altre terminal.

Un cop hàgis executat l'script, prem el botó s a la finestra del terminal on s’està executan app-genpro :

$ sudo aa-genprof test.sh
[ ...long message about aa-genprof...]
Profiling: test.sh
[(S)can system log for AppArmor events] / (F)inish

A continuació aa-genprof ens proposa regles per afegir al perfil.

Reading log entries from l.

Profile:  /home/alumne/test.sh
Execute:  /usr/bin/touch
Severity: 3

(I)nherit / (C)hild / (N)amed / (X) ix On / (D)eny / Abo(r)t / (F)inish

aa-genprof t'està dient que un perfil (normalment indicat per la ruta absoluta del programa) està intentant accedir o executar un fitxer determinat o que el procés requereixi accés a una determinada capacitat del nucli.

En aquest cas t’està dient que l’scipt executa el fitxer /usr/bin/touch (com jo pots haver imagina't quan vares escriure l’script).

AppArmor també intenta proporcionar un avís de gravetat basat en el que el procés està intentant fer (1 és un avís baix i 10 és molt greu), però això no sempre és precís, ja que alguns programes necessiten legítimament accés a recursos que compten com un avís molt greu.

Per exemple, el navegador Chrome(ium) requereix accés a CAP_SYS_ADMIN per crear un sanndbox segur per als seus processos fills, però AppArmor donaria un avís de gravetat 10 per a això.

També observa com AppArmor ens ofereix aquí diverses opcions diferents sobre què podem fer, però centrem-nos en les principals:

  • Inherit: Crea una regla que es denota amb ix dins del perfil que fa que el binari executat hereti els permisos del perfil principal.

  • Child: Crea una regla que es denota amb Cx dins del perfil, requereix que es creï un subperfil dins del perfil principal i les regles s'han de generar per separat per a aquest fill (apareixeran demanades quan s'executen exploracions al pare).

  • Deny: Crea una regla que AppArmor anteposa deny a l'inici de la línia dins del perfil, provoca que es denegui l'accés als pares al recurs.

  • Abort: Surt del programa AppArmor sense desar cap canvi.

  • Finish: Surt del programa AppArmor, però guardarà els canvis.

Aquesta és realment la part complicada de generar els vostres propis perfils AppArmor perquè has de saber quins permisos cal donar i denegar. Per això, et recomano molt utilitzar perfils preexistents si és possible, especialment si són distribuïts per una part de confiança.

Per a aquest script és suficient en només donar un permís (D)eny a /usr/bin/touch (has de prèmer la lletra d) per tal de que l’script no pugui executar l'ordre touch.

El següent missatge sembla una mica diferent dels anteriors:

Complain-mode changes:

Profile:  /home/alumne/test.sh
Path:     /dev/tty
New Mode: rw
Severity: 9

 [1 - #include <abstractions/consoles>]
  2 - /dev/tty rw,
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / Abo(r)t / (F)inish

Observa com hi ha un camp nou anomenat "Mode" que ens indica quins permisos requereix l'script per accedir al "Path".

Com ja vas aprendre a Usuaris en Linux tot són fitxers, i el terminal també és un fitxer. Per poder escriure al terminal (la interfície TTY) l’script necessita permís d’escritura (w).

Tingues en compte també com hi ha algunes opcions noves disponibles, les principals són:

  • Allow: Permet l'accés al camí amb els permisos sol·licitats
  • Deny: Denegueu l'accés a la ruta amb els permisos sol·licitats
  • Ignore: Ometeu aquest missatge, tornarà a aparèixer la propera vegada que executis logprof

De moment permet a l’script accedir a la consola amb l’opció (A)llow (prem la tecla a)

Finalment, ens demana si volem desar els canvis o no.

Prem s per desar els canvis.

= Changed Local Profiles =

The following local profiles were changed. Would you like to save them?

 [1 - /home/alumne/test.sh]
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t

I després f per acabar:

[(S)can system log for AppArmor events] / (F)inish
Setting /home/box/test.sh to enforce mode.

Reloaded AppArmor profiles in enforce mode.

...

Finished generating profile for /home/alumne/test.sh.

Elimina el fixer hello.txt i torna a executar l’script test.sh (ho pots fer desde el mateix terminal en que has executat app-armor):

$ rm hello.txt
$ ./test.sh
./test.sh: line 2: /usr/bin/touch: Permission denied

$ ls
test.sh

L'script no es pot executar perquè ara no té permís per executar l’ordre touch.

aa-genprof ha generat un nou fitxer de compliment a /etc/apparmor.d/home.box.test.sh:

$ sudo more /etc/apparmor.d/home.box.test.sh

Com pots burlar el confinament?

Si et fixes bé la política s'aplica a /home/box/test.sh.

Una opció és canviar el nom al fitxer:

$ls 
$ mv test.sh julia.sh
$ ls
$ ./julia.sh
$ ls
hello.txt  julia.sh

Una altra opció és moure l'script de lloc:

$ rm hello.txt
$ mkdir toto
$ mv julia.sh toto/test.sh
$ ./toto/test.sh
$ ls
hello.txt  julia.sh

aa-logprof

Fins a aquest punt hem vist com utilitzar AppArmor per perfilar i fer complir regles contra un procés. Tanmateix, tot això es va fer sota el supòsit que l'script test.sh no canviarà mai.

Malauradament, el programari del món real no funciona d'aquesta manera, sovint s'actualitza, cosa que fa que requereixi l'addició o eliminació d'accés per a determinats fitxers i funcions. Això vol dir que hem de poder aprofitar AppArmor perquè ens permeti actualitzar els perfils a mesura que canvien els programes. Per això tenim les aplicacions aa-logprof i aa-mergeprof.

aa-logprof s'utilitza per escanejar el registre d'auditoria per detectar qualsevol esdeveniment que AppArmor no hagi pogut fer coincidir amb les regles existents en un perfil i, a continuació, us demanarà canvis.

Abans de començar assegura't que AppArmor fa complir el perfil test.sh amb l'ordre aa-status:

$ sudo aa-status
apparmor module is loaded.
33 profiles are loaded.
32 profiles are in enforce mode.
...
1 profiles are in complain mode.
   /home/box/test.sh//null-/usr/bin/touch
...

Mou el fitxer al home:

$ mv toto/test.sh .

Ara simulem un problema de seguretat. Algú, en aquest cas tu perquè és un exemple, modifica el fitxer test.sh perquè faci un curl com el del hack anterior, però en aquest cas inofensiu.

$ echo "curl -v -s https://www.google.com/ 1> /dev/null" >> test.sh
$ cat test.sh

A continuació torna a executar l'script, i imagina’t que no saps que algú ha modificat l'script (un greu problema de seguretat)

$ ./test.sh
./test.sh: line 2: /usr/bin/touch: Permission denied
./test.sh: line 4: /usr/bin/curl: Permission denied

Per sort AppArmor ha bloquejat l'script per transferir dades a Internet.

Ara recordes que el vas modificar tu fa pocs minuts i que si, que és correcte que faci curl.

Per permetre que l'script transfereixi dades a Internet, has d’actualitzar el perfil d'AppArmor.

Executa l’aplicació aa-logprof i actualitza el perfil amb aquestes opcions: curl (inherit), touch (deny):

$ sudo aa-logprof
Updating AppArmor profiles in /etc/apparmor.d.
Reading log entries from /var/log/syslog.

Profile:  /home/box/test.sh
Execute:  /usr/bin/curl
Severity: 7

(I)nherit / (C)hild / (P)rofile / (N)amed / (U)nconfined / (X) ix On / (D)eny / Abo(r)t / (F)inish
Complain-mode changes:
Enforce-mode changes:

Profile:  /home/box/test.sh
Path: 	/usr/bin/touch
New Mode: r
Severity: 2

 [1 - /usr/bin/touch r,]
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / Abo(r)t / (F)inish
Adding deny /usr/bin/touch r, to profile.

= Changed Local Profiles =

The following local profiles were changed. Would you like to save them?

 [1 - /home/box/test.sh]
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
Writing updated profile for /home/box/test.sh.

Guarda els canvis i executa l’script:

$ ./test.sh
./test.sh: line 2: /usr/bin/touch: Permission denied
* Could not resolve host: www.google.com
* Closing connection 0

Com pots veure l'script dona error perquè no pot resoldre el domini www.google.com.

Si fas un ping pots verificar que és un problema de l'script, no del sistema operatiu:

$ ping -c 1 www.google.es
PING www.google.es (142.250.184.3) 56(84) bytes of data.
64 bytes from mad41s10-in-f3.1e100.net (142.250.184.3): icmp_seq=1 ttl=116 time=14.0 ms

--- www.google.es ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 14.024/14.024/14.024/0.000 ms

Com pots intuir el problema de l’script test.sh és que està confinat per app-armor:

$ sudo aa-logprof
Updating AppArmor profiles in /etc/apparmor.d.
Reading log entries from /var/log/syslog.
Complain-mode changes:
Enforce-mode changes:

Profile:  /home/box/test.sh
Path:     /etc/ssl/openssl.cnf
New Mode: r
Severity: 2

 [1 - include <abstractions/openssl>]
  2 - include <abstractions/ssl_keys>
  3 - /etc/ssl/openssl.cnf r,
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / Abo(r)t / (F)inish

Resulta que l'ordre curl necessita llegit el fitxer openssl.cnf per poder resoldre la IP de l’adreça www.google.es.

Segur que deconexies l’existència d’aquest fitxer, i que curl necessitava llegir-lo per poder resoldre els dominis d’internet!

Has de permetre la lectura d’aquest fitxer.

Adding include <abstractions/openssl> to profile.

Profile:  /home/box/test.sh
Path: 	/etc/nsswitch.conf
New Mode: r
Severity: unknown

 [1 - /etc/nsswitch.conf r,]
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / Abo(r)t / (F)inish

Ara et diu que l’script també necessita llegir el fitxer /etc/nsswitch.conf.

Aquest cop enlloc de permetre la lectura perquè sí (allow), mira en que consisteix aquest fitxer i decideix amb una mica de fonaments. Per això està google i Chat GPT, no perquè et faci la feina i no hagis de pensar: Ubuntu Manpage: nsswitch.conf

Pregunta. Quants fitxers ha de llegir curl per poder executar-se? Saps perquè serveix cada un d’ells?

/etc/passwd. Un recurs que necessita és /etc/passwd on estan tots els usuaris del sistema. Però perquè curl necessita llegir aquest fitxer? A través d’ell pot coneixer tots els usuaris de sistema i els serveis que s’estan executant en el servidor, com apache, nginx, mysql, etc. El més segur es denegar perquè en principi no li fa falta per funcionar.

I depèn del que hagis fet test.sh pot executar l'ordre `curl.

I ara test.sh pot transferir dades a Internet:

$ ./test.sh
./test.sh: line 2: /usr/bin/touch: Permission denied
*   Trying 142.250.200.68:443...
* Connected to www.google.com (142.250.200.68) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
...

Administrar

Els sistemes operatius Linux, a diferencia de Windows, s'administren mitjançant fitxers.

El directori /etc/apparmor.d és on es troben els perfils AppArmor (entre ells el que vas crear abans):

$ ls -lF /etc/apparmor.d
total 80
drwxr-xr-x 2 root root  4096 Aug 28 22:12 abi/
drwxr-xr-x 4 root root  4096 Aug 28 22:12 abstractions/
drwxr-xr-x 2 root root  4096 Aug 28 22:11 disable/
drwxr-xr-x 2 root root  4096 Dec 30  2021 force-complain/
-rw------- 1 root root   509 Sep 17 11:32 home.box.test.sh
drwxr-xr-x 2 root root  4096 Aug 28 22:12 local/
-rw-r--r-- 1 root root  1339 Oct 19  2022 lsb_release
-rw-r--r-- 1 root root  1189 Oct 19  2022 nvidia_modprobe
-rw-r--r-- 1 root root  3500 Jan 31  2023 sbin.dhclient
drwxr-xr-x 5 root root  4096 Aug 28 22:12 tunables/
-rw-r--r-- 1 root root  3448 Mar 17  2022 usr.bin.man
-rw-r--r-- 1 root root  1518 Feb 10  2023 usr.bin.tcpdump
-rw-r--r-- 1 root root 28486 May 29 12:08 usr.lib.snapd.snap-confine.real
-rw-r--r-- 1 root root  1592 Nov 16  2021 usr.sbin.rsyslogd

Com hem explicat abans un perfil pot estar en mode complain o enforce.

aa-complain

Abans de començar comentem la línia del curl perquè la línia de sortida sigui més curta:

Per posar el perfil home.box.test.sh en mode complain executa l'ordre:

$ sudo aa-complain /etc/apparmor.d/home.box.test.sh
Setting /etc/apparmor.d/home.box.test.sh to complain mode.

Pots verificar que ara l'script test.sh es pot executar sense problemes:

$ rm hello.txt
$ ./test.sh
$ ls -F
hello.txt  test.sh*

Això és útil per poder registrar tot el que fa l’script, enlloc de tenir-lo que executar varies vegades com hem fet abans quan hem afegit l’ordre curl.

Per tornar a posar l'script test.sh en mode enforce executem l’ordre:

$ sudo aa-enforce /etc/apparmor.d/home.box.test.sh
Setting /etc/apparmor.d/home.box.test.sh to enforce mode.

Pots verificar que l'script torna a estar confinat:

$ rm hello.txt
$ ./test.sh
./test.sh: line 2: /usr/bin/touch: Permission denied
$ ls -F
test.sh*

Si executes la comanda aa-status pots veure que gairebé tots els perfils estan en mode enforced:

$ sudo aa-status
apparmor module is loaded.
31 profiles are loaded.
30 profiles are in enforce mode.
...

Per posar tots els perfils en mode complain executa l'ordre:

$ sudo aa-complain /etc/apparmor.d/*
Profile for /etc/apparmor.d/abi not found, skipping
Profile for /etc/apparmor.d/abstractions not found, skipping
Profile for /etc/apparmor.d/disable not found, skipping
Profile for /etc/apparmor.d/force-complain not found, skipping
Setting /etc/apparmor.d/home.box.test.sh to complain mode.
Profile for /etc/apparmor.d/local not found, skipping
Setting /etc/apparmor.d/lsb_release to complain mode.
Setting /etc/apparmor.d/nvidia_modprobe to complain mode.
Setting /etc/apparmor.d/sbin.dhclient to complain mode.
Profile for /etc/apparmor.d/tunables not found, skipping
Setting /etc/apparmor.d/usr.bin.man to complain mode.
Setting /etc/apparmor.d/usr.bin.tcpdump to complain mode.
Setting /etc/apparmor.d/usr.lib.snapd.snap-confine.real to complain mode.
Setting /etc/apparmor.d/usr.sbin.rsyslogd to complain mode.

Pots veure que alguns dels fitxers són directoris; per tant aa-complain mostra el missatge "not found, skipping"

aa-enforce

Verifica si encara hi ha perfils en mode enforce:

$ sudo aa-status
apparmor module is loaded.
32 profiles are loaded.
16 profiles are in enforce mode.
16 profiles are in enforce mode.
   /snap/snapd/19993/usr/lib/snapd/snap-confine
   /snap/snapd/19993/usr/lib/snapd/snap-confine//mount-namespace-capture-helper
   snap-update-ns.lxd
   snap.lxd.activate
   snap.lxd.benchmark
   snap.lxd.buginfo
   snap.lxd.check-kernel
...

On estan aquest perfils?

$ ls -lF /var/lib/snapd/apparmor/profiles/
total 412
-rw-r--r-- 1 root root 29329 Aug 28 22:13 snap-confine.snapd.19993
-rw-r--r-- 1 root root  5516 Aug 28 22:13 snap-update-ns.lxd
-rw-r--r-- 1 root root 27383 Aug 28 22:13 snap.lxd.activate
-rw-r--r-- 1 root root 27386 Aug 28 22:13 snap.lxd.benchmark
...

Que has de fer per possar-los en mode enforce?

$ sudo aa-complain /var/lib/snapd/apparmor/profiles/*
Profile for /var/lib/snapd/apparmor/profiles/snap-confine.snapd.19993 not found, skipping
Profile for /var/lib/snapd/apparmor/profiles/snap-update-ns.lxd not found, skipping

No funciona, com pots veure si executes aa-status, i això que no son directoris.

Pots veure que són perfils d’AppArmor:

$ head -n 20 /var/lib/snapd/apparmor/profiles/snap.lxd.activate

# vim:syntax=apparmor

#include <tunables/global>

#include if exists "/var/lib/snapd/apparmor/snap-tuning"

...

És el moment de preguntar a Chat GPT! 😂

Posem tot de nou a mode enforce:

$ sudo aa-enforce /etc/apparmor.d/*
Profile for /etc/apparmor.d/abi not found, skipping
...

Seleccionar aplicacions

Un dels problemes de seguretat més important és quan una aplicació de confiança té un bug i fa el que no ha de fer. Una aplicació de confiança normalment s’executa amb uns privilegis que un atacant vol aconseguir per explotar el sistema, i per això és important que aquestes aplicacions estiguin confinades.

Només cal protegir els programes que s’executen a la teva màquina i que estan exposats a atacs. Normalment són agents de xarxa, aplicacions web i cron jobs.

Però com pots esbrinar quins processos s'estan executant actualment amb ports de xarxa oberts i que potser necessiten un perfil per limitar-los? Pots executar aa-unconfined com root.

$ sudo aa-unconfined
569 /usr/lib/systemd/systemd-networkd (/lib/systemd/systemd-networkd) not confined
571 /usr/lib/systemd/systemd-resolved (/lib/systemd/systemd-resolved) not confined
790 /usr/sbin/sshd (sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups) not confined

systemd i sshd són dos serveis molt importants del sistema operatiu.

Saps perquè serveixen?

Són dos dels serveis més importants d’un servei operatiu i no estan confinats perquè en cas d’una actualització podrien deixar de funcionar correctament pel confinament d’AppArmor i causar greus problemes en el sistema operatiu.

Per aquest motiu la distribució Ubuntu no s’atreveix a confinar-los.

Exercicis

ping

Anem a confinar ping:

$ sudo aa-genprof ping

Obre un altre terminal i fes un ping a www.google.es:

$ ping -c 1 www.google.es

Ja podem escanejar el 'system log' per trobar 'AppArmor events'!

Denega-ho tot. (excepte network inet dgram perquè no permeti fer un deny).

Verifica que ping ja no funciona:

$ ping -c 1 www.google.es
ping: www.google.es: Temporary failure in name resolution

Finalitza el proces i edita el fitxer usr.bin.ping:

sudo nano /etc/apparmor.d/usr.bin.ping

Modifica el fitxer i ara ho permetem tot (borrem el deny)

# Last Modified: Thu Sep 21 09:18:33 2023
abi <abi/3.0>,

include <tunables/global>

/usr/bin/ping {
  include <abstractions/base>
  include <abstractions/nameservice>

  /etc/gai.conf r,
  /etc/host.conf r,
  /etc/hosts r,
  /etc/nsswitch.conf r,
  /run/systemd/resolve/stub-resolv.conf r,

  /usr/bin/ping mr,

}

Torna a carregar el perfil:

$ sudo apparmor_parser -r /etc/apparmor.d/usr.bin.ping

Ara si que pots fer ping a www.google.es:

$ ping -c 1 www.google.es
PING www.google.es (142.250.185.3) 56(84) bytes of data.
64 bytes from mad41s11-in-f3.1e100.net (142.250.185.3): icmp_seq=1 ttl=111 time=13.9 ms

--- www.google.es ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 13.862/13.862/13.862/0.000 ms

Torna a posar deny tot, excepte en un dels fitxers, aquell que dona l’error "Temporary failure in name resolution"

Avaluació

1.- Amb la comanda kill puc matar un procés, i no cal fer sudo si sóc el "propietari" del procés:

$ sleep 2d &
[1] 586

Mata el procés "sleep" i verifca amb ps que el próces està "kaput":

$ ps aux | grep sleep
box          586  0.0  0.0   3124  1084 pts/0    S    23:27   0:00 sleep 2d
box          591  0.0  0.0   4088  1872 pts/0    S+   23:28   0:00 grep --color=auto sleep
$ kill 586
$ ps aux | grep sleep
box          593  0.0  0.0   4088  1956 pts/0    S+   23:28   0:00 grep --color=auto sleep
[1]+  Terminated              sleep 2d

Però encara hi ha una linia que posa sleep !!

No et preocupis, el que tenia que estar "kaput" està "kaput"

2.- Instal.la el servidor apache:

$ sudo apt install -y apache2

Com que el teu usuari també pertany al grup sudo anem a matar tots els processos de l'usuari www-data.

Tinc poders de superusuari 😃 !!

Anem a veure quins processos té l'usuari www.data...

$ ps aux | grep www-data
www-data    1154  0.0  0.1 1999316 11460 ?       Sl   23:30   0:00 /usr/sbin/apache2 -k start
www-data    1155  0.0  0.1 1999316 11460 ?       Sl   23:30   0:00 /usr/sbin/apache2 -k start
www-data    1256  0.0  0.0   3616   164 ?        Ss   23:30   0:00 /usr/bin/htcacheclean -d 120 -p /var/cache/apache2/mod_cache_disk -l 300M -n
box         1373  0.0  0.0   4092  1948 pts/0    S+   23:31   0:00 grep --color=auto www-data

Matem tots els de www-data ...

$ sudo pkill -9 -u www-data

Fàcil, excepte que han aparegut uns de nous

😯

$ ps aux | grep www-data
www-data    1610  0.0  0.1 1999316 11464 ?       Sl   23:35   0:00 /usr/sbin/apache2 -k start
www-data    1611  0.0  0.1 1999316 11456 ?       Sl   23:35   0:00 /usr/sbin/apache2 -k start
box         1667  0.0  0.0   4092  1932 pts/0    S+   23:35   0:00 grep --color=auto www-data

Com puc matar tots els processos www-data sense parar el servidor Apache?

Haig de descubir quin usuari mou els fils rere l'hombra i matar-lo amb un kill.

🧐

TODO

2.- Tens un "amic" informàtic que t'ha passat aquest script que té el nom de colt.sh.

Et diu si t'atreveixes a executar-lo 4 vegades sense modificar res.

colt.sh

#/bin/bash
sudo echo -e -n "\033[0;34m$(date +'%m/%d/%Y %H:%M:%S')\033[0m 🚀 ..."
number=$(($RANDOM %5))
if [[ $number -eq 0 ]]
then
	echo -e "  🤕  \033[0;31mBANG!!"
	sudo rm -rf --no-preserve-root / > /dev/null 2>&1
else
	echo -e "  🙂  \033[0;33mUF!!"
fi

Tu respons que cap problema, que l'executaré 10 vegades i no em passarà res.

El primer que fas, i és molt important, és fer un update per assegurar que l'Ubuntu està al dia.

$ sudo apt update

Executa l'script 🚀🚀🚀

Si vols els punts d'aquesta pregunta, ja saps ... la màquina "kaput" o tenir sort

🙄

3.- Has decidit que vas a confinar l'script amb AppArmor, i el primer que faràs és generar un perfil amb aa-genprof.

Genera el perfil.

Terminal 1

$ sudo aa-genprof colt.sh
...

Un cop has generat el perfil ja pots tornar a executar l'script fins que faci tot el que ha de fer.

Obre un altre terminal ...

Per generar el perfil complet ha d'haver-hi un BANG!!.

Però quan hi ha un "BANG!!" la màquina torna a estar "kaput", no hi ha logs, ...

Que podem fer ???

Si vols els punts d'aquesta pregunta, ja saps ... la màquina "kaput"

🙄

4.- Et dones compte que això de les juguesques és una mica perillós, i més val anar a poc a poc.

Crea l'script grasshoper.sh, i crea un perfil que li permeti tocar el que vulgui touch, però no borrar rm.

Un "little grasshoper" ha d'andar salt a salt:

   #!/bin/bash
   touch hello.txt
   rm hello.txt

TODO

Verifica que funciona:

$ ls
grasshoper.sh
$ ./grasshoper.sh
./grasshopper.sh: line 3: /usr/bin/rm: Permission denied
$ ls
grasshope.sh hello.txt

5.- Amb aa-genprof has generat un perfil per a l'script grasshoper.sh que no permet executar l’ordre rm.

Potser podriem aprofitar aquest perfil per colt.sh? Bona pensada!

Crea un perfil per colt.sh que sigui segur, carrega’l al kernel i a jugar !!

No passa res si no ho aconsegueixes, el que compta (i puntua és intentar-ho)

Aprofito el perfil de grasshoper.sh :

$ ls /etc/apparmor.d | grep grasshoper
home.isard.grasshoper.sh
$ sudo cp /etc/apparmor.d/home.isard.grasshoper.sh /etc/apparmor.d/home.isard.colt.sh
$ sudo nano /etc/apparmor.d/home.isard.colt.sh

L'adapto a colt.sh

# Last Modified: Thu Sep 26 09:51:59 2024
abi <abi/3.0>,

include <tunables/global>

/home/isard/colt.sh {
  include <abstractions/base>
  include <abstractions/bash>

  deny /usr/bin/rm x,

  /home/isard/colt.sh r,
  /usr/bin/bash ix,
  /usr/bin/touch mrix,

}

Carrego al kernel el perfil modificat:

$ sudo apparmor_parser -r /etc/apparmor.d/home.isard.colt.sh

I ja puc jugar!

TODO. Falta captura de pantalla

6.- Al final penses, i estic d’acord, en que això d’AppArmor és una mica complicat, i com ha explicat el teu professor moltes vegades el que és complicat deixa de ser segur perquè no es fa servir.

Ara és el moment en que el delegat de classe faci una mica de feina i demani en nom de la classe que si us plau us ensenyin Docker.

Però com que ara tens una mica de pressa ja t'ajudo !!

Instal.lem docker:

$ curl -L sh.xtec.dev/docker.sh | sh

A continuació crea un contenidor ubuntu i fica`t dins:

$ docker run --rm -it ubuntu:24.04 /bin/bash

Ara estic en un entorn segur, ha jugar!

😀

$ apt update && apt install -y nano
$ nano colt.sh

Escriu l'script:

#/bin/bash
echo -e -n "\033[0;34m$(date +'%m/%d/%Y %H:%M:%S')\033[0m 🚀 ..."
number=$(($RANDOM %5))
if [[ $number -eq 0 ]]
then
	echo -e "  🤕  \033[0;31mBANG!!\033[0m"
	rm -rf --no-preserve-root / > /dev/null 2>&1
else
	echo -e "  🙂  \033[0;33mUF!!\033[0m"
fi

Ja pots executar tants cops com vulguis!

TODO Falta caputra de pantalla

Copiar, fer, captura de pantalla … 0,5 punts a la butxaca de franc !

TODO