FreeRADIUS 2

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é.

See Also