Gestion de LetsEncrypt sous FreeBSD avec nginx et une jail

LetsEncypt est une autorité de certification utilisant une API basée sur des appels HTTP et un client côté serveur qui va générer des tokens lus par les serveurs LetsEncrypt. Nous allons ici voir une architecture LetsEncrypt typique dans laquelle nous allons utiliser le client acme-client d'OpenBSD disponible dans les ports et les packages FreeBSD.

Installation

Dans un premier temps installez le client sur votre machine hôte (et pas votre jail web):

pkg install acme-client

Configuration de nginx

Nous allons maintenant configurer nginx afin de pouvoir interagir avec l'API letsencrypt. Créez tout d'abord le répertoire suivant dans votre jail avec l'utilisateur et le groupe nobody

mkdir /usr/local/www/.well-known && chown nobody:nobody /usr/local/www/.well-known

Ensuite configurez vos virtual hosts afin de faire pointer les appels vers /.well-known dans ce répertoire:

server {
        listen 80;
        server_name www.unix-experience.fr;
        location /.well-known {
            alias /usr/local/www/.well-known;
        }
        location / {
            return 301 https://www.unix-experience.fr$request_uri;
        }
        add_header X-Frame-Options "DENY";
        add_header Strict-Transport-Security "max-age=86400; preload";
}

Note: nous ajoutons ici le support du protocole HSTS avec un TTL d'1 journée spécifiant aux navigateurs que le site supporte SSL et qu'il faudrait passer dessus. Vous pouvez sans souci faire pointer plusieurs de vos virtual hosts dans ce même répertoire.

Configuration du client LetsEncrypt

Retournez maintenant sur votre hôte et créez le fichier /usr/local/etc/acme/domains.txt puis ajoutez y un domaine par ligne:

www.unix-experience.fr
ftp.unix-experience.fr

Créez ensuite le script ci-dessous (basé sur le script présent dans le même répertoire sous forme d'exemple) dans /usr/local/etc/acme/acme-client.sh

#!/bin/sh -e
WEBJAIL="web"
BASEDIR="/usr/local/etc/acme"
SSLDIR="/usr/local/etc/ssl/acme"
DOMAINSFILE="${BASEDIR}/domains.txt"
CHALLENGEDIR="/jails/${WEBJAIL}/usr/local/www/.well-known/acme-challenge"

[ ! -d "${SSLDIR}/private" ] && mkdir -pm700 "${SSLDIR}/private"

cat "${DOMAINSFILE}" | while read domain line ; do
   CERTSDIR="${SSLDIR}/${domain}"
   [ ! -d "${CERTSDIR}" ] && mkdir -pm755 "${CERTSDIR}"
   set +e # RC=2 when time to expire > 30 days
   acme-client -b -C "${CHALLENGEDIR}" \
               -k "${SSLDIR}/private/${domain}.pem" \
               -c "${CERTSDIR}" \
               -n -N -v \
               ${domain} ${line}
   RC=$?
   set -e
   [ $RC -ne 0 -a $RC -ne 2 ] && exit $RC
done

Ce script lit les domaines présents dans le fichier domains.txt puis il va s'occuper de créer vos clefs privées et de les faire signer par LetsEncrypt, en se basant sur le répertoire .well-known présent dans votre jail. Une fois ce script exécuté, si tout s'est passé correctement vous trouverez votre clef privée dans le répertoire /usr/local/etc/ssl/acme/private/example.org et votre clef publique et les chaînes de certificats dans le répertoire /usr/local/etc/ssl/acme/example.org. Ces répertoires sont situés sur votre hôte et non dans votre jail web. Pour déployer les scripts un script d'exemple est présent dans le répertoire /usr/local/etc/**acme, mais nous allons légèrement le modifier. Créez le fichier /usr/local/etc/acme/deploy.sh**:

#!/bin/sh

set -e

BASEDIR="/usr/local/etc/acme"
DOMAINSFILE="${BASEDIR}/domains.txt"
LEDIR="/usr/local/etc/ssl/acme"
JAILSDIR="/jails"
TARGETS="web"
cat "${DOMAINSFILE}" | while read domain line ; do
    for jail in ${TARGETS}; do
        targetdir="${JAILSDIR}/${jail}/etc/ssl"
        # Check if the certificate has changed
        [[ -z "`diff -rq ${LEDIR}/${domain}/fullchain.pem ${targetdir}/certs/${domain}.pem`" ]] && continue
        cp -L "${LEDIR}/private/${domain}.pem"   "${targetdir}/private/${domain}.pem"
        cp -L "${LEDIR}/${domain}/fullchain.pem" "${targetdir}/certs/${domain}.pem"
        chmod 400 "${targetdir}/private/${domain}.pem"
        chmod 644 "${targetdir}/certs/${domain}.pem"
        # Restart/-load relevant services
        [[ "${jail}" = "web" ]] && jexec ${jail} service nginx restart
    done
done

Ce script va copier tous les certificats associés à vos dernières négociations LetsEncrypt et va les déployer dans votre jail web puis redémarrer nginx.

Renouvellement automatique

Pour finir il ne reste plus qu'à configurer le cron ajouté par le paquet acme-client afin de configurer la tâche hebdomadaire. Pour se faire, éditez le fichier /usr/local/etc/periodic.conf et ajoutez les entrées suivantes:

# letsencrypt
weekly_acme_client_enable="YES"
weekly_acme_client_user="nobody"
weekly_acme_client_deployscript="/usr/local/etc/acme/deploy.sh"

Cela va vous permettre d'activer le cron, et de lancer le déploiement automatiquement toutes les semaines.

Conclusion

Vous pouvez désormais faire des demandes de certificats LetsEncrypt facilement et les renouveler automatiquement via un cron fourni par acme-client.

Fail2ban sous FreeBSD

Fail2ban est un outil en python très pratique qui va inspecter vos logs de connexion afin de bannir des adresses IP au niveau de votre pare-feu. Si l'intégration au niveau de Linux se fait facilement, sous FreeBSD elle nécessite un petit peu plus de modifications. Nous allons ici intégrer fail2ban avec Packet Filter sous FreeBSD.

Installation

Installez tout d'abord le package/port py27-fail2ban

pkg install py27-fail2ban

ou

cd /usr/ports/security/py-fail2ban
make install

Configuration

Nous ne configurerons pas ici la base de PF, nous considérerons que vous avez déjà un Packet Filter opérationnel. On va dans un premier temps configurer votre Packet Filter afin de créer un conteneur d'adresses bloquées. En haut de votre fichier /etc/pf.conf créez une table persistante (elle ne sera pas effacée à chaque rechargement des règles PF)

table <banssh> persist

Créez ensuite une règle de blocage précédant votre règle d'autorisation fail2ban block in quick inet proto tcp from to self port ssh pass in quick inet proto tcp to self port ssh On va maintenant créer un filtre fail2ban associé à SSH et le binder sur PF. Créez le fichier /usr/local/etc/fail2ban/jail.d/ssh-pf.conf et associez lui le contenu suivant.

[ssh-pf]
enabled  = true
filter   = sshd
action   = pf
logpath  = /var/log/auth.log
findtime  = 600
maxretry = 3
bantime  = 86400

On créée ici un filtre sur le démon sshd qui va effectuer l'action pf. On bannit ici pour une durée d'une journée (86400 secondes) Modifiez ensuite le fichier /usr/local/etc/fail2ban/action.d/pf.conf en éditant la ligne tablename

tablename = banssh

Enfin activez et lancez le service fail2ban

sysrc fail2ban_enable=YES
service fail2ban start

Vérifier les IP bloquées

Pour vérifier les adresses IP bloquées, interrogez la table PF de la manière suivante

pfctl -t banssh -T show

Postfix: support du SMTPS authentifié (SASL)

Avoir un serveur SMTP qui envoie des mails est bien, le sécuriser c'est mieux.

La législation française impose d'enregistrer les méta-données de connexion aux serveurs, que ce soit vers l'Internet ou en interne. L'authentification est alors une étape primordiale dans la configuration de notre serveur d'envoi SMTP.

Afin de sécuriser nos échanges, nous ajouterons une couche de chiffrement SSL à Postfix, évitant à des attaquants d'intercepter des mails en clair sur le réseau.

Ce tutoriel a été réalisé et testé sur des infrastructures de production en FreeBSD 9.2 et OpenBSD 5.3

Prérequis

Vérifiez que votre version de postfix est compilée avec le support TLS/SSL et SASL2

Support SSL

Dans un premier temps nous allons créer nos certificats.

Je vous convie à regarder cet article afin de générer des certificats, valides ou non.

Installation de cyrus-sasl avec support LDAP

Nous allons utiliser cyrus-sasl afin d'authentifier nos utilisateurs sous Postfix.

Sous FreeBSD:

cd /usr/ports/security/cyrus-sasl2-saslauthd
make install clean

Cochez l'option OpenLDAP.

Sous OpenBSD:

pkg_add -i cyrus-sasl

Sélectionnez la version ldap.

Configuration de cyrus-sasl (saslauthd)

La configuration de cyrus-sasl se fait très rapidement. Ouvrez le fichier /usr/local/etc/saslauthd.conf (/etc/saslauthd.conf sur OpenBSD/Debian) et renseignez les champs nécessaires à l'authentification LDAP.

ldap_servers: ldaps://10.0.0.10/
ldap_search_base: dc=mydomain,dc=tld
ldap_filter: uid=%u
ldap_start_tls: no
ldap_use_sasl: no
ldap_version: 3
ldap_scope: sub
ldap_bind_dn: cn=rootldap,dc=mydomain,dc=tld
ldap_bind_pw: rootpw

Si vous autorisez la lecture de manière anonyme, vous pouvez retirer les deux dernières lignes.

On va maintenant activer et configurer le lancement du service:

Sous FreeBSD, fichier /etc/rc.conf:

saslauthd_enable="YES"
saslauthd_flags="-a ldap -m /var/spool/postfix/var/run/saslauthd"

Sous OpenBSD, fichier /etc/rc.conf.local:

saslauthd_flags="-a ldap -m /var/spool/postfix/var/sasl2"

Nous devons changer le chemin des pipes SASL afin que postfix puisse les utiliser, celui-ci étant chrooté par défaut. L'option -m est celle qui offre cette possibilité.

Créez ensuite le dossier précédemment cité, nécessaire dans une configuration de postfix chrootée, changez le propriétaire et lancez le service

Sur FreeBSD:

mkdir -p /var/spool/postfix/var/run/saslauthd
chown -R postfix:postfix /var/spool/postfix/var/run/saslauthd
service saslauthd star

Sur OpenBSD:

mkdir -p /var/spool/postfix/var/sasl2
chown -R _postfix:_postfix /var/spool/postfix/var/sasl2
chmod +x /etc/rc.d/saslauthd
/etc/rc.d/saslauthd start

Note: sur OpenBSD 5.3 il faut rajouter les droits d'exécution sur /etc/rc.d/saslauthd, autrement il n'est pas possible de lancer le service directement.

Test de cyrus-sasl

On va maintenant tester cyrus-sasl.

testsaslauthd -u <user> -p <password>

Si tout se passe bien vous aurez le résultat suivant:

0: OK "Success."

En cas d'erreur de mot de passe, vous aurez l'erreur suivante, dans ce cas corrigez le mot de passe:

0: NO "authentication failed"

Si vous ne parvenez pas à détecter pourquoi cela ne fonctionne pas, regardez le fichier /var/log/auth.log

saslauthd[39043]: do_auth         : auth failure: [user=myuser] [service=imap] [realm=] [mech=pam] [reason=PAM auth error]

Dans l'exemple précédent, vous avez omis d'activer l'option d'authentification LDAP au lancement du service, de ce fait saslauthd veut s'authentifier via le PAM.

Pour terminer on va ajouter les options d'authentification de SASL dans le fichier /usr/local/lib/sasl2/smtpd.conf

pwcheck_method: saslauthd
mech_list: plain login

Configuration de postfix

On va maintenant configurer postfix. Ouvrez tout d'abord le fichier main.cf. Allez en fin de fichier et collez les lignes suivantes:

# SASL
broken_sasl_auth_clients = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =

# SSL/TLS
smtp_use_tls = yes
smtpd_use_tls = yes
smtpd_tls_key_file = /etc/postfix/postfix.key
smtpd_tls_cert_file = /etc/postfix/postfix.crt
smtpd_tls_CAfile = /etc/postfix/ca.crt
smtpd_tls_loglevel = 1
smtpd_recipient_limit = 200
smtpd_sender_restrictions = permit_sasl_authenticated,reject
smtpd_client_restrictions = permit_sasl_authenticated,reject

On relie ici postfix à l'authentification SASL. On n'autorise pas l'authentification anonyme (smtpd_sasl_security_options) et on rejette tout client non authentifié (smtpd_client_restrictions), ou dont le login est incorrect (reject final). Par ailleurs, on limite le nombre de destinataire d'un message à 200 personnes (smtpd_recipient_limit).

Ajustez les chemins vers vos certificats.

Pour finir ouvrez le fichier main.cf et décommentez les lignes suivantes:

smtps     inet  n       -       n       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes

Cela aura pour effet d'activer l'écoute SMTPS (port 465), d'activer TLS et l'authentification SASL).

