Tag Archive for 'ldap'

NAT authentifié avec authpf

A mon sens le NAT est une horrible (mais nécessaire) verrue. Le pire étant quand même lorsque l’on ose qualifier de sécurité le fait de NATer des machines : “On peut initier des connexions vers l’exterieur mais pas l’inverse“. C’est vrai, sauf que les machines compromises initient des connexions vers l’extérieur pour signifier à leur botnet de raccordement leur disponibilité. Devant garantir un minimum de traçabilité de ces accès, j’ai décidé de mettre en place une passerelle de NAT authentifié avec authpf. Authpf permet de jouer des règles PF via les ancres lors d’une connexion SSH. The big picture :




La machine authpf est un OpenBSD 4.6. La problématique est que cette machine n’est pas notre pare-feu principal (snif …). Les flux doivent donc être routés vers cette machine au niveau du pare-feu en fonction du réseau source. Ceci n’est possible qu’en appliquant du “policy routing” qui permet d’appliquer des règles de routage en fonction d’autres critères que le réseau (ou la machine) de destination. On définit ensuite le routeur externe comme passerelle du NAT authentifié et c’est gagné.

1. Configuration de la passerelle

Au niveau de la passerelle, il faut ajouter les lignes suivantes au niveau du rc.conf :

pf=YES
pf_rules=/etc/pf.conf.local

J’aime bien mettre mes règles PF dans un fichier à part.

Examinons le pf.conf.local (seule les sections intéressantes sont affichées) :

set skip on lo
block in log all
block out log all
 
nat-anchor "authpf/*"
rdr-anchor "authpf/*"
binat-anchor "authpf/*"
 
anchor "authpf/*"

On laisse tout passer sur 127.0.0.1 (lo), ensuite on bloque tout et on loggue en entrée et en sortie. Enfin, on pose les ancres pour ajouter dynamiquement les règles des utilisateurs authpf.

2. Création des utilisateurs

Dans tout organisme moderne, on dispose d’un LDAP avec les utilisateurs dedans (et surtout un uid associé à un userPassword). Dans ce cas, on peut connecter son NAT authentifié au LDAP. Pour ce faire, deux options : ypldap ou login_ldap. J’ai choisi la méthode via login_ldap car je ne dispose pas de vrai posixAccount dans mon LDAP et des informations telles que l’UID sont nécessaires. Voila ma section dans le /etc/login.conf pour associer LDAP et authpf :

ldap-authpf:\
        :auth=-ldap:\
        :x-ldap-server=monldap.mondomaine:\
        :x-ldap-basedn=ou=People,dc=mondomaine:\
        :x-ldap-binddn=cn=toto,ou=user4bind,dc=mondomaine:\
        :x-ldap-bindpw=azerty:\
        :x-ldap-filter=(&(objectClass=inetOrgPerson)(uid=%u)):\
        :welcome=/etc/motd.authpf:\
        :shell=/usr/sbin/authpf:\
        :tc=default:

Pour créer les utilisateurs :
useradd -L ldap-authpf -d /var/empty -s /usr/sbin/authpf -r 1500..3000 -g =uid pastounus
Cela crée l’utilisateur pastounus avec une home bidon (-d /var/empty) qui va utiliser la “login class” ldap-authpf (-L ldap-authpf) ainsi que le shell authpf (-s /usr/sbin/authpf) et un groupe privé UPG (-g =uid).

3. Utilisation

On ajoute les règles de l’utilisateur pastounus dans le fichier /etc/authpf/users/pastounus/authpf.rules :

int_if=bge0
 
nat pass log on $int_if from $user_ip to any -> XXX.XXX.XXX.XXX

Et voila : une fois authentifié, pastounus est naté ! On notera quand même qu’il convient d’ajouter les routes de retour sur la passerelle pour les réseaux derrière le NAT authentifié. La passerelle devra également proxifier les réponses ARP pour les IP vers lesquelles elle effectue les translations. Tout cela se passe dans le rc.local. Dans notre exemple XXX.XXX.XXX.XXX est l’adresse de NAT, YYY.YYY.YYY.YYY est le réseau privé à NATer et ZZZ.ZZZ.ZZZ.ZZZ est la patte du pare-feu sur laquelle est raccordée la passerelle.

