Sécuriser un serveur SSH

SSH est un protocole de communication et un programme/daemon/service qui permet un accès en ligne de commande à une machine Unix dont Linux.
C’est un programme client/serveur dont la communication est chiffrée.
L’authentification se fait soit à partir d’un mot de passe, soit par un échange de clés asymétriques.
Enfin, la connexion SSH peut se faire à partir d’un client Unix ou Windows.

Voici un tutoriel qui explique comment sécuriser son accès SSH.

ssh_logo

Survol rapide SSH

Les fichiers de configuration

  • /etc/ssh/sshd_config : Fichier de configuration du serveur OpenSSH.
  • /etc/ssh/ssh_config : Fichier de configuration du client OpenSSH.
  • ~/.ssh/ : Dossier de configuration SSH de l’utilisateur
  • ~/.ssh/authorized_keys ou ~/.ssh/authorized_keys : Liste les clés publiques (RSA / DSA) du l’utilisateur.
  • Le port par défaut SSH : TCP 22

Exemple de connexion SSH établit sur le serveur www.malekal.com.
A partir de cet accès, vous pouvez saisir n’importe quelle commande. Si l’accès est root, vous avez un accès total au système.
Les pirates cherchent donc à obtenir des accès utilisateurs pour faire tourner des scripts malicieux permettant par exemple des attaques DoS.

ssh_client

clés SSH vs mot de passe

Comme indiqué dans l’introduction, l’authentification SSH peut s’effectuer de deux façons différentes.

  • par des mots de passe
  • ou une authentification par clés asymétrique

Désavantages des mots de passe :

  • Les mots de passe des utilisateurs systèmes créé, par exemple l’utilisateur toto avec le mot de pase 54ds39_23
  • Les clés publiques sont générées par le serveur à partir d’une clé privée. (fonctionnement des clés privée/publique)
  • Les mots de passe sont envoyés vers le serveur, et peuvent éventuellement être récupérés (attaque MiT ) ou par /etc/shadow (attaque par bruteforce / base de données)
  • Les mots de passe sont plus courts que les phrases utilisées dans les clés.

Avantages des mots de passe :

  • Les mots de passe sont gérés par l’administrateur contrairement aux clefs : Ils peuvent forcer le changement et sur une période.

Avantages des clés et désavantages des mots de passe :

  • L’administrateur ne maîtrise les mots de passe des utilisateurs
  • Si le mot de passe est utilisé sur plusieurs serveurs, et que l’un d’en entre eux permet de le récupérer. Votre système peut-être compromis.
  • Non sujet aux attaques par bruteforce

Désavantage des clés :

  • La protection est surtout côté cliente, si un utilisateur non averti, utilise des clés et que son système est compromis, l’accès au serveur est possible depuis son ordinateur.

Bref ici, à vous de voir quelle méthode vous souhaitez privilégier.
Sachant que vous pouvez parfaites mixer les deux, c’est d’ailleurs la configuration par défaut de SSH.

Les deux options suivantes du fichier /etc/ssh/sshd_config permettent d’activer/désactiver l’authentification par mot de passe ou clés.
Il suffit de positionner celles-ci à Yes ou No.

PasswordAuthentication
PubkeyAuthentication

Sécuriser l’authentification

Si vous souhaitez bloquer l’utilisateur root, vous pouvez ajouter l’option suivante au fichier /etc/ssh/sshd_config :

PermitRootLogin no

il est aussi possible de n’autoriser que certains utilisateurs et d’en bloquer d’autres.
Pour n’autoriser que les utilisateurs suivants, ajouter le paramètre  :

AllowUsers root kevin sabrina

Pour interdire, certains utilisateurs, ajoutez :

DenyUsers www-data nicolas

TCP Wrappers

Vous pouvez limiter l’accès SSH à certaines machines.
Au lieu de bloquer le port par iptables, vous pouvez déclarer les machines autorisées partir des IPs depuis dans le fichier /etc/hosts.allow

Voici un exemple :

sshd : 192.168.1.2 172.16.23.12

De manière générale, la syntaxe est :

daemon: ip ip2 ip3

Bloquer les attaques par bruteforce

Les attaques par bruteforce consiste à tenter une authentification en testant plusieurs couples d’utilisateur / mot de passe.
Le but étant de trouver un couple d’utilisateur ayant un mot de passe faible, exemple l’utilisateur john avec le mot de passe admin.
Les serveurs SSH sont très ciblées par ces attaques par bruteforce.
Plus d’informations sur les attaques brute-force, lire : les attaques par brute-force.