Attention: il se peut que sur FreeBSD les options du master.cf ne passent pas bien. Dans ce cas ajoutez les lignes suivantes dans le main.cf.

smtpd_sasl_auth_enable = yes
smtpd_tls_wrappermode = yes

Attention: après redémarrage de postfix, si la commande postconf retourne smtpd_sasl_type = dovecot, rajoutez la ligne suivante dans le fichier master.cf.

smtpd_sasl_type = cyrus

Conclusion

Voilà qui conclut cette partie chiffrement et authentification. Prenez bien le temps de vérifier que les authentifications fonctionnent correctement (mot de passe correct et pas d'anonymous), les variables ne sont pas évidentes à ajuster et dépendent des version de Postfix et de votre OS.

SquidGuard: blacklists pour squid

Squidguard est un plugin qui se greffe sur un serveur Squid. Il permet la gestion plus poussée des ACL par le biais notamment de la gestion de blacklists compilées. SquidGuard permet également de gérer des accès horaires, des conditions plus poussées et la modification de la page par une autre page.

Installation et configuration ## Installation

Pour installer SquidGuard rien de plus simple:

aptitude install squidguard

Sous FreeBSD:

cd /usr/ports/www/squidguard
make install clean

Ensuite modifiez le fichier de configuration principal de squid pour intégrer les lignes suivantes (ou décommentez les): Versions 3.1 et antérieures

redirect_program /usr/bin/squidGuard -c /etc/squid/squidGuard.conf
url_rewrite_program /usr/bin/squidGuard -c /etc/squid/squidGuard.conf
url_rewrite_children 10

Version 3.2 et supérieures:

url_rewrite_program /usr/local/bin/squidGuard -c /etc/squidguard/squidguard.conf
url_rewrite_children 10 startup=4 idle=2 concurrency=0

Squid est désormais lié à squidGuard. Il lancera 10 processus simultanés de squidGuard pour filtrer. Maintenant nous allons installer une blacklist (celle de l'université de Toulouse 1). Version Linux

wget ftp://ftp.univ-tlse1.fr/pub/reseau/cache/squidguard_contrib/blacklists.tar.gz
tar xvzf blacklists.tar.gz
chown -R squid:squid /etc/squidguard/blacklists
rm blacklists.tar.gz

Version BSD

wget ftp://ftp.univ-tlse1.fr/pub/reseau/cache/squidguard_contrib/blacklists.tar.gz
tar xvzf blacklists.tar.gz
chown -R _squid:_squid /etc/squidguard/blacklists
rm blacklists.tar.gz

Configuration

Ouvrez le fichier /etc/squid/squidGuard.conf Configurez tout d'abord le répertoire de base de données de SquidGuard avec la directive dbhome.

 dbhome /etc/squidguard/blacklists

Ensuite tapez squidGuard -C all pour configurer les blacklists créées (squidGuard -f /etc/squidguard/squidguard.conf -C all pour BSD) SquidGuard utilise un mécanisme de sources et de destinations pour définir les blacklists. Voici un exemple de sources

 source localnet {
    ip 10.0.0.0/8
    192.168.0.0/16
 }

et voici une destination, ici en l'occurence une blacklist de sites pornographiques

 destination porno {
    domainlist porn/domains
    urllist porn/urllist
    expressionlist porn/expressions
 }

La valeur porn/domains définit le dossier porn et fichier domains.db dans celui-ci. Attention, on ne peut pas mettre plusieurs domainlist, urllist et expressionlist, seule la dernière sera prise en compte. La dernière directive principale à connaître est la directive ACL. Celle-ci définit les règles de filtrage que squidGuard va appliquer. On définit la source, et ce qui va passer.

 acl {
    localnet {
       pass !porno
       redirect http://localhost/403.html
    }

    admin {
       pass all
    }

    invites {
       pass none
       redirect http://localhost/403.html
    }
 }

Ces acl définissent que la source localnet peut accéder à tout sauf les sites et URLS de la liste porno, la source admin peut accéder à n'importe quoi et les invités n'ont aucun accès. Il est possible de pousser plus loin la chose en déclarant également des plages horaires. Par exemple, les sites de réseaux sociaux sont autorisés lors des pauses et refusés autrement. La définition d'une plage horaire se fait au moyen de la directive time.

# s = sun, m = mon, t =tue, w = wed, h = thu, f = fri, a = sat

time personnel-pause {
   weekly s     00:00 - 23:59
   weekly mtwhfa    12:00 - 14:00
}

L'ACL s'applique ensuite en se greffant sur une source de la manière suivante:

acl {
  personnel within personnel-pause {
        pass     !common-blacklist
  } else personnel {
        pass     !common-blacklist !social-networks
  }
}

Mise à jour automatique

Pour faire une mise à jour automatique de la blacklist créez le bash suivant pour mettez le dans le cron Version Linux

wget ftp://ftp.univ-tlse1.fr/pub/reseau/cache/squidguard_contrib/blacklists.tar.gz
tar xvzf blacklists.tar.gz
chown -R squid:squid /etc/squidguard/blacklists
rm blacklists.tar.gz
squidGuard -C all

Version BSD

wget ftp://ftp.univ-tlse1.fr/pub/reseau/cache/squidguard_contrib/blacklists.tar.gz
tar xvzf blacklists.tar.gz
chown -R _squid:_squid /etc/squidguard/blacklists
rm blacklists.tar.gz
squidGuard -f /etc/squidguard/squidguard.conf -C all

Ajouter des exceptions

Nous allons créer une whitelist afin de pouvoir facilement autoriser un site. Tapez la suite de commandes suivante:

mkdir /etc/squidguard/blacklists/exceptions/
touch /etc/squidguard/blacklists/exceptions/domains
touch /etc/squidguard/blacklists/exceptions/urllist

Ensuite ouvrez le fichier de configuration de squidGuard et créez l'ACL suivante:

 destination exceptions {
    domainlist exceptions/domains
    urllist exceptions/urllist
 }

et appliquez la ensuite à un ensemble, par exemple:

acl {
  personnel within personnel-pause {
        pass    exceptions !common-blacklist
  } else personnel {
        pass    exceptions !common-blacklist !social-networks
  }
}

Pour l'utiliser, il suffit d'aller dans /var/firewall/blacklists/exceptions. Ajoutez ensuite une ligne par domaine à autoriser dans le fichier domains. Par exemple:

 linkedin.com
 linkedin.fr
 viadeo.com

Ensuite fermez le fichier et tapez ceci: Version Linux:

squidGuard -C exceptions
killall squidGuard

Version BSD:

/usr/local/sbin/squidGuard -f /etc/squidguard/squidguard.conf -C exceptions
pkill squidGuard

Cela aura pour effet de régénérer les fichiers de la "blacklist" exceptions et de tuer les processus squidGuard lancés par squid. Squid relancera lui même les processus manquants.

OpenLDAP

Introduction

OpenLDAP est l'annuaire libre de référence. Il intègre l'ensemble des fonctionnalités que l'on peut attendre d'un annuaire, et se base sur un système de schémas. Chaque schéma définit un ensemble d'attributs et de contraintes associées qui vont définir l'objet associé.

Un annuaire LDAP se base sur une arborescence d'objets, dont chacun est indentifié par un DN (dinstinguished name), réparti dans des unités d'organisation (OU) sous une racine (origin)

Installation d'OpenLDAP

Sous FreeBSD, on va installer OpenLDAP 2.4

cd /usr/ports/net/openldap24-server
make install clean

Sélectionnez les options suivantes suivant votre besoin:

  • Fetch
  • BDB
  • Passwd
  • Sock
  • ODBC
  • TCP_Wrappers
  • Collect
  • DynGroup
  • DynList
  • PPolicy
  • ProxyCache
  • SeqMode
  • Unique
  • Valsort
  • SmbPwd
  • Dynamic-Backends

Configuration

La configuration d'OpenLDAP s'effectue dans le fichier /usr/local/etc/openldap/slapd.conf

Schémas de base

On va ajouter quelques schémas de base utiles à l'annuaire, nous permettant de définir ce qu'est une personne, une unité d'organisation et le schéma posix nécessaire pour que les UNIX s'appuient dessus (l'ordre est important)

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/misc.schema
include         /usr/local/etc/openldap/schema/nis.schema
include         /usr/local/etc/openldap/schema/openldap.schema

Racine LDAP

Il faut maintenant configurer la racine de l'annuaire. Editez la ligne suivante (cela peut ne pas correspondre à votre nom de domaine):

suffix          "dc=unix-experience,dc=fr"

Super utilisateur LDAP

L'utilisateur racine LDAP est l'objet qui a tous les pouvoirs sur l'annuaire, il n'existe pas forcément de manière visible dans l'arborescence et peut même être dans un chemin qui n'existe pas:

rootdn          "cn=admin,dc=unix-experience,dc=fr"

Afin de lui attribuer un mot de passe chiffré, exécutez la commande suivante:

slappasswd -s motdepasse
{SSHA}DRA+C7TAbDR+tWdD9x6cQBPnDKafBCLvY

Ensuite ajoutez le résultat de la commande au fichier slapd.conf, de la manière suivante:

rootpw {SSHA}DRA+C7TAbDR+tWdD9x6cQBPnDKafBCLvY

Lancement du service OpenLDAP

L'annuaire étant maintenant configuré de façon sommaire, on va désormais pouvoir le peupler et créer sa racine.

service slapd start

Créez un fichier root.ldif et entrez les données suivantes:

dn: dc=unix-experience,dc=fr
dc: unix-experience
objectClass: dcObject
objectClass: organization
o: unix-experience

dn: ou=people,dc=unix-experience,dc=fr
objectClass: top
objectClass: organizationalUnit
ou: people

La première entrée est l'origine LDAP, la seconde une première unité d'organisation contenant les utilisateurs dans des configurations standard.

On l'injecte désormais dans l'annuaire:

ldapadd -f root.ldif -D cn=admin,dc=unix-experience,dc=fr -W

Afin de vérifier que vos données sont présentes, on dump l'ensemble de l'annuaire:

slapcat

On aurait pu faire une recherche sur l'ensemble de l'annuaire

ldapsearch -b dc=unix-experience,dc=fr

Il faut noter qu'aucune identification n'est demandée, c'est parce qu'on est sur le serveur LDAP lui-même.

Support SSL

Un annuaire est un des éléments les plus sensibles d'un système d'informations. Celles-ci peuvent être extrêmement sensibles, il convient donc de les chiffres afin qu'elles ne puissent ni être interceptées ni altérées. On va rajouter la couche de chiffrement SSL au protocole LDAP.

On créée tout d'abord un certificat

openssl req -x509 -new -out ldap_cert.pem -keyout ldap_key.pem -days 3650 -nodes

Ensuite on définit le chemin vers les certificats au service OpenLDAP

TLSCertificateFile /usr/local/etc/openldap/ldap_cert.pem
TLSCertificateKeyFile /usr/local/etc/openldap/ldap_key.pem

Et enfin on active le support SSL en rajoutant les flags au service dans le fichier /etc/rc.conf

slapd_flags='-h "ldaps://0.0.0.0/ ldap://0.0.0.0/"'

Intégration du schéma SMB/MS-CHAP

Afin d'intégrer le schéma SMB à notre annuaire et ainsi pouvoir utiliser de l'authentification type MS-CHAPv2 voire de faire contrôleur de domaine Active Directory, on a besoin de quelques outils supplémentaires

cd /usr/ports/net/samba36
make KRB5_HOME=/usr/local
make install clean
cd /usr/ports/net/smbldap-tools
make install clean

On copie le schéma

cp /usr/local/share/examples/samba36/LDAP/samba.schema /usr/local/etc/openldap/schema/

et on l'intègre dans le slapd.conf:

include         /usr/local/etc/openldap/schema/samba.schema

Plus d'informations sur la gestion de ce schéma seront ajoutées ultérieurement.

Intégration du schéma Supann (enseignement supérieur)

Copiez le contenu de ce fichier dans le fichier /usr/local/etc/openldap/schema/supann.schema et supprimez les commentaires avec des accents qui risquent d'empêcher le démarrage d'OpenLDAP.

Ajoutez ensuite le schéma à OpenLDAP

include         /usr/local/etc/openldap/schema/supann.schema

Réplication OpenLDAP

Depuis la version 2.4 d'OpenLDAP, celui-ci intègre un mécanisme de réplication LDAP. Il était auparavant possible de configurer des serveurs maîtres esclave, mais cette fonctionnalité est plus intéressante dans un contexte de haute disponibilité et permet la répartition de charge.

Lorsqu'une donnée est altérée sur l'un des noeuds, celui-ci va envoyer, dès que la queue de réplication sera disponible, un ordre via LDAP pour définir la mise à jour sur les autres noeuds.

Si vous ne l'avez pas activé pour la compilation, activez le module syncprov et recompilez OpenLDAP.

Configuration de l'utilisateur de réplication

Il n'est pas recommandé d'utiliser le superutilisateur pour la réplication, on va donc configurer un compte de réplication:

dn: cn=replicator,ou=system,dc=unixperience,dc=it
objectClass: top
objectClass: organizationalPerson
userPassword: {SSHA}cqz/RnlJiooZ12aseBczGK87VrpR25mZ
sn: replicator
ldapadd -Z -c -f replica.ldif -D cn=admin,dc=unixperience,dc=it -W

Ouvrez le fichier slapd.conf afin de donner les droits d'écriture à l'utilisateur de réplication:

access to *
        by self write
        by dn="cn=replicator,ou=system,dc=unixperience,dc=it" write
        by anonymous auth

Configuration de la réplication

Chaque noeud LDAP possède un serverID l'identifiant au sein du cluster LDAP et un RID (replication ID) qui doit être identique sur chaque noeud.

serverID        1
overlay syncprov
syncprov-checkpoint 100 10
syncprov-sessionlog 100
syncrepl        rid=1
        provider=ldap://ldap2.unixperience.it:389/
        bindmethod=simple
        binddn="cn=replicator,ou=system,dc=unixperience,dc=it"
        credentials=r3pl1c@t0r
        searchbase="dc=unixperience,dc=it"
        schemachecking=on
        type=refreshAndPersist
        retry="5 +"
mirrormode on

La directive searchbase est pratique, car elle permet de n'effectuer qu'une réplication partielle de l'annuaire en sélectionnant une branche.

La directive retry définit un délai avant nouvel essai, ici 5 secondes. Le symbole + définit une boucle de nouvel essai. Il est possible de définir des périodes plus spéciques en inscrivant retry="5 10 30 60 180 +", ce qui aura pour effet d'essayer après 5,10,30... secondes.

Les directives de checkpoint sont extrêmement importantes, et les positionner comme ici devrait satisfaire vos besoins courants.

Amélioration de la sécurité

Empêcher de voir le mot de passe

Par sécurité vous pouvez empêcher les utilisateurs de voir leur mot de passe dans l'annuaire. ajoutez les règles suivantes, avant la règle globale d'accès:

access to attrs=userPassword
        by self =wx
        by * =x

Améliorations de performances

Configuration du cache

Dans le cas d'un annuaire très gros (plus de 3000 utilisateurs), avec énormément d'attributs, il peut être nécessaire de bien gérer le cache LDAP. Pour permettre à OpenLDAP d'utiliser plus de mémoire pour son cache copiez tout d'abord le fichier suivant:

cp /usr/local/etc/openldap/DB_CONFIG.example /var/db/openldap-data/DB_CONFIG

et éditez la ligne suivante (ici on affecte 768Mo de ram au cache)

 set_cachesize 0 768435456 1

Configuration de l'indexation

Lors de recherches, la notion d'index est un point fondamental. Certains attributs d'un annuaire peuvent être demandés afin de référencer un utilisateur et de le retrouver de manière régulière. Dans ce cas, il convient de réorganiser la base OpenLDAP en indexant efficacement. Ajoutez par exemple la ligne suivante:

index   cn,uid          eq

L'indexation se fait à froid. Coupez le service et lancez la commande suivante (avant de le redémarrer)

slapindex

Gestion au quotidien

Commandes générales

Ajout d'entrées dans l'annuaire

La commande permettant d'ajouter des entrées à l'annuaire LDAP est la suivante:

ldapadd -f /path/file.ldif

On peut également utiliser ldapmodify

ldapmodify -a -f /path/file.ldif

Si vous n'êtes pas sur la machine contenant l'annuaire ou que vous avez interdit la modification de l'annuaire de manière non authentifiée, tapez la commande suivante (il n'est pas nécessaire d'utiliser le super utilisateur LDAP, un utilisateur avec les droits d'écriture suffit):

ldapadd -x -D "cn=admin,dc=unix-experience,dc=fr" -W -f /path/file.ldif

Attention ! ldapadd ne fusionne pas une entrée, si elle existe la commande échouera et passera à l'entrée suivante.

Suppression d'une entrée de l'annuaire

La commande est très simple:

ldapdelete <dn>
ldapdelete < /path/file
ldapdelete -f /path/file

Dans le cas des fichiers, il s'agit d'une liste de DN (un DN par ligne).

Ajouter un groupe

Si cela n'existe pas, vous pouvez rajouter une OU dédiée aux groupes, afin de garder une vision claire de l'annuaire:

dn: ou=groups,dc=unix-experience,dc=fr
objectclass:organizationalunit
ou: groups
description: generic groups branch

Voici maintenant un fichier ldif simple contenant un groupe:

dn: cn=unixadm,ou=groups,dc=unix-experience,dc=fr
objectclass: groupofnames
cn: unixadm
description: UNIX admins
member: cn=titi.toto,ou=people,dc=unix-experience,dc=fr
member: cn=misc.user,ou=people,dc=unix-experience,dc=fr

Résolution de problèmes OpenLDAP

Si vous remarquez qu'OpenLDAP ne se lance pas, ou qu'il met énormément de temps à se lancer, une fois la commande de lancement effectuée, tuez la commande et démarrez OpenLDAP en mode debug. Pour se faire prenez votre ligne de commande slapd et ajoutez l'option -d 50. Exemple:

/usr/local/libexec/slapd -d 50 -h "ldapi://%2fvar%2frun%2fopenldap%2fldapi/ ldap://0.0.0.0/ ldaps://0.0.0.0/"

Cas du "unable to join the environment"

Cela signifie que votre base LDAP est inconsistante et qu'OpenLDAP ne comprend pas le contexte de la base (backend bdb). Il faut procéder à une récupération de la base via les commandes OpenLDAP/bdb associées. Pour se faire, tapez simplement la commande suivante (changez la version par votre version bdb ou ultérieure et le chemin par celui de votre distribution, ici FreeBSD):

db-recover4.6 -h /var/db/openldap-data

Patientez, normalement rien ne s'affiche et au bout d'un moment on vous rend la main. Vous devriez maintenant pouvoir démarrer OpenLDAP, le mode debug vous montrera si ca a marché.

Articles complémentaires

Nettoyer les logs d'OpenLDAP

PPTPD (Poptop)

Introduction

Les tunnels PPTP sont des tunnels qui sont intégrés nativement dans la plupart des OS depuis une dizaine d'années. S'appuyant sur PPP et ajoutant une couche d'authentification plus robuste voire du chiffrement, ils permettent aux utilisateurs distants de pouvoir se connecter à leur réseau d'entreprise.

Installation:

Sous Debian tapez la commande suivante:

aptitude install pptpd radiusclient1

Sous FreeBSD:

cd /usr/ports/net/poptop
make install clean

Configuration du service PPTPD

Ouvrez/créez le fichier /usr/local/etc/pptpd.conf (/etc/pptpd.conf sous Debian) et insérez les lignes suivantes:

#
# PPTPD configuration
#

name pptpd

# Authentication
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
require-mppe-128

plugin radius.so
plugin radattr.so

# Routing
proxyarp
nodefaultroute

# Misc
nobsdcomp
noipparam
logwtmp

Le nom est très important, car c'est ce nom qui permettra de faire le lien entre pptpd et pppd. Si le lien est incorrect et qu'il manque un label, l'erreur suivante apparaîtra dans les logs:

pptp: Configuration label not found

L'authentification est configurée au niveau de sécurité maximal sur MSChapv2, et on refuse explicitement toutes les autres méthodes. On active le chiffrement MPPE-128 bits sur la connexion et enfin on fait le lien avec le plugin du serveur radius.

Les options suivantes permettent

  • aux requêtes ARP d'aboutir (proxyarp)
  • de ne pas distribuer la route par défaut (nodefaultroute)
  • de ne pas utiliser la compression BSD (nobsdcomp) afin d'être interopérable
  • de loguer les connexion en WTMP (logwtmp)

Configuration de PPP (sous FreeBSD uniquement)

Adressage et tunnel

Ouvrez maintenant le fichier /etc/ppp/ppp.conf et ajoutez les lignes suivantes:

loop:
    set timeout 0
    set log phase chat connect lcp ipcp command
    set device localhost:pptp
    set dial
    set login
    set ifaddr 10.4.7.250 10.4.7.1-10.4.7.200 255.255.255.255
    add default HISADDR
    set server /tmp/loop "" 0177

loop-in:
    set timeout 0
    set log phase lcp ipcp command
    allow mode direct

pptp:
    load loop
    disable pap
    disable ipv6cp
    enable proxy
    accept dns
    enable MSChapV2
    enable mppe
    set dns 129.175.196.160
    set device !/etc/ppp/secure
    set radius /etc/ppp/radius.conf

Dans le label loop, changez les IP de ifaddr par celles que vous souhaitez, la première étant l'adresse du tunnel VPN. Il est important que le masque soit 255.255.255.255 afin que vous n'ayez pas de mauvaise surprise !

Dans le label pptp, spécifiez un serveur DNS afin que le client l'utilise de manière préférable à celui de sa connexion physique (accept dns puis set dns ), activez MSChapv2 (enable MSChapV2) et MPPE (enable mppe). On a désactivé IPCP pour IPv6 ici car notre réseau ne le supporte pas (disable ipv6cp).

Créez maintenant le fichier /etc/ppp/secure et insérez les lignes suivantes:

#!/bin/sh
exec /usr/sbin/ppp -direct loop-in

et rendez le exécutable:

chmod +x /etc/ppp/secure

Ceci permettra à PPP de créer une interface de loopback direct pour relier le tunnel et l'interface physique du serveur.

Authentification

Pour terminer on va configurer le serveur Radius en créant le fichier /etc/ppp/radius.conf

auth 10.4.3.1:1812 radPwd
acct 10.4.3.2:1813 radPwd2

Activation du service & NAT

Il faut maintenant nater le trafic du tunnel (à moins que vous ne souhaitiez le router), grâce à Packet Filter. Ouvrez le fichier pf.conf et ajoutez la ligne suivante:

nat on em0 inet proto { tcp, udp, icmp } from 10.4.7.0/24 to any -> <ip publique>

Editez le fichier /etc/rc.conf afin d'ajouter les lignes suivantes:

gateway_enable="YES"
pptpd_enable="YES"

Ensuite rechargez vos règles Packet Filter, activez le routage et lancez le service:

pfctl -f /etc/pf.conf
sysctl -w net.inet.ip.forwarding=1
service pptpd start

Configuration de PPP (Debian uniquement)

Adressage des clients

Dans le fichier /etc/pptpd.conf ajoutez les lignes suivantes permettant de configurer l'IP du tunnel et des clients:

localip 10.4.7.250
remoteip 10.4.7.1-250

Authentification

On va maintenant configurer l'authentification radius, ouvrez le fichier /etc/radiusclient/radiusclient.conf et modifiez les lignes suivantes:

authserver      10.4.3.1:1812
acctserver      10.4.3.2:1813

Ouvrez maintenant le fichier /etc/radiusclient/servers et ajoutez les mots de passe de vos serveurs radius

10.4.3.1 radPwd
10.4.3.2 radPwd2

Activation du service & NAT

Activez le routage en éditant le fichier /etc/sysctl.conf:

net.ipv4.ip_forward=1

puis ajoutez la ligne suivante au fichier /etc/rc.local (permettant le nat au démarrage)

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

et exécutez les lignes suivantes pour prendre en compte la configuration et lancer le service

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
service pptpd start

Sources

PPTPD + FreeRadius + MySQL

FreeRadius, serveur Radius OpenSource

Introduction

Freeradius est un serveur Radius libre permettant de s'authentifier. Le protocole radius permet de se connecter via un échange de paquets UDP, généralement sur le port 1812. Radius intègre également un module d'accounting, permettant par exemple de la facturation. Radius permet de s'authentifier via diverses moyens comme une authentification en clair, par adresse MAC, via base MySQL/PgSQL, protocole MSCHAPv1 et MSCHAPv2 ou encore annuaire LDAP.

Radius gère également le 802.1X avec l'authenfication via tunnel EAP (PEAP/TLS/TTLS), qui sera étudiée en fin de tutoriel.

Freeradius s'appuie sur un système de modules qui sont activés/désactivés lors des phases d'autorisation et d'authentification. Le service peut gérer différents serveurs virtuels, afin de pouvoir gérer plusieurs types d'authentifications conflictuelles, des tunnels internes ou encore des requêtes de proxy radius (en cas de chaînage de différents serveurs radius).

La phase d'autorisation (authorization) définit les modules qui vont intervenir pour autoriser l'utilisateur à utiliser la connexion. La phase d'authentification va s'appuyer sur différents modules pour authentifier l'utilisateur, via son mot de passe ou son adresse MAC par exemple.

Installation

Pour installer Freeradius sous Debian, tapez la commande suivante (les paquets ne sont pas tous nécessaires):

aptitude install freeradius freeradius-ldap freeradius-mysql freeradius-postgresql

Pour l'installer sous FreeBSD:

cd /usr/ports/net/freeradius2
make install clean

Configuration

Allez dans le répertoire /usr/local/etc/raddb/ (/etc/freeradius/ sous Debian) pour trouver l'ensemble des fichiers de configuration. Sous Freeradius 2.x (celle qui sera utilisée tout au long de ce tutoriel) la configuration est répartie en dossiers de manière à simplifier l'administration.

Les différents dossiers sont:

  • certs: les certificats nécessaires pour le 802.1X
  • modules: l'ensemble des modules avec chacun un fichier de configuration séparée
  • sites-available/sites-enabled: a l'instar d'Apache, les différents serveurs virtuels radius
  • sql (si vous avez installé l'un des modules SQL): fichiers de configuration des différentes bases SQL

La configuration principale est lue à partir du fichier radiusd.conf, contenant la définition et les liens vers les modules et les serveurs virtuels.

Configuration générale

Nous allons tunner un peu la configuration du serveur avant de s'occuper de la partie authentification.

Afin de gagner en temps de réponse, augmentez la taille des buffers de requête, de manière à avoir environ 32 fois le nombre de clients simultanés (la configuration suggère 256 fois, ceci dit ne passez pas en dessous de 1024):

# Pour 300 clients simultanés environ
max_requests = 10240

Ensuite, si c'est activé, pensez à désactiver la résolution des noms d'hôte, de façon à gagner en traitement. Cette valeur ne doit être mise à 'yes' que si vous souhaitez vraiment avoir les noms d'hôte au lieu des adresses IP dans vos logs:

hostname_lookups = no

Dans la section log, afin de respecter les mesures de sécurité de votre SI, activez l'option permettant d'identifier les authentifications ayant échoué

auth_badpass = yes

Si votre réseau 802.1X a plus de 500 clients, il peut être judicieux d'augmenter le nombre de threads de traitement des requêtes en simultanés (32 pour 500 est suffisant), modifiez alors ceci le nombre de serveurs maximum et le nombre de serveurs en spare en conséquence, ou alors redondez et utilisez des load balancers:

max_servers = 32
min_spare_servers = 3
max_spare_servers = 10

Votre serveur est désormais taillé afin de pouvoir supporter le maximum de requêtes.

Voyons maintenant comment gérer les différents clients radius

Gestion des clients radius

Les clients radius ne sont pas les utilisateurs, mais les services/binaires qui vont permettre d'authentifier l'utilisateur, comme par exemple le client d'une borne Wifi, le mod_auth_xradius d'Apache et bien d'autres encore. Ouvrez le fichier clients.conf

client 127.0.0.1 {
        secret      = pwdTest
        shortname   = localhost
        nastype     = other     # localhost isn't usually a NAS...
}

client 192.168.12.0/24 {
        secret      = wifiPwd
        shortname   = wifiAP
        nastype     = other
}

Ce fichier contient les différents clients, identifiés par leur adresse IP ou adresse réseau. Chaque client utilise un secret afin de savoir s'il peut utiliser le serveur radius, et utilise un NASType, option bien souvent inutile ou obsolète. Il est conseillé de la positionner à other, par exemple si vous utilisez des bornes WiFi CISCO.

Voyons maintenant la partie authenfication. Nous étudierons tout d'abord une authentification simple, basée sur un annuaire LDAP, puis ensuite la couche EAP, avant de coupler les deux pour faire du 802.1X avec VLAN dynamiques.

Authentification via Annuaire LDAP

Ouvrez le fichier modules/ldap présent au sein des fichiers de configuration. Voici la configuration de base que vous devriez avoir afin de lier radius et LDAP:

ldap ldap_1 {
        server = "ldaps://ldaps.domain.tld"
        identity = "cn=admin,dc=domain,dc=tld"
        password = admPwd
        basedn = "ou=people,dc=domain,dc=tld"
        filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
        dictionary_mapping = "${raddbdir}/ldap.attrmap"
        ldap_connections_number = 5
        access_attr = "uid"
        timeout = 4

        timelimit = 3

        net_timeout = 1

        tls {
                start_tls = no
        }
        set_auth_type = yes
        edir_account_policy_check = no
}

Cette configuration permet de définir un module de type LDAP nommé _ldap1. Les premiers champs sont les champs classiques du LDAP (URI, RootDN, RootPwd, BaseSearch, Filter). Vous remarquerez que le filtre est un peu plus complexe que d'habitude. Afin de pouvoir trouver l'utilisateur en fonction de son uid, il faut passer par l'attribut radius Stripped-User-Name.

On va indiquer un dictionnaire LDAP. Ce dictionnaire est ESSENTIEL, puisqu'il va servir à permettre d'aller chercher certain attributs permettant l'authentification, notamment via le module MSCHAP pour 802.1X.

Le champ access_attr permet d'accélérer le traitement des authentifications en indiquant l'attribut de référence qui permet de définir si un utilisateur existe. SI l'utilisateur n'a pas été trouvé, le serveur radius indiquera directement echec en sortie d'autorisation (hormis si vous spécifiez plusieurs types d'authentifications en parallèle), et ne cherchera pas à savoir si l'utilisateur a mis le bon mot de passe, ou a utiliser un tunnel EAP par exemple.

Les autres champs permettent de définir les différents timeout et éventuellement les options TLS, si vous l'utilisez.

Maintenant que le serveur ldap est défini, nous allons l'activer dans les phases d'autorisation et d'authentification. Ouvrez le fichier sites-enabled/default

authorize {
        preprocess
        suffix
        files
        group {
                ldap_1
        }
}

authenticate {
        unix

        Auth-Type LDAP1 {
                ldap_1
        }
}

# --- fin non exhaustive --- #

Nous créons dans la section authorize un groupe dans lequel se trouve l'appel à notre module ldap_1 (attention l'indentation est importante). Ce groupe permet de définir un ensemble de serveurs qui peuvent servir à authentifier l'utilisateur. Par exemple si votre entreprise possède un OpenLDAP et un ActiveDirectory avec deux identifiants/mots de passe différents, cela permet de pouvoir s'authentifer sur l'un OU l'autre. Sans la notion de groupe ce serait l'un ET l'autre.

Dans la section authenticate, on créé un type d'authentification LDAP1 qui utilise le module ldap_1. L'Auth-Type permet de pouvoir positionner la variable Auth-Type avec la valeur associée afin de pouvoir effectuer des tests dessus, notamment via le fichiers users, étudié plus loin dans ce tutoriel.

Vous pouvez désormais lancer votre serveur radius (voir plus loin) en mode démon, ou en mode debug afin de tester la configuration.

Authentification via Tunnel EAP

Un tunnel EAP est un tunnel chiffré et négocié entre le client radius et le serveur. Il existe différents types d'EAP, avec différents niveaux de sécurité:

  • PAP: authentification en clair
  • MD5: authentification en clair avec mot de passe hashé en MD5
  • PEAP: authentification via tunnel TLS
  • TTLS: authentification par certificat (PKI)
  • LEAP: protocole CISCO

Nous étudierons ici l'authentification PEAP, plus simple à mettre en place via l'authentification MSCHAP. Il existe également PEAP avec authentification GTC.

Ouvrez tout d'abord le fichier eap.conf

eap {
      default_eap_type = peap
      timer_expire     = 60
      ignore_unknown_eap_types = no
      max_sessions = 4096
      tls {
              certdir = ${confdir}/certs
              cadir = ${confdir}/certs
              private_key_password = whatever
              private_key_file = ${certdir}/server.key
              certificate_file = ${certdir}/server.pem
              CA_file = ${cadir}/ca.pem
              dh_file = ${certdir}/dh
              random_file = ${certdir}/random
              CA_path = ${cadir}
              make_cert_command = "${certdir}/bootstrap"
      }
      peap {
               default_eap_type = mschapv2
               copy_request_to_tunnel = yes
               use_tunneled_reply = yes
               virtual_server = "inner-tunnel"
      }
      mschapv2 {
      }
}

On définit tout d'abord le type d'eap par défaut à PEAP. Ceci permet d'initier la connexion via le tunnel PEAP lorsqu'EAP sera sollicité. Pour la sécurité, vous pouvez définir d'ignorer les types EAP non connus (non définis) sur le serveur Radius. Le nombre de sessions EAP simultanées à été défini à 4096, sachant que chaque requête peut engendrer entre 2 et 3 sessions suivant le type d'EAP utilisé.

La section TLS permet de définir les certificats utilisés. Ici ce sont les certificats par défaut, mais je vous convie à en générer de nouveaux au nom de votre entreprise, signés ou auto-signés suivant la situation.

La section peap est la plus intéressante ici. Tout d'abord on va redéfinir le type d'EAP à utiliser en tant que mschapv2, ce qui permettra d'utiliser l'authentification via NT-Password. On va ensuite activer deux éléments essentiels au 802.1X, notamment pour l'attribution dynamique de VLANs, ce sont la copie de la requête dans le tunnel et la copie de la réponse du tunnel dans la réponse EAP (ce qui permet ainsi de ramener des attributs de l'authentification MSCHAPv2, autrement ce ne serait pas possible). Pour finir, on définit un serveur virtuel local qui va permettre de traiter l'authentification MSCHAPv2.