# Add your local startup actions here.
 
echo '.'
route add -net YYY.YYY.YYY.YYY/24 ZZZ.ZZZ.ZZZ.ZZZ
 
arp -s XXX.XXX.XXX.XXX @mac_nat_auth pub

Installation / Mutualisation de Trac (sous FreeBSD)

Un petit post pour donner un retour sur l’installation et administration de Trac. Ce projet propose d’habiller un dépôt subversion avec un wiki, une gestion de tickets etc. Le tout est réalisé en python (chouette une application web sans PHP). Dans un cadre professionnel, j’ai du mettre en œuvre une solution de gestion de versions pour différents projets. J’ai retenu subversion, trac et apache sous FreeBSD comme briques de cette infrastructure. J’ai choisi FreeBSD car les ports sont très proches des versions courantes des logiciels (et pour des application web c’est important) et surtout Jail est intégré au système de base (stabilité des mises à jour). Au niveau de l’existant, je disposais d’un serveur OpenLDAP (avec les comptes utilisateurs dedans). j’ai décidé de faire mon Jean-Pierre Troll et de n’utiliser aucun des systèmes “hype” de virtualisation (non pas que je les aimes pas, c’est juste que c’était un peu overkill par rapport à mes besoins). La manière de mutualiser le système a directement été dictée par la façon dont sont structurés les systèmes d’informations dans les universités. Petit rappel : chaque université dispose d’un CRI (Centre de Ressources Informatique) qui s’occupe des services mutualisés (mail, web, annuaire et dans notre cas subversion / trac). Ces services sont utilisés par différentes composantes. J’ai donc décidé de dédié un environnement confiné à chaque composante. Un environnement confiné est un Jail FreeBSD. C’est presque comme une machine virtuelle à part qu’on a une seule instance du noyau en exécution (raccourci très très grossier, que les gurus me pardonnent). Il en résulte un confinement un peu plus poreux qu’avec des systèmes comme XEN (para-virtualisation) ou VMWare (virtualisation complète). la mise en œuvre basique d’un Jail FreeBSD est détaillée ici. Je considère donc que vous avez un FreeBSD rutilant, un serveur OpenLDAP qui fonctionne et un Jail dans lequel déployer les instances de Subversion / Trac. Pour toutes les manipulation l’identifiant choisi est le mail et pas le login UNIX (le mail est bien pus générique). Let’s go !

Round 1 : Apache

Apache est LE composant principal de l’installation. C’est lui qui va servir de base pour l’authentification des utilisateurs sur Trac et Subversion. Apache va aussi réaliser l’affichage du site Trac via le mod_python. Nous allons utiliser le module LDAP fourni avec Apache pour l’authentification. un coup de portinstall :

portinstall www/apache22

Ne pas oublier d’activer LDAP dans apr* et l’authentification LDAP dans apache.

portinstall www/mod_python3
portinstall trac
portinstall mod_security

Le mod_security est facultatif. Nous avons vu qu’un Jail était dédié à une composante. Or une composante peut avoir plusieurs activités (recherche, enseignements, valorisation etc.). L’incidence au niveau informatique est que l’on peut avoir des URL différentes pour ces activités. Nous allons donc utiliser les virtualhost Apache. Considérons le virtualhost trac01.garnett.fr (ça change de je te foo sur le bar). Pour l’authentification LDAP, un précédent post donne la démarche. Une fois cette étape validée, on peut passer à la suite. J’exclu volontairement la partie SSL entre le virtualhost et le serveur LDAP pour plus de lisibilité.

Round 2 : Subversion

Toutes les interactions avec le serveur Subversion se feront sur HTTPS. L’accès en HTTPS à un serveur Apache est largement documenté sur Internet. Nous avons donc la configuration suivante :

<Virtualhost *:443> 
        <Location /svn> 
        DAV svn 
        SVNParentPath /usr/local/svn-trac/svn_of_trac01
        AuthzSVNAccessFile /usr/local/svn-trac/acls/acl-repo 
        AuthType Basic 
        AuthName "SVN"
        AuthBasicProvider "ldap" 
        AuthLDAPURL "ldap://mon_ldap/dc=example,dc=org?mail?sub?(objectClass=inetOrgPerson)" 
        authzldapauthoritative Off 
        require valid-user 
        </Location> 
