Accueil
Rechercher:
sur developpez.com sur les forums
Forums | Tutoriels | F.A.Q's | Participez | Hébergement | Contacts
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi MS-Office SQL & SGBD Oracle  4D  Business Intelligence
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
ACCUEIL BSD FORUM BSD TUTORIELS BSD LIVRES BSD SYSTEMES BSD BSD TV UNIX

Mise en place d'une passerelle d'authentification à l'aide de authpf

Date de publication : 15/01/07

Par julp (Autres articles)
 

Une étude du shell authpf : applications, mise en place, interaction avec Packet Filter au moyen d'une ancre. Le tout agrémenté de quelques exemples simples.


1. Présentation
2. Attribution du shell authpf
2.1. Attribution individuelle : changement de shell
2.2. Attribution groupée : utilisation des classes de session
3. Configuration de Packet Filter
3.1. Pré-requis
3.2. Configuration
3.3. Règles propres à chaque utilisateur
3.4. Règles principales
4. Administration et gestion des utilisateurs
4.1. Gestion des utilisateurs
4.2. Lister les utilisateurs actuellement connectés
4.3. Affichage de messages de bienvenue et d'erreur
4.4. Journalisation des évènements
4.5. La sécurité autour de SSH
4.5.1. Paramétrage de SSH
4.5.2. Se prémunir contre les attaques par dictionnaire
5. Après la théorie : la pratique par l'exemple
5.1. Permettre aux utilisateurs de travailler depuis chez eux
5.2. Autoriser l'accès au réseau sans fil
6. Conclusion
6.1. Epilogue
6.2. Remerciements


1. Présentation

Une passerelle d'authentification par rapport à une passerelle normale demande à ce que l'utilisateur s'identifie afin que le trafic généré par ce dernier puisse la traverser. Pour cela chaque utilisateur se voit attribuer un shell différent de ceux que nous connaissons déjà : authpf, et lors d'une connexion SSH réussie à la passerelle, ce shell chargera dynamiquement les règles correspondant à cet usager.

Ces règles peuvent être globales ou bien spécifiques, c'est-à-dire propres à chacun. Il est ensuite possible d'appliquer sans restriction tout type de règles proposé par Packet Filter : passer au travers du filtre, redirection, traduction d'adresse (NAT), etc.

Les connexions et déconnections sont enregistrées par authpf via syslog, fournissant ainsi à l'administrateur l'adresse IP de la machine utilisée, le login de l'utilisateur, l'heure de l'établissement de la session, l'heure à laquelle la session s'est terminée et sa durée. Vous trouverez ici un exemple de parser écrit en Perl.

Quelques utilisations courantes :
  • Exiger une authentification de la part des utilisateurs avant de leur permettre d'utiliser ou d'avoir accès aux ressources réseaux (Intranet comme Internet) :
    • Rendre possible le travail à domicile
    • Accès à un réseau sans fil
  • Adapter le dispositif de filtrage à l'utilisateur connecté :
    • Donner des accès supplémentaires à des administrateurs
    • Etre plus permissif envers les utilisateurs connus
    • Rediriger vers la machine attribuée à un utilisateur

2. Attribution du shell authpf

Tout d'abord il est nécessaire que authpf soit reconnu comme étant un shell par le système, ce qui n'est pas le cas par défaut. Pour cela exécutez la commande :
grep '^/usr/sbin/authpf$' /etc/shells || echo '/usr/sbin/authpf' >> /etc/shells

2.1. Attribution individuelle : changement de shell

Dans le cas d'utilisateurs déjà présents sur le système, il faut modifier manuellement le shell de chacun d'eux. Voici une liste (non exhaustive) des commandes permettant d'effectuer cette opération :

Plusieurs méthodes sont possibles :
  • A l'aide de chsh. Exemple d'utilisation :
    chsh -s /usr/sbin/authpf login_utilisateur
    
  • Un équivalent très proche, basé sur la commande pw :
    pw usermod login_utilisateur -s /usr/sbin/authpf
    
  • Editez tous les comptes présents sur la machine à l'aide de vipw pour modifier les shells des utilisateurs concernés en /usr/sbin/authpf (le shell étant le dernier champ).

