Serveur Dédié: Sécurité
# Par Neck le dimanche 2 mars 2008, 13h06 (Informatique)
La distribution en place, il est temps de s'assurer que des indésirables ne puissent pas y mettre leur grain de sable.
Connexion SSH
On se connecte à son serveur avec SSH, il vaut mieux modifier la configuration par défaut:
# nano /etc/ssh/sshd_config
Remplacer le port par défaut part un autre, préférer un nombre au dessus de 10000 pour éviter d'interférer avec d'autres services.
Port 22 -> Port <port>
Interdire l'authentification directe de l'administrateur. Cela devrait déjà être le cas sur la distribution de Gandi mais la mise à jour peut avoir altéré le fichier.
PermitRootLogin Yes -> PermitRootLogin No
Autoriser uniquement notre utilisateur. Cette directive n'existe pas, ajoutez-la en fin de fichier. Le nom est celui utilisé lors de la connexion ssh.
AllowUsers <nom>
Limiter le nombre de connexion simultanées. Décommenter et modifier la ligne:
MaxStartups 3:30:10
Le comportement est le suivant: au delà de 3 connexions non authentifiées, il y a 30% d'échec; ce taux augmente jusqu'à atteindre 100% pour 10 connexions.
Tout ceci enregistré il reste à redémarrer SSH.
# /etc/init.d/ssh restart
Facultatif
Quelques options supplémentaire qui peuvent être ajoutées.
Désactiver la possibilité d'utiliser X11 (mode graphique). C'est inutile pour un serveur donc autant l'enlever.
X11Forwarding Yes -> X11Forwarding No
Mettre un message de bienvenue amical et chaleureux, décommenter la ligne:
Banner /etc/issue.net
Ensuite il faut écrire ledit message.
# nano /etc/issue.net
Voici un exemple tiré de la documentation Ubuntu Anglophone.
***************************************************************************
NOTICE TO USERS
This computer system is the private property of its owner, whether
individual, corporate or government. It is for authorized use only.
Users (authorized or unauthorized) have no explicit or implicit
expectation of privacy.
Any or all uses of this system and all files on this system may be
intercepted, monitored, recorded, copied, audited, inspected, and
disclosed to your employer, to authorized site, government, and law
enforcement personnel, as well as authorized officials of government
agencies, both domestic and foreign.
By using this system, the user consents to such interception, monitoring,
recording, copying, auditing, inspection, and disclosure at the
discretion of such personnel or officials. Unauthorized or improper use
of this system may result in civil and criminal penalties and
administrative or disciplinary action, as appropriate. By continuing to
use this system you indicate your awareness of and consent to these terms
and conditions of use. LOG OFF IMMEDIATELY if you do not agree to the
conditions stated in this warning.
****************************************************************************
Chez le Client
Pour utiliser un port différent lors de la connexion on utilise "-p":
$ ssh <nom>@<ip du serveur> -p <port>
Il est aussi possible de l'enregistrer dans la configuration locale:
$ nano ~/.ssh/config
Ajouter:
# Mon serveur dédié Host <ip du serveur> Port <port>
Iptables
Les noyaux Linux actuels possèdent un module appelé Netfilter qui agit, en autre, comme un pare-feu. La configuration se fait avec Iptables. Tout d'abord l'installer:
# apt-get install iptables
Précaution
Manipuler le pare-feu implique de restreindre les accès extérieurs, or la connexion ssh qui permet l'administration en fait partie. Je vous laisse imaginer qu'une mauvaise manipulation peut avoir de fâcheuses conséquences. Par précaution, il est possible de ménager une issue de secours, elle consiste en une tâche cron qui va supprimer toutes les règles d'Iptables après un certain temps:
// Effectuer cette commande en tant qu'administrateur, // sans quoi le cron n'aura pas les droits nécessaires. # crontab -e
Ajouter deux commandes qui nettoieront la configuration d'iptables à <heure>:<minute>. Utiliser date pour obtenir l'heure courante du serveur et y ajouter 10 minutes par exemple.
# m h dom mon dow command <minute> <heure> * * * /sbin/iptables -F; /sbin/iptables -P INPUT ACCEPT
En cas d'erreur la configuration sera remise à zéro, évitant de se retrouver coincé dehors.
Configuration
La logique est la suivante: interdire puis autoriser au compte-goutte.
// Faire le ménage par le vide # iptables -F # iptables -X // accepter le trafic d'une connexion ouverte # iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT // accepter le trafic local # iptables -A INPUT -i lo -j ACCEPT # iptables -A INPUT -s <ip du serveur> -j ACCEPT // accepter le trafic du web (http) # iptables -A INPUT -i eth0 -d <ip du serveur> -p tcp --dport 80 -j ACCEPT // accepter le trafic ssh, utiliser le port choisi ci-dessus # iptables -A INPUT -i eth0 -d <ip du serveur> -p tcp --dport <port ssh> -j ACCEPT // refuser et log tout le reste # iptables -A INPUT -j LOG --log-prefix 'Iptables denied: ' # iptables -P INPUT DROP # iptables -P FORWARD DROP
Sauver tout ça
Le problème est que la configuration d'Iptables est remise à zéro à chaque redémarrage. Nous allons pallier à ceci avec l'aide d'un petit script maison.
# nano /etc/init.d/iptables
Le fichier ne doit pas exister, sinon choisir un autre nom. Ce dernier ouvert, y écrire:
#! /bin/sh
# Restaurer et sauver la configuration d'Iptables
case "$1" in
# sauver
"save" )
echo "Sauvegarde de la configuration d'Iptables."
iptables-save > /etc/iptables
;;
# restaurer
"start" | * )
echo "Restauration de la configuration d'Iptables."
iptables-restore < /etc/iptables
;;
esac
exit 0
Ensuite utiliser le script pour régler notre problème.
// Donner les droits d'exécution. # chmod +x /etc/init.d/iptables // Enregistrer la configuration actuelle d'iptables # /etc/init.d/iptables save // Demander l'exécution du script au démarrage # update-rc.d iptables defaults
C'est fini, votre configuration sera restaurée automatiquement au démarrage. Au cas ou vous la modifiez, n'oubliez pas d'exécuter:
# /etc/init.d/iptables save
Ne pas oublier...
Avec une telle configuration le serveur ne répondra plus aux ping, c'est normal. Si vous souhaitez qu'il le fasse ajoutez:
# iptables -I INPUT 6 -i eth0 -d <ip du serveur> -p icmp --icmp-type 8 -s 0/0 -j ACCEPT
De plus les ports sont bloqués par défaut, il faut penser à les ouvrir en cas de besoin avec:
# iptables -I INPUT 4 -i eth0 -d <ip du serveur> -p tcp --dport <port> -j ACCEPT
Bloquer les attaques par force brute
Si vous laissez la configuration ssh telle quelle (à plus forte raison sur le port par défaut), vous ne tarderez probablement pas à enregistrer des milliers de tentatives de connexion. Il s'agit d'attaques par force brute, voici deux moyens de les bloquer, à vous de choisir.
Fail2Ban
Fail2Ban est un service qui analyse les logs et modifie la configuration d'iptables pour rejeter les curieux provoquant trop d'erreurs. Tout d'abord on l'installe.
# apt-get install fail2ban // Désactiver le service pendant que l'on configure. # /etc/init.d/fail2ban stop
Ensuite, on créer un fichier activant la surveillance de la connexion ssh.
# nano /etc/fail2ban/jail.local
# Configuration de fail2ban pour la connexion SSH. [ssh] # Activer le filtre. enabled = true # Utiliser notre version des interactions avec iptables banaction = iptables-optimized # Insérez ici le port que vous avez choisi pour ssh. port = <port> # Politique appliquée: # 3 essais en 10 minutes (600s) pour un ban de 20 min (1200s). maxretry = 3 fintime = 600 bantime = 1200
Il reste une chose à faire, si vous regardez attentivement le fichier vous remarquerez qu'il est question de "notre version des interactions avec iptables". En effet les commandes utilisées par défaut peuvent être optimisées, nous créons donc un fichier avec les nouvelles.
# nano /etc/fail2ban/action.d/iptables-optimized.conf
Ne remplacez aucune valeur entre < et > dans le fichier ci-dessous, fail2ban s'en chargera à la volée.
# Réécriture optimisée des interactions avec iptables.
[Definition]
actionstart = iptables -N fail2ban-<name>
iptables -I INPUT -p <protocol> --dport <port> -j fail2ban-<name>
actionstop = iptables -D INPUT -p <protocol> --dport <port> -j fail2ban-<name>
iptables -F fail2ban-<name>
iptables -X fail2ban-<name>
actioncheck = iptables -n -L INPUT | grep -q fail2ban-<name>
# Règles de bannissement créant une entrée dans les log d'iptables.
# Si ce ne'st pas souhaité, les commenter et les remplacer par celles en dessous.
actionban = iptables -A fail2ban-<name> -s <ip> -j LOG --log-prefix "Iptables denied (Fail2Ban): " --log-ip-options --log-tcp-sequence --log-tcp-options
iptables -A fail2ban-<name> -s <ip> -j DROP
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
iptables -D fail2ban-<name> -s <ip> -j LOG --log-prefix "Iptables denied (Fail2Ban): " --log-ip-options --log-tcp-sequence --log-tcp-options
# Version sans log.
# actionban = iptables -A fail2ban-<name> -s <ip> -j DROP
# actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
[Init]
name = default
port = ssh
protocol = tcp
Une fois ceci en place fail2ban est prêt à monter la garde.
# /etc/init.d/fail2ban start // Vérifier que tout marche. # /etc/init.d/fail2ban status
Iptables
Iptables est également capable de bloquer ce genre d'attaque. Il suffit d'ajouter quelques règles à notre par-feu.
// <pos. ssh> est la position de la règle existante concernant ssh en partant du haut. // Si vous avez utilisé la configuration proposée plus haut c'est 5. // Lorsqu'une nouvelle connexion ssh est détectée, ajouter une entrée dans la liste "SSH". # iptables -I INPUT <pos. ssh> -i eth0 -d <ip du serveur> -p tcp --dport <port ssh> -m recent --set --name SSH // Si il existe déjà 4 entrées dans "SSH" par la même ip datant de moins de 1 minute refuser l'accès. # iptables -I INPUT <pos. ssh> -i eth0 -d <ip du serveur> -p tcp --dport <port ssh> -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
L'effet de ces règles est: s'il y a plus de 4 (hitcount) connexions en 1 minute (seconds) alors on refuse l'accès.
N'oubliez pas de les sauver.
# /etc/init.d/iptables save
Comparaison
Fail2Ban est légèrement plus compliqué à mettre en place et représente un service supplémentaire sur la machine. De plus il souffre d'un court temps de réaction dû au fait qu'il doit lire et analyser les log, ainsi il peut y avoir plus de requêtes qu'autorisées qui passent avant que le bannissement ne soit effectif. Cependant il permet une configuration très fine et ne se limite pas aux connexions ssh.
Iptables est simple et rapide à mettre en place, mais il traite indifféremment une tentative de connexion réussie et une ratée. Donc quatre connexions réussies en une minute (avec notre configuration) provoqueraient tout de même un rejet. Il faut également souligner que la configuration est basique et ne permet pas une gestion indépendante du temps de ban et du temps de détection.
Configurer IPv4
Nous allons modifier quelques options IPv4 qui pourraient être problématiques:
// Passer en mode root pour les commandes suivantes $ sudo -s // Activer les SYN cookies # echo "1" > /proc/sys/net/ipv4/tcp_syncookies // Activer la vérification de route # echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter // Refuser les redirections # echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects # echo "0" > /proc/sys/net/ipv4/conf/all/secure_redirects // Loguer les "martiens" # echo "1" > /proc/sys/net/ipv4/conf/all/log_martians // Retourner en mode utilisateur normal # exit
Chkrootkit
Les rootkits sont des sortes de virus, ils n'ont donc rien à faire sur votre serveur. Chkrootkit est un petit utilitaire qui traque leur présence, l'installation et l'utilisation sont des plus simples:
// installer # apt-get install chkrootkit // utiliser # chkrootkit
Automatisation
Vous l'aurez deviné il faut effectuer la chose régulièrement. Ajoutons donc une entrée au cron.
// Effectuer cette commande en tant qu'administrateur, // sans quoi le cron n'aura pas les droits nécessaires. # crontab -e
Ajouter à la fin du fichier.
# Vérifier la présence de rootkits tous les matins à 5h55. 55 5 * * * chkrootkit > /var/log/rootkit.log
Note: Il serait bien plus intéressant d'envoyer le résultat par mail, nous verrons comment procéder lors de l'installation d'un smtp.
Références
- Prendre un Café: Sécuriser son Ubuntu Server (chkrootkit, fail2ban, ssh).
- Fourre-tout.com: Installation Ubuntu Server - Chapitre 1 (IPv4, fail2ban, chkrootkit, ssh).
- JujuSeb, Fail2Ban contre l'attaque par brute force.
- Billyboylindien: Log ssh et bruteforce, iptables, interdire root.
- Christian CALECA: Iptables.
- MySecureShell: Sécurité (ssh).
- Groupes Gandi: Changement du port SSH, Attention aux mots de passe! (ssh).
- Documentation Ubuntu Francophone: ssh, Cron, Iptables, Shell.
- The Art of Web: System: fail2ban and iptables.
- MDLog:/sysadmin: Using fail2ban to Block Brute Force Attacks
- nixCraft: Linux Iptables allow or block ICMP ping request.
- Documentation Ubuntu Anglophone: Iptables, AdvancedOpenSSH.
- Site officiel de Fail2Ban.
- Apache Security, RISTIC Ivan, Ed. O'Reilly, 2005 USA, 380p (Anglais).
Sommaire | Dernière modification le 8 mars 2008

