Administration serveur web

Objectif du TP :

L'objectif de ce TP est de découvrir et se préparer un lexique des commandes que vous pouvez saisir. On va détailler chaque étape après, mais voici le planning :

  • Découvrir le manuel
  • Naviguer dans le dossier /var
  • Créer un dossier learning dans var
  • Écrire dans un fichier cours-1 (sans extension)

Rendu :

  • Répondre aux questions mise en commentaire au format qui vous semble le plus adapté.

TP1 - Travailler sous un environnement Linux

Travail de recherche préparatoire

Cette partie concerne des questions auxquelles vous devez répondre avant d'attaquer le travail.

  • Qu'est-ce qu'un système d'exploitation ?
  • Qu'est-ce qu’Ubuntu ?

Inscrivez-vous sur le site :

Play with Docker

Si le site à quelques soucis vous pouvez continuer avec celui-ci :

Deploy Static HTML Website as Container | Docker | Katacoda
Interactive Learning and Training Platform for Software Engineers

Découverte de la ligne de commande

Depuis le site lancez une instance et tapez dans la ligne de commande :

uname -a

Trouvez à quoi correspond chaque mot affiché.
Que veut dire le -a de la commande uname ?

Avant de commencer il faut définir plusieurs notions :

  • root directory (/)
  • home directory (~)
  • parent directory (..)
  • working directory (.)

Répondez aux questions suivantes :

  • Définissez chaque terme ci-dessus et à quoi sert le symbole entre parenthèse qui leur est associé ?
  • Qui a accès a chacun de ces dossiers ?
  • À quoi servent chacun de ces dossiers (Qu'est-ce qu'il contient) ?
  • Quel sont (le cas échant) leurs chemins absolus ?

Que font les commandes suivantes ?

  • pwd
  • cd
  • ls
  • mkdir
  • sudo

Pour commencer, on va simplement afficher le chemin courant. On va remonter dans le dossier parent, récupérer de nouveau son chemin.

L'objectif après est de récupérer le contenu du dossier courant, ainsi que son chemin. Puis se rendre dans /var.

Enfin, on va créer le dossier learning et entrer dedans.

Écrire dans un fichier

Que font les commandes suivantes ?

  • nano
  • touch
  • mv
  • cp
  • rm
n.b. ^C signifie ctrl + c

Pour écrire le fichier COURT-1 on va commencer par créer un fichier vide. Puis l'ouvrir avec l'éditeur de texte en ligne de commande. Ajouter un petit texte qui donnera votre avis sur le cours puis fermez le fichier.

Comment enregistrer le fichier ?

Renommez le fichier COURT-1 en COURS-1.

Retournez rapidement (pas plus de 4 caractères la commande) dans le dossier de départ et écrivez la commande.

Effectuez une copie du dossier /var/learning dans un sous-dossier cours du dossier home. Supprimez enfin le dossier contenu learning de /var sans changer de dossier. Écrivez les commandes effectuées dans votre fichier de rendu.

Récréez en ligne de commande l'architecture de dossier suivante (écrivez les commandes dans votre rendu) :

Je suis actuellement dans le dossier /a/b/2, donnez le chemin absolu dans lequel je suis après avoir tapé la commande suivante :

cd ../../a/./../../b/../a/../

Les variables d'environnements

Qu'est-ce qu'une variable d'environnement ?

Tapez la commande suivante :

printenv

Qu'affiche-t-elle ? Tapez ensuite la commande suivante puis refaite un printenv

export EDITOR=nano

Que constatez-vous ? À quoi sert la commande export ? Et la commande unset ?

Premier script bash

Si vous ne pouvez pas exécuter de script bash sur votre machine vous pouvez utiliser ce site :

Online Bash Compiler - Online Bash Editor - Online Bash IDE - Bash Coding Online - Practice Bash Online - Execute Bash Online - Compile Bash Online - Run Bash Online

Un script contient des séquences de commandes telles que l’on pourrait les taper dans un terminal. Les commandes successives peuvent être séparées par des retours à la ligne (qui sont interprétés comme des points virgules).

  • Tout fichier de script commence par une ligne permettant d’identifier le programme qui doit être utilisé pour l’exécuter. Dans le cas d’un script bash, la première ligne du fichier doit contenir : #!/bin/bash
  • Une ligne commençant par le caractère : # est considérée comme un commentaire et n’est pas exécutée par le shell. Comme toujours, il est très important de bien commenter son script pour qu’il soit compréhensible pour le reste du monde. - Par convention, l’extension d’un script est : .sh
  • Pour qu’un utilisateur puisse exécuter un script, il doit posséder les droits en exécution, mais aussi en lecture sur ce script (c’est un cas particulier où la lecture est nécessaire à l’exécution).
  • Pour exécuter un script, on peut taper directement dans le terminal le chemin absolu du fichier, ou taper directement le chemin relatif du fichier en le faisant commencer par ./ ou taper la commande bash suivie d’un chemin du fichier.