A la création d'utilisateurs avec la commande adduser vous pourrez spécifier authpf comme shell.


2.2. Attribution groupée : utilisation des classes de session

Méthode particulièrement adaptée si les utilisateurs devant utiliser ce mécanisme d'authentification ne sont pas encore créés.

Nous allons créer une nouvelle classe pour les utilisateurs concernés dans notre fichier /etc/login.conf telle que :
authpf:\
    :shell=/usr/sbin/authpf:\
    :tc=default:
info Il vous est possible d'ajouter de nombreuses limitations aux utilisateurs associés à une classe. Pour vous en rendre compte consultez la page man de /etc/login.conf.
Après avoir effectuer des changements dans ce fichier il est impératif d'en regénérer la base afin de les prendre en considération. Utiliser la commande cap_mkdb à cette fin :
cap_mkdb /etc/login.conf
Vous pourrez alors utiliser cette nouvelle classe lors de la création de nouveaux utilisateurs avec adduser.

En revanche, si vos utilisateurs existent déjà, vous pouvez utiliser la commande pw pour les changer de classe. Voici un exemple où l'utilisateur julp se voit attribuer cette classe :
pw usermod julp -L authpf

3. Configuration de Packet Filter


3.1. Pré-requis

Le répertoire accueillant les fichiers de configuration de authpf n'existant pas par défaut, il nous faut donc le créer :
mkdir /etc/authpf/
Authpf requiert également un autre répertoire, qui lui héberge des fichiers temporaires dont les noms sont les adresses IP des machines distantes où une connexion SSH est ouverte pour l'exécuter. Sa particularité c'est que le groupe du même nom doit avoir tous les droits sur celui-ci :
mkdir /var/authpf/
chmod 0770 /var/authpf
chgrp authpf /var/authpf
Dernière spécificité, et non des moindres, ce shell utilise le système de fichier nommé fdescfs, qui permet d'accéder à un fichier (déjà ouvert) à partir de son descripteur. Afin de le prendre en charge, nous ajoutons dans /etc/fstab, la ligne suivante :
# Device                Mountpoint      FStype  Options         Dump    Pass#
fdescfs                 /dev/fd         fdescfs rw              0       0

3.2. Configuration

Authpf refusera systématiquement toute connexion en l'absence du fichier /etc/authpf/authpf.conf, c'est pourquoi il faut absolument le créer même vide. Il permet de spécifier deux options de configuration :
  • anchor : définit le nom de l'ancre. Sa valeur par défaut est authpf.
  • table : permet de spécifier le nom de la table contenant l'ensemble des adresses IP d'où les utilisateurs sont actuellement connectés. Sa valeur par défaut est authpf_users.
Voilà comment il sera défini pour la suite de cet article :
/etc/authpf/authpf.conf :
anchor=authpf
table=utilisateurs_authpf

3.3. Règles propres à chaque utilisateur

Authpf présente également l'intérêt de pouvoir charger des règles de filtrage spécifiques à chaque utilisateur. Pour cela, il suffit de les écrire dans un fichier de la forme /etc/authpf/users/$USER/authpf.rules où $USER correspond au login de l'utilisateur en question. Pas d'inquiétude, vous n'aurez pas réécrire les règles pour chaque utilisateur puisque authpf propose d'utiliser des règles par défaut définies dans /etc/authpf/authpf.rules si ce dernier n'existait pas.

Il paraît dès lors évident qu'au moins un de ces deux fichiers doit toujours être disponible quelque soit l'utilisateur qui se connectera. En effet, le shell mettra immédiatement fin à la connexion de l'utilisateur si aucune règle (par défaut ou non) ne peut lui être appliquée. Par conséquent, il est préférable de définir dans /etc/authpf/authpf.rules les règles s'appliquant aux utilisateurs lambda ou de le laisser vide si celles-ci sont directement définies parmi vos règles principales. Nous y venons justement dans la prochaine partie.

Deux macros sont automatiquement disponibles pour la création de vos règles dans les fichiers cités ci-dessus, à savoir :
  • $user_ip : l'adresse IP de la machine depuis laquelle l'utilisateur a établi la connexion vers la passerelle
  • $user_id : l'identifiant (login) de l'utilisateur en question
