Hébergement virtuel multi domaine basé sur LDAP

Posted by

1. Introduction

Nous étudierons dans cette documentation succinte comment mettre en place un serveur DNS, FTP et mail qui gèrera plusieurs domaines indépendant en centralisant l’authentification dans un annuaire LDAP.
De plus, ces domaines seront virtuels. C’est à dire qu’on ne créera pas un compte UNIX dédié pour chaque compte. En route!

2. Le serveur LDAP

2.1 Installation et configuration

debian:~# apt-get install slapd ldap-utils

Mot de passe administrateur : xxxx

2.2 Structure de base

Le serveur Openldap fourni par Debian génère une partition d’annuaire dc=domaine,dc=suffixedns. Par exemple, dans mon cas le nom de domaine à l’installation de slapd est morot.local, alors la partition d’annuaire sera dc=morot,dc=local et l’administrateur LDAP sera cn=admin,dc=morot,dc=local.

Le contenu de l’annuaire sera organiser dans es Unité Organisationnelles (OU) suivantes :

  • dnsdomains : pour les noms de domaine
  • mails : pour les comptes mails
  • ftp : pour les comptes FTP
  • relaydomains : pour les noms de domaine pris en charge par le serveur de mail

On va ainsi créer le fichier LDIF ci-dessous :

dn: ou=dnsdomains,dc=morot,dc=local
objectclass: top
objectclass: organizationalUnit
ou: dnsdomains

dn: ou=mails,dc=morot,dc=local
objectclass: top
objectclass: organizationalUnit
ou: mails

dn: ou=relaydomains,dc=morot,dc=local
objectclass: top
objectclass: organizationalUnit
ou: relaydomains

dn: ou=ftpusers,dc=morot,dc=local
objectclass: top
objectclass: organizationalUnit
ou: ftpusers

Et l’ajouter de cette façon :

debian:~# ldapadd -h localhost -W -x -D cn=admin,dc=morot,dc=local -f ou_base.ldif
Enter LDAP Password:
adding new entry "ou=dnsdomains,dc=morot,dc=local"

adding new entry "ou=mails,dc=morot,dc=local"

adding new entry "ou=relaydomains,dc=morot,dc=local"

adding new entry "ou=ftpusers,dc=morot,dc=local"

3.Configuration du serveur DNS

Le serveur DNS PowerDNS a l’avantage de posséder un système de backend réellement efficace comparé à Bind. Le backend LDAP de Bind par exemple, charge entièrement les zones en mémoire au démarrage et n’interroge pas dynamiquement le serveur LDAP. Passons à sa mise en oeuvre, sachant que vous trouverez toute la documentation originale à cette url : http://www.linuxnetworks.de/doc/index.php/PowerDNS_LDAP_Backend.

Installation de PowerDNS :

debian:~# apt-get install pdns-server pdns-recursor pdns-backend-ldap

Il ne reste plus qu’à ajouter à OpenLDAP le schéma ci-dessous :

3.1 Population de l’annuaire

Exemple de zone directe domaine.com et de zone de recherche inverse pour le réseau 192.168.69.0/24 :

dn: dc=domaine.com,ou=dnsdomains,dc=morot,dc=local
objectclass: top
objectclass: dcobject
objectclass: dnsdomain
objectclass: domainrelatedobject
dc: domaine.com
soarecord: ns.domaine.com hostmaster@domaine.com 1 1800 3600 86400 7200
nsrecord: ns.domaine.com
mxrecord: 10 mail.domaine.com
associateddomain: domaine.com 

dn: dc=ns,dc=domaine.com,ou=dnsdomains,dc=morot,dc=local
objectclass: top
objectclass: dnsdomain
objectclass: domainrelatedobject
dc: ns
arecord: 192.168.69.11
associateddomain: ns.domaine.com

dn: dc=ldap,dc=domaine.com,ou=dnsdomains,dc=morot,dc=local
objectclass: top
objectclass: dnsdomain
objectclass: domainrelatedobject
dc: ldap
arecord: 192.168.69.11
associateddomain: ldap.domaine.com

dn: dc=www,dc=domaine.com,ou=dnsdomains,dc=morot,dc=local
objectclass: top
objectclass: dnsdomain
objectclass: domainrelatedobject
dc: www
arecord: 192.168.69.11
associateddomain: www.domaine.com

dn: dc=mail,dc=domaine.com,ou=dnsdomains,dc=morot,dc=local
objectclass: top
objectclass: dnsdomain
objectclass: domainrelatedobject
dc: mail
arecord: 192.168.69.11
associateddomain: mail.domaine.com

dn: dc=ftp,dc=domaine.com,ou=dnsdomains,dc=morot,dc=local
objectclass: top
objectclass: dnsdomain
objectclass: domainrelatedobject
dc: ftp
cnamerecord: www.domaine.com
associateddomain: ftp.domaine.com 

