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

  • Apache Security, RISTIC Ivan, Ed. O'Reilly, 2005 USA, 380p (Anglais).



Sommaire | Dernière modification le 8 mars 2008