Créer un conteneur Docker

Logo DockerMaintenant que tu as installé docker sur ta bête de course tu vas pouvoir créer un conteneur Docker. Pour cela je vais te faire un petit exemple en déployant un serveur de jeux dans Docker. Le serveur est le DarkMultiPlayer pour Kerbal Space Program. Il a la particularité de ne pas avoir été compilé pour Linux :/, il faudra donc le faire fonctionner avec mono … Bref on va pouvoir tester les performances de docker au passage :)

Aller c’est parti!

1. Création de l’image docker

On commence par télécharger le serveur du jeu :

(un petit wget des familles)

$ wget https://d-mp.org/downloads/release/latest/DMPServer.zip

On extrait avec unzip et on oubliera pas de supprimer notre zip une fois que tout sera fonctionnel afin de garder un plan de travail toujours propre.

$ unzip DMPServer.zip 

Il est venu le temps, des rires et des chants, ha non c’est pas ça…

Il est venu le temps de créer notre image docker. Pour se faire rien de plus simple, on créer un fichier nommé Dockerfile.

$ touch Dockerfile

On l’ouvre avec notre éditeur de fichiers préféré :

$ vi Dockerfile

Là on commence les choses sérieuses :

On sait que le serveur à besoin de mono pour fonctionner. On va donc prendre un image de mono déjà construite dans les dépôts de docker, qui nous apportera au passage une l’image OS avec laquelle elle à été construite. pour cela dans notre docker file on va en écrire ceci en haut du fichier :

 FROM mono:4.4 

(/!\ on lui indique toujours une version plutôt que latest, de cette façon on est sûr que notre image reste fonctionnelle dans le temps.)

En dessous on doit indiquer un mainteneur (utile si on souhaite le publier sur les repo docker) sous la forme nom prénom <mail>

MAINTAINER tonton tux <tux@domaine.fr>

On va ensuite lui passer des commandes afin de se faire un endroit cosy dans cette image … ou pas

On commence par créer un utilisateur (ici kerman en faisant référence au jeu) avec son group, homedir,…
Cet utilisateur sera créé dans le docker, en aucun cas sur l’OS hôte.

RUN useradd -m -d /home/kerman

Le RUN de docker réalise en réalité appel au shell de l’image OS. Les commandes disponibles peuvent donc varier en fonction de votre image de base.

On lui ajout notre dossier précédemment « dé-zippé » dans le home de l’utilisateur kerman et on met ce dernier propriétaire de l’ensemble.

ADD DMPServer /home/kerman/DMPServer
RUN chown -R kerman:kerman /home/kerman

Ensuite on va définir le répertoire de travail et l’utilisateur owner qui sera utilisé lors du lancement du docker :

WORKDIR /home/kerman/DMPServer
USER kerman

On ouvre le port de sur lequel notre service écoute sur l’image. Ce port n’a pas besoin d’être libre sur votre machine, en effet Docker intègre une couche réseau avancé permettant de créer un nat ou proxy.

EXPOSE 6702

Et enfin avec l’instruction CMD on défini la commande que va exécuter notre serveur.

CMD mono /home/kerman/DMPServer/DMPServer.exe

Ce qui nous donne :

#Image de base
FROM mono:4.4

#Personne en charge
MAINTAINER tonton tux <tux@tontontux.fr>

#On créer notre utilisateur et groupe
RUN useradd -m -d /home/kerman

#On insère les binaires dans l'image 
ADD DMPServer /home/kerman/DMPServer  

#On attribut les bons droits 
RUN chown -R kerman:kerman /home/kerman  

#On définit l'utilisateur qui exécutera le binaire du serveur
USER kerman 

#On définit le port d'écoute de l'image
EXPOSE 6702

 #On définit la commande exécutée par l'image
CMD mono /home/kerman/DMPServer/DMPServer.exe

Puis il nous reste plus qu’a installer l’image pour pouvoir l’utiliser.

Pour se faire il suffit de taper :

