letsencrypt, le SSL gratuit pour tous !

Ayant testé la beta, je suis désormais fan de ce service.

Voici comment l’utiliser sous Freebsd:

* Récupérer les sources

git clone https://github.com/letsencrypt/letsencrypt.git

* Installer les dépendances

 ./letsencrypt-auto --help --debug

* Créer un fichier common.ini

mkdir /usr/local/www/letsencrypt
mkdir /usr/local/etc/letsencrypt
vi mkdir /usr/local/etc/letsencrypt/common.ini

authenticator = webroot
webroot-path = /usr/local/www/letsencrypt
server = https://acme-v01.api.letsencrypt.org/directory
renew-by-default
agree-tos
email = xxxx@domain.com
rsa-key-size = 4096

* Editer la conf apache sur son vhost http/80


        ##################
        # LETS ENCRYPT
        ##################
    Alias "/.well-known/acme-challenge" "/usr/local/www/letsencrypt/.well-known/acme-challenge"
    
        Header set Content-Type "application/jose+json"
    

* Si vous avez une rewriteRule qui redirige le http => https; il faut ajouter une condition d’exclusion:

        RewriteEngine On
        RewriteCond %{REMOTE_PORT}  !^443$
        RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
        RewriteRule ^/(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

* Générer son certif

root@j-transmission:~/letsencrypt # ./letsencrypt-auto --server https://acme-v01.api.letsencrypt.org/directory certonly -c /usr/local/etc/letsencrypt/common.ini -d blog.distran.org
Updating letsencrypt and virtual environment dependencies.......
Running with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt --server https://acme-v01.api.letsencrypt.org/directory certonly -c /usr/local/etc/letsencrypt/common.ini -d blog.distran.org

IMPORTANT NOTES:
 - If you lose your account credentials, you can recover through
   e-mails sent to letsencrypt@distran.org.
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/blog.distran.org/fullchain.pem. Your cert
   will expire on 2016-03-11. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.
 - If like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

* Editer la conf apache pour que ca pointe sur le certif

SSLCertificateFile "/etc/letsencrypt/live/blog.distran.org/fullchain.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/blog.distran.org/privkey.pem"

* EN crontab pour une execution tous les 31 de chaque mois; donc 1 fois tous les 2 mois sachant que ca expire au bout de 3 mois:

10 3 31 * *   ( /root/letsencrypt/letsencrypt-auto --server https://acme-v01.api.letsencrypt.org/directory certonly -c /usr/local/etc/letsencrypt/commo
n.ini -d seed2.distran.org && /usr/local/etc/rc.d/apache24 restart ) > /tmp/cron_letsencrypt.log 2>&1

Setup d’un Annuaire LDAP s’appuyant sur le backend SQL de postfixadmin

L’idée est d’avoir une base source unique pour ses utilisateurs.
Postfixadmin s’appuye sur une db sql et ne permet pas l’usage d’un annuaire LDAP en backend. Pourtant beaucoup d’applications s’appuyent sur du LDAP, c’est donc handicapant de n’avoir qu’une base sql.
Alors voici un moyen d’avoir également un annuaire LDAP automatiquement mappé sur la base sql utilisateurs de postfixadmin.

Ce setup s’appuye sur des HASH SHA512 pour le stockage des passwords.

* /usr/local/www/postfixadmin/config.inc.php

Par default, postfixadmin créé des hash MD5 pour stocker les password, c’est pas très rassurant, alors mettons nous plutot sur du SHA512, réputé plus solide.

/ Encrypt
// In what way do you want the passwords to be crypted?
// md5crypt = internal postfix admin md5
// md5 = md5 sum of the password
// system = whatever you have set as your PHP system default
// cleartext = clear text passwords (ouch!)
// mysql_encrypt = useful for PAM integration
// authlib = support for courier-authlib style passwords
// dovecot:CRYPT-METHOD = use dovecotpw -s 'CRYPT-METHOD'. Example: dovecot:CRAM-MD5
$CONF['encrypt'] = 'dovecot:SHA512-CRYPT';

* Cette étape n’a d’importance uniquement si vous souhaitez faire du PAM LDAP sur vos OS.

– Ajouter une colonne id sur le schéma existant de postfixadmin de la table mailbox:
Et Pas d’inquiétude; ca ne casse rien au bon fonctionnement de postfixadmin

ALTER TABLE mailbox ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE KEY;

– Alimenter cette colonne avec des id sur les entrées existantes; à partir de 1100 pour ne pas empiéter sur des services utilisant les ranges inférieures.

– Installer l’annuaire Openldap

# cd /usr/ports/net/openldap24-server
# make config

Cocher ODBC
Cocher SHA2

# make install clean

– Editer /usr/local/etc/openldap/slapd.conf


# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include         /usr/local/etc/openldap/schema/core.schema
include         /usr/local/etc/openldap/schema/cosine.schema
include         /usr/local/etc/openldap/schema/inetorgperson.schema
include         /usr/local/etc/openldap/schema/nis.schema


TLSCipherSuite HIGH:MEDIUM:+SSLv3
TLSCertificateFile /usr/local/etc/openldap/cert.crt
TLSCertificateKeyFile /usr/local/etc/openldap/cert.key


pidfile         /var/run/openldap/slapd.pid
argsfile        /var/run/openldap/slapd.args

# Load dynamic backend modules:
modulepath      /usr/local/libexec/openldap
moduleload      back_sql

# Module for supporting SHA512
moduleload      pw-sha2

#######################################################################
# sql database definitions
#######################################################################

database        sql
suffix          "dc=infranix,dc=eu"
# You only need these if normal ldap backends are defined and hold the "root"
rootdn          "cn=admin,dc=infranix,dc=eu"

# Postfixadmin Password format (SHA512) using libcrypt)
password-hash {CRYPT}
password-crypt-salt-format "$6$%.16s"

dbhost          192.168.X.Y
dbname          ldap
dbuser          ldap_user
dbpasswd        xxxxxxxxxx

lastmod off

subtree_cond    "ldap_entries.dn LIKE CONCAT('%',?)"
has_ldapinfo_dn_ru      no

* Créer une db ldap

create database ldap;

La suite du schéma de la base va avoir beaucoup de vues afin d’avoir une automatisation extrême.

* Pour privilégier un domain le schéma aura 2 vues users quasi-identiques, l’une incluant le domaine privilégié et l’autre l’excluant.

* Vue users_publics

drop view users_public;

create view users_public AS

select 
  id as id, 
  local_part as username ,
 password,
  name,
  name as surname,
  username as email,
  domain as domain
from postfix.mailbox where mailbox.active =1 and mailbox.username  NOT LIKE '%@infranix.eu';

– Vue users_people

drop view users_people;

create view users_people AS

select 
  id as id, 
  local_part as username ,
 password,
  name,
  name as surname,
  username as email,
  domain as domain
from postfix.mailbox where mailbox.active =1 and mailbox.username  LIKE '%@infranix.eu';

– users

drop view users

create view users AS

select * from users_people
UNION
select * from users_public

– org_unit_original

c’est à la base ce schéma qui est fourni par default.

CREATE TABLE `org_unit_original` (
  `id` int(11) NOT NULL,
  `o` varchar(32) DEFAULT NULL,
  `dn` varchar(255) DEFAULT NULL,
  `parent` int(11) DEFAULT NULL,
  `oc_map_id` int(2) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `dn` (`dn`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `org_unit_original` VALUES (1,'Infranix','dc=infranix,dc=eu',0,3),(2,'People','ou=People,dc=infranix,dc=eu',1,2),(3,'Groups','ou=Groups,dc=infranix,dc=eu',1,2),(4,'Public','ou=Public,dc=infranix,dc,eu',1,2),(6,'Devnix','dc=devnix.fr,dc=infranix,dc=eu',1,3),(7,'People','ou=People,dc=devnix.fr,dc=infranix,dc=eu',6,2);


mysql> select id,o,dn,parent,oc_map_id from org_unit_original;
+—-+———-+——————————————+——–+———–+
| id | o | dn | parent | oc_map_id |
+—-+———-+——————————————+——–+———–+
| 1 | Infranix | dc=infranix,dc=eu | 0 | 3 |
| 2 | People | ou=People,dc=infranix,dc=eu | 1 | 2 |
| 3 | Groups | ou=Groups,dc=infranix,dc=eu | 1 | 2 |
| 4 | Public | ou=Public,dc=infranix,dc,eu | 1 | 2 |
| 6 | Devnix | dc=devnix.fr,dc=infranix,dc=eu | 1 | 3 |
| 7 | People | ou=People,dc=devnix.fr,dc=infranix,dc=eu | 6 | 2 |
+—-+———-+——————————————+——–+———–+

– org_unit_distributed

On va créé une orgUnit pour chaque domaine via une vue s’appuyant sur la vue users_distributed, elle même une vue générée par la table mailbox de postfixadmin.

drop view org_unit_distributed;
create view org_unit_distributed AS


   select 
    (domain) as o,
   MIN((id)+50000) as id,
   CONCAT('dc=',domain,',dc=infranix,dc=eu') AS dn, 
        3 as oc_map_id,
        1 as parent
   from users_distributed group by domain
 
UNION 

select * from org_unit_original;

* org_unit

Cette vue définit l’arbre du LDAP avec la relation entre niveau (parent).

drop view org_unit;
create view org_unit AS

select id,o,dn,parent,oc_map_id from org_unit_original

UNION

   select 
   
   MIN((id)+50000) as id,
    (domain) as o,
   CONCAT('dc=',domain,',dc=infranix,dc=eu') AS dn, 

        1 as parent,
                3 as oc_map_id
   from users_distributed group by domain
 
UNION 


    SELECT
     (users_distributed.id)+90000 as id,
        'People' ,
        CONCAT('ou=People,dc=',domain,',dc=infranix,dc=eu') AS dn, 
  
        org_unit_distributed.id as parent,
                2 as oc_map_id
        from users_distributed, org_unit_distributed
        where org_unit_distributed.o = domain
        group by domain
mysql> select * from org_unit limit 10;
+--------+-------------------+------------------------------------------+--------+-----------+
| id     | o                 | dn                                       | parent | oc_map_id |
+--------+-------------------+------------------------------------------+--------+-----------+
|     1  | Infranix          | dc=infranix,dc=eu                        |      0 |         3 |
|     2  | People            | ou=People,dc=infranix,dc=eu              |      1 |         2 |
|     3  | Groups            | ou=Groups,dc=infranix,dc=eu              |      1 |         2 |
|     4  | Public            | ou=Public,dc=infranix,dc,eu              |      1 |         2 |
|     6  | Devnix            | dc=devnix.fr,dc=infranix,dc=eu           |      1 |         3 |
|     7  | People            | ou=People,dc=devnix.fr,dc=infranix,dc=eu |      6 |         2 |
| 60047  | toto.net          | dc=toto.net,dc=infranix,dc=eu            |      1 |         3 |
| 60045  | titi.com          | dc=titi.com,dc=infranix,dc=eu            |      1 |         3 |
| 60009  | tutu.biz          | dc=tutu.biz,dc=infranix,dc=eu            |      1 |         3 |
| 60021  | aaaa.com          | dc=aaaa.com,dc=infranix,dc=eu            |      1 |         3 |
| 100044 | People            | ou=People,dc=toto.net,dc=infranix,dc=eu  |  60044 |         2 |
| 100000 | People            | ou=People,dc=titi.com,dc=infranix,dc=eu  |  60000 |         2 |
| 100007 | People            | ou=People,dc=tutu.biz,dc=infranix,dc=eu  |  60007 |         2 |
| 100014 | People            | ou=People,dc=aaaaa.com,dc=infranix,dc=eu |  60014 |         2 |
+--------+-------------------+------------------------------------------+--------+-----------+
10 rows in set (0.01 sec)

* ldap_entries

drop view ldap_entries;


CREATE VIEW ldap_entries AS 
 
SELECT 
    org_unit.id AS id,
    org_unit.dn AS dn,
    org_unit.oc_map_id AS oc_map_id,
    org_unit.parent AS parent,
    org_unit.id AS keyval
FROM
    org_unit
 

UNION 

 
SELECT 
    (users_people.id) AS id,
    CONCAT('uid=',
                    users_people.username,
                    ',ou=People,dc=infranix,dc=eu') AS dn,
    1 AS oc_map_id,
    2 AS parent,
    (users_people.id) AS keyval
FROM
    users_people



 
UNION 
 
SELECT 
 
    (groups.id) AS id,
    CONCAT( 'cn=',
                    groups.name,
                    ',ou=Groups,dc=infranix,dc=eu') AS dn,
    5 AS oc_map_id,
    3 AS parent,
    groups.id AS id
FROM
    groups


UNION

SELECT 
    (users_distributed.id) AS id,
    CONCAT('uid=',
            users_distributed.username,
            ',ou=People,dc=',
            users_distributed.domain,
            ',dc=infranix,dc=eu') AS dn,
    1 AS oc_map_id,
    org_unit.id AS parent,
    (users_distributed.id) AS keyval
FROM
    users_distributed,org_unit
WHERE
    org_unit.dn = CONCAT('ou=People,dc=',users_distributed.domain,',dc=infranix,dc=eu');

* ldap_entry_objclasses

Pour l’usage de pam, il fallait ajouter de nouveaux objectClass à inetOrgPerson, notamment posixAccount et shadowAccount.
L’astuce est de créer une vue pour construire la table optionnelle ldap_entry_objclasses en l’autogénérant via la table users.

drop view ldap_entry_objclasses;

CREATE VIEW ldap_entry_objclasses AS 
 
SELECT 
    (users.id) AS entry_id,
    'posixAccount' AS oc_name
FROM
    users
 
UNION 

SELECT 
    (users.id) AS entry_id,
    'shadowAccount' AS oc_name
FROM
    users

* ldap_oc_mappings

Cette table permet d’identifier la table de toutes les objectCLass

CREATE TABLE `ldap_oc_mappings` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(64) NOT NULL,
  `keytbl` varchar(64) NOT NULL,
  `keycol` varchar(64) NOT NULL,
  `create_proc` varchar(255) DEFAULT NULL,
  `delete_proc` varchar(255) DEFAULT NULL,
  `expect_return` tinyint(4) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

INSERT INTO `ldap_oc_mappings` VALUES (3,'organization','org_unit','id',NULL,NULL,0),(2,'organizationalUnit','org_unit','id',NULL,NULL,0),(1,'inetOrgPerson','users','id',NULL,NULL,0),(5,'posixGroup','groups','id',NULL,NULL,0),(6,'posixAccount','users','id',NULL,NULL,0);

son contenu:

mysql> select * from ldap_oc_mappings;
+----+--------------------+----------+--------+-------------+-------------+---------------+
| id | name               | keytbl   | keycol | create_proc | delete_proc | expect_return |
+----+--------------------+----------+--------+-------------+-------------+---------------+
|  3 | organization       | org_unit | id     | NULL        | NULL        |             0 |
|  2 | organizationalUnit | org_unit | id     | NULL        | NULL        |             0 |
|  1 | inetOrgPerson      | users    | id     | NULL        | NULL        |             0 |
|  5 | posixGroup         | groups   | id     | NULL        | NULL        |             0 |
|  6 | posixAccount       | users    | id     | NULL        | NULL        |             0 |
+----+--------------------+----------+--------+-------------+-------------+---------------+

* ldap_attr_mappings

Cette table est cruciale; c’est elle qui définit les attributs de chaque objectClass.
Dans mon usage pour du pam_ldap, il fallait donc bien définir homeDirectory, userPassword, uidMember, gidNumber, loginShell:

CREATE TABLE `ldap_attr_mappings` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `oc_map_id` int(10) unsigned NOT NULL,
  `name` varchar(255) NOT NULL,
  `sel_expr` varchar(255) NOT NULL,
  `sel_expr_u` varchar(255) DEFAULT NULL,
  `from_tbls` varchar(255) NOT NULL,
  `join_where` varchar(255) DEFAULT NULL,
  `add_proc` varchar(255) DEFAULT NULL,
  `delete_proc` varchar(255) DEFAULT NULL,
  `param_order` tinyint(4) NOT NULL,
  `expect_return` tinyint(4) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;

INSERT INTO `ldap_attr_mappings` VALUES (1,1,'cn','users.username','','users',NULL,NULL,NULL,3,0),(2,1,'telephoneNumber','users.phone','','users','NULL',NULL,NULL,3,0),(3,1,'sn','users.name','','users',NULL,NULL,NULL,3,0),(7,1,'homeDirectory','concat(\'/home/\',users.domain, \'/\',users.username)',NULL,'users',NULL,NULL,NULL,3,0),(5,1,'mail','users.email',NULL,'users',NULL,NULL,NULL,3,0),(6,2,'ou','Groups',NULL,'groups',NULL,NULL,NULL,3,0),(13,1,'userPassword','replace(users.password, \'SHA512-CRYPT\', \'CRYPT\')',NULL,'users','users.password IS NOT NULL',NULL,NULL,3,0),(8,3,'o','org_unit.o',NULL,'org_unit',NULL,NULL,NULL,3,0),(14,1,'displayName','users.name',NULL,'users',NULL,NULL,NULL,3,0),(9,1,'loginShell','concat(\'/bin/bash\')',NULL,'users',NULL,NULL,NULL,3,0),(4,1,'uidNumber','users.id',NULL,'users',NULL,NULL,NULL,3,0),(21,5,'cn','groups.name',NULL,'groups',NULL,NULL,NULL,3,0),(15,5,'gidNumber','groups.id',NULL,'groups',NULL,NULL,NULL,3,0),(16,5,'memberUid','users.username',NULL,'groups,group_member,users','group_member.users_id=users.id and group_member.groups_id=groups.id',NULL,NULL,3,0),(11,1,'gidNumber','100',NULL,'users',NULL,NULL,NULL,3,0),(17,3,'objectClass','concat(\'top\')',NULL,'org_unit',NULL,NULL,NULL,3,0),(18,3,'objectClass','concat(\'dcObject\')',NULL,'org_unit',NULL,NULL,NULL,3,0),(19,1,'uid','users.username',NULL,'users',NULL,NULL,NULL,3,0),(20,3,'dc','org_unit.o',NULL,'org_unit',NULL,NULL,NULL,3,0);

Le contenu des attributs de l’objectClass inetOrgPerson (id àa 1 dans la table ldap_oc_mappings ci-dessus) via un SELECT :


mysql> mysql> select * from ldap_attr_mappings where oc_map_id=1;
+----+-----------+-----------------+---------------------------------------------------+------------+-----------+----------------------------+----------+-------------+-------------+---------------+
| id | oc_map_id | name            | sel_expr                                          | sel_expr_u | from_tbls | join_where                 | add_proc | delete_proc | param_order | expect_return |
+----+-----------+-----------------+---------------------------------------------------+------------+-----------+----------------------------+----------+-------------+-------------+---------------+
|  1 |         1 | cn              | users.username                                    |            | users     | NULL                       | NULL     | NULL        |           3 |             0 |
|  2 |         1 | telephoneNumber | users.phone                                       |            | users     | NULL                       | NULL     | NULL        |           3 |             0 |
|  3 |         1 | sn              | users.name                                        |            | users     | NULL                       | NULL     | NULL        |           3 |             0 |
|  7 |         1 | homeDirectory   | concat('/home/',users.domain, '/',users.username) | NULL       | users     | NULL                       | NULL     | NULL        |           3 |             0 |
|  5 |         1 | mail            | users.email                                       | NULL       | users     | NULL                       | NULL     | NULL        |           3 |             0 |
| 13 |         1 | userPassword    | replace(users.password, 'SHA512-CRYPT', 'CRYPT')  | NULL       | users     | users.password IS NOT NULL | NULL     | NULL        |           3 |             0 |
| 14 |         1 | displayName     | users.name                                        | NULL       | users     | NULL                       | NULL     | NULL        |           3 |             0 |
|  9 |         1 | loginShell      | concat('/bin/bash')                               | NULL       | users     | NULL                       | NULL     | NULL        |           3 |             0 |
|  4 |         1 | uidNumber       | users.id                                          | NULL       | users     | NULL                       | NULL     | NULL        |           3 |             0 |
| 11 |         1 | gidNumber       | 100                                               | NULL       | users     | NULL                       | NULL     | NULL        |           3 |             0 |
| 19 |         1 | uid             | users.username                                    | NULL       | users     | NULL                       | NULL     | NULL        |           3 |             0 |
+----+-----------+-----------------+---------------------------------------------------+------------+-----------+----------------------------+----------+-------------+-------------+---------------+

A suivre, je vais alimenter au fur et à mesure.

FreeBSD 10.2 – pam_ldap howto

– Il faut installer les packages:

# pkg install -y nss_ldap pam_ldap openldap-client p5-Mozilla-CA

– Faire la conf du client ldap

vi /usr/local/etc/nss_ldap.conf

BASE ou=People,dc=infranix,dc=eu
URI ldaps://ldap1
TLS_CACERTDIR /usr/local/lib/perl5/site_perl/Mozilla/CA/cacert.pem
TLS_REQCERT allow
SASL_NOCANON    on

– Créer des symlink pour simplier la configuration vers ldap.conf

# ln -s /usr/local/etc/nss_ldap.conf /usr/local/etc/openldap/ldap.conf
# ln -s /usr/local/etc/nss_ldap.conf /usr/local/etc/ldap.conf

– Modifier nsswitch pour qu’il s’appuye sur ldap pour passwd et group

[root@app001 ~]# cat /etc/nsswitch.conf
#
# nsswitch.conf(5) - name service switch configuration file
# $FreeBSD: releng/10.2/etc/nsswitch.conf 224765 2011-08-10 20:52:02Z dougb $
#
group: files ldap
group_compat: nis
hosts: files dns
networks: files
passwd: files ldap
passwd_compat: nis
shells: files
services: compat
services_compat: nis
protocols: files
rpc: files

– Modifier /etc/pam.d/ssh

root@app001 ~]# cat /etc/pam.d/sshd
#
# $FreeBSD: releng/10.2/etc/pam.d/sshd 197769 2009-10-05 09:28:54Z des $
#
# PAM configuration for the "sshd" service
#

# auth
auth        sufficient  /usr/local/lib/pam_ldap.so    no_warn try_first_pass
auth		sufficient	pam_opie.so		no_warn no_fake_prompts
auth		requisite	pam_opieaccess.so	no_warn allow_local
#auth		sufficient	pam_krb5.so		no_warn try_first_pass
#auth		sufficient	pam_ssh.so		no_warn try_first_pass
auth		required	pam_unix.so		no_warn try_first_pass

# account
account     required    /usr/local/lib/pam_ldap.so    no_warn ignore_authinfo_unavail ignore_unknown_user
account		required	pam_nologin.so
#account	required	pam_krb5.so
account		required	pam_login_access.so
account		required	pam_unix.so

# session
#session	optional	pam_ssh.so		want_agent
session     required    /usr/local/lib/pam_mkhomedir.so
session		required	pam_permit.so

# password
#password	sufficient	pam_krb5.so		no_warn try_first_pass
password	required	pam_unix.so		no_warn try_first_pass

– modifier /etc/pam.d/su pour mettre le bon groupe

[root@app001 ~]# cat /etc/pam.d/su
#
# $FreeBSD: releng/10.2/etc/pam.d/su 219663 2011-03-15 10:13:35Z des $
#
# PAM configuration for the "su" service
#

# auth
auth		sufficient	pam_rootok.so		no_warn
auth		sufficient	pam_self.so		no_warn
auth		requisite	pam_group.so		no_warn group=wheel,users root_only fail_safe ruser
auth		include		system

# account
account		include		system

# session
session		required	pam_permit.so

– modifier /etc/pam.d/system

root@app001 /etc/pam.d]# cat system

# $FreeBSD: releng/10.2/etc/pam.d/system 197769 2009-10-05 09:28:54Z des $
#
# System-wide defaults
#

# auth
auth		sufficient	/usr/local/lib/pam_ldap.so   no_warn try_first_pass
auth		sufficient	pam_opie.so		no_warn no_fake_prompts
auth		requisite	pam_opieaccess.so	no_warn allow_local
#auth		sufficient	pam_krb5.so		no_warn try_first_pass
#auth		sufficient	pam_ssh.so		no_warn try_first_pass
auth		required	pam_unix.so		no_warn try_first_pass nullok

# account
#account	required	pam_krb5.so
account         required        /usr/local/lib/pam_ldap.so   ignore_unknown_user ignore_authinfo_unavail
account		required	pam_login_access.so
account		required	pam_unix.so

# session
#session	optional	pam_ssh.so		want_agent
session		required	/usr/local/lib/pam_mkhomedir.so
session		required	pam_lastlog.so		no_fail

# password
#password	sufficient	pam_krb5.so		no_warn try_first_pass
password	required	pam_unix.so		no_warn try_first_pass

– modifier /etc/pam.d/passwd

[root@app001 /etc/pam.d]# cat passwd
#
# $FreeBSD: releng/10.2/etc/pam.d/passwd 113967 2003-04-24 12:22:42Z des $
#
# PAM configuration for the "passwd" service
#

# passwd(1) does not use the auth, account or session services.

# password
#password	requisite	pam_passwdqc.so		enforce=users
#password  required    pam_ldap.so
password	required	pam_unix.so		no_warn try_first_pass nullok

– OPTIONNEL : forcer le gidMember

vi /etc/group
users:*:100:

– pour tester

getent passwd

Adapter LDAP pour supporter le SHA512 de postfixadmin

Dans un prochain post; je présenterais comment créer un schéma LDAP automatiquement en s’appuyant sur un backend SQL; et en l’occurence, celui de postfixadmin.
Toujours est-il que voici en avance une astuce pour qu’openldap reconnaisse les password SHA512 de postfixadmin.

* slapd.conf

Il faut avant tout activer le module sha2 qui permet de supporter des hash SHA étendu (256, 512):

moduleload      pw-sha2

Le format salt ici est ‘$6$’ qui invoque une méthode hash basée sur SHA512 et fournit 16 caractères de salt.

password-hash {CRYPT}                                                                                                                                                  
password-crypt-salt-format "$6$%.16s"

* SQL

update ldap_attr_mappings set sel_expr='replace(users.password, \'SHA512-CRYPT\', \'CRYPT\')' where id=13;

MySQL [ldap]> select * from ldap_attr_mappings where id=13;
+----+-----------+--------------+--------------------------------------------------+------------+-----------+----------------------------+----------+-------------+-----
--------+---------------+
| id | oc_map_id | name         | sel_expr                                         | sel_expr_u | from_tbls | join_where                 | add_proc | delete_proc | para
m_order | expect_return |
+----+-----------+--------------+--------------------------------------------------+------------+-----------+----------------------------+----------+-------------+-----
--------+---------------+
| 13 |         1 | userPassword | replace(users.password, 'SHA512-CRYPT', 'CRYPT') | NULL       | users     | users.password IS NOT NULL | NULL     | NULL        |
     3 |             0 |
+----+-----------+--------------+--------------------------------------------------+------------+-----------+----------------------------+----------+-------------+-----
--------+---------------+
1 row in set (0.01 sec)