# GNU/Linux

## Namespaces & cgroups

### Isolation du système

#### Mount Namespace

Isole la vue des partitions montées.

#### UTS Namespace

Identification du système : nom de machine et de domaine.

#### PID Namespace

Crée un arbre d'exécution parallèle où le premier process à être
exécuté devient le PID 1 de cet arbre.

### Isolation du système

#### Network Namespace

Isole la pile réseau ; crée un nouveau groupe d'interfaces.

#### User Namespace

Crée une liste d'utilisateurs et de groupe distincte.

#### IPC Namespace

Isolation des files de messages de communication interprocessus (IPC).


### Implémentation

```c
#include <sched.h>

#define STACKSIZE (1024*1024)
static char child_stack[STACKSIZE];

int clone_flags = CLONE_NEWNET | SIGCHLD;

pid_t pid = clone(do_execvp,
                  child_stack + STACKSIZE,
				  clone_flags,
				  &args);
```

### cgroups

`/sys/fs/cgroup/`

#### Block I/O

* Limitation de la bande passante lecture/écriture ;
* poids d'un groupe ;
* métriques: IOPS, latence, file d'attente.

#### CPU

* Poids d'utilisation du CPU ;
* statistiques d'utilisation

### cgroups

`/sys/fs/cgroup/`

#### Mémoire

* Limite de taille ;
* métriques : total rss, swap, nb pages in/out

#### Autres

Réseau, périphériques, gel de processus, ...


### cgroups

#### Création de cgroups

```
mkdir -p /sys/fs/cgroup/blkio/test1/ /sys/fs/cgroup/blkio/test2
```

#### Altération d'une valeur

```
echo 1000 > /sys/fs/cgroup/blkio/test1/blkio.weight
echo 500 > /sys/fs/cgroup/blkio/test2/blkio.weight
```

#### Assignation des tâches aux cgroups

```
dd if=/mnt/sdb/zerofile1 of=/dev/null &
echo $! > /sys/fs/cgroup/blkio/test1/tasks

dd if=/mnt/sdb/zerofile2 of=/dev/null &
echo $! > /sys/fs/cgroup/blkio/test2/tasks
```


## Capabilities

### Résumé

#### Historiquement

* Processus privilégiés : `UID == 0`.
* Processus non-privilégiés : `UID != 0`.

#### Depuis Linux 2.2

* Séparation des privilèges de l'UID 0.
* Chaque thread peut posséder ses propres capacités.
* `prctl(2)`, `execve(2)`, `clone(2)`, ...

### Principales capacités

#### Ne pas oublier de désactiver

* `CAP_MKNOD` : `mknod`
* `CAP_NET_RAW` : permet d'écouter tout le réseau
* `CAP_SYS_MODULE` : charge et décharge des modules noyau
* `CAP_SYS_RAWIO` : accès brut aux entrées/sorties
* `CAP_SYS_RESOURCE` : dépassement des quotas, utilisation de l'espace réservé, ...
* `CAP_SYS_TIME` : changer l'heure de la machine
* `CAP_SYS_ADMIN` : misc
* ...

## Isolateurs

### `systemd`

* Chaque service est démarré dans un cgroup ;
* on peut appliquer des limites au groupe en modifiant le `.service` ;
* `systemd-nspawn` pour créer manuellement un nouveau namespace.

```ini
[Service]
CPUShares=1500
MemoryLimit=1G
BlockIOWeight=500
```

### LXC

* Lance un système complet à partir de `/sbin/init` ;
* se configure via un fichier de configuration :

```ini
lxc.rootfs = /var/lib/lxc/toto/rootfs
lxc.utsname = toto

lxc.network.type = veth
lxc.network.hwaddr = 00:16:3e:c6:0e:04
lxc.network.flags = up
lxc.network.link = tap0
lxc.network.name = eth0

lxc.tty = 4
lxc.pts = 1024
lxc.cap.drop = mac_admin mac_override
```

### Docker

* Lance une application, packagée dans son environnement ;
* création d'environnement possible à partir de `Dockerfile` :

```
FROM debian:wheezy
RUN groupadd -r mysql && useradd -r -g mysql mysql
RUN apt-get update && apt-get install -y perl
ENV MYSQL_MAJOR 5.7
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 3306
CMD ["mysqld", "--datadir=/var/lib/mysql"]
```


## Réseau

### Réseaux physiques

#### empty

Loopback uniquement, n'ajoute aucune interface.

#### phys

Utilisation d'une interface physique directement.

#### vlan

Assignation d'un VLAN à chaque conteneur.


### Réseaux virtuels

#### veth

On crée une interface virtuelle sur l'hôte que l'on connecte à un bridge.

#### MAC VLAN

* **VEPA :** tous les paquets sortants sortent, y compris ceux à destination
  d'une autre machine locale. Le switch derrière doit rerouter les paquets vers
  la machine.
* **Bridge :** le noyau analyse les paquets avant de les transmettre.