Vous trouverez plus bas dans l'exemple intitulé Autoriser l'accès au réseau sans fil une utilisation de celles-ci.


3.4. Règles principales

Voyons comment sont gérées les règles dans le fichier principal de configuration de Packet Filter. Ci-dessous une ébauche générique complète qui vous servira de base. Vous trouverez les explications correspondantes après celui-ci :
##### Macros #####
interface = "de0"

# Table contenant la liste des adresses IP des utilisateurs actuellement connectés
table <utilisateurs_authpf> persist

# Ancre pour la traduction d'adresses
# (une adresse IP publique pour l'ensemble du réseau interne)
nat-anchor "authpf/*"
# Ancre pour les redirections
rdr-anchor "authpf/*"
# Ancre pour la traduction d'adresses
# (chaque machine possède une adresse IP publique et privée)
binat-anchor "authpf/*"

##### Filtrage #####
# Règle par défaut : tout bloquer
block drop all

# SSH accepté
pass in quick on $interface inet proto tcp from any \
    to $interface port ssh flags S/SA keep state

# Ancre pour le filtrage
anchor "authpf/*"
La déclaration de la table dont vous avez donné le nom par la directive table dans /etc/authpf/authpf.conf n'est nécessaire que si vous envisagez de l'utiliser. Celle-ci contiendra la liste des adresses IP des machines depuis lesquelles une personne s'est authentifiée à la passerelle. La présence du mot-clé persist est obligatoire pour maintenir son existence en mémoire même si celle-ci venait à être vide.

Il existe quatre types d'ancres, comme montré ci-dessus, dont chacune dépend de la nature des règles qui seront dynamiquement chargées. Cette dernière est indiquée par son préfixe. Toutes ne sont pas requises, vous ne pouvez faire figurer que celles dont vous avez besoin ainsi dans le cas où vous ne faites aucune traduction d'adresse vous pouvez omettre les lignes commençant par nat-anchor et binat-anchor.

Enfin, on notera la présence impérative d'une règle qui autorise le trafic SSH en vue de permettre l'authentification de nos différents utilisateurs.


4. Administration et gestion des utilisateurs


4.1. Gestion des utilisateurs

L'administrateur peut décider de bannir (bloquer) un utilisateur, pour cela il lui suffit de créer le fichier /etc/authpf/banned/$USER, où $USER désigne le login de cet utilisateur. Ce fichier peut avoir pour contenu la raison de cette interdiction et ce message sera affiché lors de la connexion de celui-ci par SSH. En guise d'exemple, nous souhaitons interdire l'utilisateur julp :
echo "Interdit de réseau pour utilisation de réseaux pear to pear." > /etc/authpf/banned/julp
A l'inverse le fichier /etc/authpf/autpf.allow indique les utilisateurs autorisés à avoir recours à authpf en y spécifiant leurs logins. Toutefois, si ce dernier n'est pas présent sur votre système ou bien s'il a pour contenu * alors tout le monde est autorisé à s'y connecter.

Le fichier d'interdiction est toujours cherché avant celui d'autorisation. En clair, l'interdiction prévaut sur l'autorisation. De plus, si authpf n'est pas capable de déterminer l'un ou l'autre alors il met fin à la connexion SSH.

Il est dès lors possible de déterminer deux approches :
  • politique permissive : placer * dans /etc/authpf/authpf.allow et bloquer les utilisateurs au cas par cas
  • politique restrictive : ne lister que les personnes autorisées dans /etc/authpf/authpf.allow

4.2. Lister les utilisateurs actuellement connectés

Le moyen le plus commode pour savoir qui est en train d'utiliser la passerelle et depuis où reste ps. En effet, lorsque la connexion est établie avec succès, authpf modifie le nom de son processus pour y intégrer le login de l'utilisation ainsi que l'adresse IP de la machine cliente. En voici une démonstration :
# ps ax | grep authpf
 1123  p0  Ss+    0:00,05 -authpf: stéphane@192.168.100.1 (authpf)
