Archive for the 'OpenSSH' Category

Point de RDV SSH

Voila bien longtemps qu’il n y avait pas eu de nouveau post sur ce blog. Disons que ma vie personnelle a pas mal changée et ça a influé sur mes priorités. Enfin je tente de revenir au top avec un billet sur comment mettre en place un point de RDV SSH. Un point de RDV SSH implique trois protagonistes :
- Un service réseau ;
- Une passerelle SSH ;
- Un client.
Le principe est que le client doit pouvoir accéder à un service du réseau interne sur une machine type passerelle SSH.

Schéma :

1) On exporte la socket du service MySQL vers la passerelle SSH. L’administrateur réseau fait ça en tapant la commande suivante sur le serveur MySQL (le -R crée un tunnel inversé) :

ssh -N -f -R 4406:127.0.0.1:3306 admin@gw_ssh

Le service est joignable sur le loopback de la passerelle SSH.

2) Le client crée ensuite un tunnel SSH vers la socket fraichement crée sur le loopback de la passerelle :

ssh -N -f -L 5506:127.0.0.1:4406 client@gw_ssh

Et hop, le client peut joindre le service MySQL sur lo loopback port 5506 de son laptop.

Avantages :
- Le client n’a pas de compte système sur le serveur MySQL ;
- On n’est pas obligé d’autoriser des connexion de la passerelle vers le serveur de BD (uniquement l’inverse) ;
- A aucun moment le service MySQL est exposé sur un interface “réelle” (uniquement sur des loopback) ;
- Tout le trafic est chiffré (il passe dans des tunnels SSH).

Inconvénient :
- Le client doit savoir utiliser SSH.

Gestion des invité(es) SVN

Aujourd’hui j’ai du installer un serveur subversion. J’utilise l’accès svn+ssh seulement et un serveur LDAP. Le problème s’est posé pour gérer les invités : des gens qui collaborent aux projets gérés par subversion mais pour qui il n’est pas forcément souhaitable de créer un compte LDAP. Enfin, je veux qu’a la première connexion l’utilisateur soit obligé de changer son mot de passe.

J’ai géré le problème de la manière suivante :

1 – Pour chaque invité je crée un utilisateur qui a comme groupe primaire “svn_queue” et qui appartient à un ou plusieurs groupes liés aux projets sous subversion. Le groupe svn_queue contient les utilisateurs en attente de changement de mot de passe. Ces utilisateurs ont un shell particulier :

svn# less /usr/local/bin/wrapper_passwd.sh

#!/bin/sh
 
/usr/bin/passwd
ret_pw=$?
if [ $ret_pw -eq 0 ]
then
        /usr/local/bin/sudo /usr/sbin/pw usermod $USER -g svn_enable -s /bin/sh
        exit 0
else
        exit 1
fi

Création de l’utilisateur :

pw useradd -n svntest -g svn_queue -d /nonexistent -s /usr/local/bin/wrapper_passwd.sh

2 – Ce script à ajouter dans le /etc/shells force l’utilisateur à changer de mot de passe à la première connexion. Pourquoi ne pas le forcer avec de l’accounting ? En fait j’ai aussi besoin qu’a la connection SSH initiale, le GID primaire de l’utilisateur change pour le passer dans le group svn_enable. Ce groupe est utilisé par mon serveur SSH pour forcer l’execution de svnserve à la connexion des membres du groupe.

svn# tail -n 2 /usr/local/etc/ssh/sshd_config

Match group svn_enable 
	ForceCommand /usr/local/bin/svnserve -t -r /usr/local/repositories

Faille OpenSSH chez RedHat …

Après la faille OpenSSL chez Debian, la faille OpenSSH chez RedHat.
Un message sur la liste d’annonce CentOS relate une intrusion sur les serveurs RedHat. Cette intrusion a conduit au remplacement du paquet OpenSSH. Aucun détail sur la manière dont les pirates ont pénétrés les serveurs RedHat ni sur les “features” de leur openSSH modifié. Le communiqué sur le site de RedHat est extrêmement laconique.

Le RHN c’est cher mais c’est sécurisé : c’est en HTTPS.

Pourquoi j’aime pas fail2ban

Un message est passé sur la liste debian-security il y a peu de temps pour demander comment réagir d’un point de vue aussi bien administratif que technique aux scans / bruteforces / attaques par dictionnaires sur OpenSSH. Une floppée de réponses lui ont donné les méthodes de base :
- Changer le port par défaut
- Utiliser un système de port knocking
- Utiliser authentification par clés
- Utiliser des systèmes assimilés aux HIPS [1] (type fail2ban)

Ce dernier point me gêne un peu. L’aspect “réactif” des HIPS est à double tranchant. Si les éléments sur lesquels se basent ces outils sont falsifiés alors on s’expose à des problèmes type DoS. Les outils type fail2ban utilisent les logs du système. Ces logs sont le plus souvent gérés par syslog. Or syslog n’intègre aucun mécanisme de sécurité. Tout les logs envoyés au démon syslogd sont traités pour peu que celui ci écoute sur le réseau. Après si on connait les patterns recherchés, on peut très bien déclencher une action en forgeant un paquet conforme au pattern attendu. Sur un pare-feu normalement syslogd est utilisé uniquement en local.