Commentaires
Bonjour,
Bravo pour votre article. C'est bien sympa de partager votre connaissance. Cela m'a été bien utile pour configurer mon serveur.
Bonjour,
un premier commentaire, j'en suis tout ému !
Je suis heureux que cet article puisse servir à autre chose qu'une trace écrite pour moi-même.
Par contre ce n'est pas vraiment ma connaissance, je ne suis ni administrateur réseau ni professionnel. Il s'agit plutôt d'une compilation, de recoupes et de traductions de diverses lectures.
PS: j'autorise tous ceux qui le souhaitent à me tutoyer
Merci pour cette compilation, alors.
J'ai appliqué à peu près tout ça. Dans un deuxième temps il faudra que je me penche sur l'analyse de logs et le reporting automatique par courriel. Je jetterai un oeil à ton article du 19 mars à ce sujet.
Sinon, la seule chose que j'ai laissée de côté pour l'instant c'est la configuration d'Iptables. Je suis resté sur la config de base (hors modifications éventuelles faites par fail2ban). J'aurais bien appliqué ce que tu préconises, mais sans plus d'explications je trouve ça un peu obscur, je tâcherai de trouver un peu de temps pour me pencher sur la question.
En passant, un détail: est-ce que configurer SSH avec X11Forwarding No n'empêcher pas le montage des répertoires distants via SSH dans Gnome (Nautilus) ou KDE (Konqueror)? Pour ma part c'est une fonctionnalité que j'utilise beaucoup.
[Un peu plus tard] Hum, à vue de nez, non.
Je suis également sur l'analyse et le report des logs en ce moment, un autre article à venir dans pas trop longtemps normalement.
Je vais aussi ajouter un petit passage explicatif pour iptables dans celui-ci à l'occasion
À propos de "X11Forwarding", non cela ne posera pas de problème car pour l'utilisation que tu décris c'est le serveur graphique local qui est utilisé. Cette option empêche uniquement l'utilisation d'un serveur graphique distant (cas ou tout l'environnement graphique est géré par le serveur et ou l'ordinateur local ne fait qu'afficher ce qu'on lui dit).
Merci pour ce tutorial ça m'a été très utile,
par contre j'ai une petit question depuis que j'ai installée je n'arrive plus à envoyer de fichiers par ftp (commande put), ya t'il qqchose à faire dans iptables pour autoriser cela ?
Bonsoir Yeri,
oui c'est normal il faut débloquer le port utilisé par ftp. Par défaut il s'agit du port 21, ce qui donne:
# iptables -I INPUT 4 -i eth0 -d <ip du serveur> -p tcp --dport 21 -j ACCEPT
La config fail2ban dans cet article ne fonctionne pas. Je présume qu'elle correspond à une ancienne version de fail2ban et que la syntaxe de config a changé depuis.
C'est fort possible, l'article ayant été publié il y a plus de 6 mois.
Entre temps je suis passé sur un serveur Debian et j'ai pas vraiment eu le temps de réécrire d'autres tutoriels ou d'actualiser ceux-ci.
Mes excuses, peut-être qu'un de ces quatre je trouverai le temps et la motivation de finir ça.