Il est possible de mettre fin à la connexion de stéphane établie depuis la machine d'adresse 192.168.100.1 en envoyant un signal TERM (15) au processus associé à celle-ci. Dans de tel cas, Authpf se chargera de la suppression des connexions dont l'état a été mémorisé (option keep state et similaires) et des règles spécifiques à cet utilisateur s'il y a lieu, de nettoyer la table.
kill -TERM 1123
# ou encore
kill -15 1123
info Toutefois, pour des questions de praticité, j'ai mis au point un petit programme qui vous permettra de lister et de mettre fin à une session. Celui-ci ne possède aucune dépendance particulière. Les sources sont à votre disposition ici.

4.3. Affichage de messages de bienvenue et d'erreur

Il existe plusieurs méthodes pour afficher un message particulier à l'ensemble des utilisateurs recourant à authpf. Voici la liste des fichiers de message reconnus par authpf :
  • /etc/authpf/authpf.message est un fichier dont le contenu est affiché, lorsqu'il existe, après authentification d'un utilisateur (comprenez par là que celle-ci est fructueuse).

  • /etc/authpf/authpf.problem en sa présence, authpf imprimera son contenu sur la sortie standard lorsqu'il rencontrera une erreur en plus d'être écrite dans le journal système via syslog. Il peut être utilisé afin que le service informatique soit informé de ce problème technique par les usagers.
Voyons un exemple :
echo -n > /etc/authpf/authpf.message

cat > /etc/authpf/authpf.problem
Il semblerait que le système rencontre quelques difficultés techniques.

Reportez ce problème en téléphonant au 0X-XX-XX-XX-XX ou en envoyant un
email à administrateur@domaine.fr afin que nous puissions le résoudre
au plus vite.
^D

cat > /etc/authpf/authpf.motd
Vous pouvez maintenant accéder au réseau. Cette connexion est établie à votre
nom et vous devenez à cet instant responsable du trafic généré à partir de
votre machine.
^D
Ici /etc/authpf/authpf.motd est un fichier qui servira à cultiver l'obscurantisme, c'est-à-dire à ne pas dévoiler une quelconque information au sujet du système d'exploitation (typiquement ses nom et version). Par contre, son recours requiert l'appel à une classe de session et nous complèterons celle que nous avons défini plus haut, dans la partie Attribution groupée : utilisation des classes de session, dans /etc/login.conf tel que :
authpf:\
        :shell=/usr/sbin/authpf:\
        :welcome=/etc/authpf/authpf.motd:\
        :tc=default:
Regénérons la base de données :
cap_mkdb /etc/login.conf
/etc/authpf/authpf.motd sera affiché lorsque tout va bien, c'est pourquoi nous créons /etc/authpf/authpf.message vide.


4.4. Journalisation des évènements

La question de journalisation a été abordée précédemment lors de la présentation de authpf et celle-ci est inactive par défaut. Nous allons modifier /etc/syslog.conf pour la prendre en charge :
!authpf
*.*                                             /var/log/authpf.log
Puis nous procédons ensuite à la création du fichier de log qui sera dédié à authpf :
touch /var/log/authpf.log
chmod 0600 /var/log/authpf.log
Nous terminons par le redémarrage du démon syslog afin que les modifications apportées soient prises en compte dès maintenant :
/etc/rc.d/syslogd restart
# ou
pkill -1 syslogd

4.5. La sécurité autour de SSH


4.5.1. Paramétrage de SSH

Il peut s'avérer nécessaire de reconfigurer le service SSH au niveau de la sécurité puisque SSH est la clé d'accès au réseau pour vos utilisateurs. Voici la liste des options qui nous intéressent :
  • Protocol 2 : seule la version 2 du protocole est acceptée et gérée par sshd. Préférable pour des raisons de sécurité.

  • AllowTcpForwarding no : il est recommandé de refuser les redirections TCP car celles-ci peuvent entraîner le blocage des paquets par PF.

  • ClientAliveInterval 15 : fréquence, en secondes, de vérification de la validité de la connexion du client. Option ne s'appliquant qu'à la version 2 du protocole - valeur par défaut 0, inactive.

    Combinée à la directive ClientAliveCountMax (présentée ci-dessous), elle permet de terminer les connexions inactivent ou qui font l'objet d'une tentative de vol par usurpation (spoofing).

  • ClientAliveCountMax 3 : nombre maximum de vérifications infructueuses acceptées par sshd avant de mettre fin à la session.


