Hacker Lab


Docker est un outil qui permet d'empaqueter une application et ses dépendances dans un conteneur isolé.
Ce containeur pourra ensuite être exécuté sur n'importe quel serveur.
Il est ainsi possible de garder un serveur minimaliste, les librairies, dépendances et configurations étant dans le containeur.

Un container docker est aussi simple à lancer qu'une application. Il ne s'agit pas d'une machine vituelle (VM).

Pour réaliser cet atelier, ouvrez un onglet [Ma kali], et connectez-vous au serveur Ubuntu.
Sur ce serveur, vous faites partie du groupe docker, ce qui vous permet de lancer des commandes docker.

Référence: wikipedia

1 / 16 - Slides
5

Merci de jeter un oeil aux slides :)

Le flag est le prenom de l'auteur en minuscule sans accents.

2 / 16 - Lancer un container
5

Nous voulons hégerger un petit site web.

Utilisons l'image docker prépackagée officielle php:7.2-apache. Elle contient un serveur apache, et php 7.2

docker run --name yolo-apache php:7.2-apache 

Nous lui donnons un nom avec l'argument --name yolo-apache.
Les autres container pouront discuter avec elle sur le réseau interne docker en utilisant ce nom.
Nous pourons la manipuler en ligne de commande avec ce nom.
Si l'image n'est pas disponible en local, elle sera téléchargée sur le site hub.docker.com.
Les traces de l'application s'affichent.

Lister les containers en activité
Dans un autre onglet, demandons la liste des containers sur notre serveur.

docker ps 

Filtrons nos containers

docker ps -f name=yolo-apache 


Le flag est le contenu du champ PORTS.

3 / 16 - Supprimer un container arrété
5

Exposer un port
Le port 80 est exposé sur le container, mais il n'est pas ouvert sur le host.
Chaque container a sa propre adresse IP, et est accessible par son nom sur le réseau interne docker.

Si nous voulons y accéder à partir du host, nous devons mapper ce port.
Arrétons notre docker avec un Ctrl-C.
Puis relançons le en demandant une publication du port...

docker run --name yolo-apache -p 80 php:7.2-apache 

Le container refuse de se lancer...

The container name "yolo-apache" is already in use by container xxx 

Le container a été arrété, mais pas effacé.
Pourtant un docker ps ne montre rien...

docker ps -f name=yolo-apache 

Lister les containers arrétés
Il faut utiliser l'option docker ps -a pour afficher les dockers arrétés.

Supprimer un container
Pour supprimer un container : docker rm xxxxx.
Les containers lancés sans nom ont un nom généré aléatoirement au format xxxx_xxxxx

docker ps -a -f name=yolo-apache 
docker rm yolo-apache 

Il est possible de relancer le container avec l'option --rm pour qu'il soit supprimé automatiquement quand on l'arrète.

docker run --rm --name yolo-apache -p 80 php:7.2-apache 
'AH00558: xxxxxx: Could not reliably determine...' 


Le flag est le nom du programme remplacé par xxxxxx qui apparait dans les logs.

4 / 16 - Exposer le port 80 du container de façon dynamique
5

Trouver le port mappé sur le host
Relançons notre container avec :

docker run --rm --name yolo-apache -p 80 php:7.2-apache 

Dans un autre onglet, obtenons des informations:

docker ps -f name=yolo-apache 

Le port est maintenant au format

0.0.0.0:32770->80/tcp 

Si nous lançons firefox sur http://localhost:32xxx, nous accédons au serveur apache.

Forbidden 
You don't have permission to XXXXX this resource. 
apache/2.4.38 (Debian) Server at localhost Port 32770 

Pour l'instant, le serveur apache n'a aucun fichier à servir.
Arrétons le container avec un Ctr-C. Il va se supprimer tout seul.

Le flag est le mot remplacé par XXXX

5 / 16 - Monter un répertoire du host
5

Commençons par créer une page html.

echo "<h2>Yolo Site Web</h2><br/>Hello le monde" > index.html 

Puis lançons le container, en précisant que le répertoire courant du host est mounté sur le répertoire /var/www/html/ dans le container.
Celà permet de modifier le code du site et tester en direct les modifications.

docker run --volume=$(pwd):/var/www/html/ --name yolo-apache -p 80 --rm  php:7.2-apache 

Récupérons la valeur du port dynamique

docker ps -f name=yolo-apache 

Lançons firefox sur http://localhost:32xxx

6 / 16 - Pages web en php
5

Crééons une page dynamique en php.

echo "<h2>Site Web PHP</h2><?php system('id;pwd;uname -a'); ?>">index.php 


Le flag est l'identifiant sous lequel tourne le serveur web

7 / 16 - Démarrer en arrière plan
5

Le container peut démarrer en arrière plan avec l'argument -d

docker run -d --volume=$(pwd):/var/www/html/ --name yolo-apache -p 80 --rm  php:7.2-apache 

On vérifie qu'il tourne:

docker ps -f name=yolo-apache 

Le flag est le status de votre container.

Il est possible de l'arréter avec

docker stop yolo-apache 

Il a été lancé avec l'option -rm, il va donc s'effacer automatiquement.

8 / 16 - Arréter et redémarrer un container
5

Si nous démarrons le container en arrière plan sans l'option -rm, il est possible de l'arréter, et de le redémarrer

docker run -d --volume=$(pwd):/var/www/html/ --name yolo-apache -p 80  php:7.2-apache 

pour l'arréter

docker stop yolo-apache 

On vérifier qu'il ne tourne pas.

docker ps -f name=yolo-apache 

On vérifier qu'il existe a l'état arrété

docker ps -a -f name=yolo-apache 

Le flag est le status de votre container.
On redémarre le container arrété.

docker restart yolo-apache 

