Supprimer une clé SSH de ses hôtes connus

J’ai profité de mes récentes migrations de serveur pour re-générer des clés SSH toutes neuves. Je ne pense pas avoir été piraté ni visité depuis que je tiens ce blog mais de temps en temps, une petite remise à frais de la sécurité ne fait pas de mal.

Remise à frais de la sécurité implique que tous mes shells, qui avaient enregistrés l’ancienne clé SSH, détectaient une modification et pensaient à un piratage. Il fallait donc enlever l’ancienne clé de la base des hôtes connus.

On peut faire ça manuellement en modifiant le fichier ~/.ssh/known_hosts mais il faut être sûr de soi quant-à la ligne que l’on enlève. Pas toujours évident.

La manière la plus simple est la commande :

ssh-keygen -f "/home/<USERNAME>/.ssh/known_hosts" -R <NOM_DU_DOMAINE_OU_ADRESSE_MACHINE>

qui se charge d’enlever la clé SSH correspondante à la machine que l’on vise sans risquer d’enlever la mauvaise clé. Il ne reste plus qu’à se connecter de nouveau et les nouvelles informations de connexion seront ajoutées à la liste des hôtes connus.

Désactiver la commande sudo

Pour l’administration de mes serveurs, afin d’éviter tout risque de piratage, il est nécessaire d’avoir 2 mots de passe pour effectuer des commandes root.

Imaginons que notre compte utilisateur a accès à la fonction sudo, comme c’est le cas du première utilisateur créé dans la plupart des distributions GNU/Linux, et que le mot de passe de connexion en SSH est le mot de passe de ce compte. Si quelqu’un arrive à prendre connaissance du mot de passe lors de la connexion (keylogger, regard indiscret, …), il pourra ensuite se reconnecter et avoir un contrôle total du serveur distant.

Afin d’éviter cela, nous allons désactiver la fonction sudo pour l’utilisateur en question. Ainsi, pour effectuer des commandes administrateurs, il faudra se connecter préalablement en tant que super utilisateur.

On changera aussi le mot de passe du super utilisateur pour qu’il soit différent de celui du compte de l’utilisateur, sinon ceci n’a aucun intérêt.

Pour changer le mot de passe de root, rien de plus simple :

  • Si il a déjà été fixé, il suffit de faire
su
passwd

et de taper son nouveau mot de passe.

  • Si il n’a jamais été fixé, il faut se connecter avec un utilisateur possédant le droit d’utilisation de la fonction sudo et faire :
sudo su
passwd

et de taper le nouveau mot de passe.

Maintenant que nous sommes sûr d’avoir un utilisateur root avec un mot de passe que l’on connait, on va désactiver la fonction sudo. Pour ceci plusieurs possibilités :

  • Désinstaller purement et simplement la fonction sudo avec :
apt-get purge sudo
  • Modifier le fichier /etc/sudoers et commenter/supprimer les lignes correspondantes aux utilisateurs. Vous pouvez choisir de laisser ou d’enlever root du fichier. L’intérêt de le laisser est de na pas avoir une erreur lorsque, machinalement, on tape sudo alors qu’on est connecté en root. L’enlever vous forcera à bien séparer les commandes administrateurs des commandes utilisateur dans votre tête. Une autre solution pour se forcer est de retirer la commande sudo du path de l’utilisateur root. Ne connaissant plus la commande sudo, il indiquera systématiquement une erreur.

Il ne reste plus qu’à valider les changements soit en redémarrant la machine, soit à l’aide de la commande :

/etc/init.d/sudo restart

Comment personnaliser sa bannière de connexion SSH

Lorsque l’on se connecte à son serveur en SSH, on a souvent un texte de base contenant des informations sur le serveur. Nous allons ici personnaliser le texte affiché.

La première étape consiste à activer la bannière dans le fichier de configuration d’openSSH. Pour ce faire, on va dans /etc/ssh/ et on modifie le fichier sshd_config. On décommentera la ligne :

#Banner /etc/issue.net

ou on la créera si elle n’y est pas. L’URI indique le fichier qui contiendra notre message d’accueil. On peut modifier son emplacement si on le veut ou simplement utiliser celui qui existe déjà. Après modification du fichier de bannière, un redémarrage à l’aide de la commande

/etc/init.d/ssh restart

suffit à faire prendre en compte les modifications. La bannière est maintenant affichée dès qu’une demande de connexion est effectuée.

Installation d’un serveur web sous Debian

J’avais lors d’un précédent post, expliqué comment installer WordPress sur son serveur Web mais je n’avais pas expliqué comment installer ce serveur.

