Voici quelques bonnes pratiques pour sécuriser son serveur Linux. Pour ma part, je les utilise pour sécuriser mon serveur VPS hébergé chez OVH. Attention, il est important de mettre à jour ces connaissances régulières et cette article montre simplement les bases pour sécuriser un serveur (il existe d'autres pratiques qui ne sont pas listées dans cet article).

1 - Modifier le mot de passe root

Lorsqu'on commande un serveur ou qu'on installe son propre serveur, il est primordial de choisir un mot de passe complexe. Je vous conseille de relire l'article sur les conseils pour un bon mot de passe. Voici la commande pour changer le mot de passe :

passwd root

2 - Création d'un utilisateur

Il est important de n'utiliser les privilèges root qu'en cas de besoin et surtout ne pas se connecter avec l'utilisateur root. On va donc commencer par créer un utilisateur :

adduser nom_utilisateur

Pour me connecter en ssh avec cet utilisateur, je n'utilise pas de mot de passe mais le chiffrement RSA : Voici un tuto.

3 - Interdire la connexion ssh avec ROOT

Il faut éditer le fichier /etc/ssh/sshd_config et modifier la ligne PermitRootLogin

Attention ! Avant de redémarrer le service SSH, il est important qu'on puisse se connecter avec l'utilisateur précédemment créé. Il est donc impératif de tester la nouvelle configuration avant de quitter la session en cours. Une mauvaise configuration occasionne la perte de l'accès à votre serveur.

...
# Interdire à root de se connecter en SSH
PermitRootLogin no
...

On redémarre le service SSH :

service ssh restart

4 - Modifier le port SSH

De nombreuses attaques sont automatisées via des robots et le port d'attaque est souvent le port par défaut SSH : le port 22. Pour palier simplement à ce problème, il est possible de le changer facilement. Pour cela, il suffit d'éditer le fichier /etc/ssh/sshd_config :

...
# Facultatif : Modifier le port de connexion pour le SSH
Port 4854
...

On redémarre le service SSH :

service ssh restart

5 - Paramétrer le firewall

En règle général, le firewall n'est pas configuré lorsque vous installez un nouveau serveur, il va laisser passer tout le trafic. Il va donc être nécessaire de lister les ports que vous allez utiliser et fermer tous les autres. Pour cela, on va utiliser le paquet iptables pour définir l'ensemble de ses règles.

IPtables (associé à Netfilter) est un des meilleurs firewalls pour Linux, et certainement le plus répandu. Vous pourrez trouver de nombreux scripts de configuration à son sujet. En voici un, à adapter à votre configuration. A tout instant, utilisez la commande iptables -L -v pour lister les règles en place.

Celles-ci portent sur 3 chaînes : INPUT (en entrée), FORWARD (dans le cas d'un routage réseau) et OUPUT (en sortie). Les actions à entreprendre sont ACCEPT (accepter le paquet), DROP (le jeter), QUEUE et RETURN.

Arguments utilisés :

  • i : interface d'entrée (input)
  • i : interface de sortie (output)
  • t : table (par défaut filter contenant les chaînes INPUT, FORWARD, OUTPUT)
  • j : règle à appliquer (Jump)
  • A : ajoute la règle à la fin de la chaîne (Append)
  • I : insère la règle au début de la chaîne (Insert)
  • R : remplace une règle dans la chaîne (Replace)
  • D : efface une règle (Delete)
  • F : efface toutes les règles (Flush)
  • X : efface la chaîne
  • P : règle par défaut (Policy)
  • lo : localhost (ou 127.0.0.1, machine locale)

Nous allons créer un script qui sera lancé à chaque démarrage pour mettre en place des règles de base.

Dans la config suivante, n'oubliez pas de modifier le port 22 (port SSH) si vous avez décidé de le déplacer.

vi /etc/init.d/firewall

#!/bin/sh

# Vider les tables actuelles
iptables -t filter -F

# Vider les règles personnelles
iptables -t filter -X

# Interdire toute connexion entrante et sortante
iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT DROP

# ---

# Ne pas casser les connexions etablies
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# Autoriser loopback
iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A OUTPUT -o lo -j ACCEPT

# ICMP (Ping)
iptables -t filter -A INPUT -p icmp -j ACCEPT
iptables -t filter -A OUTPUT -p icmp -j ACCEPT

# ---

# SSH In
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT

# SSH Out
iptables -t filter -A OUTPUT -p tcp --dport 22 -j ACCEPT

# DNS In/Out
iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT

# NTP Out
iptables -t filter -A OUTPUT -p udp --dport 123 -j ACCEPT
Si vous hébergez un serveur web (Apache) :
# HTTP + HTTPS Out
iptables -t filter -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 443 -j ACCEPT

# HTTP + HTTPS In
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 8443 -j ACCEPT
Si vous hébergez un serveur FTP :
# FTP Out
iptables -t filter -A OUTPUT -p tcp --dport 20:21 -j ACCEPT

# FTP In
modprobe ip_conntrack_ftp # ligne facultative avec les serveurs OVH
iptables -t filter -A INPUT -p tcp --dport 20:21 -j ACCEPT
iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Si vous hébergez un serveur de mail avec SMTP, POP3 et IMAP :
# Mail SMTP:25
iptables -t filter -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 25 -j ACCEPT

# Mail POP3:110
iptables -t filter -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 110 -j ACCEPT

# Mail IMAP:143
iptables -t filter -A INPUT -p tcp --dport 143 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 143 -j ACCEPT

# Mail POP3S:995
iptables -t filter -A INPUT -p tcp --dport 995 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 995 -j ACCEPT

Si vous hébergez un serveur Mysql :

# Mysql
Iptables -t filter -A INPUT -m state --state NEW -p tcp --dport 3306 --syn -j ACCEPT
Si vous utilisez l'outil de monitoring Monit sur le port 1337 (à modifier selon votre configuration) autorisez cette connexion :
# Monit
iptables -t filter -A INPUT -p tcp --dport 1337 -j ACCEPT
Si vous utilisez le moteur de recherche Solr sur le port 8983 (à modifier selon votre configuration) autorisez cette connexion :
# Apache Solr
iptables -t filter -A OUTPUT -p tcp --dport 8983 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 8983 -j ACCEPT
Si vous utilisez gitlab sur le port 10080 (à modifier selon votre configuration) autorisez cette connexion :
# Gitlab
iptables -t filter -A OUTPUT -p tcp --dport 10080 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 10080 -j ACCEPT
Si vous utilisez ntp sur le port 123 (à modifier selon votre configuration) autorisez cette connexion :
# Network Time Protocol
iptables -t filter -A OUTPUT -p udp --sport 123 -j ACCEPT
iptables -t filter -A INPUT -p udp --dport 123 -j ACCEPT

Si vous utilisez le LDAP autorisez cette connexion :
# LDAP
#iptables -t filter -A INPUT -m state --state NEW -p tcp --dport 389 -j ACCEPT
#iptables -t filter -A INPUT -m state --state NEW -p tcp --dport 636 -j ACCEPT
iptables -t filter -A OUTPUT -m state --state NEW -p tcp --dport 389 -j ACCEPT
iptables -t filter -A OUTPUT -m state --state NEW -p tcp --dport 636 -j ACCEPT

Si vous utilisez un serveur RPS d'OVH, le disque iSCSI nécessite un accès réseau qui rend obligatoire une règle supplémentaire au début des filtres. Sans cela, votre serveur deviendra inutilisable :
iptables -A OUTPUT -p tcp --dport 3260 -m state --state NEW,ESTABLISHED -j ACCEPT

Lorsque vous avez défini toutes les règles, rendez ce fichier exécutable :

chmod +x /etc/init.d/firewall

Vous pourrez le tester en l'exécutant directement en ligne de commande. Assurez-vous d'avoir toujours le contrôle de votre machine (reconnectez-vous en SSH, vérifiez la disponibilité des services web, ftp, mail...). En cas d'erreur, redémarrez le serveur, les règles seront oubliées et vous permettront de reprendre la main. En revanche, si les tests s'avèrent concluants, ajoutez le script au démarrage pour que celui-ci protège le serveur dès le boot.

Afin de l'ajouter aux scripts appelés au démarrage :

update-rc.d firewall defaults

Pour le retirer, vous pouvez utiliser la commande suivante :

update-rc.d -f firewall remove

Redémarrez, ou exécutez /etc/init.d/firewall pour activer le filtrage.

N'oubliez pas de tester vos règles. Elles doivent absolument être adaptées à votre configuration réseau. Un mauvais choix peut entraîner une indisponibilité de votre serveur ou une perte de contrôle sur celui-ci avec le blocage de votre connexion SSH.

Vous pouvez utiliser IPtables sans passer par un script de démarrage et entrer directement les instructions en mode console. Pour bannir temporairement une adresse IP en cas de nécessité, utilisez la commande iptables -A INPUT -s adresse_ip -j DROP

6 – Cacher certaines infos

Supprimer l'affichage de la version d'Apache

Se rendre dans le répertoire /etc/apache2/conf-enabled

Editer le fichier :

pico security.conf

Mettre :

ServerTokens Prod
ServerSignature Off

On redémarre le service Apache :

service apache2 restart

Supprimer la version de PHP

Se rendre dans le répertoire /etc/php5/apache2

Editer le fichier :

pico php.ini

Mettre :

expose_php Off

On redémarre le service Apache :

service apache2 restart

7 – Un système toujours à jour

Il est primordial d'effectuer les mises à jour de sécurité lorsque celles-ci sortent. Nous allons voir comment automatiser ce processus. Pour cela, nous allons utiliser le paquet cron-apt :

sudo apt install cron-apt

Dans notre cas, on ne veut que les mises à jour de sécurité :

grep security /etc/apt/sources.list > /etc/apt/security.sources.list

Maintenant on va configurer cron-apt pour spécifier ce qu'il doit mettre à jour et nous envoyer un rapport par mail. On édite /etc/cron-apt/config :

APTCOMMAND=/usr/bin/apt-get
OPTIONS="-o quiet=1 -o Dir::Etc::SourceList=/etc/apt/security.sources.list"
MAILTO="moi@mondomain.fr"
MAILON="upgrade"

On va maintenant indiquer à cron-apt d'installer les mises à jour lorsqu'il en trouve.

On édite /etc/cron-apt/action.d/3-download :

dist-upgrade -y -o APT::Get::Show-Upgraded=true

Cron-apt se lance par défaut toute les nuits à 4h du matin

8 – Sécurité avancée

Rkhunter : Détecter les intrusions

En quoi consiste cet outil ? Tout simplement à créer une empreinte de ce qui est installé et d'avertir lorsqu'il y a des modifications « louches ».

Il faut installer le paquet :

sudo apt-get install rkhunter

Ensuite, on modifie le fichier /etc/default/rkhunter :

# Pour effectuer une vérification chaque jour
CRON_DAILY_RUN="yes"
REPORT_EMAIL="moi@mondomaine.fr"

Dans une utilisation courante, vous aurez certainement des faux positifs. Cela étant du aux mises à jour qui peuvent être effectué sur la machine. Pour mettre à jour l'empreinte, il faut lancer la commande :

sudo rkhunter --propupd

Logwatch : Surveiller vos logs

Logwatch est un outil qui analyse les logs et envoie chaque jour un rapport par mail. Cela peut permettre de détecter les anomalies.

On installe d'abord le paquet :

sudo apt install logwatch

On le configure :

sudo cp /usr/share/logwatch/default.conf/logwatch.conf /etc/logwatch/conf/logwatch.conf

Il faut maintenant le configurer avec notamment la bonne adresse email. On édite le fichier /etc/logwatch/conf/logwatch.conf :

# Pour recevoir les mails au format html, c'est plus agréable à lire
Format = html
# Adresse sur laquelle recevoir les mails
MailTo = moi@mondomaine.fr
# Niveau de détail des logs
Detail = Med

Et pour recevoir un rapport immédiatement :

sudo logwatch --mailto moi@mondomaine.fr --output html

Une alarme SSH

Pour être averti à chaque connexion d'un utilisateur, on peut ajouter la ligne suivante à la fin du fichier .bashrc qui se trouve dans le homedir :

echo "Objet : Alerte connexion SSH.
Serveur : `hostname`
Date : `date`
`who` " | mail -s "`hostname` connexion ssh de : `who | cut -d"(" -f2 | cut -d")" -f1`" moi@mondomaine.fr

Ainsi à chaque connexion de l'utilisateur, vous recevrez un email avec les infos de connexion. Il est possible de le mettre également pour l'utilisateur root.