La on arrive à une situation un peu paradoxale. Pour que l’utilisation de fail2ban soit securisée, il faut installer fail2ban sur la machine et traiter les logs locaux à la machines. Si on superpose avec une architecture de détection d’intrusions [2] ça revient à placer la sonde et le manager ainsi que la base d’alerte sur la machine à protéger. D’un point de vue architecturale cela me gène un peu. La faiblesse du système de collecte empêche la distribution de l’architecture.

Une alternative peut être de se baser sur les statistiques de connexions vers le port SSH. Je l’ai fait avec PF sous OpenBSD dans ce billet.

Notes :

[1] Les HIPS (Host Intrusion Prevention System) sont des logiciels dont le but est de relever des tentatives d’intrusions et de déclancher une action en fonction de l’alerte levée.

[2] Un système classique de détection d’intrusions est composé de trois éléments :
- Une sonde qui collecte les évènements
- Un moteur de stockage qui stock les alertes
- Un manager qui traite les alertes

ClusterSSH

Today j’ai installé quelques vieux Dell en Ubuntu 8.04 pour faire une salle de libre service.
J’ai pour habitude sur ce genre de machines de me mettre un petit script qui me remonte un résumé logwatch et les paquets nécessitants une mise à jour.

Seulement sur des machines complètement identiques et dont la disponibilité n’est pas un facteur critique, je trouve dommage de réaliser les mises à jour (ou tout autre opération de maintenance) au cas par cas. J’ai donc cherché comment envoyer une commande sur plusieurs machines. J’ai trouvé un paquet de liens sur des scripts bash qui font un for sur une liste d’hôtes et passent des traitements en forced commands. L’avantage de ce genre de trucs est que c’est “cronable” mais il faut avoir des clès SSH sans passphrase. Argh !

J’ai fini par trouver un truc très sympa : ClusterSSH. Cette utilitaire s’installe sur la console d’administration. Une fois installé, on crée des groupes de n machines (sous la forme groupe1 = admin@host1, admin@host2 etc …). Une fois ces groupes crées, on lance le client SSH fourni par ClusterSSH : cssh.


[root@admin]# cssh groupe1

Cette commande vous ouvre n+1 fenêtres :
- n xterm connectés aux machines du groupe.
- 1 zone de saisie dédiée à cssh qui, une fois sélectionnée, vous permet d’écrire sur vos n consoles en même temps.

Je vais pouvoir ranger mon usine à gaz PXELinux / Netboot au placard : elle me servait uniquement à pousser une installation “à jour” sur mes postes ;-)

Arno m’a donné quelques alternatives : capistrano, dsh et pssh

Bloquer les bruteforces SSH juste avec PF

Les scans SSH sont une véritable plaie.

Il existe une multitude d’outils pour les stopper (sshguard, fail2ban, snort-inline etc.).

Ces outils ont tous des aspects assez contraignants :

  • Ils ajoutent une “couche” logicielle supplémentaire (soit sous forme de scripts interprétés, soit d’exécutable compilés) qui manipulent vos fichiers de logs.
  • Il faut les maintenir, suivre leurs évolutions et mises à jour.
  • Ces couches sont elles même susceptibles de contenir des vulnérabilités.

Ce court billet va vous expliquer comment utiliser des fonctionnalités de Packet Filter (Pare-feu *BSD) pour mettre fin aux scans SSH. Tout est à réaliser dans votre fichier de configuration de PF (pf.conf).

Tout d’abord, il nous faut déclarer une table pour stocker les IP des brutes épaisses.

table <ssh-brute> persist

Cette table va nous permettre de bloquer le trafic issu de ces hôtes indélicats.

block quick from <ssh-brute>

Enfin, nous allons nourrir cette table avec la règle suivante :

pass in on $ext_if proto tcp from any to ($ext_if) port ssh keep state (max-src-conn-rate 2/20, overload <ssh-brute> flush global)

Explications : cette règle qui match les connexions entrantes sur le port 22 (ssh) n’autorise pas plus de deux connexions issues de la même IP¨sur une durée de 20 secondes (max-src-conn-rate 2/20). En cas de dépassement de ces paramètres l’hôte est ajoutée dans la table ssh-brute (overload <ssh-brute>) et ses connexions en cours sont coupées (flush global).

Pour gérer la péremption des enregistrements dans la table <ssh-brute> on peut utiliser le port expiretable disponible dans l’arbre des ports FreeBSD et OpenBSD. Un simple ajout de la ligne suivante dans votre crontab donne une durée de vie de 24 heures aux enregistrements /usr/local/sbin/expiretable -t 24h ssh-brute