Créez un dossier "exercices" puis créez un fichier "exercice1.sh" qui contient la commande suivante :

echo Bonjour

Exécutez le fichier avec la commande suivante : ./exercice1.sh. Que constatez-vous ? Pourquoi ?
Exécutez la commande suivante puis essayez d'exécuter le fichier précédemment crée :

chmod 777 exercice1.sh
  • À quoi sert la commande chmod ?
  • À quoi corresponde les chiffres ?

Exercices :

1) Échauffement

Écrivez un script shell qui affiche "J'aime", "les", "cours", "d'administration", "système" à l'écran, chaque mot doit apparaitre sur une ligne distincte. Essayez de faire cela en aussi peu de lignes que possible.

2) Tests sur des fichiers

Écrivez un script qui demande à l'utilisateur le nom d'un fichier ou d'un répertoire et indique s'il s'agit d'un fichier, d'un dossier. Exécutez également une commande `ls` sur le fichier ou le dossier avec l'option de liste longue.

Indice :

[[ -f /etc/passwd ]] && echo "This file exists!"

3) FizzBuzz

Le « FizzBuzz » est à l’origine un jeu pour apprendre aux enfants le principe de la division. Les enfants doivent énoncer les chiffres dans l’ordre et remplacer le nombre par « Fizz » s’il est divisible par 3 ou « Buzz » s’il est divisible par 5.

Dans le monde des développeurs, ce jeu est repris sous forme de test.
Lors d’un entretien d’embauche, ce test peut être proposé parmi d’autres tests techniques.  Il permet à l’employeur de vérifier si, sous environ 15 minutes, le candidat est capable d’écrire ce programme dans le langage demandé.

Écrivez un programme qui affiche tous les nombres entre 1 et 100 avec les exceptions suivantes :
Il affiche :
– « Fizz » à la place du nombre si celui-ci est divisible par 3.
– « Buzz » à la place du nombre si celui-ci est divisible par 5 et non par 3.
– « FizzBuzz » à la place du nombre si celui-ci est divisible à la fois par 3 et par 5.

Faites en sorte que l'on puisse définir les mots « Fizz » et « Buzz » grâce à des variables d'environnement.

Essayer de rédiger le programme en respectant le concept DRY :

Ne vous répétez pas — Wikipédia

4) Plus ou moins ?

Écrivez un script shell qui reprends le "célèbre" jeu du plus ou moins.

Pour rappel le principe est le suivant.

  1. L'ordinateur tire au sort un nombre entre 1 et 100.
  2. Il vous demande de deviner le nombre. Vous entrez donc un nombre entre 1 et 100.
  3. L'ordinateur compare le nombre que vous avez entré avec le nombre « mystère » qu'il a tiré au sort. Il vous dit si le nombre mystère est supérieur ou inférieur à celui que vous avez entré.
  4. Puis l'ordinateur vous redemande le nombre.
  5. … Et il vous indique si le nombre mystère est supérieur ou inférieur.
  6. Et ainsi de suite, jusqu'à ce que vous trouviez le nombre mystère.

Le but du jeu, bien sûr, est de trouver le nombre mystère en un minimum de coups.

Pour les plus rapides :

  • Faites un compteur de nombre de coups
  • Faire en sorte que le programme vous re-demande de jouer
  • Faites jouer l'ordinateur à votre place
  • Ajouter la gestion des niveaux de difficultés, exemple : un nombre entre 1 et 1000

5) Lister des utilisateurs

Écrivez un script bash affichant la liste des logins des utilisateurs définis dans /etc/passwd.

Indication :

for user in $(cat /etc/passwd); do echo $user; done

Permet presque de parcourir les lignes dudit fichier. Cependant, quel est le problème ? Résoudre ce problème en utilisant cut (avec les bons arguments) au lieu de cat.

Faites la même chose avec la commande awk.

6) Tester si un utilisateur existe