EAP est maintenant correctement configuré, ouvrez maintenant le fichier ldap.attrmap et ajoutez les lignes suivantes:

checkItem       LM-Password                     sambaLmPassword
checkItem       NT-Password                     sambaNtPassword

En ajoutant ces lignes vous pourrez utiliser les attributs LDAP NT-Password et LM-Password avec l'authentification MS-CHAPv2

Maintenant que les attributs LDAP sont mappés, ouvrez sites-enabled/default:

authorize {
        preprocess
        mschap

        suffix
        eap {
                ok = return
        }

        files
        group {
                ldap_1
        }
}

authenticate {
        Auth-Type MS-CHAP {
                mschap
        }

        unix

        Auth-Type LDAP {
                ldap_1
        }

        Auth-Type eap {
                eap {
                        handled = 1
                }
                if (handled && (Response-Packet-Type == Access-Challenge)) {
                        attr_filter.access_challenge.post-auth
                        handled  # override the "updated" code from attr_filter
                }
        }
}

# sortie volontairement omise

post-proxy {
        eap
}

Vous remarquerez quelques ajouts par rapport à la section précédente concernant LDAP. On doit activer EAP dans la section authorize. La sous section ok=return permet de définir de ne pas aller ailleurs si cette autorisation s'est bien déroulée.