dn: dc=69.168.192.in-addr.arpa,ou=dnsdomains,dc=morot,dc=local
objectclass: top
objectclass: dnsdomain2
objectclass: domainrelatedobject
dc: 69.168.192.in-addr.arpa
soarecord: ns.domaine.com hostmaster@domaine.com 1 1800 3600 86400 7200
nsrecord: ns.domaine.com
associateddomain: 69.168.192.in-addr.arpa 

dn: dc=11,dc=69.168.192.in-addr.arpa,ou=dnsdomains,dc=morot,dc=local
objectclass: top
objectclass: dnsdomain2
objectclass: domainrelatedobject
dc: 11
ptrrecord: ldap.domaine.com
associateddomain: 11.69.168.192.in-addr.arpa 

Il n’y a plus qu’à ajouter ces entrées à l’aide de la commande :
debian:~# ldapadd -h localhost -W -x -D cn=admin,dc=morot,dc=local -f dns.ldif

3.2 Paramétrage de PowerDNS

À la fin du fichier /etc/powerdns/pdns.conf, nous allons ajouter les lignes suivantes :

launch=ldap
ldap-host=127.0.0.1
ldap-basedn=ou=dnsdomains,dc=morot,dc=local
ldap-binddn=cn=admin,dc=morot,dc=local
ldap-secret=root
ldap-method=simple

On peut tester via la commande nslookup :

debian:~# nslookup ftp.domaine.com
Server:         127.0.0.1
Address:        127.0.0.1#53

ftp.domaine.com canonical name = www.domaine.com.
Name:   www.domaine.com
Address: 192.168.69.11

4. Paramétrage du serveur Mail

4.1 Compte mail dans l’annuaire