Écrivez un script qui vérifie si un utilisateur existe déjà :

  • En fonction d’un login passe en paramètres
  • En fonction d’un UID passe en paramètres
  • Si l’utilisateur existe renvoyer son UID a l’affichage.
  • Sinon ne rien renvoyer.

7) Création d'un utilisateur

Écrivez un script qui permet de créer un compte utilisateur voir : man adduser.

Utilisez votre script de vérification d’existence d’utilisateur avant de créer.

  • Il faudra vérifier que l’utilisateur en cours d’exécution est bien root voir echo $USER.

Il faudra répondre à une suite de question :

  • Login
  • UID
  • GID

TP 2 - Travailler avec NGINX (Virtual host et Reverse proxy)

HTTP

En guise de rappel répondez à ces questions :

  • Que veut dire HTTP ? À quoi cela sert ? Comment cela fonctionne ?
  • Qu-est-ce que le problème C10K ?

Pourquoi Nginx ?

Nginx a été conçu pour répondre au problème C10K où le but est d'être capable de répondre à plus de 10 000 requêtes simultanées. Nginx est du coup plus performant lors d'un traffic important avec un système de worker. Là où apache crée un processus par connexion, nginx lance une série de workers qui vont chacun être capable de gérer de multiples connexions d'une manière non bloquante.

Lisez le site suivant puis répondez aux questions suivantes :

Optimisez Nginx pour de meilleurs performances – Buzut
Nginx est réputé pour sa rapidité, mais quand votre serveur fait face à un trafic énorme, il est possible d’en tirer encore plus. Voyons comment !
  • Qu'est-ce qu'un worker ?
  • Où sont situé les buffers ?
  • Qu'est-ce que la thread pool ?

Les virtual host

Qu'est-ce qu'un virtual host ?

Créer un fichier HTML et nommé le index.html, écrivez quelques lignes d'HTML dedans.

Installez Nginx sur votre machine puis configurer un virtual host pour que votre localhost pointe sur votre fichier HTML. Répondez à cette question en écrivant votre configuration Nginx ainsi que d'une copie d'écran.

Vous pouvez vous aider de ce site :

Nginx — Formation Mettre en place un serveur Web

Parfois, nous avons besoin d'accéder à nos projets web dans un environnement local avec des noms de domaine. Dans ce cas, nous pouvons utiliser des domaines virtuels. Ce qui nous permet d'utiliser des noms de domaine fictif ou réel pour voir nos projets locaux.

En vous aidant des ressources suivantes :

events { worker_connections 1024; }

http {

    # Configuration for the server
    server {
        #TODO
    }
}
Un début de configuration à compléter
FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
Le fichier Dockerfile qui va écraser la configuration par défaut
version: "3"

services:
    client:
        build: .
        ports:
            - 8000:80
            - 8001:81
        volumes:
            - ./src:/usr/share/nginx/html
Le Docker-compose avec un volume pour le site statique

Faites en sortes que les adresses suivantes (i.e le server_name ) pointes tous sur le même fichier HTML précédemment créer :

  • jaimelesysadmin
  • jaimepaslesysadmin

Loadbalancing

La suite de ce TP nécessite de savoir utiliser Docker pour des raisons de simplicité, si vous n'êtes pas encore familier avec Docker je vous invite a faire le TP3 présent ici :

Déploiement des solutions
TP 1 - Introduction au Cloud computingQu’est-ce que le “cloud computing” ? Le cloud computing est la fourniture de différents services par le biaisd’Internet. Ces ressources comprennent des outils et des applications comme lestockage de données, les serveurs, les bases de données, les réseaux et…

Les loadbalancers sont utilisés pour assurer la disponibilité et l'évolutivité d'une application web. En effet, un site peut évoluer au-delà de la capacité ou de la charge d'un seul serveur. Le loadbalancer a pour mission de diriger le trafic vers un pool de serveurs disponibles grâce à divers algorithmes d'équilibrage de charge. Si des ressources supplémentaires sont nécessaires, des serveurs supplémentaires peuvent être ajoutés.

Citez des méthodes de loadbalancing.

Pour commencer créez un dossier que vous appellerez loadbalancer. Mettez à l'intérieur de ce dossier tous les fichiers que vous allez créer par la suite.

Pour bien matérialiser le changement d'API qui va s'opérer grâce au loadbalancing nous avons petit serveur pour nous afficher le nom de la machine, voici pour vous aider un serveur express qui affichera le nom de la machine hôte lors d'une requête get :