La section authenticate contient maintenant en plus le type MS-CHAP et eap. quelques instructions et modules supplémentaires sont invoqués afin de parfaire l'échange au sein du tunnel.

La section post-proxy a été complétée, si vous utilisez le mode proxy sur votre serveur Radius, afin que l'échange EAP se termine correctement dans ce cas là.

Ouvrez maintenant le fichier sites-enabled/inner-tunnel

authorize {
        mschap
        suffix
        update control {
               Proxy-To-Realm := LOCAL
        }
        eap {
                ok = return
        }
        files
        group {
                ldap_1
        }
}

authenticate {
        Auth-Type MS-CHAP {
                mschap
        }
        unix
        eap
}

post-proxy {
        eap
}

La configuration est similaire ici au serveur par défaut. La section update control permet de forcer la mise à jour de la requête afin de définir que le Realm utilisé est LOCAL. Vous remarquerez qu'ici on n'utilise pas l'authentification LDAP, ceci est dû au fait que PEAP va s'appuyer sur le module MS-CHAP au sein du tunnel.

On aurait pu se passer de MS-CHAP et forcer l'authentification en LDAP ici, mais il aurait fallu que l'attribut userPassword de l'annuaire soit en clair, ce qui est fortement déconseillé !

Attention ! Utilisant le protocole d'authentification MSCHAP, il faut obligatoirement avoir le schéma et les attributs remplis dans votre annuaire !