Tout d’abord, voyons comment structurer notre annuraire pour gérer les comptes mails. Les schémas par défaut contiennent bien un attribut mail, mais c’est assez limité dans le cadre d’un serveur gérant plusieurs domaines. Personnellement j’utilise celui du projet [qmail-ldap->http://www.qmail-ldap.org/wiki/Main_Page] que je mes à disposition ici également :

Il est donc logiquement à include dans la configuration du serveur LDAP et redémarrer celui-ci par la suite.

On va ajouter deux comptes mail. Un utilisateur julien@domaine.com avec postmaster@domaine.com comme alias et un compte arthur.dent@domaine.com dont les mails seront renvoyés sur arthur.dent@gmaille.com. Enfin, on va également ajouter le domaine.com dans la liste des domaines que le serveur SMTP acceptera de relayer.

Pour une description détaillée des attributs, veuillez vous référer à cette page : [http://www.qmail-ldap.org/wiki/Category:LDAP_Fields->http://www.qmail-ldap.org/wiki/Category:LDAP_Fields].

dn: cn=Julien Morot,ou=mails,dc=morot,dc=local
userPassword: {SSHA}hr66KNRSnfRPeAjgBZYwm8wnd12RiQjW
givenName: Julien
sn: Morot
mailMessageStore: /data/mails/domaine.com/julien/Maildir/
mail: julien@domaine.com
mailAlternateAddress: postmaster@domaine.com
uid: julien@domaine.com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: qmailUser
cn: Julien Morot
mailHost: domaine.com
accountStatus: active
qmailGID: 2001
qmailUID: 2001
mailQuotaSize: 100000000

dn: cn=Arthur Dent,ou=mails,dc=morot,dc=local
userPassword: {SSHA}hr66KNRSnfRPeAjgBZYwm8wnd12RiQjW
givenName: Arthur
sn: Dent
mailMessageStore: /data/mails/domaine.com/arthur.dent/Maildir/
mail: arthur.dent@domaine.com
mailForwardingAddress: arthur.dent@gmaille.com
uid: arthur.dent@domaine.com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: qmailUser
cn: Arthur Dent
mailHost: domaine.com
accountStatus: active
qmailGID: 2001
qmailUID: 2001
mailQuotaSize: 100000000

dn: dc=domaine.com,ou=relaydomains,dc=morot,dc=local
objectclass: top
objectclass: domainrelatedobject
objectClass: dNSDomain2
dc: domaine.com

4.2 Paramétrage du serveur SMTP Postfix

La suite des étapes consiste à dire à Postfix comment il doit prendre en exploiter ce qui ce trouve dans l’annuaire. Deja, installons Postfix en choisissant l’option « Site internet ». La plupart des options par défaut doivent convenir. Enfin, on ajoute un compte Unix pour les comptes virtuels de même uid/gid que ce que l’on a définit dans les options ldap qmailUID et qmailGID

debian:~# apt-get install postfix postfix-ldap
debian:/etc/postfix# addgroup --gid 2001 mailgroup
Ajout du groupe « mailgroup » (identifiant 2001)...
Terminé.
debian:/etc/postfix# adduser --uid 2001 --gid 2001 --disabled-login mailusers
Ajout de l'utilisateur « mailusers »...
Ajout du nouvel utilisateur « mailusers » (2001) avec le groupe « mailgroup »...
debian:/etc/postfix# mkdir /data/mails
debian:/etc/postfix# chown -R mailusers:mailgroup /data/mails/

Le fichier /etc/postfix/main.cf :

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
debug_peer_list = 192.168.69.10
append_dot_mydomain = no
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${queue_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${queue_directory}/smtp_scache
myhostname = debian.morot.local
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, localhost.localdomain
relayhost =
mynetworks = 127.0.0.0/8, 192.168.69.0/24
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
home_mailbox = Maildir/
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
virtual_uid_maps = static:2001
virtual_gid_maps = static:2001
virtual_minimum_uid = 500
virtual_transport = virtual
virtual_mailbox_limit = 0
virtual_mailbox_maps = ldap:/etc/postfix/ldap-accounts.cf,ldap:/etc/postfix/ldap-alias.cf
virtual_mailbox_domains = ldap:/etc/postfix/ldap-domains.cf
virtual_maps = ldap:/etc/postfix/ldap-forward.cf
virtual_mailbox_base = /

Le fichier /etc/postfix/ldap-accounts.cf gère les recherches des utilisateurs pour les comptes mails dans l’annuaire LDAP :

server_host = localhost
search_base = ou=mails,dc=morot,dc=local
query_filter = (&(objectClass=qmailUser)(mail=%s)(|(accountStatus=active)(accountStatus=noaccess)))
result_attribute = mailMessageStore
scope = sub
bind = yes
bind_dn = cn=admin,dc=morot,dc=local
bind_pw = root
version = 3

Le fichier /etc/postfix/ldap-alias.cf gère les recherches des alias de mails :

server_host = localhost
search_base = ou=mails,dc=morot,dc=local
query_filter = (&(objectClass=qmailUser)(mailAlternateAddress=%s)(|(accountStatus=active)(accountStatus=noaccess)))
result_attribute = mailMessageStore
scope = sub
bind = yes
bind_dn = cn=admin,dc=morot,dc=local
bind_pw = root
version = 3

Le fichier /etc/postfix/ldap-forward.cf gère les recherches des adresses mails vers lesquelles un utilisateur souhaite qu’on renvoie les messages :

server_host = localhost
search_base = ou=mails,dc=morot,dc=local
query_filter = (&(objectClass=qmailUser)(mail=%s)(|(accountStatus=active)(accountStatus=noaccess)))
result_attribute = mailForwardingAddress
scope = sub
bind = yes
bind_dn = cn=admin,dc=morot,dc=local
bind_pw = root
version = 3

Enfin, le fichier /etc/postfix/ldap-domains.cf gère les recherches pour les domaines que postfix prend en charge :

server_host = localhost
server_port = 389
bind = yes
bind_dn = cn=admin,dc=morot,dc=local
bind_pw = root
version = 3
scope = sub
search_base = ou=relaydomains,dc=morot,dc=local
query_filter = (associatedDomain=%s)
result_attribute = associatedDomain

4.3 Configuration de l’accès SMTP Authentifié SASL :

Installation :

debian:~# apt-get install sasl2-bin
debian:/etc/postfix/sasl# adduser postfix sasl
Ajout de l'utilisateur « postfix » au groupe « sasl »...
Terminé.

On active le démarrage de saslauthd dans le fichier /etc/default/saslauthd avec les bons paramètres de démarrage :

START=yes
MECHANISMS="ldap"
MECH_OPTIONS=""
THREADS=5
OPTIONS="-r -c -m /var/spool/postfix/var/run/saslauthd"
# mkdir -p /var/spool/postfix/var/run/saslauthd"

Puis, il faut dire à Postfix comment accéder au mécanisme SASL dans le fichier /etc/postfix/sasl/smtpd.conf :
pwcheck_method: saslauthd
mech_list: plain login

Enfin, dans le fichier /etc/postfix/main.cf on met en place la gestion du SASL :

broken_sasl_auth_clients = yes
smtpd_recipient_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous

4.4 Paramétrage du serveur POP3/IMAP

Installation :

debian:/etc/postfix# apt-get install courier-imap courier-pop courier-ldap

On indique dans le fichier /etc/courier/authdaemonrc qu’il faudra s’authentifier via LDAP :

authmodulelist="authldap"

Enfin, dans le fichier /etc/courier/authldaprc, il ne reste plus qu’à définir comment gérer cette authentification :

LDAP_URI                ldap://localhost
LDAP_PROTOCOL_VERSION   3
LDAP_BASEDN             ou=mails,dc=morot,dc=local
LDAP_BINDDN             cn=admin,dc=morot,dc=local
LDAP_BINDPW             root
LDAP_TIMEOUT            5
LDAP_AUTHBIND           1
LDAP_MAIL               mail
LDAP_FILTER             (&(objectClass=qmailUser)(accountStatus=active))
LDAP_HOMEDIR            mailMessageStore
LDAP_MAILDIR            mailMessageStore
LDAP_FULLNAME           cn
LDAP_CRYPTPW            userPassword
LDAP_UID                qmailUID
LDAP_GID                qmailGID
LDAP_DEREF              never
LDAP_TLS                0

5. Mise en place des accès FTP

5.1 Installation :

debian:~# apt-get install pure-ftpd-ldap

Ensuite, il faut copier le schéma ldap contenu dans le fichier /usr/share/doc/pure-ftpd-ldap/pureftpd.schema sous le répertoire /etc/ldap/schema et l’inclure dans le fichier /etc/ldap/slapd.conf.

Important, à la ligne 46 le fichier de schéma fournit avec la Debian Etch contient une erreur et contient 2 fois le mot “SYNTAX”, il faut donc en supprimer un pour qu’il soit valide. Sans cela, slapd refusera de démarrer.

5.2 Paramétrage :

L’avantage de PureFTPD réside dans une configuration extrêmement simple. Dans un premier temps, le fichier /etc/pure-ftpd/db/ldap.conf gère la partie LDAP :

LDAPServer 127.0.0.1
LDAPPort   389
LDAPBaseDN ou=ftpusers,dc=morot,dc=local
LDAPBindDN cn=admin,dc=morot,dc=local
LDAPBindPW root
LDAPDefaultUID 65534
LDAPDefaultGID 65534
LDAPFilter (&(objectClass=posixAccount)(uid=L))
LDAPHomeDir homeDirectory
LDAPVersion 3

Le reste concerne quelques réglages afin d’affiner le paramétrage :

debian:~# echo "no" > /etc/pure-ftpd/conf/PAMAuthentication
debian:~# echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone
debian:~# echo "yes" > /etc/pure-ftpd/conf/NoAnonymous
debian:~# echo "yes" > /etc/pure-ftpd/conf/CreateHomeDir
debian:~# echo "5" > /etc/pure-ftpd/conf/MaxClientsPerIP
debian:~# echo "50" > /etc/pure-ftpd/conf/MaxClientsNumber

Puis il faut ajuster cette valeur dans le fichier /etc/default/pure-ftpd-common afin que pureftpd démarre en démon :

STANDALONE_OR_INETD=standalone

Note : penser à commenter la ligne correspondante dans le fichier /etc/inetd.conf et redémarrer le service inetd avec la commande killall -HUP inetd.

Enfin, on ajoute un groupe et un compte UNIX qui va représenter les utilisateurs FTP virtuels sur le système :

debian:~# addgroup --gid 2000 ftpgroup
Ajout du groupe « ftpgroup » (identifiant 2000)...
Terminé.
debian:~# adduser --uid 2000 --gid 2000 --disabled-password ftpusers

5.3 Ajout d’un compte utilisateur dans l’annuaire :

Voici une entrée LDIF correspondant à un utilisateur nommé domaine. Le mot de passe peut être obtenu via la commande slappasswd.

dn: uid=domaine,ou=ftpusers,dc=morot,dc=local
objectClass: PureFTPdUser
objectClass: posixAccount
cn: domaine
uid: domaine
uidNumber: 2000
gidNumber: 2000
homeDirectory: /data/www/domaine.com
userPassword: {SSHA}CnmX3wW1iC+twmC2Q0eDL7sxaSKcyBys
FTPQuotaFiles: 50
FTPQuotaMBytes: 1000
FTPDownloadBandwidth: 50
FTPUploadBandwidth: 50
FTPDownloadRatio: 5
FTPUploadRatio: 1

Enfin, on ajoute cet utilisateur et on créé les répertoires qui vont bien :

debian:~# ldapadd -h localhost -W -x -D cn=admin,dc=morot,dc=local -f ftp.ldif
debian:~# mkdir /data/www/domaine.com/
debian:~# chown -R ftpusers:ftpgroup domaine.com/

Conclusion :

C’est fini? Ah ben non mon bon monsieur! Il reste encore beaucoup à faire. En premier lieu, le serveur LDAP n’est pas répliqué, ensuite, toutes les connexions faites par les différents démons sont réalisées avec l’accès administrateur LDAP. Des comptes dédiés et des ACLs bien placées seraient un plus en matière de sécurité. Enfin, on a bien un attribut LDAP permettant d’indiquer un quota, par contre Postfix ne sait pas le prendre en charge, je vous laisse regarder du côté du patch postfix-vda pour ça. Donc vous savez maintenant ce qu’il reste à faire…

Leave a Reply

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.