const express = require('express');
const dotenv = require('dotenv');
var os = require("os");
dotenv.config();
const app = express();


app.get('/', (req, res) => {
    res.send(os.hostname());
    console.log('Get request on : ' + os.hostname());
});


app.listen(process.env.LISTEN_PORT, ()=>{
    console.log('Server started on port ' + process.env.LISTEN_PORT);
});
app.js

De plus, il vous faudra créer un fichier package.json pour rendre plus simple le lancement et l'installation de votre serveur depuis votre Dockerfile

Utilisez la commande suivante pour en créer un par défaut :

npm init --yes

Installer les packages suivant : express et dotenv, n'oublier pas non plus de configurer une commande nommé startqui démarera le serveur express :

  "scripts": {
    "start": "node app.js"
  },

Puis il vous faut le Dockerfile qui vous servira à creer l'image :

FROM node:12.18-alpine
ENV NODE_ENV production
ENV LISTEN_PORT=3003
WORKDIR /usr/src/app
COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
RUN npm install --production --silent && mv node_modules ../
COPY . .
CMD npm start
Dockerfile

Créer un dossier nommé nginx qui contiendra, le dockerfile de nginx ainsi que son fichier de configuration :

FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
Nginx.Dockerfile
events { worker_connections 1024; }

http {

    # List of application servers
    upstream api_servers {
        server loadbalancer_api_1:3003;
    }

    # Configuration for the server
    server {

        # Running port
        listen [::]:5100;
        listen 5100;

        # Proxying the connections
        location / {
            proxy_pass         http://api_servers;
        }
    }
}
nginx.conf

Expliquez a quoi sert la ligne :  upstream et proxy_pass

Revenez dans votre dossier loadbalancer et il ne reste plus qu'a créer un fichier docker-compose  :

version: '3.4'

services:

  nginx:
    build:
      context : ./nginx/
      dockerfile: Nginx.Dockerfile
    depends_on:
      - api
    ports:
      - "5100:5100"
    restart: always


  api:
    build: .
    environment:
      NODE_ENV: production
    restart: always
docker-compose.yml

Expliquez à quoi sert le fichier docker-compose.

Si vous avez des soucis, n'oublier de re-build les images a chaque fois, vous pouvez le faire diretecment depuis le docker-compose avec cette commande : docker-compose up --build

Faite en sortes que la stack fonctionne puis configurer nginx pour mettre en place une stratégie de loadbalancing un utilisant un algorithme simple de type "roundrobin".

Pour tester l'algorithme vous pouvez utilisez la commande suivante :

docker-compose up --scale api=3 -d

Expliquez en quoi vous pouvez être sûr que ce que vous avez fait fonctionne.

TP 3 - Mettre en œuvre HTTPS

Le   protocole   HTTPS   (HTTP   sur   SSL/TLS)   est   couramment   utilisé   pour   sécuriser   les communications   entre  un   serveur   Web   et   un   navigateur.   Pour   cela,   une  session   HTTPS s'appuie   sur   un   certificat   diffusé   par   le   serveur   permettant   d'effectuer   une   session d'authentification initiale et ensuite un chiffrement du canal de communication dans lequel transite l'échange HTTP.

  • Qu'est-ce que SSL et TLS ?
  • Qu'est-ce que letsencrypt ?
  • À quoi sert une autorité de certification ?

Pour générer ce certificat utilisez openssl :

# Use 'localhost' for the 'Common name'
openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 365 -keyout localhost.key -out localhost.crt

# Add the cert to your keychain
open localhost.crt

Détaillez chaque argument de la ligne de commande ci dessus. (Sous MacOS n'oubliez pas de toujours autoriser ce certificat).

Exécutez sur votre machine le serveur node express ci-dessous :

var express = require('express'); // Get the module
var http = require('http');
var https = require('https');
const fs = require('fs');

var privateKey  = fs.readFileSync('localhost.key', 'utf8');
var certificate = fs.readFileSync('localhost.crt', 'utf8');

var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var app = express(); // Create express by calling the prototype in var express

var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);

httpServer.listen(8080);
httpsServer.listen(8443);

var httpsServer = https.createServer(credentials, app);

app.get('/', function(req, res){
    res.send('hello world');
});

Puis faite en sorte que votre machine puisse accéder en HTTPS a votre site.

Une petite aide sous windows pour authorizer le certificat :

https://support.kaspersky.com/CyberTrace/1.0/en-US/174127.htm