Comprenez ici que le problème ne se situe pas vraiment du côté de la parade de ces attaques, en clair installer des protections directement contre elles.
Mais plutôt dans une bonne gestion des mots de passe par les utilisateurs.

Il existe des programmes qui vérifie les logs ou tentatives d’authentification non réussies pour bloquer les hôtes sources.
Si vous êtes le seul à gérer le serveur et n’avez que quelques utilisateurs, ces programmes ne sont pas forcément utiles.

  • DenyHosts est un script python qui permet de protéger votre serveur SSH. Le script vérifie les logs et bloque les IPs qui tentent des attaques par bruteforce.
  • Fail2ban est aussi un programme qui vérifie les logs pour bloquer les adresses sources d’attaques par bruteforce.
  • security/sshguard-pf protect hosts from brute force attacks against ssh and other services using pf.
  • security/sshguard-ipfw protect hosts from brute force attacks against ssh and other services using ipfw.
  • security/sshguard-ipfilter protect hosts from brute force attacks against ssh and other services using ipfilter.
  • security/sshblock est un daémon qui bloque les tentatives d’authentification SSH abusives
  • security/sshit bloque les attaques par bruteforces sur les services SSH/FTP.
  • Brute Force Detection est un script modulaire qui vérifie les tentatives d’authentification non réussies. Un règle APF, Shorewall, raw iptables, ip route peut-être ensuite créée pour bloquer l’hôte source.
  • IPQ BDB filter est Fail2ban like.

Limiter les ports 22

Iptables permet de limiter les requêtes sur le port 22 pour limiter les attaques par bruteforces.
Voici quelques syntaxes qui peuvent être utilisées :

#!/bin/bash
inet_if=eth1
ssh_port=22
$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent  --set
$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent  --update --seconds 60 --hitcount 5 -j DROP

ou encore cet exemple :

$IPT -A INPUT  -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT
$IPT -A INPUT  -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o ${inet_if} -p tcp --sport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT
# another one line example
# $IPT -A INPUT -i ${inet_if} -m state --state NEW,ESTABLISHED,RELATED -p tcp --dport 22 -m limit --limit 5/minute --limit-burst 5-j ACCEPT

Changer le port d’écoute

Utile contre les attaques automatisées.
Inutile contre les attaques ciblées.

Simplement, éditez le fichier /etc/ssh/sshd_config :
Change le contenu du paramètre Port qui doit être sur 22.
Par exemple pour mettre sur le port 3333

Port 3333

relancez sshd : /etc/init.d/sshd restart

Port knocking

Le port Knocking est la dissimulation d’un service à travers une séquence de ports pré-définies.
Le service est inaccessible via des règles Iptables.
En utilisant, une séquence de port, une règle iptables va être créées qui va rendre le service accessible sur l’IP qui émet cette séquence.

Le Port knocking est très utile pour des serveurs n’ayant pas d’utilisateurs.
Si vous commencez à avoir des dizaines d’utilisateur sur le serveur, cela peut devenir difficile à gérer pour eux.

Pour se faire, vous devez installer un daemon de port knocking comme knockd

aptitude install knockd

Sur le serveur, knockd doit tourner en daemon, pour cela, on modifie /etc/default/knockd :

START_KNOCKD=1

Ensuite on modifie /etc/knockd.conf en créant la séquence de ports qui va permettre de créer la règle.
Par exemple, ci-dessous, il faut envoyer une connexion TCP sur les ports 7000 puis 8000 et enfin 9000 afin que la règle Iptables permettant l’accès soit générée :
(attention, bien mettre -I INPUT pour l’open)

[options]
UseSyslog
[openrsync] sequence = 7000,8000,9000
seq_timeout = 5
command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn

[closerync] 
sequence = 9000,8000,7000 
seq_timeout = 5 
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT 
tcpflags = syn

Enfin, on créé la règle pour fermer le port 22

/sbin/iptables -A INPUT -p tcp --dport 22 -j DROP

Côté client, vous pouvez générer la séquence comme ceci :

knock -v host port1 port2 port3

puis comme « d’habitude

ssh user@host
Print Friendly, PDF & Email
(Visité 1 734 fois, 2 visites ce jour)
Noter cet article

Add Comment