</Virtualhost>

Cette section active DAV (DAV svn) pour la location /svn. Elle donne aussi le répertoire parent des dépôts subversions (SVNParentPath /usr/local/svn-trac/svn_of_trac01). Ce répertoire doit être readable par Apache. Les sous répertoires qui constituent donc les projets doivent donc être readable et writable par Apache. Il reste un détail : les ACLs sur les différents projets (AuthzSVNAccessFile /usr/local/svn-trac/acls/acl-repo). Ce fichier va contenir les différents droits sur les dêpots. Voyons un exemple :

[repo01:/] 
nico@bidule.fr = rw 
toto@bidule.fr = r
tutu@machin.fr = r

Nico à tous les droits tandis que toto et tutu ont juste la lecture sur la racine du projet repo01 situé dans /usr/local/svn-trac/svn_of_trac01. J’ai décidé de restreindre l’accès a ce fichier en chrootant un utilisateur dédié dans le répertoire /usr/local/svn-trac/acls. Très simple, il faut ajouter dans /etc/ssh/sshd_config :

[...]
AllowUsers  mon_user
[...] 
Subsystem	sftp	internal-sftp
[...]
Match User mon_user
	ForceCommand internal-sftp
	ChrootDirectory /usr/local/svn-trac/acls

Attention aux espaces dans le fichier de configuration, notamment sur le “ForceCommand internal-sftp”. Le moindre espace terminal fait merder le tout. Pour le chroot, tout les répertoires de niveau supérieurs doivent appartenir à root. Cette manipulation permet à un informaticien de composante de mettre à jour ses ACLs de manière autonome sans compromettre l’intégrité du serveur (Jail + chroot SFTP).

Pour tester le dêpot depuis une machine lambda :

# svn co https://trac01.garnett.fr/svn/repo01 --username nico@garnett.fr

Round 3 : Trac

La partie la plus simple. J’ai repris la documentation du site officiel sur l’installation avec le mod_python. La seule différence est que je force l’utilisateur à s’authentifier sur HTTPS et l’incite à rester sur un canal chiffré après authentification. Je donne ma configuration en commentant ce qui diffère par rapport à la documentation originale :

<VirtualHost *:80> 
        ServerName trac01.garnett.fr
        DocumentRoot /usr/local/www-trac/trac01 
        ErrorLog /var/log/httpd-error-www-trac01.log 
        CustomLog /var/log/httpd-access-www-trac01.log combined 
        Options none 
 
        RedirectMatch /([^/]+)/login https://trac01.garnett.fr/$1/login 
 
        <Location /> 
        SetHandler mod_python 
        SetEnv PYTHON_EGG_CACHE "/usr/local/www-cache/eggs" 
        PythonInterpreter main_interpreter 
        PythonHandler trac.web.modpython_frontend 
        PythonOption TracEnvParentDir /usr/local/www-trac/trac01 
        PythonOption TracUriRoot / 
        </Location> 
</VirtualHost> 
 
<Virtualhost *:443> 
        ServerName trac01.garnett.fr 
        DocumentRoot /usr/local/www-trac/trac01 
        ErrorLog /var/log/httpd-error-www-tractrac01-ssl.log 
        CustomLog /var/log/httpd-access-www-tractrac01-ssl.log combined 
        Options none 
 
        SSLEngine On 
 
        SSLCertificateFile /usr/local/etc/apache22/ssl/trac01/server.crt 
        SSLCertificateKeyFile /usr/local/etc/apache22/ssl/trac01/server.key 
 
        <Location /> 
        SetHandler mod_python 
        SetEnv PYTHON_EGG_CACHE "/usr/local/www-cache/eggs" 
        PythonInterpreter main_interpreter 
        PythonHandler trac.web.modpython_frontend 
        PythonOption TracEnvParentDir /usr/local/www-trac/trac01 
        PythonOption TracUriRoot / 
        </Location> 
        <LocationMatch "/[^/]+/login"> 
        SSLRequireSSL 
        SetHandler mod_python 
        SetEnv PYTHON_EGG_CACHE "/usr/local/www-cache/eggs" 
        PythonInterpreter main_interpreter 
        PythonOption TracEnvParentDir /usr/local/www-trac/trac01 
        AuthType Basic 
        AuthName "Trac" 
        AuthBasicProvider "ldap" 
        AuthLDAPURL "ldap://mon_ldap/dc=example,dc=org?mail?sub?(objectClass=inetOrgPerson)" 
        authzldapauthoritative Off 
        require valid-user 
        </LocationMatch> 
