Premières étapes de sécurisation du serveur

Préambule

Voilà la liste des étapes que je fais habituellement à la main et qu'il est toujours possible de faire à la main. J'ai décidé dans ce tutoriel d'utiliser ansible pour pouvoir automatiser ensuite la création de serveurs, plus rapide en cas de crash de disque dur ou compromission. (et aussi pour apprendre de nouvelles techniques ...)

Préparation du poste de travail

Sur notre poste de travail, nous allons préparer la configuration de SSH et de Ansible.

SSH

Il y a 2 parties à configurer:

Nous allons utiliser les recommandations de Mozilla: Mozilla recommendations

Ansible

Nous allons créer un répertoire dans notre home qui contiendra nos ""playbook"". J'ai vu qu'il existait un programme appelé ansible-galaxy qui permet de gérer la structure de ce répertoire et de charger des roles tout prêts à partir du hub.

Dans un premier temps, nous allons utiliser notre répertoire naïvement. Il sera toujours temps de passer à ansible-galaxy ensuite.

Méthode manuelle

Nous allons commencer par exécuter toutes les étapes manuellement; il sera plus facile ensuite de les automatiser.

Pour mon usage personnel, j'installe systématiquement mc, un programme de gestion de fichiers en mode texte qui permet de se déplacer facilement dans les répertoires, d'éditer, de déplacer les fichiers etc.

Notez l'utilisation de sudo: les taches d'administration seront faite sous l'utilisateur ericadmin avec l'aide de sudo pour l'élévation des privilèges.

sudo apt install mc

J'installe aussi vim, pour remplacer l'éditeur vi ou nano installé par défaut par Debian.

sudo apt install vim

Installation des utilitaires système comme netstat etc.

sudo apt install net-tools

Ajoute des dépots contrib et non-free:

sudo vim /etc/apt/sources.list

Pour obtenir ceci:

deb http://deb.debian.org/debian/ buster main contrib non-free
deb-src http://deb.debian.org/debian/ buster main contrib non-free

deb http://security.debian.org/debian-security buster/updates main contrib non-free
deb-src http://security.debian.org/debian-security buster/updates main contrib non-free

# buster-updates, previously known as 'volatile'
deb http://deb.debian.org/debian/ buster-updates main contrib non-free
deb-src http://deb.debian.org/debian/ buster-updates main contrib non-free

# buster-backports
deb http://deb.debian.org/debian buster-backports main contrib non-free
deb http://deb.debian.org/debian/ buster-proposed-updates contrib non-free main
deb-src http://deb.debian.org/debian buster-backports main

Mise à jour des dépôts de paquets, et mise à jour du système:

sudo apt update && sudo apt upgrade

Méthode avec ansible

Nous allons donc réaliser exactement la même chose, mais avec ansible:

Récupération de l'IP du serveur:

Il nous faut connaître l'adresse IP de notre serveur qui est allouée dynamiquement par dhcp.

Sur le poste client à partir duquel nous nous connectons par ssh sur le serveur, nous allons lancer une commande qui va scruter notre réseau local et faire apparaître les IPs des machines du réseau. Bien sûr, cela ne fonctionne que si le serveur est "at home". Ne lancez pas un scan de tout l'internet! :D

root@aldebaran:~# nmap -sP 192.168.111.0/24 | grep "Nmap scan"
Nmap scan report for 192.168.111.20
Nmap scan report for 192.168.111.48
Nmap scan report for switch.yojik.net (192.168.111.140)
Nmap scan report for goulya.yojik.net (192.168.111.151)
Nmap scan report for 192.168.111.153
Nmap scan report for atom.yojik.net (192.168.111.160)
Nmap scan report for freebox.yojik.net (192.168.111.254)
Nmap scan report for aldebaran.yojik.net (192.168.111.150)
root@aldebaran:~#

Vous voyez là toutes les machines allumées sur mon réseau local. Celle qui nous intéresse est la suivante:

**192.168.111.48**

Si c'est une machine distante (pas sur votre réseau local), la procédure est différente:

    ericadmin@aijan:~$ sudo ip a
    [sudo] Mot de passe de ericadmin : 
    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
        inet6 ::1/128 scope host
           valid_lft forever preferred_lft forever
    2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
        link/ether 38:ea:a7:a6:cf:93 brd ff:ff:ff:ff:ff:ff
        inet 192.168.111.48/24 brd 192.168.111.255 scope global dynamic enp2s0
           valid_lft 28610sec preferred_lft 28610sec
        inet6 2a01:e0a:d0:3c20:3aea:a7ff:fea6:cf93/64 scope global dynamic mngtmpaddr
           valid_lft 86372sec preferred_lft 86372sec
        inet6 fe80::3aea:a7ff:fea6:cf93/64 scope link
           valid_lft forever preferred_lft forever
    ericadmin@aijan:~$

Vous retrouvez les mêmes valeurs pour l'adresse IPV4: 192.168.111.48

Voilà, nous avons toutes les données nécessaires pour lancer ansible

Sécurisation de ssh

Voir le lien suivant: Le blog de Guillaume. Nous ajouterons une deuxième étape de sécurisation avec "OTP", "one time password". Il y aura donc l'authentification par clef de SSH, avec sa phrase de passe, plus un mot de passe à usage unique généré par l'application OTP installée sur un autre poste, smartphone ou tablette.

Nous allons aussi appliquer les recommandations de Mozilla concernant les algorithmes à utiliser. Voir ici: Mozilla SSH recommandations

Opérations à effectuer sur le poste principal

Nous générons notre paire de clefs pour l'authentification par clefs sur votre poste principal (si vous n'avez pas encore de jeu de clefs). Opération à effectuer sur votre poste principal. Comme nous gérons nous-mêmes nos postes et serveurs, nous allons utiliser des algorithmes modernes pour générer les clefs SSH: article sur Tutox.

Au lieu d'utiliser la même clef SSH sur tous nos serveurs, nous allons générer une clef distincte pour chaque serveur et rajouter la configuration spécifique à chaque serveur (adresse, port de connexion,n utilisateur etc ...dans le fichier de configuration du client SSH. J'envisage aussi l'utilisation de certificats SSH qui évitent de copier ses clefs publiques SSH sur tous les serveurs.