Ceci conclut cette partie sur EAP. Cela permettra de faire du 802.1X statique au sein de votre réseau (en WiFi, via WPA/WPA2 Enterprise notamment).

VLAN dynamiques via 802.1X (Méthode 1)

La puissance de 802.1X réside dans l'attribution dynamique de VLAN, en fonction de catégories d'utilisateurs et/ou de permissions et de politique de sécurité.

L'ensemble de la configuration ne sera pas redétaillé ici, il suffit de reprendre la configuration sur EAP et de s'appuyer sur un annuaire LDAP. Afin de configurer l'attribution dynamique de VLANs, deux choix apparaissent.

Le premier, et le plus simple à mettre en oeuvre, est celui de l'annuaire qui founit la configuration 802.1X.

Sur votre annuaire LDAP, rajoutez le schéma radius adapté. Ouvrez ensuite le fichier ldap.attrmap et rajoutez l'ensemble des lignes suivantes:

checkItem       Expiration                      radiusExpiration
checkItem       NAS-IP-Address                  radiusNASIpAddress
replyItem       Service-Type                    radiusServiceType
replyItem       Framed-Protocol                 radiusFramedProtocol
replyItem       Framed-IP-Address               radiusFramedIPAddress
replyItem       Framed-IP-Netmask               radiusFramedIPNetmask
replyItem       Framed-Route                    radiusFramedRoute
replyItem       Framed-Routing                  radiusFramedRouting
replyItem       Filter-Id                       radiusFilterId
replyItem       Framed-MTU                      radiusFramedMTU
replyItem       Framed-Compression              radiusFramedCompression
replyItem       Login-IP-Host                   radiusLoginIPHost
replyItem       Login-Service                   radiusLoginService
replyItem       Login-TCP-Port                  radiusLoginTCPPort
replyItem       Callback-Number                 radiusCallbackNumber
replyItem       Callback-Id                     radiusCallbackId
replyItem       Framed-IPX-Network              radiusFramedIPXNetwork
replyItem       Class                           radiusClass
replyItem       Session-Timeout                 radiusSessionTimeout
replyItem       Idle-Timeout                    radiusIdleTimeout
replyItem       Termination-Action              radiusTerminationAction
replyItem       Login-LAT-Service               radiusLoginLATService
replyItem       Login-LAT-Node                  radiusLoginLATNode
replyItem       Login-LAT-Group                 radiusLoginLATGroup
replyItem       Framed-AppleTalk-Link           radiusFramedAppleTalkLink
replyItem       Framed-AppleTalk-Network        radiusFramedAppleTalkNetwork
replyItem       Framed-AppleTalk-Zone           radiusFramedAppleTalkZone
replyItem       Port-Limit                      radiusPortLimit
replyItem       Login-LAT-Port                  radiusLoginLATPort
replyItem       Reply-Message                   radiusReplyMessage
replyItem       Tunnel-Type                     radiusTunnelType
replyItem       Tunnel-Medium-Type              radiusTunnelMediumType
replyItem       Tunnel-Private-Group-Id         radiusTunnelPrivateGroupId

En ajoutant ce mappage d'attributs au serveur radius, celui-ci va lire les données de l'annuaire LDAP et les mapper à ses propres attributs. Les attributs qui nous intéressent pour le 802.1X sont les 3 derniers.

En positionnant les valeurs de Tunnel-Type à "VLAN", Tunnel-Medium-Type à "IEEE-802" et en inscrivant l'ID du VLAN dans le champ Tunnel-Private-Group-Id, vous renverez l'ordre à votre équipement de commuter l'utilisateur dans le VLAN associé.

Ce technique a le mérite d'être simple, mais alourdit votre serveur d'annuaire d'autant d'entrées que d'utilisateurs, ce qui peut dans certains cas s'avérer gênant. Dans certains cas également, il se peut que l'annuaire ne soit pas sous votre contrôle mais soit externalisé ou mutualisé, auquel cas vous ne pouvez pas opérer à cette manipulation, c'est pourquoi il existe une seconde alternative.

VLAN dynamiques via 802.1X (Méthode 2)

Toujours dans ce fichier ldap.attrmap, ajoutez cette fois-ci uniquement cette ligne:

checkItem       LDAP-Desc                     description

Cette entrée aura pour effet d'aller chercher le champ description de votre annuaire et de le mapper à l'attribut LDAP-Desc. Ce champ n'étant pas conventionnel, nous allons le déclarer dans le dictionnaire. Ouvrez le fichier dictionnary et ajoutez la ligne suivante en fin de fichier:

ATTRIBUTE  LDAP-Desc             3000    string

Le dictionnaire définit des attributs. Ici on créée un attribut LDAP-Desc d'ID 3000 sous forme de chaîne de caractères.

Note: Les attributs radius d'ID 3000 à 4000 ne sont pas rediffusés vers le client radius.

Maintenant que nous relions l'attribut LDAP description à notre attribut radius nous allons pouvoir l'utiliser. Ouvrez maintenant le fichier sites-enabled/innel-tunnel.

post-auth {
        if ("%{check:LDAP-Desc}" == "Administration") {
                update reply {
                        Tunnel-Private-Group-Id = 15
                }
        }
        elsif ("%{check:LDAP-Desc}" == "Recherche") {
                update reply {
                        Tunnel-Private-Group-Id = 18
                }
        }
        elsif ("%{check:LDAP-Desc}" == "Eleves") {
                update reply {
                        Tunnel-Private-Group-Id = 72
                }
        }
       else {
                update reply {
                        Tunnel-Private-Group-Id = 37
                }
        }

        update reply {
                Tunnel-Type = "VLAN"
                Tunnel-Medium-Type = "IEEE-802"
        }

        Post-Auth-Type REJECT {
                attr_filter.access_reject
        }
}

Ceci est la partie intéressante du 802.1X. Dans la section post-auth vous serez en mesure de scripter des éléments une fois l'authentification effectuée.

Dans le cas présent, on regarde la valeur de l'attribut radius LDAP-Desc, et suivant sa valeur, on définit un ID de VLAN (18 pour la recherche, 72 pour les élèves et 37 par défaut, si la valeur présente dans l'annuaire n'est pas connue). Avec la méthode update reply, on va ajouter/modifier un champ de la réponse à notre guise.

En sortie de phase, la réponse contiendra donc les deux définitions nécessaire au VLAN et l'ID du VLAN.

Ceci conclut notre partie sur le 802.1X et Freeradius. Vous êtes désormais en mesure de créer des Tunnels EAP avec attribution dynamique de VLAN, que ce soit en WiFi ou en filaire. Je vous convie à regarder la documentation de votre équipement afin de valider les fonctionnalités 802.1X.

Note: il faut que les VLAN soient connus de l'équipement pour que cela marche et il faut un bridge DotRadio/FastEthernet pour chaque VLAN qui sera attribué via le serveur Radius.

Authentification par adresse MAC et VLAN dynamique

L'authentification par adresse MAC permet de n'autoriser que certaines machines à accéder au réseau, et à défaut de les mettre dans un vlan dit guest. Nous allons ici nous appuyer sur une base SQL pour effectuer l'authentification des adresses MAC et leur attribuer un VLAN.