</VirtualHost>

La différence part rapport à la documentation originale est le passage sur HTTPS pendant et après l’authentification. La directive RedirectMatch permet ce genre de chose. La regexp “/([^/]+)/login https://trac01.garnett.fr/$1/login” redirige l’URL http://trac01.garnett.fr//login vers https://trac01.garnett.fr//login. Sauf si le client réecrit l’URL dans son navigateur, il est en HTTPS jusqu’à la fin de sa session. J’ai fait comme ça car un cookie transite de temps en temps entre le navigateur et le serveur une fois le client authentifié.

Conclusion

La solution ne serait pas complète sans un moyen simple d’ajouter des utilisateurs externes (qui n’ont pas de mail @garnett.fr). Cela peut être fait de manière super simple avec phpldapadmin et ce post qui proposait de merger une branche répliquée avec une branche writable pour enrichir un annuaire dédié avec des comptes locaux à l’application. Cette partie fera l’objet d’un autre post.

Fusionner des bases de données OpenLDAP

2 posts la même journée, quelle folie ! Ce deuxième post donne un moyen de résoudre le problème suivant sur OpenLDAP. J’ai une base d’utilisateur sur un serveur central (ou=people,dc=example,dc=org). Cette base est répliquée sur un autre serveur via syncrepl. Ce serveur esclave servira à authentifier des gens sur un serveur subversion HTTPS. Seulement, on aimerait pouvoir ajouter des gens à cette base sans recréer une nouvelle instance slapd et utiliser les overlay proxy / meta. Un truc genre ou=extern,dc=example,dc=org nous irait à merveille. On va donc utiliser le mécanisme de glue pour faire ça. Deux bases bdb seront définies : une avec le suffix ou=people,dc=example,dc=org (le replica) et l’autre avec dc=example,dc=org (pour les ajouts locaux). Éditer le slapd.conf :

# Base replica
database             bdb
suffix                  ou=people,dc=example,dc=org
rootdn                cn=admin,dc=example,dc=org
# Pour activer la "glue"
subordinate
 
# Infos de syncrepl + index
[...]
 
# Base parente (inscriptible)
database             bdb
suffix                  dc=example,dc=org
rootdn                cn=admin,dc=example,dc=org
rootpw               secret
 
# Index
[...]

Les deux instances doivent avoir le même rootdn et les bases “subordinate” ne doivent pas avoir de rootpw. A noter que l’on peut utiliser ça avec des bases meta (slapo-meta), ldap (slapd-ldap) etc. Dans des topologies de répartition de charge c’est assez pratique. OpenLDAP c’est vraiement un truc que j’exploite à 5% de ce que ça sait faire …

Clés USB et comptes LDAP

L’utilisation d’une clé USB sous Ubuntu par un utilisateur lambda est conditionée par son appartenance (ou non) au groupe “plugdev”. Plusieurs solutions :
- Passer sur toutes les machines ajouter les utilisateurs dans le groupe plugdev : autant se tirer une balle tout de suite.
- Faire un groupe posix dans LDAP “plugdev” et mettre les gens dedans. L’objection principal que je vois est que le GID de ce groupe est local (donc bas) : les GID distribués par LDAP doivent être sur une plage supérieure.
- Ajouter dynamiquement l’utilisateur dans le groupe “plugdev” après l’authentification.

J’ai retenu la dernière solution. On peut faire ça en utilisant la PAM pam_group.so.

/etc/security/group.conf

*;*;*;Al0000-2400;cdrom,floppy,plugdev