$ docker build -t mon_serveur_ksp ./

(/!\ le ./ definit la position du fichier Dockerfile)

Et on vérifie que tout s’est bien passé avec un:

$ docker images

Cela devrait donner quelque chose dans ce genre la :

mon_serveur_ksp     latest              42f2966021b6        8 minutes ago       699.4 MB
mono                4.4                 4bcf669858be        3 weeks ago         698.3 MB

Si on veut être économe en place on vas pouvoir supprimer l’image mono qui nous a seulement servi pour la compilation.

$ docker rmi mono:4.4

/!\ Vous ne pourrez et ne devez pas la supprimer si elle est utilisée ailleurs pour pour un autre container.

Et … voila on a créé notre image docker !

Heu ouai … mais c’est pas finit !

 2. Création du conteneur

Le conteneur est une instance de notre image et à partir d’une image donnée on peut créer autant de conteneur qu’on veux. Aller c’est parti !

Pour créer le conteneur on lance :

$ docker  run -t mon_serveur_ksp &

On peux vérifier qu’il est bien lancé avec la commande :

$ docker ps

Ce qui devrait nous donner :

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
a4235aadace9        mon_serveur_ksp     "/bin/sh -c 'mono /ho"   4 seconds ago       Up 3 seconds        6702/tcp                 elegant_lamport

Et voila le conteneur est lancé a+!

Ok,ok… on peux mieux faire.

Déjà docker est démarré en jobs et ça … c’est pas top, du coup on le passe en démon en ajoutant l’option « -d »

$ docker  run -t -d mon_serveur_ksp

Après on peu remarquer que notre container a été nommé par docker et il est pas vraiment simple à apprendre par coeur … on va donc lui donner un nom plus parlant avec l’option « --name serveur-ksp »

$ docker  run -t -d --name serveur-ksp mon_serveur_ksp

Ensuite afin que le conteneur puisse parler avec le monde (Hello world), on va utiliser la fonction proxy de docker afin de lui attribuer un port d’écoute de la machine physique. On utilise donc pour cela l’option « -p [port reel]:[port conteneur] »

$ docker run -t -d --name serveur-ksp -p 42:6702 mon_serveur_ksp

Et on finit en externalisant les logs avec l’option « -v » qui permet de monter un répertoire local dans le conteneur

$ docker run -t -d --name serveur-ksp -p 42:6702 -v /var/log:/home/kerman/DMPServer/logs mon_serveur_ksp

Et voila votre serveur est opérationnel.

Et en extra je rajoute quelques commandes pour la route :

- Pour ouvrir un shell sur le docker :

$ docker exec -it [nom du conteneur] /bin/bash

- Pour supprimer un conteneur :

$ docker rm [nom du conteneur]

- Pour arrêter un conteneur :

$ docker stop [nom du conteneur]

- Pour redémarrer un conteneur :

$ docker start [nom du conteneur]

Detection d’intrusion avec OSSEC 2.9

Tout administrateurs ayant un serveur sur Internet et ayant déjà consulté ses logs (tu ne sais pas comment faire Oo … aller un indice -> /var/log/) sait qu’Internet … C’est la Jungle. Mais il existe des outils permettant de faire de la détection d’intrusion ou plus précisément (je l’espère) de la détection de tentative d’intrusion.

Pour réaliser cela j’appelle donc OSSEC à la barre (il est existe d’autre). OSSEC est un HIDS (Host Intrusion Detection System) avec option HIPS (Host Intrusion Prevention System), il va analyser le système, puis il alerter (dans son rôle passif) et/ou réaliser des actions (dans son rôle actif), mais on parle alors d’IPS (Intrusion Prevention System).