On partira donc du principe que l’on a besoin de mettre en place un serveur HTTP, un interpréteur PHP, un SGBD (Système de Gestion de Base de Données) et un serveur FTP. De plus pour le contrôler facilement à distance on utilisera le protocole SSH.

Tout d’abord le choix de la distribution. Ayant toujours utilisé des distributions basées sur Debian et Debian étant réputé pour sa stabilité, il m’a semblé évident de prendre cette distribution comme base. De plus les installations sont facilitées grâce à des dépôts bien remplis (pas toujours à jour, mais fournis).

Ainsi, après une installation standard de cette distribution, enfin, en tout cas sans gestionnaire de fenêtre vu que c’est pour un serveur, nous allons passer à la phase d’installation.

Les logiciels que j’ai choisis d’utiliser pour combler tous nos besoins sont :

  • Serveur HTTP : Apache
  • Serveur FTP : vsFTPd
  • Serveur SSH : openSSH
  • interpréteur PHP : PHP5
  • SGBD : MySQL

Nous allons commencer par installer openSSH afin de pouvoir administrer le serveur à distance par la suite à l’aide de la commande :

apt-get install ssh

Nous verrons les configurations à apporter à chaque logiciel par la suite. Installons maintenant le serveur Apache à l’aide de la commande :

apt-get install apache2

Puis PHP et son module pour apache en tapant :

apt-get install php5 libapache2-mod-php5

Pour MySQL, Debian se charge normalement tout seul de récupérer les paquets qui permettent les interactions avec PHP. Dans le cas contraire il faudra les rajouter en plus (paquet php5-mysql). On tapera donc :

apt-get install mysql-server

Un mot de passe root est demandé à ce moment là. Bien penser à en mettre un fort.

Nous allons enfin installer vsFTPd en tapant :

apt-get install vsftpd

Maintenant que tous les logiciels dont nous avons besoin sont installés, il va nous falloir les configurer. Toujours garder en tête cependant que les configurations sont la partie la plus personnelle de ce genre de mise en place car elles dépendent principalement de ce que l’on désire faire. Je ne détaillerais pas les configurations d’SSH car j’ai déjà mis un exemple détaillé dans ce post ci.

Commençons donc avec la configuration d’Apache. Un fichier de configuration extrêmement important est le fichier /etc/apache2/conf.d/security. C’est ce fichier qui déterminera le niveau de détail des messages d’erreur. Pour un serveur en production, afin d’éviter toute fuite d’information sensible en cas de faille, on mettra les lignes :

ServerTokens Prod
ServerSignature Off
TraceEnable Off

Pour un serveur de développement, le but étant d’obtenir un maximum d’informations, on mettra :

ServerTokens Full
ServerSignature On
TraceEnable Extended

La configuration de base d’Apache donne le dossier /var/www/ comme dossier du site principal. On peut héberger plusieurs sites sur un seul serveur en rajoutant des fichiers de configuration dans le dossier /etc/apache2/sites-available/ (De manière globale, tout fichier présent dans ce dossier est inclus dans le fichier de configuration au lancement d’Apache). Une configuration minimale de site possible est :

<VirtualHost <ADRESSE_DU_SERVEUR>:<PORT_DE_CONNEXION>>
ServerName <NOM_DU_SERVEUR>
ServerAdmin <ADRESSE_DU_WEBMASTER>

DocumentRoot <DOSSIER_DU_SITE>
<Directory <DOSSIER_DU_SITE>>
Options -Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>

CustomLog <URI_DU_FICHIER_DE_LOG> combined
LogLevel warn
</VirtualHost>

Pour plus de détail on peut aller sur la documentation officielle d’Apache sans oublier les conseils sur la sécurité. On pourra, selon la distinction que l’on voudra faire entre les différents sites web (différentes adresses IP, différents ports de connexion), utiliser cette page de documentation ou celle ci pour choisir ses options.
Vous remarquerez le -Indexes qui permet de ne pas lister le contenu d’un dossier lorsque le fichier index.html ou index.php n’existe pas. Pour d’autres options de sécurités on peut aller voir par là.

Il ne reste alors plus qu’à activer le site nouvellement configuré à l’aide de la commande

a2ensite <NOM_DU_FICHIER_DE_CONFIGURATION>

et à redémarrer apache (nous ferons ceci à la fin).

En ce qui concerne PHP, je ne rentrerais pas dans les détails de la configuration car ils sont beaucoup trop dépendants de ce que l’on souhaite mettre en place. De plus, ceux de base conviendront la plupart du temps.

La configuration de MySQL étant plus une configuration par base de données que dans sa globalité, les paramètres originaux feront largement l’affaire. Cependant, il ne faudra pas oublier de créer un nouvel utilisateur pour chaque base afin d’améliorer la sécurité et de ne pas laisser traîner le mot de passe root quelque part. J’avais détaillé le script de création dans mon post sur la mise en place de mon blog.