Cette ligne nous dit en gros que n’importe qui qui se connecte sur la machine à n’importe quelle heure et par n’importe quel moyen (ssh, login en mode texte, [k|x|g]dm etc.) se voit ajouter aux groupes locaux cdrom, floppy et plugdev.

/etc/pam.d/common-auth

auth    optional        pam_group.so
auth    sufficient      pam_ldap.so
auth    requisite       pam_unix.so nullok_secure
auth    optional        pam_smbpass.so migrate missingok

On active la pam_group qui va réaliser les actions définies dans /etc/security/group.conf. Attention a bien la placer en tête de fichier.

Enfin dans /etc/dbus-1/system.d/hal.conf, il faut remplacer “deny” par “allow” à la ligne :

<deny send_interface="org.freedesktop.Hal.Device.Volume"/>

Sudo et LDAP

Arno (encore lui) m’a indiqué une feature interessante de sudo : on peut stocker le sudoers dans LDAP.
Fini les /etc/sudoers à gérer sur chaques machines !

Partie serveur LDAP

Un petit exemple vaut mieux qu’un long discours. Ici l’utilisateur toto veut invoquer n’importe quelle commande en tant que “root” (j’utilise cette règle dans des salles de libre service sous Ubuntu 8.04).

dn: ou=sudoers,dc=example,dc=net
objectclass: organizationalUnit
ou: sudoers
 
dn: cn=defaults,ou=sudoers,dc=example,dc=net
objectClass: top
objectClass: sudoRole
cn: defaults
description: Default sudoOption's go here
sudoOption: logfile=/var/log/sudolog
 
dn: cn=root,ou=sudoers,dc=example,dc=net
objectClass: top
objectClass: sudoRole
cn: root
sudoUser: root
sudoHost: ALL
sudoCommand: ALL
 
dn: cn=toto_to_root,ou=sudoers,dc=example,dc=net
objectClass: top
objectClass: sudoRole
cn: toto_to_root
sudoUser: toto
sudoHost: ALL
sudoCommand: ALL

Un “ldapadd” pour envoyer la sauce et c’est fini.

Partie client Ubuntu 8.04

On installe sudo-ldap (par défaut sudo n’intègre pas le support de LDAP, la version de ce paquet est compilée avec les librairies LDAP).