Ici je vais montrer comment le déployer en mode HIDS/HIPS (Host IDS/Host IPS). Autrement dit OSSEC aura pour charge de protéger la machine sur laquelle il est installé en surveillant les logs/fichiers sensible … La tout en activant des actions active sur les détection d’intrusion. OSSEC fonctionne en mode local ou agent/serveur afin de centralisé les alertes sur un serveur dédié. Dans notre cas le serveur sera installé en mode local ce qui ne permet pas de recevoir d’alerte depuis un autre serveur, ce qui correspond donc à un mode « standalone ».

Pour plus de détail, je vous ajoute le lien vers la dernière documentation :

http://ossec-docs.readthedocs.io/en/latest/

Aller c’est partie :)

On commence par télécharger les sources depuis le git

git clone https://github.com/ossec/ossec-hids.git

Entrer dans le dossier et lancer le install.sh

cd ossec-hids/
./install.sh

Dans les choix d’installation j’ai mis en place une installation « local », j’ai activé les alertes par mail, la détection de rootkit (HIDS), l’active response (HIPS), le firewall-drop (HIDS).

Par défaut OSSEC va donc s’installer dans /var/ossec/, créer un daemon /etc/init.d/ossec et ne se lancera pas après son installation. Mais Il se lancera à chaque démarrage. L’active réponse se déclenchera au niveau 6, pour plus d’info sur les niveaux d’alerte d’ossec je vous renvoi vers la doc http://ossec-docs.readthedocs.io/en/latest/manual/rules-decoders/rule-levels.html

Ok maintenant allons affiner la conf :)

Commençons par le fichier /var/ossec/etc/ossec.conf

La partie <global> permet d’envoyer les notification par mail. Vous pouvez donc la modifier au besoin. Elle permet aussi de whitlister des IP. Je vous conseille d’ajouter, au minimum, vos serveurs DNS, passerelle et l’IP ou les IP de votre serveur.

La partie <rules> liste les règles utilisés par OSSEC, les règles se trouvent dans le dossier /var/ossec/rules/ et il vaut mieux commenter toutes les règles correspondantes à des services non utilisé. Pour commenter une ligne utiliser les balises

<!– Ma ligne commenté –>

Si vous avez des doutes sur la désactivation d’une règle je vous conseil de jeter un oeil sur ce doc http://www.ossec.net/ossec-docs/OSSEC-book-ch4.pdf et n’oublier pas Google :)

La partie <syscheck> va vérifier de manière périodique les fichiers et binaires du système afin de détecter les modifications en se basant sur un checksum MD5/SHA1. Ici vous pouvez ignorer ou ajouter des répertoires/fichiers à surveiller. Par exemple il peut être intéressant de surveiller votre répertoire hébergeant les fichiers de votre serveur web en ajoutant quelque exclusions sur les répertoires stockant des données dynamique.

La partie <alerts> permet de modifier le niveau d’alerte générant un envoi de mail ou un log en local. Par défaut le log en local est à 1 et par mail est à 7, si votre serveur est sur Internet, je vous déconseille de trop descendre la dernière valeur sous peine d’être spammé par votre propre serveur :) Par contre ce niveau de déclenchement ne viendra pas s’appliquer à certaines règles sensible.

La partie <active-response> permet de modifier le niveau d’activation de l’active reponse. L’activation de l’active réponse ajoutera une règle de blocage dans le firewall suivant un temps donné. Par défaut le déclenchement ce fait au niveau 6 avec un ban pour 10 minutes.

La partie <localfile> liste tout les fichiers de logs sous surveillance avec le type de format de log.

Voila pour les principales options et donc si tous vous semble ok vous pouvez lancer le daemon avec la commande :

/etc/init.d/ossec start

Pour info les logs OSSEC sur toutes ses alertes sont disponibles dans le répertoire /var/ossec/logs/

Enjoy :)

Installer docker sur Debian Jessie (8.5)

Docker est un service permet de lancer un lot applicatif avec ses dépendances dans un environnement cloisonné et indépendant de l’OS. On parle alors d’application virtualisé … cool alors installons le :)

Avant de commencer lancer un (la base !)

apt-get update

Installer les 2 pré-requis suivant