Il nous reste enfin à configurer vsFTPd. Mon choix s’est porté sur ce logiciel plutôt que sur ProFTP, qui est le plus souvent cité lorsque l’on cherche un serveur FTP, car, notamment, il a été conçu en étant orienté sécurité. Le fichier de configuration est /etc/vsftpd.conf. Il est bien détaillé et facile à paramétrer. On peut choisir de chrooter les utilisateurs, utiliser le serveur en IPv4/IPv6, autoriser l’accès anonyme, etc … J’ai détaillé une des configuration que j’utilise sur l’un de mes serveurs dans ce post.

Il suffit ensuite soit de redémarrer la machine (le plus simple), soit de redémarrer tous les services, après configuration. On peut les relancer un par un à l’aide des commandes :

/etc/init.d/apache restart
/etc/init.d/ssh restart
/etc/init.d/vsftpd restart

On a alors un serveur HTTP/FTP/MySQL/SSH prêt à être utilisé.

Configuration de mes connexions SSH

J’administre tous mes serveurs (tous sous Linux) en ligne de commande. L’interface graphique consomme en effet beaucoup de ressources inutilement et n’est pas nécessaire pour seulement quelques accès par mois. De plus, la ligne de commande est plus puissante.

Pour me connecter simplement et en toute sécurité j’utilise le protocole SSH qui est parfaitement adapté à la situation. Voici les quelques configurations que j’applique systématiquement.

Je commence tout d’abord par me générer une paire de clés qui me serviront à me connecter par la suite. Cette étape peut n’être faite qu’une fois, puisqu’il suffira d’utiliser la même clé pour tous ses serveurs après. La commande est :

ssh-keygen -t rsa -b 2048

Ceci générera une paire de clés RSA de 2048 bits. Il suffit de suivre les instructions lors de la génération des clés pour mettre un mot de passe à ces clés. Je copie ensuite la clé publique générée dans <HOME>/.ssh/authorized_keys sur le serveur.

Je modifie ensuite le fichier /etc/ssh/sshd_config de la manière suivante pour appliquer mes réglages de sécurité (ATTENTION : sans accès physique à la machine, laisser le paramètre PasswordAuthentication à yes jusqu’à ce que la connexion soit réussie avec la clé, autrement il sera très contraignant d’arriver à se reconnecter) :

# Numéro du port en écoute sur lequel on se connecte
Port <NUMERO DE PORT>

# Vérifier que la version est bien la 2 car la version 1 avait une faille critique
Protocol 2

# Bannière affichée avant l’autorisation de connexion (Je le met rarement mais ça égaye un peu la console à la connexion)
#Banner /etc/issue.net

# Empêche la connexion directe en root
# N’empêche pas de se connecter en root depuis un autre utilisateur
PermitRootLogin no

# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key

# Temps en seconde pendant laquelle une connexion est ouverte sans être loggué
LoginGraceTime 10

# Nombre maximum d’essais d’authentification autorisés
MaxAuthTries 1

#Types d’authentifications autorisés
PubkeyAuthentication yes
RSAAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
UsePAM no
PasswordAuthentication no

# Fichier contenant les clés autorisées
AuthorizedKeysFile %h/.ssh/authorized_keys

#Privilege Separation is turned on for security
UsePrivilegeSeparation yes

# Logging
SyslogFacility AUTH
LogLevel INFO

# check file modes and ownership of the user’s files and home directory before accepting login
StrictModes yes

# Don’t read the user’s ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don’t trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes

# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes

X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no
#MaxStartups 10:30:60

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

# Set this to ‘yes’ to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of « PermitRootLogin without-password ».
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to ‘no’.

# La plupart du temps je n’autorise que mon compte à se connecter
AllowUsers <NOM_DES_UTILISATEURS_AUTORISES>

# Si il faut mettre plusieurs comptes, mieux vaut utiliser ceci
#AllowGroups <NOM_DU_GROUPE_AUQUEL_APPARTIENNENT_TOUS_LES_COMPTES_AUTORISES>

# On peut aussi choisir de refuser juste certains utilisateurs/groupes
#DenyUsers <NOM_DES_UTILISATEURS_REFUSES>
# DenyGroups <NOM_DU_GROUPE_AUQUEL_APPARTIENNENT_TOUS_LES_COMPTES_REFUSES>

Une fois ce fichier modifié, je relance ssh à l’aide de :

/etc/init.d/ssh restart

et me voilà avec un serveur disposant d’une connexion SSH correctement sécurisée.