Nous allons implémenter tout ça de manière incrémentale, pour savoir ce que nous faisons, et pouvoir rectifier si quelque chose foire :( .

Voilà donc la structure de notre gestion des clefs SSH:

ssh-keygen

Il vous faut copier maintenant la clef sur le serveur:

ssh-copy-id -i ~/.ssh/id_rsa.pub ericadmin@192.168.111.23

ou

ssh-copy-id ericadmin@192.168.111.23

N'oubliez pas de mettre vos identifiants propres, bien sûr.

On teste comme le recommande ssh:

eric@aldebaran:~$ ssh 'ericadmin@91.121.72.10'
Linux adara 4.9.103-xxxx-std-ipv6-64 #222672 SMP Mon Jun 4 15:16:03 UTC 2018 x86_64

  Debian GNU/Linux 9 (stretch)
  Linux adara.yojik.eu 4.9.103-xxxx-std-ipv6-64 #222672 SMP Mon Jun 4 15:16:03 UTC 2018 x86_64 GNU/Linux

  Server    : 141519
  IPv4      : 91.121.72.10
  IPv6      : 2001:41d0:1:7d0a::1
  Hostname  : adara.yojik.eu

Last login: Sun Jun 24 15:08:32 2018 from 82.64.48.5

Et on teste qu'on peut passer super-utilisateur à partir de ce compte.

ericadmin@adara:~$ su
Mot de passe :
root@adara:/home/ericadmin#

Opérations à effectuer sur le serveur en mode super-utilisateur.

La configuration se fait dans le fichier /etc/ssh/sshd_config, fichier qu'il va falloir éditer avec vim pas exemple.

Nous allons d'abord en faire une copie de sauvegarde:

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig

vim /etc/ssh/sshd_config

Nous n'allons autoriser que la connexion d'un user d'administration (pas de connexion de root par exemple), activer l'authentification par clefs, et supprimer l'authentification par login/mot de passe (en mode ssh). Vous pourrez toujours vous connecter avec le couple login/mot de passe si vous avez un accès physique à votre serveur.

Nous garderons le port standard d'écoute (rien à changer dans le fichier), mais j'ai ajouté une note sur le changement de port (suggéré par Laurent). Je ne suis pas convaincu que le changement de port puisse diminuer la surface d'attaque du serveur, mais pourquoi pas, c'est un changement mineur:

Port 22

Nous interdisons la connexion par root:

PermitRootLogin no

Activation de l'authentification par clef (rien à changer dans le fichier):

PubkeyAuthentication yes

Nous ajoutons une liste d'utilisateurs autorisés à se connecter.

AllowUsers ericadmin

A la place de ericadmin mettez bien sûr le nom de l'utilisateur que vous avez entré pendant la phase d'installation.

Nous pouvons limiter le nombre de tentatives de connexion:

MaxAuthTries 1

Interdiction de la connexion par couple login/mot de passe:

PasswordAuthentication no

Désactivation de PAM

UsePAM no

Sauvegarde du fichier de configuration. (commande escape, suivie de ZZ pour vim)

Redémarrage du service ssh

systemctl restart sshd

Test de connexion

Sur votre ordinateur principal, dans un terminal, tapez:

ssh ericadmin@192.168.111.23

Vous devez être connectés (logués) sur le serveur.

Essayez avec l'utilisateur root:

ssh root@192.168.111.23

Cela doit échouer.

eric@aldebaran:~$ ssh 'ericadmin@192.168.111.23'
Last login: Sun Dec 17 16:37:40 2017 from 192.168.111.150
ericadmin@atom:~$

Voilà pour la première phase.

Note: Il est possible de changer le port d'écoute de SSH en changeant celui-ci dans le fichier de configuration **/etc/ssh/sshd_config:

Faites la modification suivante:

vim /etc/ssh/sshd_config

Port 2222

Et relancez sshd:

service sshd restart

Pour se connecter, utilsez la commande suivante:

ssh -p 2222 ericadmin@192.168.111.23

Sécurisation plus poussé de SSH

Les récentes attaques sur les méthodes de chiffrage imposent l'utilisation de clef de chiffrement plus évoluées. Les anciennes ont des failles.

Le site de Mozilla nous permet d'ajuster nos configurations et d'utiliser les meilleures méthodes de chiffrement actuelles.

Deuxième phase

Sécurisation des mots de passe

J'utilise un générateur de mots de passe pour le compte root et le compte ericadmin. Il y a pléthore de générateurs de mots de passe, certains à base d'utilitaires tout prêts, d'autres créés à l'aide commande unix standards.

Les 3 générateurs tout prêts les plus cités dans la documentation sont:

Pour l'installation, utilisez les commandes suivantes:

Exemples d'utilisation de ces programmes:

Utilisation de pwgen:

Pour obtenir de l'aide à l'utilisation de cet utilitaire, tapez: pwgen --help. Vous pouvez faire varier le niveau de sécurité ainsi que le nombre de mots de passe générés et la longueur des mots de passe.

eric@aldebaran:~$ pwgen
oow1Osho teM3chai Aim5shee Sheme1yo aiR6aem1 Vooxeiv0 Iabeenu1 kae7Xie5
oacei4aV Ohb8ceib zo0shu6F Dob2chie Roo5eeLa fee5Nooh Phi0suim OMeigh2w
nah2Ool5 Saix6lie EeNaem5u ooVoh3ki IN5aeF9p CuHu8Aib vaim2Jia chah0Ier
ShieC6ze Teex4tie mei6ou7I Ath6aiFe uw4quoHa lad8Quee ohQuai9Y Sho5Eem6
aoCaol3W ooGah9th bix6Aic9 thee1Coo lie0ahTe eiz0iiSh cieYu8Ie Ealu3chi
vaeYee6c ahje9aeJ Sheenee7 eesh1Iez Odaa6kah aico6Jah aphahP4U aYePh1ev
phohNie8 Chuut3ie eeb9ieDa ohp9AhGi efae5ooV Shiere5c ahV8riek Seegohv1
Eetohy1a Lievoh0k jox3uf6K chai3Woo iecoh0Iu ieGh9tuz UMeex2ah Eathaur8
Ood2oeho paeSah0p jaihoo1U eemoi9Ee ile1So4z OongeiN6 aaY9iuch ew3Iemoo
Iech0Eey OoMie0ah OhBei1ae Ohsh4aik jah0faiT ioW7oz6t yee1Uphu ies4eeNa
pooP8eeg iePoh4ya fooL3uqu ieGiej1X Ein7eifu ool7Olae eub5ooSe eyo8EiNu
ach9ohWo Foog9Oev aej9geiH Thahg6Di eegei4Ai eN7quu3b waiK2ieg foThe7zi
fu2Phoug iYaeg4if iLu6eeFi Aeshoo0i uxoGh6no id1TeRei diob7Pha vokuuN7h
Chokei8J Iemee8ah eingei0E ubieh2Ch daiyu3EB QueiQu6H Jib0uwee wi9Xoodu
eeL3osh2 Eo3Ae1ch bieWui2a ro6chiCo engu0ooF Eebeu2jo ee7Eey8t EiSeen5i
ohNgai6i Iutaez4a xah1yeeG eGhi5Ouz vaiYu6ee fae0AeP5 jee0Ib2I OS3xuwae
Eefohp1u eegiK6ae ohyuom7V Eij8eeNi Ou0ec7ye Eethoh4e eeHi2ugh ichoLae3
UT8oopoo oox6Ohx9 ohbaL2hu oht9kaiR Ieho8Ou1 Ten6saet cae7Iexi daDuas9e
ShiexaT7 Lei6etii ea4aoH8y ja8Zai8g phaeG6Hi sheNg8ee Oow5phae aa7gohPi
nahS8Eeg ba6Roh9j ooRo6epo pheNoam1 johF7ii9 vuZ4Latu xai5og6H aeS8hu2I
eric@aldebaran:~$

Vous pouvez prendre le mot de passe que vous voulez dans le tableau généré. Pour un seul mot de passe:

eric@aldebaran:~$ pwgen -1
Eerai4Sh

Pour un mot de passe mieux sécurisé:

eric@aldebaran:~$ pwgen -1 -s
tx2CqGyf

Encore plus sécurisé avec l'option -y:

eric@aldebaran:~$ pwgen -1 -s -y
a+01K!U~

Utilisation de makepasswd:

Tapez: makepasswd --help pour de l'aide à l'utilisation des paramètres.

makepasswd --count 5 --minchars 10

Sécurisation du mot de passe super-utilisateur (root)

Utilisez un des utilitaires ci-dessus. Attention à la longueur minimale!

Sous le user “admin”, tapez: passwd pour changer le mot de passe admin.

Sécurisation du mot de passe administrateur

Utilisez un des utilitaires ci-dessus. Attention à la longueur minimale! Sous le user “root”, tapez: passwd pour changer le mot de passe root.

Test du hostname

La commande hostname nous indiquera le nom “court” de notre machine, et la commande hostname -f sa version longue avec le nom de domaine.

root@atom:/home/ericadmin# hostname
atom
root@atom:/home/ericadmin#

root@atom:/home/ericadmin# hostname -f
atom.yojik.net
root@atom:/home/ericadmin#

Le résultat est bon.