AccueilFAQStatistiquesDiversContact

Auteur : Jérôme Bruandet
spamcleaner.org
Date : 15/09/2007

Linux : blinder les ports de son serveur

Plesk, Webmin, serveur FTP etc, il ne se passe jamais quelques mois sans qu'une de ces applications vitales pour l'administration d'un serveur à distance ne soit la proie d'une vulnérabilité. D'autant que les hackers en manque de reconnaissance en sont toujours informés avant nous. Avec le port knocking, les futures vulnérabilités de ces applications, tout comme les attaques par dictionnaire quotidiennes, ne seront vraiment plus un problème pour nous.

Introduction :

Le port knocking est une méthode permettant de sécuriser les ports de son serveur. Malgré tous ses avantages, il est dommage de voir qu'elle ne semble que peu utilisée, notamment à en juger par le nombre élevé d'administrateurs qui se plaignent sans cesse des attaques dictionnaire contre leurs serveurs alors qu'il est si facile d'y mettre un terme définitif:

  • elle est extrêmement efficace
  • elle ne requiert que très peu de ressources systèmes
  • sa mise en place est un jeu d'enfant, même pour un débutant
  • elle bloque toute les attaques par dictionnaire contre les ports
  • elle permet non seulement de protéger un serveur mais aussi de lancer absolument n'importe quelle commande à distance (reboot, rotation des logs etc) sans même avoir à se connecter au serveur en SSH.
  • Son fonctionnement est très simple: vous fermez tous les ports sensibles de votre serveur (SSH, FTP, Webmin, Plesk, telnet etc) et ne gardez ouverts que les ports nécessaires (HTTP/S, POP3/IMAP, BIND etc). Lorsque vous voulez ouvrir un des ports sensibles, il suffit de frapper (knock) à différents ports fermés, dans un ordre et un laps de temps prédéfinis dans la configuration. Cela se fait en envoyant de simples séquences TCP et/ou UDP. Un petit daemon va récupérer ces tentatives de connexion aux ports du firewall et les analyser afin de voir s'il s'agit bien de notre séquence et, le cas échéant, ouvrira/fermera le port souhaité ou exécutera la commande. Et, cerise sur le gâteau, il n'ouvrira le port que pour notre IP donc même si nous oublions de le refermer, personne d'autre ne pourra y accéder.
    Enfin, si vous souffrez de paranoïa aiguë, sachez que vous pouvez aussi utiliser des listes noires/blanches ou carrément des hash encryptées à défaut d'une simple séquence UDP/TCP.

    Il existe de nombreuses applications de port knocking et celle que nous utiliserons en raison de sa simplicité est knockd.

    Installation

    Vous devez l'installer sur votre serveur mais aussi sur votre ordinateur, car si le paquet contient le daemon (/usr/sbin/knockd), il contient aussi le client (/usr/bin/knock) que nous utiliserons pour ouvrir les ports à distance.

    Pour installer knockd :

       # apt-get install knockd
    
    Configuration du serveur

    Par défaut le daemon n'est pas activé. Il faut éditer /etc/default/knockd et rajouter :

       START_KNOCKD=1
    

    Vous devez aussi vérifier que l'interface est correcte (eth0 par défaut).

    Le fichier de configuration est /etc/knockd.conf Celui-ci ne contient généralement que la ligne du fichier log :

       [options]
       logfile = /var/log/knockd.log
    
    Nous allons appliquer le port knocking aux ports FTP et webmin, ainsi que créer une séquence pour rebooter le serveur à distance. Pour votre première tentative, ne bloquez pas tous les ports, surtout SSH : si vous vous trompez vous ne pourrez plus accéder à votre serveur.

    Nous allons à chaque fois frapper à 4 ports mais nous pourrions très bien en prendre moins (2 ou 3) tout comme en choisir beaucoup plus (5 ou 10).
    Pour ouvrir le port 21 nous frapperons, dans l'ordre, aux ports 23077, 12044, 13001 et 42967. Pour ouvrir le port 10000, nous frapperons aux ports 44295, 50155, 11932 et 24085 et pour rebooter nous utiliserons les ports 23654, 50443, 20978 et 31855. Pour compliquer les choses, nous utiliserons des séquences TCP (valeur par défaut) pour chaque 1er et 3e ports et UDP pour les autres.
    Pour fermer les deux ports, nous incrémenterons d'une unité ces valeurs (23077 => 23078, 12044 => 12045...) et la totalité de la commande devra être exécutée en moins de 5 secondes (seq_timeout) ce qui est bien plus qu'il n'en faut en réalité.

    Il suffit de rajouter les lignes suivantes au fichier /etc/knockd.conf :

    
    [openFTP]
      sequence    = 23077:tcp,12044:udp,13001:tcp,42967:udp
      seq_timeout = 5
      command     = /sbin/iptables -I INPUT -d xxx.xxx.xxx.xxx -s %IP% -p tcp --dport 21 -j ACCEPT
      tcpflags    = syn
    
    [closeFTP]
      sequence    = 23078:tcp,12045:udp,13002:tcp,42968:udp
      seq_timeout = 5
      command     = /sbin/iptables -D INPUT -d xxx.xxx.xxx.xxx -s %IP% -p tcp --dport 21 -j ACCEPT
      tcpflags    = syn
    
    [openWEBMIN]
      sequence    = 44295:tcp,50155:udp,11932:tcp,24085:udp
      seq_timeout = 5
      command     = /sbin/iptables -I INPUT -d xxx.xxx.xxx.xxx -s %IP% -p tcp --dport 10000 -j ACCEPT
      tcpflags    = syn
    
    [closeWEBMIN]
      sequence    = 44296:tcp,50156:udp,11933:tcp,24086:udp
      seq_timeout = 5
      command     = /sbin/iptables -D INPUT -d xxx.xxx.xxx.xxx -s %IP% -p tcp --dport 10000 -j ACCEPT
      tcpflags    = syn
    
    [REBOOT]
      sequence    = 23654:tcp,50443:udp,20978:tcp,31855:udp
      seq_timeout = 5
      command     = /sbin/shutdown -r +1
      tcpflags    = syn
    
    
    Vous devez remplacer dans l'exemple ci-dessus les xxx.xxx.xxx par l'IP de votre serveur. Vous pouvez cependant supprimer l'option de destination `-d xxx.xxx.xxx.xxx` mais aussi utiliser le paramètre -A (ajouter) au lieu de -I (insérer) suivant la configuration de votre serveur et de votre firewall. Quant à la variable %IP%, knockd la remplacera lui-même par votre IP de connexion ce qui permettra de n'ouvrir le port que pour vous.

    Bloquez complètement l'accès aux ports 21 et 10000 avec iptables, puis lancez le daemon :

       # /etc/init.d/knockd start
    
    La configuration du serveur est terminée à ce stade. Libre à vous de rajouter ultérieurement les ports, séquences et commandes que vous voulez.

    Configuration du client

    Pour utiliser le client depuis votre ordinateur il faudrait taper la ligne de commande suivante :

       /usr/bin/knock <host> <port[:proto]> <port[:proto]> ...
    
    Cela n'est pas envisageable, étant donné le nombre de séquences et commandes à mémoriser un script Perl fera bien mieux l'affaire. Entrez simplement l'adresse IP de votre serveur à la 4e ligne :

    
    #!/usr/bin/perl
    
    # adresse IP de votre serveur:
    $IP = 'xxx.xxx.xxx.xxx';
    
    $CMD = "/usr/bin/knock $IP";
    # séquences TCP/UDP:
    $openWebmin='44295:tcp 50155:udp 11932:tcp 24085:udp';
    $closeWebmin='44296:tcp 50156:udp 11933:tcp 24086:udp';
    $openFTP='23077:tcp 12044:udp 13001:tcp 42967:udp';
    $closeFTP='23078:tcp 12045:udp 13002:tcp 42968:udp';
    $reboot='23654:tcp 50443:udp 20978:tcp 31855:udp';
    
    $menu= "\n-------------------- MENU -----------------------\n";
    $menu.="-FTP\t\t: [10]=ouvrir\t[11]=fermer\n";
    $menu.="-Webmin\t\t: [20]=ouvrir\t[21]=fermer\n";
    $menu.="-Reboot\t\t: [30]\n";
    $menu.="----------------- [q] pour quitter ----------------\n";
    print $menu;
    while (<STDIN>){
      chomp; $_=lc($_);
      if (/q/){
        if ($FTP){print chr(7)."Le port FTP est ouvert !\n";}
        elsif ($WEBMIN){print chr(7)."Le port WEBMIN est ouvert !\n";}
        else{exit}
      } elsif (!/^\d{2}$/){print chr(7)."Entrez un nombre SVP, ou [q] pour quitter\n";
      # FTP:
      }elsif (/^1[01]$/){
        if ($_ eq 10){
          if ($FTP) {print chr(7)."- Le port FTP est deja ouvert !\n"}
          else{
            `$CMD $openFTP`;
            print "- Port FTP ouvert !\n";
            $FTP=1;
          }
        }else{
          `$CMD $closeFTP`;
          print "- Port FTP clos !\n";
          $FTP=0;
        }
      # WEBMIN:
      }elsif (/^2[01]$/){
        if ($_ eq 20){
          if ($WEBMIN) {print chr(7)."- Le port WEBMIN est deja ouvert !\n"}
          else{
            `$CMD $openWebmin`;
            print "- Port WEBMIN ouvert !\n";
            $WEBMIN=1;
          }
        }else{
          `$CMD $closeWebmin`;
          print "- Port WEBMIN clos !\n";
          $WEBMIN=0;
        }
      # REBOOT:
      }elsif (/^30$/){
        print chr(7)."***ATTENTION*** : rebooter le serveur [o/n] ?\n";
        while (<STDIN>){
          chomp; $_=lc($_);
          if (/o/) {
            `$CMD $reboot`;
            print "- Reboot en cours !\n";
            last;
          }else {
            print "- Annulation du reboot\n";
            last;
          }
        }
      }
    }
    exit;
    
    

    Testez le script et vérifiez qu'il ouvre et ferme bien les ports, sans oublier de consulter les logs de knockd sur votre serveur :

       # cat /var/log/knockd.log
    

    Sécurité

    Le port knocking est une méthode très sécurisée: un ordinateur dispose de 65535 ports, les séquences envoyées peuvent être TCP et/ou UDP, peuvent utiliser des hash encryptées, on ne peut pas connaître à l'avance le nombre de séquences à envoyer et de plus, il est impossible même de savoir si votre port est bien bloqué par cette technique ou non. Autant dire qu'un hacker aura plus de chance de gagner au loto que de résussir à trouver le sésame pour ouvrir votre port protégé (à moins de sniffer votre connexion, mais dans ce cas knockd n'en serait pas responsable).

    Il peut cependant y avoir un problème majeur: un crash du daemon, qui serait catastrophique puisque vous ne seriez donc plus en mesure de vous connecter au serveur. Tout comme pour beaucoup d'autres services tournant sur votre serveur, tel Apache, il est impératif de vérifier régulièrement que le daemon n'a pas planté et, le cas écheant, le relancer. Une simple tâche cron exécutant le script ci-dessous toutes les 15mn fera très bien l'affaire :

    
    #!/bin/sh
    
    # entrez votre email pour recevoir l'alerte:
    ADMIN=foo@bar
    
    res=`ps x|grep '[0-9] /usr/sbin/knockd'|wc -l`
    if [ $res = "0" ]; then
      res=`/etc/init.d/knockd restart`
      host=`hostname`
      /usr/sbin/sendmail -f root@$host -t << sendemail
    To: $ADMIN
    Subject: Relance de knockd sur [$host]
    Resultat de la relance: $res
    sendemail
    fi
    
    

    Conclusion

    Avec en plus la possibilité d'exécuter des commandes sans être obligés de vous connecter au serveur par SSH, vous trouverez sans aucun doute de nombreux usages divers: effectuer des rotations de vos logs, remplacement de la page index de votre site par une page d'attente lorsque votre site est en maintenance, bloquer tous les ports en cas d'attaques DOS/DDOS, lancement/arrêt temporaire d'un service etc.. Mais dans tous les cas, après l'installation de knockd, tout comme après l'installation de n'importe quel logiciel, n'oubliez pas l'essentiel : RTFM

       # man knockd
       # man knock
    





    Autres articles :

  • Anti-spam : les services abuse des hébergeurs enfin soulagés
  • Anti-spam : comment se débarasser des spams de referer
  • Anti-spam : comment plomber les spambots
  • Anti-spam : comment protéger son blog des spams de commentaires
  • Sécurité : Linux : mise à jour de son serveur
  • Sécurité : Linux : créer une clé USB bootable
  • Sécurité : Linux : encrypter sa clé USB
  • Sécurité : Linux : utiliser iptables pour bloquer les chaines de caractères
  • Sécurité : Windows : détectez si votre PC envoie des spams
  • Commentaires (4)

    De : Marc
    Le : 18-Sept-2007 à 11:32:01

    Merci pour cet article bien sympa

    De : n0b0dy
    Le : 19-Sept-2007 à 14:36:20

    je vien s de bloquer le port ssh et que du bonheur bye les attaques qui pourissaient mes log

    De : Courageux Anonyme
    Le : 22-Sept-2007 à 11:02:53

    est-ce qu'il existe des softs -clients uniquement- sous windows et mac?

    De : spamCle@ner
    Le : 22-Sept-2007 à 17:17:28

    Il y en a, mais je ne peux pas trop vous conseiller sur leur utilisation (je ne mange pas de pomme et ne fais pas les fenêtres). Jettez un oeil sur le site de l'auteur de knockd dans la section download: http://www.zeroflux.org/cgi-bin/cvstrac.cgi/knock/wiki


    Poster un commentaire

    Nom :

    *Message (4 Ko maxi) :

    smileys