4.5.2. Se prémunir contre les attaques par dictionnaire

Les systèmes équipés de la version 3.7 de Packet Filter ou supérieure (ce qui correspond pour FreeBSD à une version supérieure ou égale à 6.0) peuvent bloquer les tentatives d'attaque par dictionnaire à l'aide des règles suivantes :
##### Macros #####
ext_if = "votre interface sur l'extérieur"

##### Déclaration des tables #####
table <ssh-bruteforce> persist [file "/etc/ssh-bruteforce"] # La partie file est optionnelle

##### Règles #####
# [...]

# SSH
block in quick from <ssh-bruteforce>
pass in quick on $ext_if inet proto tcp from any \
    to $ext_if port ssh flags S/SA keep state (max-src-conn-rate 4/30, overload <ssh-bruteforce> flush global)

# [...]
Ainsi, lorsque quelqu'un tentera 4 connexions en moins de 30 secondes (option max-src-conn-rate 4/30) vers ssh, son adresse IP sera ajoutée à la table ssh-bruteforce (option overload) et mettra fin à toutes ses connexions (option flush global).


5. Après la théorie : la pratique par l'exemple

Les exemples suivants sont volontairement simplifiés pour mettre en lumière des applications courantes de authpf ainsi que pour montrer l'intégration des règles relatives à authpf par rapport à celles qui sont statiques.

Les pare-feu dont les configurations sont données en exemple sont marqués sur les schémas ci-dessous sous les traits d'un mur en brique.


5.1. Permettre aux utilisateurs de travailler depuis chez eux

Le directeur d'une petite entreprise spécialisée dans la création de site web souhaite, suite aux demandes répétées de ses salariés, leur permettre de travailler depuis chez eux.