apt-get install apt-transport-https ca-certificates

Installer ensuite la clé permettant d’utiliser le depôt

apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

Ajouter dans le fichier « /etc/apt/sources.list »

##Docker Depot
deb https://apt.dockerproject.org/repo debian-jessie main

Rafraichisser la base des paquets (encore)

apt-get update

Vous pouvez maintenant installer docker

apt-get install docker-engine

Enfin demarrer le deamon docker

service docker start

Vous pouvez lancer un test permettant de valider la bonne installation de docker

docker run hello-world

Cela va telécharger une image de test et l’ouvrir dans un conteneur. Le tout renverra un log sur votre console

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

Et voila \o/

Maintenant il ne vous reste plus qu’a lancer on créer vos conteneurs Docker :)

Mise en place de Let’s Encrypt pour Dovecot/Postfix

Démarrons en créant un certificat simple sans installation.

Pour cela lancer la commande suivante en suivant les instructions :

letsencrypt certonly -d votredomaine.fr --manual

Les certificats sont alors créé dans le répertoire suivant :

/etc/letsencrypt/live/votredomaine.fr

Afin d’automatiser le renouvellement des certificats ajouter une tâche cron dans le fichier /etc/crontab :

30 2 * * 1 root /bin/letsencrypt renew

Maintenant que nous avons nos certificats il faut modifier les configurations de nos logiciels afin de les prendre en compte.

  • Dovecot

ajouter ou modifier les informations suivantes dans le fichier /etc/dovecot/conf.d/10-ssl.conf :

ssl = yes
ssl_cert = </etc/letsencrypt/live/votredomaine.fr/fullchain.pem
ssl_key = </etc/letsencrypt/live/votredomaine.fr/privkey.pem