Créez un serveur virtuel dédié à l'authentification mac ou le fichier de configuration principal si votre serveur n'utilise pas d'autre (/usr/local/etc/raddb/sites-enabled/mac-auth dans notre cas) et insérez le contenu suivant:

server mac-auth {
listen {
       ipaddr = 0.0.0.0
       port = 2812
       type = auth
}

authorize {
    preprocess
    suffix

    if(!EAP-Message || User-Name) {
        sql
        if(!ok) {
            reject
        }
        else {
            update control {
                Auth-Type := Accept
            }
        }
    }
    else {
        eap
    }
    expiration
    logintime

}

authenticate {
    eap
}

session {
    radutmp
    sql
}

post-auth {
    sql

    update reply {
        User-Name = "%{request:User-Name}"
    }

    Post-Auth-Type REJECT {
        sql
        attr_filter.access_reject
    }
}

preacct {
    preprocess
}

accounting {
    sql
}
} # mac-auth server block

Nous écoutons ici sur toutes les interfaces sur le port 2812 UDP, afin de se différencier des autres hosts, vous pouvez le changer à volonté. EAP pouvant être utilisé pour les requêtes, il a été ajouté à l'authentication et à l'authorization. Les tentatives d'authentification ayant échouées sont loguées et l'accouting est effectué ici.

Le script en rouge permet de switcher de façon propre entre EAP et l'authentification normale via SQL suivant le type de requête radius.

Votre serveur radius est maintenant relié à la base de données MySQL. Maintenant voyons comme gérer efficacement l'authentification en base. Tout d'abord, on doit définir qu'on accepte l'adresse MAC dans la table radcheck.

INSERT INTO radcheck (username,attribute,op,value) VALUES ('001122334455','Auth-Type',':=','Accept');

Cette requête SQL permet d'ajouter l'adresse MAC 00:11:22:33:44:55 et de l'autoriser au niveau radius. Ici nous souhaitons aller plus loin et attribuer les VLAN dynamiquement. On va donc créer un groupe au sein du radius qui permettra de gérer les VLAN. Dans un premier temps on met les adresses dans un groupe:

INSERT INTO radusergroup (username,groupname,priority) VALUES ('001122334455','ADMIN',0);
INSERT INTO radusergroup (username,groupname,priority) VALUES ('ffcc22aa4455','COMPTA',0);
INSERT INTO radusergroup (username,groupname,priority) VALUES ('eacc22bb4488','COMPTA',0);

La seconde fonction intéressante se situe dans radgroupreply, qui permet d'ajouter des attributs à la réponse pour des groupes. Nous allons donc le faire.

INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('ADMIN','Tunnel-Private-Group-Id','=','18');
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('ADMIN','Tunnel-Type,'=','13');
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('ADMIN','Tunnel-Medium-Type','=','6');
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('COMPTA','Tunnel-Private-Group-Id','=','258');
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('COMPTA','Tunnel-Type,'=','13');
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('COMPTA','Tunnel-Medium-Type','=','6');

Cet ensemble de commandes permet d'ajouter le tag VLAN 18 aux machines faisant partie du groupe ADMIN et VLAN 256 aux machines du groupe COMPTA.

Lancement du service

Sous FreeBSD:

service radiusd start

Sous Debian:

service freeradius start

Tester la configuration

Si vous avez besoin de vérifier la configuration, deux éléments essentiels sont présent au sein de la solution. Tout d'abord, vous pouvez mettre le service en mode Debug. Pour cela éteignez le et lancez la commande

radiusd -X

Ce mode d'allumage en premier plan va permettre d'affichier le suivi des requêtes entrantes sur votre serveur radius et ainsi pouvoir debuguer les problématiques d'algorithmes, de mot de passe, de modules...

Deuxième outil essentiel (hors authentification EAP), la commande radtest permettra de se connecter à un serveur radius afin de tester l'authentification.

radtest username password localhost:1812 0 radiusSecret

Ceci conclut ce tutoriel sur Freeradius, en espérant qu'il vous aura éclairé.

Squid: Proxy Web, Authentification, Cache et Filtrage

Introduction

Squid est un service de proxy cache web. Il permet de filtrer, mettre en cache les informations et authentifier les utilisateurs. Cette solution puissante permet de pouvoir gérer efficacement son parc et de pouvoir répondre aux attentes du code des postes et télécommunications en matière de trafic Internet.

Installation

Sous Debian:

aptitude install squid

Sous FreeBSD:

cd /usr/ports/www/squid31
make install clean

Activez tous les modules dont vous avez besoin lorsque l'invite vous le demandera.

Configuration

La configuration de SQUID est extrêmement vaste et bien documentée. Elle se trouve dans /etc/squid3/squid.conf (/usr/local/etc/squid/squid.conf.documented sous FreeBSD)

Pour inclure des fichiers il suffit d'utiliser la directive suivante.

include <path>

Je vous suggère de découper le fichier squid.conf de la manière suivante, pour plus de simplicité:

  • squid.conf
  • squid.acl.conf (les définitions des listes d'accès)
  • squid.access.conf

Directives globales

Port de connexion, spécifie le port et l'interface d'écoute. Par défaut toutes les adresses sur le port 3128

http_port <host>:<port>

Les Listes d'accès

Les ACL sont des listes de contrôle, comme celles de cisco, basées sur le niveau 3 de la couche OSI. On distingue plusieurs type d'ACL:

  • ACL sur une plage d'adresses sources

Exemple:

acl compta_service src 10.4.15.0/25

on définit l'ACL nommée compta_service de source 10.4.15.0/25, donc un réseau et son masque court sur une plage IP donnée.

Note: On aurait pu mettre une IP précise plutôt qu'en réseau

  • ACL locale distante

Exemple:

acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1

Ici on autorise dans la règle to_localhost l'ensemble de la classe A 127.0.0.0/8 et son masque inverse. Comme vous le voyez on peut également utiliser l'IPv6 (::1)

  • ACL sur un port

Exemple:

acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https

Le fait de mettre plusieurs fois l'ACL correspond à une seule ACL avec plusieurs valeurs.

acl CONNECT method CONNECT

Cette règle est conseillée pour le TCP sinon cela risque de causer des soucis.

  • ACL sur des URLs

Vous pouvez également définir un mot à chercher dans une URL.

Exemple:

acl blacklisted_words url_regex porn warez blowjob

L'ACL blacklisted_words va faire un url_regex (expression régulière) et vérifier si les mots porn warez et blowjob sont dans l'URL.

  • ACL sur des domaines

On peut également bloquer des domaines (plus léger que la regex)

acl blacklisted_domains_cours dstdomain .facebook.com facebook.com .youtube.com

Cette ACL va bloquer les domaines distants facebook, youtube, dailymotion et deezer

Application des ACLs

Prenons un exemple afin de montrer l'application des ACL. Exemple:

http_access deny !sallemanip !cisco_service !admin

On refuse ici tous les trafics qui ne sont pas dans les ACL nommées. Le caractère "!" indique l'inverse d'une règle

http_access deny !Safe_ports

Ici de même on refuse les ports non autorisés

http_access deny CONNECT !SSL_ports

Et pour terminer on refuse les connexions sur un type de port donné

http_access deny blacklisted_domains !cisco_service

Cette règle va définir que l'on refuse les domaines blacklistés pour tout ce qui n'est pas matché par l'ACL cisco_service.

Mode transparent

Pour configurer le mode transparent 2 choses sont à faire : dans le fichier squid.conf, rajouter la directive transparent dans la directive http_port

http_port 3128 transparent

Il faut ensuite appliquer une redirection de ports vers le port de squid

Sous Debian:

iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 8080 -j REDIRECT --to-port 3128

Sous FreeBSD, dans le fichier de configuration de PacketFilter

rdr on em0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 3128
pass in on $int_if inet proto tcp from any to 127.0.0.1 port 3128 keep state
pass out on $ext_if inet proto tcp from any to any port www keep state

Lancement du service

Sous Debian:

service squid3 start

Sous FreeBSD:

service squid start

Configuration optionnelle

  • Limitations de bande passante

Squid intègre un filtrage de bande passante. Il faut savoir que cela consomme du CPU. Ici nous allons appliquer une limitation de bande passante à 1Mbit/sec pour chaque utilisateur du réseau 192.168.1.0/24

acl only1mbusers src 192.168.1.0/24
delay_pools 1
delay_class 1 3
delay_access 1 allow only1mbusers
delay_access 1 deny all
delay_parameters 1 512000/512000 -1/-1 128000/512000

Je vous invite à consulter le tutoriel du wiki de squid présent ICI pour plus d'informations

  • Login via LDAP

Pour vous authentifier sur un annuaire LDAP, il suffit de créer les directives suivantes dans le squid.conf

auth_param basic program /usr/lib/squid3/squid_ldap_auth -b "ou=people,dc=example,dc=com"
-h ldap.example.com
auth_param basic credentialsttl 3 hours
auth_param basic realm Merci de vous authentifier
auth_param basic children 5

Sous FreeBSD remplacer la ligne par:

auth_param basic program squid_ldap_auth -b "ou=people,dc=example,dc=com"
-h ldap.example.com
  • Login via AD

On va déjà installer les dépendances winbind, samba, krb5-config, krb5-user.

aptitude install winbind samba krb5-config krb5-user
  • Configuration de Samba

Ouvrez le fichier /etc/samba/smb.conf

[global]
   workgroup = DOMAIN
   password server = activedirectory
   realm = DOMAIN.TLD
   netbios name = squid-gateway
   server string = %h server
   dns proxy = no
   log file = /var/log/samba/log.%m
   max log size = 1000
   syslog = 0
   panic action = /usr/share/samba/panic-action %d
   security = domain
   encrypt passwords = true
   passdb backend = tdbsam
   obey pam restrictions = yes
   unix password sync = yes
   passwd program = /usr/bin/passwd %u
   passwd chat = *Entersnews*spassword:* %nn *Retypesnews*spassword:* %nn
*passwordsupdatedssuccessfully* .
   pam password change = yes
   load printers = no
   idmap uid = 10000-20000
   idmap gid = 10000-20000
   template shell = /bin/bash
   template homedir = /home/%D/%U
   winbind separator = +
   winbind enum groups = yes
   winbind enum users = yes
   winbind use default domain = yes
   prefered master = no
  • Configuration de Kerberos

Ouvrez maintenant le fichier /etc/krb5.conf

[libdefaults]
        default_realm = DOMAIN.TLD
        kdc_timesync = 1
        ccache_type = 4
        forwardable = true
        proxiable = true

        v4_instance_resolve = false
        v4_name_convert = {
                host = {
                        rcmd = host
                        ftp = ftp
                }
                plain = {
                        something = something-else
                }
        }
        fcc-mit-ticketflags = true
  [realms]
        DOMAIN.TLD = {
                kdc = activedirectory.domain.tld
                admin_server = mail@domain.tld
                default_domain = DOMAIN.tld
                a_server = activedirectory.domain.tld
        }
  [domain_realm]
        .domain.tld = activedirectory.domain.tld
        domain.tld = activedirectory.domain.tld
  [login]

  [appdefaults]
  pam = {
        debug = false
        forwardable = true
  }
  • Configuration du pam (uniquement sous Debian)

Pour terminer nous allons lier winbind au pam. Ouvrez /etc/nsswitch.conf

  passwd:         compat winbind
  group:          compat winbind
  shadow:         compat

  hosts:          files dns
  networks:       files

  protocols:      db files
  services:       db files
  ethers:         db files
  rpc:            db files

  netgroup:       nis
  • Redémarrage des services
   service winbind restart && service samba restart
  • Joindre le domaine
   net ads join -U administrateur
   kinit -V administrateur@DOMAIN.TLD
  • Vérification de la liaison au domaine

Pour Winbind:

wbinfo -u

Pour Kerberos:

klist

Pour Samba:

smbclient -L localhost -U DOMAIN\Administrateur

Il existe un problème de droits bien connu, pour le résoudre tapez les commandes suivantes:

usermod -G winbind_priv squid

Terminer par ceci pour relancer les pipes d'authentification NTLM

killall ntlm_auth
  • Configuration de Squid
auth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
auth_param ntlm children 5

Blocage de MSN-Messenger

Voici les ACL à implémenter:

   acl msnp req_mime_type -i ^application/x-msn-messenger$
   acl msnq rep_mime_type ^application/x-msn-messenger$
   http_reply_access deny msnp
   http_reply_access deny msnq

Blocage de Skype

On bloque l'user-agent de skype. Sur les version récentes, skype ne présente plus d'UserAgent. Aucun des navigateurs Internet récent ne naviguant sans UserAgent, on va donc bloquer ceci.

   acl Skype_UA browser ^skype^
   http_access deny Skype_UA
   acl invalidUserAgent browser S+
   http_access deny invalidUserAgent

OpenVPN

Introduction

OpenVPN est une solution open source de VPN tournant à la fois sous Linux, BSD, Mac et Windows. Un VPN permet d'établir un tunnel entre deux points et ainsi outrepasser certaines restrictions par exemple. Ces tunnels peuvent être en clair ou encore cryptés, compressés ou ne rediriger que certains flux. Nous allons étudier comment mettre en oeuvre de façon simple une solution openvpn. Installation

Que ce soit pour un client ou pour un serveur il suffira simplement de taper:

Sous Debian:

apt-get install openvpn

Sous FreeBSD:

pkg install openvpn
# Ou via les ports:
cd /usr/ports/security/openvpn
make install clean

Il faut absolument choisir l'option suivante lors de la configuration du port:

[*] PKCS11   Use security/pkcs11-helper

Configuration du serveur

Configuration préliminaire

Le dossier de configuration d'OpenVPN n'existe pas par défaut, nous allons le créer.

Sous Debian

mkdir -p /etc/openvpn

Sous FreeBSD

mkdir -p /usr/local/etc/openvpn/

Configuration des clés SSL

Un paquetage de scripts est disponible lors de l'installation d'OpenSSL, nous allons l'utiliser pour générer l'ensemble des clés de chiffrement.

Sous Linux:

cd /usr/share/doc/openvpn/examples/easy-rsa/2.0

Sous FreeBSD:

cd /usr/local/share/doc/openvpn/easy-rsa/2.0
chmod +x *

Le fichier vars permet de spécifier des options SSL de génération de clés, je vous suggère de l'ouvrir et de modifier les champs appropriés (KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, ...)

vi ./vars

Sous FreeBSD, il faudra utiliser bash/zsh afin que la commande export fonctionne, ainsi que la prochaine commande.

Ensuite nous allons exécuter ce fichier afin de garder la configuration dans l'environnement actuel

. ./vars

Afin de préparer la distribution des clés un petit script bien pratique permet de nettoyer toutes les données:

./clean-all

et maintenant nous allons générer les clés du serveur (diffle-hellman et le CA):

./build-ca
./build-server-key servername (ou build-key-server servername)
./build-dh

Configuration du serveur (mode tun)

Copiez les fichiers keys/ca.crt, keys/server.crt et keys/server.key dans ce dossier.

Nous allons maintenant décompresser le fichier de configuration d'exemple.

Sous Debian:

gunzip /usr/share/doc/openvpn/examples/sample-config-files/server.tar.gz
cp server.conf /etc/openvpn/server.conf
vi /etc/openvpn/server.conf

Sous FreeBSD:

cp /usr/local/share/doc/openvpn/sample-config-files/server.conf /usr/local/etc/openvpn/server.conf
vi /usr/local/etc/openvpn/openvpn.conf

Nous allons pouvoir désormais configurer openvpn. Commencez par éditer les lignes suivantes:

port 443
proto tcp

Ces règles permettront d'outrepasser la plupart des sécurités non intelligentes et ainsi de se connecter partout via le tunnel. Vous pouvez aussi spécifier le protocole UDP afin de gagner en rapidité mais il n'est pas dit que votre tunnel marche partout.

Modifiez la règle suivant afin de spécifier votre plage d'adresses locales:

server 10.1.4.0 255.255.255.0

Celle-ci définira le range 10.1.4.0/24 comme étant celui où sont l'ensemble des clients. Il est fortement conseillé d'utiliser des plages d'adresses IP non routables sur Internet (contenues dans 10.0.0.0/8, 172.16.0.0/16, 192.168.0.0/16 par exemple).

Maintenant nous allons nous intéresser au routage, la chose la plus importante. Chaque directive route enverra au client une commande lui imposant d'ajouter une route vers le tunnel VPN. Nous allons tout d'abord router comme il se doit le flux du VPN vers celui-ci

route 10.1.4.0 255.255.255.0

Ensuite, si vous souhaitez rediriger l'ensemble du trafic vers le tunnel, entrez simplement la commande suivante:

push "redirect-gateway def1"

Si vous ne souhaitez pas rediriger tout le trafic mais seulement certaines routes, utilisez plutôt le push route.

push route 8.8.0.0 255.255.0.0
push route 15.14.6.0 255.255.255.0

Lorsque vous serrez dans le tunnel VPN vous ne pourrez plus contacter votre DNS local, une directive permet de modifier votre DNS tant que la connexion est active.

push "dhcp-option DNS 147.56.36.197"

Voici deux options intéressantes en terme de gestion de clients. La première permet que les clients VPN se voient entre eux et la seconde permet d'autoriser plusieurs personnes à utiliser le même certificat (si non activé la seconde connexion sera rejetée)

client-to-client
duplicate-cn

Pour terminer gérons les logs:

log         /var/log/openvpn.log
log-append  /var/log/openvpn.log

Vous pouvez désormais lancer le service

service openvpn start

Il ne reste plus qu'à configurer le NAT et le routage.

Sous Linux, tapez les deux commandes suivantes, que je vous recommande de mettre dans le fichier /etc/rc.local afin qu'au redémarrage vous ne perdiez pas les règles:

echo "1" > /proc/sys/net/ipv4/conf/all/forwarding
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Sous FreeBSD, activez tout d'abord le routage et Packet Filter pour les prochains démarrages en ajoutant les lignes suivantes au fichier /etc/rc.conf:

gateway_enable="YES"
pf_enable="YES"

Puis activez les pour la configuration actuelle:

sysctl net.inet.ip.forwarding=1
pfctl -e

Configuration du client

Chaque client OpenVPN est défini par une clé SSL.Pour créer une clé SSL pour un client, il suffit d'aller dans le répertoire de easy-rsa et taper

./build-key name

Cela va générer un fichier .key et un fichier .crt qu'il faudra placer dans le dossier openVPN qui va bien. En ce qui concerne le fichier de configuration, vous en trouverez un ici: /usr/share/doc/openvpn/examples/sample-config-files/client.conf à vous de personnaliser le port et le serveur ainsi que le nom des certificats.

Attention, le client doit être lancé en root ou administrateur windows afin de pouvoir modifier les règles de routage. Authentification via LDAP

On va aller plus loin en poussant cette fois-ci vers l'authentification LDAP. Ceci permet de n'utiliser qu'un certificat unique et ainsi d'identifier les utilisateurs via votre annuaire favori.

Installez tout d'abord le paquet openvpn-auth-ldap.

Sous Debian:

apt-get install openvpn-auth-ldap

Sous FreeBSD:

pkg install openvpn-auth-ldap
# Ou via les ports
cd /usr/ports/security/openvpn-auth-ldap
make install clean

Créez un fichier nommé auth-ldap.conf dans le dossier /etc/openvpn et éditez les options afin de vous connecter sur votre annuaire

<LDAP>
      # LDAP server URL
      URL             ldap://ldap.domain.tld

      # Bind DN (If your LDAP server doesn't support anonymous binds)
      # BindDN                uid=Manager,ou=People,dc=example,dc=com

      # Bind Password
      # Password      SecretPassword

      # Network timeout (in seconds)
      Timeout         15

      # Enable Start TLS
      TLSEnable       no
  </LDAP>

  <Authorization>
      # Base DN
      BaseDN          "ou=people,dc=domain,dc=tld"

      # User Search Filter
      SearchFilter    "(uid=%u)"

      # Require Group Membership
      RequireGroup    false

      # Add non-group members to a PF table (disabled)
      #PFTable        ips_vpn_users
  </Authorization>

</LDAP>

Vous pouvez filtrer suivant le groupe ou encore via un filtre LDAP classique les utilisateurs.

On va ensuite binder le module sur le serveur OpenVPN en ajoutant la ligne suivante dans le fichier server.conf:

plugin /usr/lib/openvpn/openvpn-auth-ldap.so /etc/openvpn/auth/auth-ldap.conf

Vous pouvez désormais redémarrer le service. Pour que les clients soient invités à entrer leurs identifiants LDAP, il faut ajouter la directive suivante dans leur configuration.

auth-user-pass

Sans cette directive les clients ne pourront pas se loguer.

Samba + Active Directory

Introduction

Un serveur samba est un partage de fichiers de type Windows. Dans un environnement hétérogène régi par un contrôleur de domaine Active Directory il peut être utile de stocker les profils, documents et lecteurs réseaux sur des serveurs Linux. Nous allons voir comment configurer un serveur Linux pour faire serveur de fichiers Windows. Installation

3 méta packages sont nécessaires pour créer ce serveur de fichiers

apt-get install samba winbind acl libpam-mkhomedir

Configuration de winbind

Pour configurer le login via winbind éditez le fichier /etc/nsswitch.conf de la façon suivante :

passwd:         compat winbind
group:          compat winbind
shadow:         compat winbind
hosts:          files dns
networks:       files
protocols:      db files
services:       db files
ethers:         db files
rpc:            db files
netgroup:       nis

Création automatique de répertoire personnel

Afin que chaque utilisateur aie directement un homedir dès son premier login, il faut configurer le pam pour utiliser le module mkhomedir. Editez le fichier /etc/pam.d/common-account. Si la ligne suivante n'y est pas ajoutez la.

session    required     /lib/security/pam_mkhomedir.so skel=/etc/skel umask=0022

Le dossier /etc/skel contient les fichiers de base que vous souhaitez voir dans le répertoire de l'utilisateur à sa création Configuration de samba

Ouvrez maintenant le fichier /etc/samba/smb.conf. Nous allons l'intégrer au domaine AD existant en modifiant les paramètres suivants:

[global]
   workgroup = DOMAIN
# nom court de votre serveur AD
   password server = activedirectory
# domaine
   realm = DOMAIN.TLD
# nom du serveur de fichiers
   netbios name = hera-bis
# cohérence samba - AD
   security = domain
   encrypt passwords = true
   passdb backend = tdbsam
   obey pam restrictions = yes
   unix password sync = yes
# Spécifications AD
   idmap uid = 10000-20000
   idmap gid = 10000-20000
# On créé des homedir dans le répertoire /dta/homes/<username>
   template shell = /bin/bash
   template homedir = /data/homes/%U
   winbind enum groups = yes
   winbind enum users = yes
   winbind use default domain = yes
   prefered master = no
# quota disque
   max disk size = 10000

# Répertoires homes de l'utilisateur avec des droits corrects
[homes]
comment = Home Directories
browseable = no
writeable = yes
guest ok = no
directory mask = 2700
create mode = 0664
# conserver les droits Posix Windows
store dos attributes = yes
# les fichiers Linux commençant avec un . seront des fichiers cachés
hide dot files = yes
nt acl support = no

Enregistrement dans le domaine

On va joindre tout d'abord le domaine afin d'être reconnu du serveur Active Directory, entrez les identifiants d'un administrateur du domaine.

net ads join -U Administrateur%password

Afin de ne pas perdre la connectivité au domaine, rajoutez également la ligne suivante dans /etc/crontab

*/5 *   * * * root net ads join -U Administrateur%password

On va également rajouter dans le fichier /etc/rc.local la commande afin qu'elle soit effectuée au démarrage du serveur

net ads join -U Administrateur%password

Note: le fichier /etc/rc.local n'existe plus sur systemd. Il faut passer par une unit en mode oneshot

Lancement des services

Lancez maintenant les services

service samba start && service winbind start

Vous pouvez vérifiez que le domaine est joignable et lister les utilisateurs avec la commande wbinfo -u, et les groupes avec la commande wbinfo -g.

Votre serveur de fichiers samba est désormais relié à votre annuaire ActiveDirectory.

Syslog-ng

Introduction

Les logs sont l'élément essentiel de toute administration de systèmes et de réseaux. Ils permettent d'obtenir des informations concernant l'état des services, les diverses échecs, pannes, informations de comportement, qu'ont décidé de rendre visible les développeurs. Dans le monde Linux, les logs sont nettement plus poussés que dans le monde Windows. Ils sont le point clé de la compréhension de tout service.

Les logs sont stockés conventionnellement dans un dossier bien spécifique: /var/log, où ils sont répartis dans diverses fichiers/répertoires. La gestion des logs est effectuée par un démon que l'on appelle le syslog, par exemple rsyslog (par défaut sous Debian), syslog (version basique sur openSuse et redhat, ou encore syslog-ng.

Certains fichiers de logs sont des clés de voûte de la compréhension du comportement du système. Il s'agit de /var/log/syslog, qui contient les informations sur les services tournant sur la machine, de auth.log qui recence tous les problèmes d'authentification (PAM, SSH, ...) ou encore de kern.log qui correspond aux messages provenant du noyau linux. Les services ont également un log propre qui est généralement un fichier ou un ensemble de fichiers contenu dans un répertoire du nom du service.

Les logs ont généralement des niveaux de sévérité (DEBUG, INFO, WARN, CRIT, ...) qui correspondent au niveau de séverité du message qu'il fournit.

Conformément à la loi du 23 janvier 2006 du code des postes et communications électroniques (vous pourrez le lire ici), les administrateurs et ingénieurs systèmes ont pour obligation de garder une trace écrite non altérée des connections et des utilisations de leur réseau par les employés de l'entreprise dont ils ont la charge. Ces logs doivent être stockés sur un serveur extérieur, en théorie un serveur sur lequel vous n'aurez jamais la main, mais en partique c'est quasiment impossible, qui sera chargé de centraliser l'ensemble des logs de connexion et de navigation de vos utilisateurs. En cas d'enquête judiciaire, si une attaque de type terroriste ou contre la nation est véhiculée via votre réseau, vous devez avoir ses logs sous peine d'être sanctionnées.

Les logs doivent être conservés durant 1 an glissant au maximum. Ceux-ci sont consultable à volonté durant cette période mais n'auront de valeur juridique pour l'entreprise que durant les 6 mois suivant l'action enregistrée. Les logs ne peuvent être demandés aux divers services informatique de force sans l'accord d'un juge assermenté.

Cette problématique juridique, nous conduit donc sur ce tutoriel. Comment mettre en oeuvre un serveur de logs sécurisé respectant l'ensemble des conditions légales permettant à votre entreprise d'être "sur les rails". Serveur de logs Installation

Nous allons ici utiliser le paquet syslog-ng pour sa puissance et le paquet logrotate pour la fonction de glissement des logs.

apt-get install syslog-ng logrotate

Configuration des logs glissants

Nous allons tout d'abord configurer le glissement. Ouvrez le fichier /etc/logrotate.conf

monthly
rotate 12
create

/var/log/* {
    monthly
    rotate 12
    create 640 root adm
    compress
}

include /etc/logrotate.d

Ce fichier de configuration définit le logrotate tous les ans, avec création du fichier une fois supprimé au bout d'un an. La section /var/log/* définit des droit particulier sur les fichiers de ce répertoire. La directive enrichie create permet de définit les droits et propriétaires du fichier. La directive compress définit la compression du fichier une fois la taille de celui-ci trop grande.

Vous trouverez également dans le dossier logrotate.d des scripts particuliers à chaque service qu'il faudra reconfigurer pour faire perdurer 1 an.

Configuration du serveur de logs

Configurons maintenant le service syslog-ng. Ouvrez le fichier /etc/syslog-ng/syslog-ng.conf et supprimez l'ensemble du contenu pour refaire une configuration au propre

options { long_hostnames(on); flush_lines(0); use_dns(no); use_fqdn(no);
        owner("root"); group("adm"); perm(0640); stats_freq(0);
        bad_hostname("^gconfd$");
};

source s_src { unix-dgram("/dev/log"); internal();
           file("/proc/kmsg" program_override("kernel"));
};

source s_net { udp(port(65001)); };

destination net_auth{ file("/ARCHIVED-LOGS/$HOST/$YEAR/$MONTH/$DAY/auth.log" create_dirs(yes)); };
destination local_logs{ file("/var/log/syslog" create_dirs(yes)); };

filter f_debug { match("debug"); }
filter f_auth { not filter(f_debug); };

log { source(s_net); filter(f_auth); destination(net_auth);};
log { source(s_src); destination(local_logs);};

Les options en début de fichier permettent de définit l'utilisation des noms DNS des machines, le propriétaire des fichiers de logs et les permissions associées à celui ci.

Les logs avec syslog-ng sont managés par 3 catégories spécifiques:

  • La source

La source est l'endroit d'où proviennent les logs. Dans le cas de s_src il s'agit des logs de la machine. Nous les enverrons ici vers le syslog classique. Pour s_net, ces logs seront archivés et reçus sur le port 65001 qu'écoutera le serveur de logs. Il est conseillé d'utiliser UDP pour gagner du temps au vu du nombre d'entrées qui vont transiter sur le réseau.

  • La destination

La destination définit le lieu où vont être écrits les logs. Ici nous utilisons des variables syslog-ng afin de répartir les logs dans des répertoires correspondant à des machines, puis par année, mois, jour. L'option create_dirs doit être positionnée à yes afin d'éviter à avoir à créer les dossiers soit même à la main chaque jour.

  • Le filtre

Le filtre va permettre de pouvoir interragir avec le log pour le classer de façon plus précise. Notre filtre f_auth va vérifier que le log est bien un log d'authentification qui n'est pas un log de debug pour le mettre dans auth.log. La directive match permet de définir le filtre à vrai si la chaîne est trouvée dans le log et est très pratique, par exemple pour apache afin de séparer les diverses erreurs HTTP.

Pour terminer, la directive log va prendre une ou plusieurs sources, filtrée ou non par un ou plusieurs filtres et l'envoyer vers une ou plusieurs destinations.

La puissance du syslog-ng réside dans la hiérarchisation logique de vos logs. Avec ces 3 éléments vous avez de quoi logguer de façon efficace vos serveurs. Vous pouvez bien entendu écouter plus de ports pour pouvoir hiérarchiser vos logs encore plus efficacement en définissant quel service utilisera quel port.

Maintenant étudions le comportement niveau client.

Configuration côté client

Sur vos switches CISCO, Dell... la manipulation est très simple

logging 10.0.0.250

Le paquet sera envoyé en UDP sur le port 514

Maintenant étudions sur les machines Linux, installez le paquet syslog-ng s'il n'y est pas puis ouvrez le fichier /etc/syslog-ng/syslog-ng.conf

options { long_hostnames(off); flush_lines(0); use_dns(no); use_fqdn(no);
        owner("root"); group("adm"); perm(0640); stats_freq(0);
        bad_hostname("^gconfd$");
};

source s_src { unix-dgram("/dev/log"); internal();
           file("/proc/kmsg" program_override("kernel"));
};
source s_apache2 { file("/var/log/apache2/access.log"); };

destination log_server {udp("serveurdelogs.lan" port(65001)); };
destination log_local_server { file("/var/log/local_syslog };
destination log_local_apache { file("/var/log/apache2/local_access.log};

log { source(s_src); destination(log_server); destination(log_local_server)};
log { source(s_apache2); destination(log_server); destination(log_local_apache)};

Les directives sont similaires à celles du serveur de log, seul changement, la destination est un serveur en UDP sur le port 65001 comme le définit la directive:

udp("serveurdelogs.lan" port(65001));

Nous stockons une copie en local pour la simplicité d'utilisation, de surcroît, mais avec un nom différent. Pourquoi un nom différent ? Si vous ne faîtes pas ceci vous allez engendrer une boucle infinie de lecture écriture qui va saturer l'ensemble de la place disponible sur votre disque dur en moins de 10 minutes.

Et on termine par le redémarrage du service

service syslog-ng restart

Vous savez désormais manipuler le syslog-ng et stocker vos logs de manière centralisée.

PAM+LDAP

Introduction

Les annuaires sont de nos jours de plus en plus utilisés afin de centraliser les informations et l'identification des utilisateurs. Que ce soit un ActiveDirectory (Microsoft) ou un OpenLDAP, il est souvent nécessaire de pouvoir permettre aux équipements de se connecter dessus.

Dans certains établissements, les DSI ont choisi d'authentifier les utilisateurs des machines via leur annuaire. Pour les utilisateurs Windows, il suffira simplement d'utiliser un ActiveDirectory, coûteux et pratique, mais les utilisateurs Linux se retrouvent de côté.

Nous allons vous montrer dans ce tutoriel comment permettre à votre machine Linux (client ou serveur) d'autoriser l'authentification LDAP via le PAM.

Installation

Afin d'installer l'authentification ldap nous allons utiliser le gestionnaire de paquets

apt-get install libpam-ldap libpam-cracklib libpam-mkhomedir

Le paquet libpam-mkhomedir permettra de créer les répertoires utilisateurs au premier login. Configuration

Ouvrez le fichier /etc/nssswitch.conf et vérifiez que les champs passwd, group et shadow renseignent bien le mot-clé ldap.

passwd:         files ldap
group:          files ldap
shadow:         files ldap

L'ordre des mots clés signifie que pam va tout d'abord chercher l'utilisateur dans les fichiers puis sur le serveur LDAP.

Nous allons maintenant configurer la connexion LDAP. Ouvrez (ou créez) le fichier /etc/libnss-ldap.conf et configurez comme ci-dessous:

host ldapserver # nom de l'host
uri ldap://ldap.domain.tld # uri de LDAP
ldap_version 3
binddn cn=ldap,dc=domain,dc=tld
bindpw myldappwd
rootbinddn cn=ldap,ou=read-only,dc=domain,dc=tld
port 389
bind_policy soft # booter le service meme si certaines erreurs de connexion
pam_filter objectclass=* # filtre les entrées qui peuvent utiliser le PAM

Le mot de passe de l'utilisateur LDAP n'est pas indiqué. Les concepteurs de la solution ont choisi de le déporter dans le fichier Si vous avez lu, l/etc/libnss-ldap.secret.

Ouvrez donc le fichier et renseignez le mot de passe. N'oubliez pas de retirer l'accès en lecture aux utilisateurs non sollicités. Application de la configuration

service slapd restart

Vos utilisateurs peuvent désormais se connecter en login LDAP sur vos machines linux.