Cet accès se limitera au bastion faisant office de serveur Web et de serveur de gestion de configuration (subversion), leur offrant ainsi la possibilité de récupérer, mettre à jour les sources et visualiser directement le résultat de ces changements (aucune installation locale particulière n'est ainsi requise).

La représentation du réseau est la suivante :

Le fichier /etc/authpf/authpf.rules sera créé vide pour que l'ensemble des règles figure dans un seul et unique fichier. Voici comment il sera écrit :
##### Macros #####
ext_if = "de0"
int_if = "xl0"
tcpflags = "flags S/SFRA"
http_server = "192.168.100.101"
nat_ports = "port 50000:60000"

##### Options #####
set skip on lo0       # L'interface de loopback est ignorée
set block-policy drop # Les paquets sont silencieusement bloqués

##### Déclaration des tables #####
table <utilisateurs_authpf> persist

##### Normalisation des paquets #####
scrub in

##### Traduction d'adresse #####
nat on $ext_if from !($ext_if) \
    to any -> ($ext_if) $nat_ports

##### Redirections #####
rdr on $ext_if inet proto tcp from <utilisateurs_authpf> \
    to ($ext_if) port http -> $http_server port http

##### Règles #####
# Par défaut : tout bloquer
block all

# SSH autorisé (nécessaire pour assurer l'authentification)
pass in quick on $ext_if inet proto tcp from any \
    to ($ext_if) port ssh $tcpflags keep state

# HTTP autorisé de et vers uniquement les utilisateurs authentifiés
pass in quick on $ext_if inet proto tcp from <utilisateurs_authpf> \
    to $http_server port http $tcpflags keep state
pass out quick on $int_if inet proto tcp from <utilisateurs_authpf> \
    to $http_server port http $tcpflags keep state

# Trafic TCP traduit autorisé à sortir
# (les réponses associées doivent être acceptées)
pass in quick on $ext_if inet proto tcp from $int_if:network \
    to any $tcpflags keep state
pass out quick on $ext_if inet proto tcp from $ext_if $nat_ports \
    to any $tcpflags keep state

# Ancre permettant à authpf de charger dynamiquement des règles propres à chaque utilisateur
anchor "authpf/*" in on $ext_if

5.2. Autoriser l'accès au réseau sans fil

Un établissement scolaire offre un accès sans-fil pour permettre aux élèves comme aux enseignants de consulter des sites Internet. Ce trafic est contrôlé en ayant recours à des serveurs de mandatement internes pour les protocoles HTTP et DNS et doit donc obligatoirement passer par eux. De plus, ces utilisateurs devront montrer patte blanche avant d'accéder aux ressources réseau mises à leur disposition.

Les administrateurs systèmes et réseaux, qui seront également amenés à recourir au sans-fil pour travailler, souhaitent disposer d'un accès administratif (SSH) vers les machines qui assurent des services mandataires.

Le réseau est représenté de manière simplifiée comme suit :

Les règles générales sont, par conséquent, définies telles que :
##### Macros #####
ext_if = "ath0"
int_if = "sis0"
tcpflags = "flags S/SFRA"
dns_server = "192.168.100.101"
http_proxy = "192.168.100.102"

##### Options #####
set skip on lo0       # L'interface de loopback est ignorée
set block-policy drop # Les paquets sont silencieusement bloqués

##### Déclaration des tables #####
table <utilisateurs_authpf> persist

##### Normalisation des paquets #####
scrub in

##### Règles #####
# Par défaut : tout bloquer
block all

# DHCP autorisé pour des raisons de commodité
pass in quick on $ext_if inet proto tcp from any \
    to $ext_if port bootpc $tcpflags keep state

# SSH autorisé (nécessaire pour assurer l'authentification)
pass in quick on $ext_if inet proto tcp from $ext_if:network \
    to $ext_if port ssh $tcpflags keep state

# HTTP autorisé vers le mandataire pour les utilisateurs authentifiés
pass in quick on $ext_if inet proto tcp from <utilisateurs_authpf> \
    to $http_proxy port { http https } $tcpflags keep state

# DNS autorisé vers notre serveur DNS (cache et forwarding) pour les utilisateurs authentifiés
pass in quick on $ext_if inet proto udp from <utilisateurs_authpf> \
    to $dns_server port domain keep state

# Ancre permettant à authpf de charger dynamiquement des règles propres à chaque utilisateur
anchor "authpf/*" in on $ext_if
Enfin, nous attribuons des règles spécifiques à l'administrateur dupont.j lui permettant d'avoir un accès SSH vers le serveur DNS et le mandataire HTTP depuis son portable équipé de la technologie Wifi. Pour cela nous créons /etc/authpf/users/dupont.j/authpf.rules pour lui donner cet accès :
##### Macros #####
ext_if = "ath0"
tcpflags = "flags S/SFRA"
dns_server = "192.168.100.101"
http_proxy = "192.168.100.102"

# SSH permis vers le serveur DNS et le proxy
pass in quick on $ext_if inet proto tcp from $user_ip \
    to { $dns_server $http_proxy } port ssh $tcpflags keep state
warning Veillez à recopier ou remplacer les macros que vous souhaitez utiliser dans de tels fichiers de règles car celles-ci ne sont pas héritées du fichier de règles principales.

6. Conclusion


6.1. Epilogue

Authpf est un programme fiable basé sur le mécanisme appelé ancre de Packet Filter qui permet de charger dynamiquement des règles. Cette fiabilité est en grande partie assurée par le protocole SSH dont il ne faut pas, par conséquent, négliger la configuration. Sa capacité à journaliser les évènements de démarrage et fin de session raviront sans aucun doute les administrateurs.

Toutefois, sous forme d'interpréteur de commande, authpf restreint l'utilisation du compte utilisateur à cet usage : il ne sera en effet impossible d'utiliser SSH pour exécuter des commandes.

Récapitulatif des sources associées :
Liens Developpez :
Liens externes :

6.2. Remerciements

J'adresse mes remerciements à Olivier Regnier pour sa relecture attentive.

Mais également aux bénévoles de la section Linux Olivier Regnier, ovh et gorgonite pour leurs suggestions constructives et leur soutien.



Valid XHTML 1.1!Valid CSS!

Copyright © 2007 julp. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.

Responsables bénévoles de la rubrique BSD : julp et Olivier Régnier - Contacter par EMail :
Vos questions techniques : forum d'entraide BSD - Publiez vos articles, tutoriels et cours
et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones
Nous contacter - Copyright © 2000-2008 www.developpez.com - Legal informations.