[root@client01 #] apt-get install sudo-ldap

Et effectivement :

[root@client01 #] ldd `which sudo`
linux-gate.so.1 => (0xb7f48000)
libpam.so.0 => /lib/libpam.so.0 (0xb7f2a000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7f26000)
libldap_r-2.4.so.2 => /usr/lib/libldap_r-2.4.so.2 (0xb7ee5000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7d96000)
liblber-2.4.so.2 => /usr/lib/liblber-2.4.so.2 (0xb7d89000)
/lib/ld-linux.so.2 (0xb7f49000)
libresolv.so.2 => /lib/tls/i686/cmov/libresolv.so.2 (0xb7d76000)
libsasl2.so.2 => /usr/lib/libsasl2.so.2 (0xb7d5f000)
libgnutls.so.13 => /usr/lib/libgnutls.so.13 (0xb7ce8000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7cd0000)
libtasn1.so.3 => /usr/lib/libtasn1.so.3 (0xb7cc0000)
libz.so.1 => /usr/lib/libz.so.1 (0xb7cab000)
libgcrypt.so.11 => /lib/libgcrypt.so.11 (0xb7c5e000)
libgpg-error.so.0 => /lib/libgpg-error.so.0 (0xb7c59000)

Ensuite, il faut rensigner le nsswitch.conf :

sudoers:        files ldap

Puis le /etc/sudoers doit contenir uniquement le réglage suivant :

Defaults ignore_local_sudoers

Enfin, il faut ajouter la configuration suivante dans votre ldap.conf :

sudoers_base ou=sudoers,dc=example,dc=net

On note que si vous avez un fichier libnss-ldap.conf il est parsé par sudo-ldap à la place du ldap.conf. Pour mes configurations j’ai un fichier “réel” /etc/ldap/ldap.conf, /etc/ldap.conf et /etc/libnss-ldap.conf sont des liens. Mes fichiers sont cohérents.

Voili, voilou

De l’utilisation d’autofs …

Un petit post sur un truc un peu rétro mais au combien pratique : autofs.
J’ai constaté un truc qui revient souvent sur le net : l’utilisation des caractères jocker pour les montages de répertoires utilisateurs.

Je pense que c’est le mal.

En fait je faisais ça avant et c’est vrai que c’est assez pratique mais lorsqu’une machine demande un montage d’un fichier issu d’un répertoire utilisateur qui n’existe plus c’est le drame.

Ne riez pas, il y a vraiment des gens qui utilisent un compte utilisateur “env_default” pour y spécifier leurs paramètres par défaut (bashrc, profile etc.). En plus pour bien faire, ce compte n’est pas verrouillé et le mot de passe associé est “env_default” (et la quand on sort tout frais moulu d’une formation de sécurité informatique on tombe de haut !). Ainsi lorsque toto ouvre sa session le répertoire env_default est aussi monté car les fichiers du compte toto incluent ceux de env_default. Et ça produit plein de trucs dégueulasses dans les logs …

Aussi j’ai avantageusement remplacé les autofs avec caractère jocker par mon LDAP. En effet, on peut stocker les maps automount dans un LDAP. Ainsi j’ai de jolis logs et il faut juste penser à créer la map de l’utilisateur au moment de la création du compte. Comment faire ? Simple :

Coté client :

[root@machine_de_toto ~]# apt-get install autofs-ldap
[root@machine_de_toto ~]# vi /etc/nsswitch.conf

...
automount:      files ldap
...

Hop, votre client est maintenant conscient qu’il doit aller chercher ses maps sur un serveur LDAP.
Pour les puristes, on peut aussi spécifier le rdn de l’endroit ou se trouvent les maps mais je ne suis pas un puriste (grouik, grouik) !

Coté serveur LDAP :

On commence par créer l’arborescence pour autofs-ldap, ensuite il suffit d’ajouter les répertoires à auto-monter au moment de la création du compte.

1. Le /etc/auto.master :

Créons le ldif suivant :

ou=auto.master,ou=linux,o=autofs,dc=example,dc=domain,dc=org
ou: auto.master
objectClass: top
objectClass: automountMap

Je crée VOLONTAIREMENT une arborescence pour Linux car MacOS utilise un format différent pour stocker ses auto-montages dans un LDAP. Après investigations il se trouve que MacOS emploi le format autofs5 intégré dans leur Active Directo oups ! Open Directory. On ne peut pas rétrograder en autofs4. On ne peut pas non plus integrer la partie autofs de Open Directory dans les schémas LDAP car des objets ont le même nom (mais pas la même définition). Bref pour ceux qui en doutaient encore MacOS X à part faciliter mon transit ça fait pas grand chose.

On crée l’entrée pour la racine des répertoires utilisateurs :

cn=/home/users,ou=auto.master,ou=linux,o=autofs,dc=example,dc=domain,dc=org
objectClass: automount
cn: /home/users
automountInformation: ldap:ou=auto.home,ou=linux,o=autofs,dc=example,dc=domain,dc=org

Rien de bien nouveau sous le soleil sauf peut être pour la partie automountInformation. Cette partie peut inclure le nom du serveur LDAP ou aller chercher les montages. A mon avis c’est une connerie : si jamais vous ajoutez en dur un serveur LDAP, il faudra modifier votre enregistrement si vous ajoutez des replicas de secours. Il vaut mieux laisser autofs-ldap utiliser le ldap.conf du client.

Enfin l’OU qui va contenir nos montages utilisateurs :

dn: ou=auto.home,ou=linux,o=autofs,dc=example,dc=domain,dc=org
ou: auto.home
objectClass: top
objectClass: organizationalUnit
structuralObjectClass: organizationalUnit

2. Utilisateur final :

On a plus qu’a créer l’entrée dans l’OU auto.home.

cn=toto,ou=auto.home,ou=linux,o=autofs,dc=example,dc=domain,dc=org
objectClass: automount
automountInformation: -rw,hard,intr,nosuid filer:/home/users/toto
cn: toto

And … Voila !!

Mon dieu que j’aimerais avoir un kerberos pour pouvoir passer en NFSv4 …

MacOS 10.5 et OpenLDAP START_TLS

Voila deux jours que je tentais de forcer une authentification depuis MacOS 10.5 sur un serveur slapd configuré en start_tls. Le start_tls fonctionnait avec le /etc/openldap/ldap.conf adéquat et les outils ldap* (search, modify …). Confiant, je lance le cliquodrome :

Aller -> utilitaires -> utilitaires d’annuaires :
Mon serveur LDAP apparaît avec un joli point vert (“ce serveur répond normalement”).

services -> LDAPv3 :
Activer : OK
Nom de la config : bla bla
Nom serveur : mybigldap
Mappage LDAP rfc 2307 (Unix)
SSL : OK
Propriétées activées :
- Chiffrer via SSL
- Utiliser le port personnalisé 389

C’est l’erreur, j’ai supposé (ne jamais supposer en administration système !) que ça allait se démerder et passer sur du start_tls côté client comme j’avais demandé le chiffrement SSL.

Seulement, côté serveur dans le /var/log/debug, aucune mention de start_tls.
Juste des message du style :

Jun 24 10:41:41 mybigldap slapd[15075]: conn=1000 fd=47 closed (connection lost)
Jun 24 10:41:56 mybigldap slapd[15075]: conn=999 fd=31 closed (connection lost)

Juste après les ACCEPT relatifs à mon client MacOS X.
En conclusion, ça se démerde pas, ça fait vraiment du SSL.
Il faut donc lancer une instance du serveur (voir /etc/default/slapd) en SSL (ldaps sur port 636).

OpenBSD 4.3 en client LDAP

Dans le cadre d’une migration de NIS vers LDAP j’ai du lier mes passerelles OpenBSD 4.3 au nouvel annuaire LDAP.
Pour les systèmes “pingouin inside” ca va tout seul, par contre pour le poisson piquant c’est pas la même.

1. Suppression du NIS (headshot !)

# kill -TERM PID de ypbind
# rm /etc/defaultdomain
# rm -rf /etc/yp
# rm -rf /var/yp/binding/domaine_nis.version_nis

2. Installation des paquets

# pkg_add openldap-client
# pkg_add ldap_login

Le paquet openldap-client fourni les utilitaires ldap* (search, add, modify …) ainsi que le fichier de configuration ldap.conf que l’on va s’empresser d’écraser. Le ldap_login étend le fichier /etc/login.conf avec un classe de comptes ldap contenant les paramètres classiques de localisation du (des) serveur(s) LDAP (hostname, version de LDAP, certificats …).

3. Configuration du client LDAP

Tout se passe au niveau du fichier /etc/openldap/ldap.conf :

BASE    dc=my,dc=example,dc=com
URI     ldap://fake_server.my.example.com
 
TLS_CACERT      /etc/openldap/ssl/server_cert.pem
TLS_REQCERT   demand
 
ldap_version 3
ssl start_tls
scope sub
bind_policy soft

Il faut renseigner le login.conf pour que le programme ldap_login puisse réaliser l’opération de bind sur l’annuaire LDAP au moment de l’authentification du compte sur le système. Voici un exemple :

#
# LDAP
#
ldap:\
        :auth=-ldap:\
        :x-ldap-server=fake_server.my.example.com,,starttls:\
        :x-ldap-server-alt=fake_server.my.example.com,,starttls:\
        :x-ldap-basedn=ou=unix_accounts,o=people,dc=my,dc=example,dc=com:\
        :x-ldap-uscope=sub:\
        :x-ldap-noreferrals:\
        :x-ldap-filter=(&(objectclass=posixAccount)(uid=%u)):

On ne renseigne pas les attributs relatifs au chiffrement SSL dans le login.conf car par défaut il les déduit du ldap.conf.

4. Création des utiisateurs

OpenBSD n’intègre pas de système comparable au NSS. Les comptes doivent être crées via la commande useradd en utilisant la classe de login “ldap”. J’ai fait un petit script que l’on peut récuperer ici pour synchroniser les comptes.