On vérifier qu'il tourne.

docker ps -f name=yolo-apache 

On l'arrète et on n'oublie pas de le supprimer.

docker stop yolo-apache 
docker rm yolo-apache 
9 / 16 - Publier sur un port statique sur le host
5

Pour un serveur web, nous utilisons généralement le port 80, ou 8080 (pour ne pas avoir besoin des droits root). La synthaxe devient -p [port du host]:80
Les autres machines du réseau pouront accéder à notre serveur web sur le port 8080 de notre host.
Note: Pour restreindre au host, la syntaxe est : -p 127.0.0.1:[port du host]:80
Remplacez 9268 par un port aléatoire entre 9100 et 9900.

docker run -d --rm --volume=$(pwd):/var/www/html/ --name yolo-apache -p 9268:80  php:7.2-apache 

Et accédez y à partir de firefox.
N'oubliez pas de stopper votre container qui s'autodétruira.

docker stop yolo-apache 
10 / 16 - Dockerfile
5

Notre serveur est prêt, nous allons tout packager dans une image.
Ecrivons le fichier Dockerfile qui décrit la façon dont l'image est construite

FROM php:7.2-apache 
COPY index.php /var/www/html/ 

Construisons notre image que nous nommons yolo-my-apache. Le . précise que le fichier Dockerfile est dans le répertoire courant.

$ docker build -t yolo-my-apache . 

Choisissons un port du host et instançions un container à partir cette image qui contient le code de notre site web.

$ docker run -d --rm --name yolo-apache -p 9268:80 yolo-my-apache 

Et accédez y à partir de firefox.
N'oubliez pas de stopper votre container qui s'autodétruira.

docker stop yolo-apache 
11 / 16 - Dockerfile: apt install
5

Nous aimerions utiliser la commande ping dans ce container.
Mettons à jour le code de index.php

echo "<h2>Site Web PHP</h2><?php system('which ping;ping -c 1 127.0.0.1'); ?>" > index.php 

Relançons un container en mountant le répertoire courant qui va remplacer le contenu de l'image.

$ docker run -d --rm --volume=$(pwd):/var/www/html/ --name yolo-apache -p 9268:80 yolo-my-apache 

Et accédons y à partir de firefox...
Ben c'est vide.. Ping n'est pas installé dans ce container. Les container ne contiennent que le strict minimum.

docker stop yolo-apache 


Ecrivons un fichier Dockerfile qui installe ping, et copie notre nouveau fichier index.php.

FROM php:7.2-apache 
RUN apt update && apt install -y iputils-ping 
COPY index.php /var/www/html/ 

Construisons notre image.

$ docker build -t yolo-my-apache . 

Choisissons un port du host et instançions un container.

$ docker run -d --rm --name yolo-apache -p 9268:80 yolo-my-apache 

Accédons y à partir de firefox.
N'oubliez pas de stopper votre container qui s'autodétruira.

docker stop yolo-apache 
12 / 16 - Dockerfile: Simple python
5

Nous souhaitons créer un container pour faire tourner notre appli python

$ cat app.py 
print('hello docker') 


$ cat requirements.txt 
requests 


$ cat Dockerfile 
FROM python:3 

WORKDIR /usr/src/app 

COPY app.py . 
COPY requirements.txt . 

RUN pip install --no-cache-dir -r requirements.txt 

EXPOSE 5000 

CMD ["python", "./app.py"] 

Construire l'image

$ docker build -t yolo-my-python . 

Instançions un container.

$ docker run -d --rm --name yolo-python yolo-my-python 
13 / 16 - Liste des images en local
5

Pour lister les images disponibles en local sur le système aaz

docker images 
14 / 16 - Docker hub
5

Les images docker sont référencées sur https://hub.docker.com/search?q=&type=image
Une image peut contenir des malwares et/ou des backdoors.
Utilisez des images officielles comme base et lisez le fichier dockerfile pour savoir ce qu'il y a dans une image.
Vous pouvez faire des recherche en cochant:

  • Verified Publisher
  • Official images

    Cherchez l'image officielle de Wordpress
15 / 16 - Docker Tag
5

Les images docker possèdent des tags:

Regardez les tags de l'image officielle de Wordpress
https://hub.docker.com/_/wordpress

  • 5.7.0-apache, 5.7-apache, 5-apache, apache, 5.7.0, 5.7, 5, latest, 5.7.0-php7.4-apache
  • 5.7.0-fpm-alpine, fpm-alpine, 5.7.0-php7.4-fpm-alpine
  • 5.7.0-php8.0-apache, 5.7-php8.0-apache
    Les tags d'une même ligne sont équivalent.
    Le Tag latest permet d'avoir la dernière version à jour. Actuellement c'est la version 5.7.0
16 / 16 - docker-compose
5

Docker-compose permet de lancer une solution complète de containers.
Ici un serveur wordpress, et un serveur de base de donnée mysql.
Les volumes sont des systèmes de fichier persistant, gérés par docker.

version: '3.1' 

services: 

  wordpress: 
    image: wordpress 
    restart: always 
    ports: 
      - 8080:80 
    environment: 
      WORDPRESS_DB_HOST: db 
      WORDPRESS_DB_USER: exampleuser 
      WORDPRESS_DB_PASSWORD: examplepass 
      WORDPRESS_DB_NAME: exampledb 
   volumes: 
      - wordpress:/var/www/html 

  db: 
    image: mysql:5.7 
    restart: always 
    environment: 
      MYSQL_DATABASE: exampledb 
      MYSQL_USER: exampleuser 
      MYSQL_PASSWORD: examplepass 
      MYSQL_RANDOM_ROOT_PASSWORD: '1' 
    volumes: 
      - db:/var/lib/mysql 

volumes: 
  wordpress: 
  db: