New article about adlin#1
continuous-integration/drone/push Build is passing Details

This commit is contained in:
nemunaire 2023-06-07 20:44:01 +02:00
parent 02d9b18e74
commit 98e7f8b2bf
7 changed files with 803 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

View File

@ -0,0 +1,401 @@
---
title: "Gamification of a Linux system administration course"
date: !!timestamp '2023-06-07 16:07:00'
tags:
- teaching
- kernel
- network
- certificates
aliases:
- adlin
---
System administration isn't something that's obvious to everyone, and it's a subject that, when it's more to do with the basics of networking and Linux, can seem a lot more daunting than learning about the latest trendy technologies (Docker, Terraform, Kubernetes, etc.).
Also, with the bombardment of information and easy access to computer content and tutorials often more interesting than "classic" lectures, students are less and less attentive, present or participating.
Is it a waste of time to regain their attention? No !
<!-- more -->
Many solutions exist, and in this article I'll describe how I've applied the principles of "gamification".
## Define pedagogical objectives
For the Department of Studies, I had to set up an advanced Linux system administration course, aimed at students who were already familiar with the command line, had some theoretical knowledge of networks and a good grounding in Unix programming.
When preparing a course, it's important to define the pedagogical objectives you want to achieve.
For me, the aim here was to get the students to practice networking in concrete terms (without DHCP) and to get them to debug various problems common to Linux system administrators (both at system and network level).
Of course, a number of opening topics are also covered as we go through the various learning stages.
## The subject: Matrix Restarted
An important part of gamification is the context in which the students will evolve.
Over and above the pedagogical objectives, it's a question of finding a mission for them, one that's similar to a game.
Yes, we're talking about combining concrete business needs with a fictional universe that makes them want to progress towards their objectives.
In computer engineering schools, the Matrix movie is a sacred bible.
Every student knows the story and at least a little about the universe.
Over the course of a few hours, students will embody one of their favorite heroes, in his universe, with the ultimate goal of : "connect to the Internet to reach Zion".
In Matrix Revolution, Neo must reach Zion to save her.
From the very first minutes of the exercise, the environment is set up:
![The Matrix, exclamations and shivers guaranteed](the-matrix.png)
And, even more important: their final objective is explained to them in a few lines, right from the start.
![Someone's communicating with us just like at the beginning of the first film to give us instructions!](instructions.png)
For them, connecting to the Internet is an easy, reasonable and accessible task.
That's the key to getting them involved: arousing their curiosity about what they'll get when they get to Zion!
At this stage, of course, the students have no idea that there are many adventures in store for them...
## Individualized follow-up
For the teacher, one of the most important aspects of this kind of exercise is to be able to help students in difficulty.
It's well known that many students don't raise their hands to ask for help.
On the contrary, I've noticed that in this exercise, it's mainly the students who are doing the best who tend to ask for help with the bonus parts, which are obviously more difficult.
During practical work, the main source of drop-out I've observed occurs when the teacher is ahead of the student: not only do they have to hurry to catch up, but they can't benefit from the advice given orally by the teacher.
It's unfortunate that he doesn't interrupt the lesson to ask for help, but then again, many students don't dare.
In this exercise, because everything is well scripted, I was able to set up a system that supervises each student.
This has two main advantages:
- It allows me to monitor overall and individual progress: I can go and see those who are behind schedule to deal with their difficulties individually; and when it's the whole class that's stuck on a step, I can intervene without any student feeling behind: we reflect collectively on the blocking point, which encourages individual reflection, including from those who don't participate orally.
- While grading is usually a chore, here by monitoring student progress, it's easy to find out what learning objectives each student has achieved, so you can grade them accordingly.
![The dashboard for tracking each student](dashboard.webp)
But then, what are the contents, the different stages through which the student passes?
## The course "scenario"
### Step 0 : Get root privileges on the machine
In a company, it can happen that you have to work on a machine that was installed a long time ago, or by a trainee who wasn't familiar with the procedures and passwords to be used, and yet you need to recover access to it.
The first step in the course is for students to "root" their machine.
This means bypassing the login screen, becoming an administrator without knowing the password.
It's a "common" action that doesn't call on any vulnerabilities: all you need is access to the operating system's loading program.
While many students are familiar with the theoretical aspect of "rooting", very few have actually experienced it (and are aware that it's so simple that they might want to take steps to counter this possibility once they're in the working world).
### The sandbox for learners
The entire course takes place in a specially prepared machine room, and each machine is a sandbox for the student using it.
Students are on a server-driven workstation (technically, the machines are simply configured to boot over the network, in PXE).
The system used is a true standard GNU/Linux system, based on the Alpine distribution, in order to be as light as possible.
The kernel is specially compiled to have a limited number of drivers, in order to limit unintended actions such as overwriting the host disk.
As client workstations are not booted with a physical or remote disk attached, there is no persistent data: in the event of a reboot, the student returns to the initial situation.
As the exercise does not require the student to reboot voluntarily, this is not usually a problem, but it does guarantee that the teacher will return to a healthy/known state if he has to help a student who has destroyed his system.
There is one exception, because in real life, after booting our machine in `single` mode to overwrite the `root` password, we reboot back to classic mode.
Whatever mode the machine has been unmarshaled in, a program runs in the background to monitor changes made to the `/etc/shadow` file, containing the machine's account passwords.
As soon as a change is made, the file is forwarded to the server unmarshalling the machines.
To avoid overloading the server when all the students change their passwords, instead of recreating the complete system image, I take advantage of a trick related to the archive format used: there is no header or global file index, so a new file can be added at the end of the archive, in the expected format :
```
echo etc/shadow | cpio -oAF system.cpio
```
The operation is not very resource-intensive, but you'll need to ensure that the server's disk space is large enough, since each student will have his or her own complete system archive (around 30 MB per student).
### Step 1 : Understanding kernel modules
After passing the login screen, the student is presented with a full shell, with which he can run any installed commands he wishes.
There's no graphical interface, the students know how to use a shell, but here we show them that the raw terminal is an option.
Keeping in mind his mission to reach Zion by connecting to the Internet, the student will look to see if he is well connected:
```
42sh# curl https://nemunai.re
curl: (6) Could not resolve host: nemunai.re
```
Maybe we can reach an IP?
```
42sh# ping 9.9.9.9
PING 9.9.9.9 (9.9.9.9): 56 data bytes
ping: sendto: Network unreachable
```
OK, do we have an IP?
```
42sh# ip address
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
```
This approach is normally acquired through regular use of Unix systems, but it's important to remember these commands because some people, more at ease with graphical interfaces, would have looked for Firefox or the Network Manager dialog box.
The last command should be of particular interest, as it will undoubtedly be an unprecedented situation!
Only the `lo` local loop interface is present, and it's not configured.
Where in the world is the Ethernet card used to start up the machine?
This situation can be an opportunity to go back over the mechanics of booting, and explain the role of the operating system loader to make the difference clear.
The aim of this stage is to introduce the kernel modules and the `modprobe` command for loading them.
Depending on the affinity of the audience, they can be left to grope around with `lspci` to explore the hardware, get to grips with the manufacturers' names and search the `/lib/modules` tree for drivers that might match.
For students wondering how a conventional system automatically loads modules, you should of course tell them about `udev` and `mdev`.
These programs will themselves read the information they need from `/sys`.
### Step 2: Network configuration
After loading the kernel module, the network card finally appears:
```
42sh# ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:b4:bc:42 brd ff:ff:ff:ff:ff:ff
inet 172.23.0.42/24 scope global eth0
valid_lft forever preferred_lft forever
```
But it's not configured.
Some will be familiar with DHCP, but no utilities for automatic network configuration are installed on the system.
To start up a machine on the network, you need an automatic configuration service.
For the purposes of this exercise, this is a subnet dedicated exclusively to machine startup, and does not give access to the Internet, which may confuse students at this stage: normally, you get an IP and therefore the Internet!
So, to avoid confronting this received idea at this stage, I've decided to remove all automatic configuration programs.
The only way out is to configure the network manually.
They have the actual network topology at their disposal, as well as an IP address to use.
![Network topology provided for students to find their way around](topology.png)
The risk of such an exercise is that several students will take the same address and create IP conflicts, which would make the exercise far too difficult.
To eliminate any risk of conflict, each student is given a protected address: this address is registered in the server's ARP table so that it can only communicate with its own workstation.
When their network interface is configured, it's a good idea to talk to them about address allocation protocols such as DHCP, Neighbor Discovery Protocol, Router Advertisement, etc.
### Step 3: Recognize a kernel panic
As this is a multi-stage challenge, students have to unlock the stages by sending a unique token to a validation server.
To do this, they are provided with a program to generate these tokens:
```
42sh# adlin
{
"login": "nemunaire",
"challenge": 1,
"token": "db82f32ef6f2563663cb6ffa4826cfade0b822b56b4c0bc526873f3ba224bbae53b8fc6494b408720fb48f858eded6cd649e55edd8620d4ab587e1119c86072e"
}
```
At each step, the server address is given, as this is what modulates complexity, as we'll see in the following steps.
For the very first token, you are asked to send it to a machine on the local subnet, so no additional configuration is required:
```
42sh# adlin | curl -d @- http://172.23.0.1/iamalive
```
Except that in doing so, the student will trigger a *kernel panic*: a program specially designed to exploit a kernel bug will crash the machine.
While calling the `adlin` or `curl` program independently is harmless, when they are called together, an additional program is launched:
```
[ -t 1 ] || init-crypto
```
Of course, there's no cryptography to initialize: it's all about disguising a binary whose sole purpose is to create a *kernel panic*.
![The dreaded kernel panic screen](kernel-panic.png)
Few students have ever experienced a *kernel panic* in the past.
And for most, their reflex will be to restart the machine without looking at it, or trying to understand it.
The aim of this step is therefore to demystify the *kernel panic* screen.
Above all, it's about reading the very last line:
```
---[ end Kernel panic - not syncing: panic_on_oops set ... ]---
```
Sometimes, with a little help on the English terminology of the verb *to set*, the student understands that in fact this is a particular kernel parameter, which could probably be reversed, so that it is no longer defined and therefore no longer causes the crash.
### Step 4: anchoring knowledge
Apart from the interest in understanding a *kernel panic*, the forced reboot of the workstation that this induces, even though the environment is not persistent, forces the student to redo the network configuration.
As this is the key skill selected for this course, forcing the student to redo this step a second time helps to fix the method in his memory.
### Step 5: Kernel configuration
Before trying to validate the first token again, and in order to avoid another *kernel panic*, the student must disable the kernel functionality that is causing this behavior.
This is where we start to get into aspects of Linux unknown to students.
Yet many advanced features (such as the `cgroups` used by Docker) are designed around the same configuration principles: through a tree of virtual files.
Guided by the subject, the students explore the `/proc/sys` folder, looking for the famous `panic_on_oops` file whose contents need to be changed in order to disable the functionality.
Finally, the students can validate their first token, with the satisfaction of having learned and discovered many important things.
### Step 6: Network routing
Back on our thread, in order to access the Internet, an IP alone isn't enough. We need to tell our system the address of our router, which will be responsible for routing our packets to the Internet.
However, the topology only gives us the router's domain name by default.
But it's impossible to resolve a domain name at this stage.
To do this, the subject suggests we finish configuring our system by taking advantage of local services: a name resolver and a time server are accessible in a DMZ that we can reach with a dedicated network route.
Networking is often about routing.
For a student, routing means letting the company's box or router manage this task.
However, it will soon be up to him to manage these routers, hence the importance of showing here an example of "complex" routing, with both a default route and a static route to our DMZ.
A second token is expected to validate the routing.
Some students will have created a default route at this stage and it will work, but they'll see later that it causes them problems.
In any case, this is a useful learning stage.
### Step 7: Time anomaly
Whereas up to now all tokens had to be sent to a web server over an unencrypted connection (in plain HTTP), we're now asked to validate a token on an address using the HTTPS protocol.
So far, everything has seemed coherent, but this seemingly straightforward step - switching from HTTP to HTTPS - will reveal an unexpected problem, to say the least:
```
42sh# curl
curl: (60) SSL certificate problem: certificate is not yet valid
More details here: https://curl.haxx.se/docs/sslcerts.html
```
At startup, the machine is randomly assigned an aberrant date.
The student must then realize that the certificate is indeed valid and that the problem lies with the machine's clock.
As a system administrator, it's not uncommon to come across a machine whose clock has gone back to 0 because of an empty or faulty battery.
Once again, the key is to take the time to read the error message.
Many students rush to add the `-k` option to ignore certificate errors, but the validation token is based on the clock.
If the clock is too far off, the student receives a message reminding him that reflexive use of the `-k` option is not desirable.
To get past this stage, students are expected to discover clock synchronization tools, using the DMZ's NTP server.
### Step 8: Domain name resolution
We've seen that we need to resolve domain names to obtain the address of our default router (but also domain names in general).
Once the student's system can reach the DMZ, it can easily access the resolver server.
To enable the system and all programs on his machine to use domain names, the student learns to manipulate the `/etc/resolv.conf` file.
At the margin of this step, to arouse interest in DNS, a token is to be found in the zone used for the course.
### Step 9: Default route
We've already added a static route, now we need to add the default route.
Like most important actions, this is the second time the student will be adding a route, which makes it easier to learn the mechanism.
The token to be validated at this stage requires access to both the DMZ and the default route.
Students who had not done so at this stage will be forced to do so, as they cannot yet access the Internet despite the default route...
### Step 9 bis: IP conflict madness
Up to now, the student has had a protected IP, but to validate the step he must choose an IP from a /16 range.
It turns out that every time I've taught this course, many students have chosen the router's IP rather than a random IP or one similar to the one assigned to them on the initial subnet.
To ensure that all students without exception are confronted with this problem, the server performs *ARP poisoning* on all addresses seeking to contact it.
The students are thus forced to find the server's true MAC among all the MACs responding to requests.
They also discover the static entries in the ARP table.
### Step 10: Traceroute
The final step involves understanding how packets are routed on the network.
By discovering the `traceroute` tool, students can see that their packets are systematically destroyed at the 4th router!
The exercise is somewhat cavalier, but it goes back to the kernel configuration.
The lifetime of IP packets has deliberately been set to 4, to produce this result.
The student must therefore find the right parameter to set a more appropriate value, which will enable the packets to reach their destination.
As an opening remark, it's worth explaining that this maximum number of routers to be traversed can be used to recognize a target's operating system.
### The End
Finally, students are invited to connect to a remote server displaying the Star Wars movie in ASCII Art.
Perhaps a nod to the next course...?
## Bonus
### 1. Reading the code
Some curious students will have gone to read the scripts provided in the system, including the famous `adlin` script, causing *kernel panic*.
A bonus token is hidden in the script, to reward curiosity.
### 2. Monitoring awareness
Each student is actively monitored to record his or her progress.
The online/offline presence of his or her machine may raise a need for help.
The ICMP packets sent to each student contained a particular hexadecimal string, which they can observe by analyzing the traffic on their Ethernet card.
### 3. Missing file on disk
A virtual disk is created at system start-up, a file is created with a unique token, then deleted.
This bonus is designed to show the experienced student how to use file recovery tools.
## Variants
I'm showing here a standard framework for the exercise I've designed. Depending on expected needs, it is possible to deviate from this scenario.
In particular, you can add VLANs (if the underlying network doesn't filter them), tunnel technology, IPv6, a final SSH connection requiring secure key generation, etc.
## Conclusion
A 3 to 4 hour session is needed for 80% of students to pass all the levels, with 30 to 50 students.
Students systematically come away from this course with stars in their eyes.
On the one hand, they're grateful for all the learning they hadn't had the opportunity to do before, or that they didn't even know they were doing.
On the other hand, they're grateful for the originality of the format, which stimulates them and confronts them with concrete problems that they have to overcome, with reduced frustration thanks to the personalized support that can be provided with live feedback on progress.
Even so, such a course format takes a considerable amount of time to prepare.
Initially, I spent almost 165 hours on it, divided between:
- 40 hours of initial reflections on objectives and scenario,
- 20 hours to carry out some proofs of concept on the grey areas to be clarified,
- 100 hours designing the server and various mechanisms,
- 5 hours of on-site testing to ensure the compatibility of the entire scenario.

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

View File

@ -0,0 +1,402 @@
---
title: "Concevoir un cours ludique d'administration système Linux"
date: !!timestamp '2023-06-07 16:07:00'
tags:
- teaching
- kernel
- network
- certificates
aliases:
- adlin
---
L'administration système n'est pas quelque chose d'évident pour tout le monde, c'est d'ailleurs un sujet qui, lorsqu'il trait plus aux bases du réseau et de Linux, peut sembler beaucoup plus rébarbatif que l'apprentissage des dernières technologies à la mode (Docker, Terraform, Kubernetes, ...).
Aussi, avec le bombardement d'informations et la facilité d'accès à des contenus et tutoriaux informatiques souvent plus intéressant que les cours magistraux "classiques", les étudiants sont de moins en moins attentifs, présents ou participants.
Est-ce peine perdue de regagner leur attention ? Non !
<!-- more -->
De nombreuses solutions existent, dans cet article je vais décrire la manière dont j'ai appliqué les principes de la "ludification".
## Définir les objectifs pédagogiques
Pour la direction des études, je devais mettre sur pied un cours d'administration système Linux, niveau avancé, à destination d'étudiants déja familiers avec la ligne de commande, qui avaient des connaissances théoriques de réseaux et de bonnes bases en termes de programmation Unix.
Lorsque l'on prépare un cours, il est important de définir les objectifs pédagogiques que l'on cherche à atteindre.
Pour moi ici, il s'agissait d'une part de faire pratiquer du réseau concrètement (sans DHCP) et de les amener à déboguer divers problèmes courants pour un administrateur système Linux (tant au niveau système que réseau).
Bien évidemment, un certain nombre de sujets d'ouverture sont également survolés en même temps que l'on passe par les différentes étapes d'apprentissage.
## Le sujet : Matrix Restarted
Une part importante de la ludification est le contexte dans lequel les étudiants vont évoluer.
Il s'agit, au delà des objectifs pédagogiques, de leur trouver une mission, qui s'apparente à un jeu.
Oui, on parle bien de faire cohabiter des besoins métiers concrets, avec un univers fictionnel qui leur donne envie de progresser dans les objectifs.
En école d'ingénieurs en informatique, le film Matrix est une bible sacrée.
Tous les étudiants connaissent le speech de l'histoire et au moins vaguement l'univers.
Durant les quelques heures du cours, les étudiants incarneront donc un de leur héros favoris, dans son univers, avec pour but ultime de : "se connecter à Internet pour rejoindre Zion".
Dans Matrix Revolution, Neo doit rejoindre Zion pour la sauver.
Dès les premières minutes de l'exercice, on met donc en place l'environnement :
![La Matrice, exclamations et frissons garantis](the-matrix.png)
Et, encore plus primordial : leur objectif final leur est expliqué en quelques lignes, dès le début.
![Quelqu´un communique avec nous comme au début du premier film pour nous donner les instructions !](instructions.png)
Pour eux, se connecter à Internet représente une tâche facile, tout-à-fait raisonnable et accessible.
C'est la clef pour leur donner envie de s'investir : susciter leur curiosité, qui aura-t-il une fois arrivé à Zion ?!
Évidemment à ce stade les étudiants ignorent que de nombreuses péripéties les attendent...
## Suivi individualisé
Pour le professeur, un aspect de première importance dans ce genre d'exercice, est d'être capable d'aider les étudiants en difficulté.
On sait très bien que beaucoup d'étudiants ne lèvent pas la main pour demander de l'aide.
Au contraire, je constate que lors de cet exercice, ce sont principalement les étudiants qui se débrouillent le mieux qui ont tendance à demander de l'aide sur les parties bonus, évidemment plus hardues.
Lors de travaux pratiques, la principale source de décrochage que j'ai observée intervient lorsque l'enseignant est en avance sur l'étape de l'étudiant : non seulement il doit se dépêcher pour rattraper son retard, mais en plus il ne peut bénéficier des conseils donnés oralement par le professeur.
On peut déplorer qu'il n'interrompte pas le cours pour demander de l'aide, mais voilà, de nombreux étudiants n'osent pas.
Dans le cadre de cet exercice, étant donné que tout est bien scénarisé, j'ai pu mettre en place un système qui supervise chaque étudiant.
Cela a deux avantages principaux :
- Cela me permet de suivre l'avancement global et individuel : je peux aller voir ceux qui sont en retard pour gérer individuellement leurs difficultées ; et quand c'est toute la classe qui bloque sur une étape, je peux intervenir sans qu'aucun étudiant ne se sente en retard : on réfléchit collectivement sur le point bloquant, ce qui favorise la réflexion individuelle, y compris de ceux qui ne participent pas oralement.
- Alors que la notation est habituellement une corvée, ici en monitorant l'avancement des étudiants, il est aisé de connaître les objectifs pédagogiques que chacun a acquis, afin de le noter en conséquence.
![Le tableau de bord pour suivre chaque étudiant](dashboard.webp)
Mais alors, quel est le contenu, les différentes étapes par lesquelles l'étudiant passe ?
## Contenu du « scénario » du cours
### Étape 0 : Rooter la machine
Dans une entreprise, il peut arriver que l'on se retrouve à devoir intervenir sur une machine installée il y a très longtemps ou par un stagiaire qui n'était pas au fait des procédures et des mots de passe à utiliser, et pourtant il faut en récupérer les accès.
La première étape du cours consiste donc pour les étudiant à "rooter" leur machine.
C'est-à-dire passer outre l'écran de connexion, devenir administreur sans connaître le mot de passe.
C'est une action "courante" qui ne fait appel à aucune vulnérabilité, il suffit d'avoir accès au programme de chargement du système d'exploitation.
Si pour beaucoup d'étudiants l'aspect théorique du "rootage" est bien présent, ils sont très peu à l'avoir expérimenté (et à avoir conscience que c'est si simple, qu'ils pourraient vouloir prendre des mesures pour contrer cette possibilité une fois dans le monde du travail).
### Le bac à sable pour les apprenants
L'ensemble du cours se déroule dans une salle machine préparée spécialement pour l'occasion et chaque machine est un bac-à-sable pour l'étudiant qui l'utilise.
Les étudiants sont sur un poste de travail piloté par un serveur (techniquement, les machines sont tout simplement configurées pour démarrer sur le réseau, en PXE).
Le système démmaré est un véritable système GNU/Linux standard, basé sur la distribution Alpine afin d'être le plus léger possible.
Aussi, afin de limiter les actions inoportunes (écrasement du disque de l'hôte par exemple), le noyau est spécialement compilé pour avoir un nombre limité de pilotes.
Les postes clients n'étant pas démarrés avec un disque physique ou distant attaché, il n'y a aucune donnée persistante : en cas de redémmarage, l'étudiant retrouve la situation initiale.
L'exercice ne nécessitant pas de redémarrer volontairement, cela n'est donc généralement pas un problème, mais cela garanti de retrouver un état sain/connu de l'enseignant s'il doit aider un étudiant qui a détruit son système.
Il y a une exception, car dans la vraie vie, après avoir démmaré notre machine en mode `single` pour écraser le mot de passe `root`, on redémarre pour retrouver le mode classique.
Quelque soit le mode dans lequel la machine a été démmarée, un programme tourne en tâche de fond pour surveiller les modifications faites sur le fichier `/etc/shadow`, contenant les mots de passe des comptes de la machine.
Aussitôt qu'un changement est effectué, le fichier est transmis au serveur démmarant les machines.
Afin de ne pas surcharger le serveur au moment où tous les étudiants changent leur mot de passe, au lieu de recréer l'image complète du système, je tire parti d'une astuce liée au format d'archive utilisé : il n'y a pas d'en-tête ni d'index global des fichiers, on peut donc ajouter un nouveau fichier à la fin de l'archive, dans le format attendu :
```
echo etc/shadow | cpio -oAF system.cpio
```
L'opération est peu coûteuse en ressources, il faudra simplement avoir suffisamment dimensionné l'espace disque du serveur puisque chaque étudiant aura sa propre archive complète du système (de l'ordre de 30 Mo par étudiant).
### Étape 1 : Appréhender les modules noyau
Après avoir passé l'écran de connexion, l'étudiant fait donc face à un shell complet, avec lequel il peut lancer toutes les commandes installées qu'il souhaite.
Il n'y a pas d'interface graphique, les étudiants savent utiliser un shell, on leur montre ici que le terminal brut est une option.
Ayant toujours en tête sa mission de joindre Zion en se connectant à Internet, l'étudiant va regarder s'il est bien connecté :
```
42sh# curl https://nemunai.re
curl: (6) Could not resolve host: nemunai.re
```
Peut-être que l'on peut joindre une IP ?
```
42sh# ping 9.9.9.9
PING 9.9.9.9 (9.9.9.9): 56 data bytes
ping: sendto: Network unreachable
```
OK, est-ce que l'on a une IP ?
```
42sh# ip address
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
```
Cette démarche est normalement acquise lors d'une pratique courante des systèmes Unix, mais il est important de rappeler ces commandes car certains, plus à l'aise avec les interfaces graphiques auraient cherché Firefox ou la boîte de dialogue de Network Manager.
La dernière commande doit interpeler car il s'agira sans doute d'une situation inédite !
Seule l'interface `lo`, de boucle locale, est présente et elle n'est pas configurée.
Où peut donc bien se trouver notre carte Ethernet utilisée pour démmarer la machine ?
Cette situation peut être l'occasion de revenir sur les mécaniques de démarrage, expliquer le rôle du chargeur de système d'exploitation pour bien montrer la différence.
L'objectif de cette étape est de faire découvrir les modules noyau et la commande `modprobe` pour les charger.
Selon l'affinité de l'auditoire, on peut les laisser tâtonner avec `lspci` pour explorer le matériel, s'approprier le nom des constructeurs et rechercher dans l'arborescence `/lib/modules` les pilotes qui peuvent correspondre.
Pour les étudiants qui se demandent comment un système classique charge automatiquement les modules, il faut bien sûr leur parler de `udev` et `mdev`.
Ces programmes vont eux-même lire dans `/sys` les informations dont ils ont besoin.
### Étape 2 : configuration du réseau
Après avoir chargé le module noyau de la carte réseau, celle-ci apparaît enfin :
```
42sh# ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:b4:bc:42 brd ff:ff:ff:ff:ff:ff
inet 172.23.0.42/24 scope global eth0
valid_lft forever preferred_lft forever
```
Mais elle n'est pas configurée.
Certains connaîtront le DHCP, néanmoins aucun utilitaires permettant de configurer le réseau automatiquement n'est installé sur le système.
Car pour démmarer en réseau une machine, il est nécessaire d'avoir sur le réseau un service de configuration automatique.
Dans le cadre de cet exercice, il s'agit d'un sous-réseau dédié exclusivement au démarrage des machines, il ne donne pas accès à Internet, ce qui peut perturber les étudiants à ce stade : normalement on obtient une IP et donc Internet !
C'est donc pour éviter de se confronter à cette idée reçu à ce stade que j'ai préféré retirer tous les programmes de configuration automatique.
La seule voie est donc de configurer le réseau manuellement.
Ils ont à leur disposition la véritable topologie du réseau, ainsi qu'une adresse IP à utiliser.
![Topologie du réseau qui est fournie aux étudiants pour se repérer](topology.png)
Le risque d'un tel exercice est que plusieurs étudiants prennent la même adresse et créent des conflits d'IP, ce qui rendrait l'exercice bien trop difficile.
Pour annihiler tout risque de conflit, chaque étudiant se voit confier une adresse protégée : cette adresse est inscrite dans la table ARP du serveur pour qu'elle ne puisse communiquer qu'avec son poste exclusivement.
Lorsque leur interface réseau est configurée, il est utile de leur parler des protocoles d'attribution d'adresse tels que DHCP, Neighbor Discovery Protocol, Router Advertisement, ...
### Étape 3 : reconnaître un kernel panic
Comme il s'agit d'un challenge en plusieurs étapes, les étudiants doivent débloquer ces étapes en envoyant un jeton unique à un serveur de validation.
Ils disposent pour cela d'un programme pour générer ces jetons :
```
42sh# adlin
{
"login": "nemunaire",
"challenge": 1,
"token": "db82f32ef6f2563663cb6ffa4826cfade0b822b56b4c0bc526873f3ba224bbae53b8fc6494b408720fb48f858eded6cd649e55edd8620d4ab587e1119c86072e"
}
```
À chaque étape, l'adresse du serveur est donnée, car c'est ce qui module la complexité, comme on le verra dans les étapes suivantes.
Pour le tout premier jeton, il est demandé de l'envoyer à une machine du sous-réseau local, donc sans configuration supplémentaire :
```
42sh# adlin | curl -d @- http://172.23.0.1/iamalive
```
Sauf qu'en faisant cela, l'étudiant va déclencher un *kernel panic* : un programme spécialement conçu pour exploiter un bug du noyau va faire planter la machine.
Alors que l'appel indépendant du programme `adlin` ou `curl` est innofensif, lorsqu'ils sont appelés ensemble, un programme supplémentaire est lancé :
```
[ -t 1 ] || init-crypto
```
Il n'y a évidemment aucune cryptographie à initialiser, il s'agit de camoufler un binaire dont le seul but est de créer un *kernel panic*.
![L´écran tant redouté du kernel panic](kernel-panic.png)
Rares sont les étudiants à avoir été confrontés à un *kernel panic* dans le passé.
Et pour la plupart, leur réflexe sera de redémarrer la machine sans le regarder, ni chercher à le comprendre.
Le but de cette étape est donc de démystifier l'écran de *kernel panic*.
Il s'agit surtout de lire la toute dernière ligne :
```
---[ end Kernel panic - not syncing: panic_on_oops set ... ]---
```
Parfois avec un peu d'aide sur la terminologie anglaise du verbe *to set*, l'étudiant comprend qu'en fait il s'agit d'un paramètre particulier du noyau, que l'on pourrait sans doute inverser, faire qu'il ne soit plus définit et ne cause donc plus le plantage.
### Étape 4 : ancrage des connaissances
Outre l'intérêt d'appréhender un *kernel panic*, le redémarrage forcé du poste que cela induit, alors que l'environnement n'est pas persistent, oblige l'étudiant à refaire la configuration réseau.
Comme il s'agit de la compétence clef retenue pour ce cours, le fait d'obliger l'étudiant à refaire une deuxième fois cette étape permet de mieux fixer la méthode dans sa mémoire.
### Étape 5 : configuration du noyau
Avant de tester à nouveau de valider le premier jeton, et afin d'éviter un nouveau *kernel panic*, l'étudiant doit désactiver la fonctionnalité activée dans le noyau qui provoque ce comportement.
On commence ici à rentrer dans des aspects de Linux inconnu des étudiants.
Pourtant de nombreuses fonctionnalités avancées (telles que les `cgroups` utilisés par Docker) sont conçus autour des mêmes principes de configuration : par une arborescence de fichiers virtuels.
Guidés par le sujet, les étudiants explorent donc le dossier `/proc/sys`, à la recherche du fameux fichier `panic_on_oops` dont il convient de changer le contenu afin de désactiver la fonctionalité.
Enfin, ça y est, l'étudiant peut désormais valider son premier token, avec la satisfaction d'avoir appris et découvert de nombreuses choses importantes.
### Étape 6 : le routage réseau
De retour sur notre fil conducteur, afin d'accéder à Internet, une IP seule n'est pas suffisante, il faut indiquer à notre système l'adresse de notre routeur qui sera chargé d'acheminer nos paquets vers l'Internet.
Néanmoins la topologie ne nous donne que le nom de domaine du routeur par défaut.
Mais impossible de résoudre un nom de domaine à ce stade.
Pour se faire, le sujet suggère de terminer la configuration de notre système en tirant parti des services locaux : un résolveur de noms ainsi qu'un serveur de temps sont accessibles dans une DMZ que l'on peut joindre avec une route réseau dédiée.
En réseaux, il est très souvent question de routage.
Pour un étudiant, le routage consiste à laisser la box ou le routeur de l'entreprise gérer cette tâche.
Pourtant ce sera bientôt à lui de gérer ces routeurs, d'où l'important de montrer ici un exemple d'un routage "complexe", avec à la fois une route par défaut et une route statique vers notre DMZ.
Un second jeton est attendu pour valider le bon fonctionnement du routage.
Certains étudiants auront à ce stade créé une route par défaut et cela fonctionnera, mais ils verront plus tard que cela leur posera des problèmes.
Dans tous les cas c'est une étape d'apprentissage utile.
### Étape 7 : anomalie temporelle
Alors que jusque là tous les jetons devaient être envoyés vers un serveur web au travers d'une connexion non chiffrée (en HTTP en clair), il est maintenant demandé de valider un jeton sur une adresse utilisant le protocole HTTPS.
Si jusque là tout semblait être cohérent, cette étape qui avait pourtant l'air simple : passer du protocole HTTP au HTTPS, va révéler un problème pour le moins inattendu :
```
42sh# curl
curl: (60) SSL certificate problem: certificate is not yet valid
More details here: https://curl.haxx.se/docs/sslcerts.html
```
Il se trouve qu'au démarrage, une date aberrante est aléatoirement attribuée à la machine.
L'étudiant doit alors prendre conscience que le certificat est bien valide et que le problème vient de l'horloge de sa machine.
Il n'est pas rare, en tant qu'administrateur système, de rencontrer une machine dont l'horloge est repartie à 0 à cause d'une pile vide ou défectueuse.
Encore une fois, le point clef de l'étape consiste à prendre le temps de lire le message d'erreur.
Beaucoup d'étudiants se précipitent à ajouter l'option `-k` pour ignorer les erreurs de certificats, cependant le jeton de validation est basé sur l'horloge.
Si l'horloge est trop éloignée, l'étudiant reçoit un message lui rappelant que l'usage réflexe de l'option `-k` n' est pas souhaitable.
Pour passer cette étape, il est attendu de découvrir les outils de synchronisation d'horloge, en utilisant le serveur NTP de la DMZ.
### Étape 8 : résolution des noms de domaine
On a vu que l'on avait besoin de résoudre des noms de domaine pour obtenir l'adresse de notre routeur par défaut (mais aussi les nons de domaines de manière générale).
Une fois que le système de l'étudiant peut joindre la DMZ, il peut accéder aisément au serveur résolveur.
Pour que le système et tous les programmes de sa machine soient en mesure d'utiliser des noms de domaine, l'étudiant apprend à manipuler le fichier `/etc/resolv.conf`.
À la marge de cette étape, afin d'éveiller l'intérêt du DNS, un jeton est à retrouver dans la zone utilisée pour le cours.
### Étape 9 : route par défaut
On approche du but, on a déjà ajouté une route statique, il faut maintenant ajouter la route par défaut.
Comme la plupart des actions importantes, c'est la deuxième fois que l'étudiant va ajouter une route, ce qui favorise l'apprentissage du mécanisme.
Le jeton à valider à cette étape néce ssite d'avoir à la fois accès à la DMZ et à la route par défaut.
Les étudiants qui n'avaient pas procédés ainsi à ce stade seront contraint de le faire car ils ne peuvent pas encore accéder à Internet malgré la route par défaut...
### Étape 9 bis : la folie des conflits d'IP
Jusque là l'étudiant disposait d'une IP protégée, mais pour valider le palier il doit seul choisir une IP parmi une plage /16.
Il s'avère qu'à chaque fois que j'ai donné ce cours, de nombreux étudiants ont choisi l'IP du routeur plutôt que de choisir une IP aléatoire ou similaire à celle qui leur avait été attribuée sur le sous-réseau initial.
Pour que tous les étudiants sans exeption soient confrontés à ce problème, le serveur réalise de l'*ARP poisoning* sur toutes les adresses qui cherchent à le contacter.
Les étudiants sont donc obligés de retrouver la véritable MAC du serveur parmis toutes les MAC qui répondent aux requêtes.
Ils découvrent à cette occasion les entrées statiques dans la table ARP.
### Étape 10 : Traceroute
L'ultime étape nécessite de comprendre le cheminement des paquets sur le réseau.
En découvrant l'outil `tracerooute`, l'étudiant peut s'apercevoir que ses paquets sont systématiquement détruits au 4ème routeur !
L'exercice est quelque peu cavalier, mais il revient sur la configuration du noyau.
La durée de vie des paquets IP a volontairement été fixée à 4, pour produire ce résultat.
L'étudiant doit donc retrouver le bon paramètre pour remettre une valeur plus appropriée qui permettront aux paquets d'atteindre leur destination.
En ouverture, il est intéressant d'expliquer que ce nombre maximal de routeurs à traverser peut être utilisé pour reconnaître le système d'exploitation d'une cible.
### Fin
Pour finir, les étudiants sont invités à se connecter à un serveur distant affichant le film Star Wars en ASCII Art.
Peut-être un clin d'œil au prochain cours...?
## Les Bonus
### 1. Lecture du code
Certains étudiants curieux seront allés lire les scripts mis à leur disposition dans le système, notamment le fameux script `adlin`, causant le *kernel panic*.
Un jeton bonus est caché dans le script, afin de récompenser la curiosité.
### 2. Prendre conscience du monitoring
Chaque étudiant est activement monitoré pour enregistrer sa progression.
La présence en ligne/hors ligne de sa machine pouvant soulever un besoin d'aide.
Les paquets ICMP envoyés à chaque étudiant contenait une chaîne hexadécimale particulière qu'ils peuvent observer en analysant le trafic de leur carte Ethernet.
### 3. Fichier disparu sur le disque
Un disque virtuel est créé au démarrage du système, un fichier est créé avec un jeton unique, puis supprimé.
Ce bonus vise à montrer à l'étudiant averti l'usage d'outils de récupération de fichiers.
## Variantes
Je montre ici une trame standard de l'exercice que j'ai conçu. Selon les besoins attendu il est possible de dévier de ce scénario.
On peut notamment ajouter des VLAN (si le réseau sous-jacent ne les filtres pas), une technologie de tunnel, de l'IPv6, une connexion SSH finale nécessitant de générer des clefs sûres, ...
## Conclusion
Une session de 3 à 4 heures est nécessaire pour que 80 % des étudiants valident tousles paliers prévus, avec 30 à 50 élèves.
Les étudiants ressortent de ce cours systématiquement avec des étoiles dans les yeux.
Ils sont reconnaissant d'une part pour tous les apprentissages qu'ils n'avaient pas eu l'occasion de pratiquer avant ou même qu'ils ignoraient.
D'autre part ils sont reconnaissant de l'originalité du format, qui les stimule et les mets face à des problèmes concrets qu'ils doivent dépasser, avec une frustration réduite du fait de l'accompagnement personnalisé qui peut être réalisé avec la remontée en direct de la progression.
Un tel format de cours prend tout de même un temps conséquent à préparer.
Initialement j'y ai passé près de 165 heures réparties entre :
- 40 heures de reflexions initiales sur les objectifs et le scénario,
- 20 heures pour réaliser quelques preuves de concepts sur les zones d'ombre à éclairer,
- 100h de conception du serveur et des différents mécanismes,
- 5h de tests sur place pour s'assurer de la compatibilité de l'ensemble du scénario.