Vérifier aussi dans le fichier /etc/dovecot/conf.d/10-master.conf que le ssl est bien activé sur les services intéressés :

 service imap-login {
  inet_listener imap {
  }
  inet_listener imaps {
    ssl = yes
  }

Recharger la configuration du service :

service dovecot reload

Vous pouvez vérifier que le port (993) souhaité est bien en écoute avec la commande :

netstat -tpln
  • Postfix

ajouter ou modifier les informations suivantes dans le fichier /etc/postfix/main.cf :

smtpd_use_tls=yes
smtp_tls_CAfile = /etc/letsencrypt/live/votredomaine.fr/chain.pem
smtpd_tls_cert_file = /etc/letsencrypt/live/votredomaine.fr/cert.pem
smtpd_tls_key_file = /etc/letsencrypt/live/votredomaine.fr/privkey.pem

ajouter ou modifier les informations suivantes dans le fichier /etc/postfix/master.cf  :

smtps     inet  n       -       -       -       -       smtpd

Recharger la configuration du service :

service postfix reload

Vous pouvez vérifier que le port (465) souhaité est bien en écoute avec la commande :

netstat -tpln

Et voila votre service mail chiffre les informations entre le client et le serveur.

Un petit point d’attention sur le SMTPS, veiller à laisser le port SMTP ouvert et utilisable afin de ne pas empêcher la réception de mail de certain serveur.

Installer Let’s Encrypt

Let’s Encrypt s’utilise avec un client et il en existe plusieurs. Voici un lien qui liste les différents clients : https://letsencrypt.org/docs/client-options/

Ici je vais vous montrer comment installer le client certbot qui est le plus utilisé.

Pour l’installer il faut déjà récupérer les source sur le github avec un :

$ git clone https://github.com/certbot/certbot

Entrons ensuite dans le dossier certbot pour puis lançons l’installation assisté :

$ cd certbot
$ ./letsencrypt-auto --help

Les binaires seront dans le répertoire suivant :

~/.local/share/letsencrypt/bin/letsencrypt

Créons un lien symbolique pour simplifier l’exploitation (Vous pouvez utiliser le binaire certbot cela reviens au même) :

ln -s /root/.local/share/letsencrypt/bin/letsencrypt /bin

le commande suivante nous donne des informations sur son utilisation :

letsencrypt -h

 

Voici le résultat de la commande :

 certbot [SUBCOMMAND] [options] [-d domain] [-d domain] ...

Certbot can obtain and install HTTPS/TLS/SSL certificates. By default,
it will attempt to use a webserver both for obtaining and installing the
cert. Major SUBCOMMANDS are:

 (default) run Obtain & install a cert in your current webserver
 certonly Obtain cert, but do not install it (aka "auth")
 install Install a previously obtained cert in a server
 renew Renew previously obtained certs that are near expiry
 revoke Revoke a previously obtained certificate
 register Perform tasks related to registering with the CA
 rollback Rollback server configuration changes made during install
 config_changes Show changes made to server config during installation
 plugins Display information about installed plugins

Choice of server plugins for obtaining and installing cert:

 --apache Use the Apache plugin for authentication & installation
 --standalone Run a standalone webserver for authentication
 (nginx support is experimental, buggy, and not installed by default)
 --webroot Place files in a server's webroot folder for authentication

OR use different plugins to obtain (authenticate) the cert and then install it:

 --authenticator standalone --installer apache

More detailed help:

 -h, --help [topic] print this message, or detailed help on a topic;
 the available topics are:

 all, automation, paths, security, testing, or any of the subcommands or
 plugins (certonly, install, register, nginx, apache, standalone, webroot,
 etc.)

Failed to create session – timed out

Si lors de vos authentifications vous avez des temps de réaction long et le message d’erreur suivant dans votre log :

 Failed to create session: Activation of org.freedesktop.login1 timed out

Le bug semble avoir été patché mais peux encore apparaitre dans certain cas. Pour le solutionner temporairement lancer la commande suivante :

systemctl restart systemd-logind
Pour info vous pouvez suivre le report du bug fais chez debian :
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=770135

Ou directement sur le github qui va bien

https://github.com/systemd/systemd/issues/1961

SSL pour tous !

La mise en place d’un cryptage SSL demande une autorité de certification qui se portera garant du certificat utilisé. Pour avoir une autorité de certification il existe deux solutions, soit on paye (ou on trouve une autorité gratuite qui impose quelques limites) ou alors on s’installe un autorité de certification sur son serveur. Mais cette dernière technique nécessite d’installer le certificat d’autorité sur chaque poste client :/ ce qui peut correspondre si on connais notre parc de client, mais qui est impensable lorsqu’on doit gérer un parc anonyme comme sur Internet.

MAIS ce n’est pas tous car il faut savoir que lorsque vous avez réussi à avoir votre précieux certificat, serveur validé par l’autorité de certification, que vous avez bien transpiré et géléré, et bien vous vous retrouvé avec un certificat valide 1 an (mouai c’est pas étonnant, la sécurité tousa tousa). Ce qui est super en 1 an, c’est qu’on à le temps d’oublier comment on à fait et surtout on à le temps d’oublié qu’on l’a fait ! A la limite si vous en avez un seul à géré, une croix sur votre calendrier suffit mais si vous en avez 10 … 20 … là c’est galère …

Mais il existe maintenant une solution : Let’s Encrypt

Et alors comment ça marche … et bin y a une commande … tu la lance et … c’est tout Oo https://letsencrypt.org/howitworks/.

En plus c’est gratuit alors que demande le peuple …

Je vous invite donc à aller faire un tour sur leur site https://letsencrypt.org/

Leur binaire est optimisé pour apache mais on peux mettre du ssl partout (mail, ftp …) Je vous ferai donc d’autre post pour vous présenter l’implémentation du SSL sur votre serveur.

Le port de ton service SSH tu changera

Lorsque vous vivez sur le « méchant » Internet, laisser son port SSH sur le 22 est comme donner son numéro de téléphone sur un site ou des gens ne vous aime pas … En effet sur Internet certain serveur passe leur vie à scanner les autres serveurs. Comme pourrais le dire certain hacker, si tu n’as pas scanner au moins une fois Internet, tu as raté ta vie … Mouai !

Bref, si vous voulez pas voir certain méchant serveur tester la solidité de votre mot de passe ou les éventuelles faille de votre service SSH, le meilleur moyen est de changer son port d’écoute.

Oui mais je mets quoi ?

Et bien le mieux est d’en choisir un au dessus des 1000 premiers ports. En effet certain logiciel de scan de port, commence par cela par défaut. Tu as donc le choix entre 1001 et 65535. en évitant les truc évidant dans le genre 2222 :/

Aller place à l’action !

Editer le fichier de configuration de votre service SSH

/etc/ssh/sshd_config

Puis modifier la ligne contenant Port comme cela :

Port MON_NUMERO_DE_PORT

Recharger la conf du service

service ssh reload

Et voila !

Bloquer la connexion root en SSH

Certain se dirons « pourquoi est-il si méchant » …

Non mais !

Oui cette réponse n’est pas suffisante, en effet. Alors pourquoi bloquer root sur la connexion SSH. Et bien pour éviter les brutes forces, car dans la tête d’un attaquant, trouver le mot de passe root, c’est un peu comme le graal, alors le simple fait de lui en donner la possibilité est une faille !

Et pour ce qui ce demande comment devenir root sans pouvoir si connecter directement, je leur dirais d’aller voir sur côté de su et sudo.

Bref passons à l’action !

Editer le fichier de configuration de votre service SSH

/etc/ssh/sshd_config

Puis modifier la ligne contenant PermitRootLogin comme cela :

PermitRootLogin no

Recharger la conf du service

service ssh reload

Et voila !

TARPIT & Iptables

TARPIT est un outil qui possède plusieurs utilités (Honeypot, anti-DDOS, anti script-kiddie …). L’outil s’utilise avec iptables, il permet de remplacer DROP. La différence est simple, DROP jette le paquet et ferme la connexion distante, alors que TARPIT jette le paquet et met la connexion distante en attente, la laissant inutilisable jusqu’au timeout du client, ainsi une fois toutes les connexions utilisées, la machine attaquante ne peut plus avoir d’accès réseau. De plus la méthode TARPIT génère nue plus grosse consommation CPU côté attaquant.

Attention chérie, ça va couper !

Tout d’abord pour utiliser TARPIT il va falloir installer quelques paquets (testé sur Debian Jessie). Pour cela :

apt-get update
apt-get install iptables module-assistant xtables-addons-common
module-assistant auto-install xtables-addons-source

Ensuite il faut rajouter les lignes ci-dessous dans votre script iptables :

# Cette ligne fait croire, à la personne qui scanne le serveur que le port 25 est ouvert 
# et bloque son accès réseau, si il s'acharne.
iptables  -I INPUT -p tcp -s 0.0.0.0/0 --dport 25 -j TARPIT
# Cette ligne fait croire, à la personne qui scanne le serveur que les ports 1 à 24 sont ouvert 
# et bloque son accès réseau, si il s'acharne.
iptables -I INPUT -p tcp -s 0.0.0.0/0 --dport 1:24 -j TARPIT
# Cette ligne permet de bloquer les connexion avec des paquets contenant un mot clé 
# (exemple phpmyadmin, admin, w00tw00t ...)
iptables -I INPUT -p tcp -s 0.0.0.0/0 -m string --string "la_chaine" --algo bm -j TARPIT
# Cette ligne permet de bloquer les connexions trop rapide (DDOS, script ...)
# Ici, si une machine fait plus de 2 connexions par seconde, elle est bloquée
iptables -I INPUT -p tcp -s 0.0.0.0/0 -m state --state NEW -m limit --limit 2/second --limit-burst 1 -j TARPIT
# Cette ligne bloque une IP ou un sous-réseaux particulier
iptables -I INPUT -p tcp -s 192.168.0.0/24 -j TARPIT