[ Accueil ] [ FreeRADIUS ] [ Pour les VLANs ] [ Pour WPA2 ] [ Révocations ]
RADIUS (Remote Authentication Dial-In User Service) est un vaste programme. Pour essayer de faire simple (donc schématique et incomplet), ce service est capable :
Etudier dans le détail toutes les possibilités de RADIUS est hors de la portée de cet exposé. (c'est, de toutes façons, également hors de ma propre portée). Nous nous contenterons ici de le mettre en oeuvre dans les deux cas qui nous intéressent :
Installer et surtout configurer un serveur radius pour la première fois a quelque chose d'assez rebutant, voire repoussant. Nous allons passer un peu de temps à détailler cette opération, ceci aidera probablement ceux qui n'ont encore jamais tenté l'aventure. Nous utilisons FreeRADIUS sur une Debian Etch.
FreeRadius peut fonctionner en s'appuyant uniquement sur des fichiers texte. Ce n'est pas forcément ce qu'il y a de plus simple à gérer, si l'on doit manipuler un grand nombre de clients. Ici, nous utiliserons MySQL pour stocker les adresses MAC des clients. Outre la souplesse qu'apportent des outils comme phpmyadmin pour gérer la liste des clients, cette solution offre l'avantage de ne pas nécessiter de redémarrage de FreeRADIUS à chaque modification de la base.
Pour des raisons de compatibilité de licences, FreeRadius est compilé par défaut sur Debian sans le support de TLS (ni de Postgresql). TLS nous servira pour le WPA2. Nous allons donc reconstruire un paquet binaire à partir du paquet source, en tenant compte de cet usage.
Nous aurons besoin de quelques outils de compilation et de gestion des paquets source :
# apt-get install build-essential ... # apt-get install apt-src
Puis nous devons mettre à jour la liste des paquets source :
# apt-src update
Enfin, nous installons le paquet source de FreeRadius dans un répertoire que nous aurons créé dans ce but. La commande apt-src install offre, entre autres, l'avantage d'installer automatiquement les dépendances.
# mkdir ~/build_freeradius # cd ~/build_freeradius # apt-src install freeradius
Nous devons retrouver dans notre répertoire :
# ls -l total 2552 drwxr-xr-x 15 root root 4096 2007-01-11 16:35 freeradius-1.1.3 -rw-r--r-- 1 root root 15130 2006-09-01 20:07 freeradius_1.1.3-3.diff.gz -rw-r--r-- 1 root root 975 2006-09-01 20:07 freeradius_1.1.3-3.dsc -rw-r--r-- 1 root root 2587376 2006-09-01 20:07 freeradius_1.1.3.orig.tar.gz
Dans le répertoire ~/build_freeradius/freeradius-1.1.3/debian nous avons un fichier nommé "rules", qui contient les directives de compilation. Dans ce fichier, nous trouvons dans les premières lignes, quelques informations qui nous intéressent :
# If you want to use SSL and/or the postgres module, comment # out these two lines and uncomment the two after # You will also need to add a Build-Depends on libssl-dev and libpq-dev # and remove the Build-Conflicts on libssl-dev # Finally you need to cat debian/control.postgresql >> debian/control
Tant que nous y sommes, ajoutons le support de Postgresql, ce qui simplifiera la manipulation et permettra à ceux qui préfèrent, d'utiliser Postgresql plutôt que MySQL.
La première modification est facile à réaliser :
#buildssl=--without-rlm_eap_peap --without-rlm_eap_tls --without-rlm_eap_ttls --without-rlm_otp --without-rlm_sql_postgresql --without-snmp #modulelist=krb5 ldap sql_mysql sql_iodbc buildssl=--with-rlm_sql_postgresql_lib_dir=`pg_config --libdir` --with-rlm_sql_postgresql_include_dir=`pg_config --includedir` modulelist=krb5 ldap sql_mysql sql_iodbc sql_postgresql
La seconde est peut-être moins évidente si l'on ne sait pas qu'il faut réaliser l'opération dans le fichier ~/build_freeradius/freeradius-1.1.3/debian/control :
Source: freeradius Build-Depends: debhelper (>= 5), libltdl3-dev, libpam0g-dev, libmysqlclient15-dev | libmysqlclient-dev, libgdbm-dev, libldap2-dev, libsasl2-dev, libiodbc2-dev, libkrb5-dev, snmp, autotools-dev, dpatch (>= 2), libperl-dev, libtool, dpkg-dev (>= 1.13.19), libssl-dev, libpq-dev Build-Conflicts:
Enfin, il faut ajouter à ce fichier le contenu de control.postgresql :
# cd ~/build_freeradius/freeradius-1.1.3/debian # cat control.postgresql >> control
Comme nous avons un peu bousculé les dépendances et les conflits, nous devons réparer ça :
# apt-get install libssl-dev libpq-dev
Si nous compilons maintenant le paquet binaire, nous obtiendrons des paquets ayant le même nom (version comprise), que les binaires de la distribution, et les mises à jour futures ne manqueront pas de nous remplacer notre construction à la première occasion.
Une solution élégante consiste à obtenir des paquets binaires, avec un nom différent. Pour ce faire, nous pouvons agir dans le fichier ~/build_freeradius/freeradius-1.1.3/debian/changelog en ajoutant quelques lignes en tête du fichier. Par exemple :
freeradius (1.1.3-3tls) unstable; urgency=low
* Add TLS support for compilation
-- Christian Caleca <for.spam.only@eme-enseignement.fr> Fri, 11 Jan 2007 15:46:11 +0100
freeradius (1.1.3-3) unstable; urgency=medium
* Fix POSIX compliance problem in init script. Closes: #403384.
-- Mark Hymers <mark@hymers.orgue.uk> Sat, 16 Dec 2006 20:45:11 +0000
...
Il nous reste à construire les binaires :
# cd ~/build_freeradius # apt-src build freeradius ... ... ... I: Successfully built in /root/build_freeradius/freeradius-1.1.3
# ls -l | grep deb$ -rw-r--r-- 1 root root 761896 2007-01-11 18:10 freeradius_1.1.3-3tls_i386.deb -rw-r--r-- 1 root root 114398 2007-01-11 18:09 freeradius-dialupadmin_1.1.3-3tls_all.deb -rw-r--r-- 1 root root 31892 2007-01-11 18:10 freeradius-iodbc_1.1.3-3tls_i386.deb -rw-r--r-- 1 root root 32586 2007-01-11 18:10 freeradius-krb5_1.1.3-3tls_i386.deb -rw-r--r-- 1 root root 46894 2007-01-11 18:10 freeradius-ldap_1.1.3-3tls_i386.deb -rw-r--r-- 1 root root 31836 2007-01-11 18:10 freeradius-mysql_1.1.3-3tls_i386.deb -rw-r--r-- 1 root root 32280 2007-01-11 18:10 freeradius-postgresql_1.1.3-3tls_i386.deb
Nous n'avons ici besoin que de deux de ces paquets :
# dpkg -i freeradius_1.1.3-3tls_i386.deb freeradius-mysql_1.1.3-3tls_i386.deb
Vérifions que Freeradius est bien lancé :
# ps aux | grep radius freerad 4118 0.0 0.8 44608 2224 ? Ssl 18:16 0:00 /usr/sbin/freeradius
Nous devons maintenant préparer une base Mysql et configurer FreeRadius pour qu'il s'en serve.
Nous supposons que Mysql est correctement installé. Nous utilisons ici :
# mysql -V mysql Ver 14.12 Distrib 5.0.30, for pc-linux-gnu (i486) using readline 5.2
Création de la Base " radius" et de l'utilisateur du même nom :
# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 12 Server version: 5.0.30-Debian_3-log Debian etch distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> create database radius; Query OK, 1 row affected (0.04 sec) mysql> grant all on radius.* to radius@'localhost' identified by 'epikoi'; Query OK, 0 rows affected (0.06 sec) mysql> exit Bye
La base est créée mais elle reste vide. Pour créer les tables, le paquet freeradius-mysql nous donne le schéma dans /usr/share/doc/freeradius/examples/mysql.sql.gz :
# zcat /usr/share/doc/freeradius/examples/mysql.sql.gz | mysql -u root -p radius Enter password: #
Tout semble s'être correctement passé. Vérification :
# mysql -u radius -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 48 Server version: 5.0.30-Debian_3-log Debian etch distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> connect radius Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Connection id: 49 Current database: radius mysql> show tables; +------------------+ | Tables_in_radius | +------------------+ | nas | | radacct | | radcheck | | radgroupcheck | | radgroupreply | | radpostauth | | radreply | | usergroup | +------------------+ 8 rows in set (0.00 sec) mysql>
Assurez-vous que seules les options définies dans ce qui suit sont activées (certaines options dans radiusd.conf sont à dé commenter, d'autres sont à commenter).
authorize { preprocess eap sql }
authenticate { Auth-Type CHAP { chap } eap }
accounting { detail radutmp sql }
(Notez que cette section ne concerne pas l'authentification et qu'il est donc possible de la supprimer).
session { sql }
Voici un exemple complet de configuration, qui correspond à notre besoin du moment :
prefix = /usr exec_prefix = /usr sysconfdir = /etc localstatedir = /var sbindir = ${exec_prefix}/sbin logdir = /var/log/freeradius raddbdir = /etc/freeradius radacctdir = ${logdir}/radacct confdir = ${raddbdir} run_dir = ${localstatedir}/run/freeradius log_file = ${logdir}/radius.log libdir = /usr/lib/freeradius pidfile = ${run_dir}/freeradius.pid user = freerad group = freerad max_request_time = 30 delete_blocked_requests = no cleanup_delay = 5 max_requests = 1024 bind_address = * port = 0 hostname_lookups = no allow_core_dumps = no regular_expressions = yes extended_expressions = yes log_stripped_names = no log_auth = no log_auth_badpass = no log_auth_goodpass = no usercollide = no lower_user = no lower_pass = no nospace_user = no nospace_pass = no checkrad = ${sbindir}/checkrad security { max_attributes = 200 reject_delay = 1 status_server = no } $INCLUDE ${confdir}/clients.conf snmp = no thread pool { start_servers = 5 max_servers = 32 min_spare_servers = 3 max_spare_servers = 10 max_requests_per_server = 0 } modules { chap { authtype = CHAP } $INCLUDE ${confdir}/eap.conf checkval { item-name = Calling-Station-Id check-name = Calling-Station-Id data-type = string } preprocess { huntgroups = ${confdir}/huntgroups hints = ${confdir}/hints with_ascend_hack = no ascend_channels_per_line = 23 with_ntdomain_hack = no with_specialix_jetstream_hack = no with_cisco_vsa_hack = no } files { usersfile = ${confdir}/users compat = no } detail { detailfile = ${radacctdir}/%{Client-IP-Address}/detail-%Y%m%d detailperm = 0600 } acct_unique { key = "User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port" } $INCLUDE ${confdir}/sql.conf radutmp { filename = ${logdir}/radutmp username = %{User-Name} case_sensitive = yes check_with_nas = yes perm = 0600 callerid = "yes" } radutmp sradutmp { filename = ${logdir}/sradutmp perm = 0644 callerid = "no" } attr_filter { attrsfile = ${confdir}/attrs } counter daily { filename = ${raddbdir}/db.daily key = User-Name count-attribute = Acct-Session-Time reset = daily counter-name = Daily-Session-Time check-name = Max-Daily-Session allowed-servicetype = Framed-User cache-size = 5000 } sqlcounter dailycounter { counter-name = Daily-Session-Time check-name = Max-Daily-Session sqlmod-inst = sql key = User-Name reset = daily query = "SELECT SUM(AcctSessionTime - \ GREATEST((%b - UNIX_TIMESTAMP(AcctStartTime)), 0)) \ FROM radacct WHERE UserName='%{%k}' AND \ UNIX_TIMESTAMP(AcctStartTime) + AcctSessionTime > '%b'" } sqlcounter monthlycounter { counter-name = Monthly-Session-Time check-name = Max-Monthly-Session sqlmod-inst = sql key = User-Name reset = monthly query = "SELECT SUM(AcctSessionTime - \ GREATEST((%b - UNIX_TIMESTAMP(AcctStartTime)), 0)) \ FROM radacct WHERE UserName='%{%k}' AND \ UNIX_TIMESTAMP(AcctStartTime) + AcctSessionTime > '%b'" } always fail { rcode = fail } always reject { rcode = reject } always ok { rcode = ok simulcount = 0 mpp = no } expr { } digest { } exec { wait = yes input_pairs = request } exec echo { wait = yes program = "/bin/echo %{User-Name}" input_pairs = request output_pairs = reply } } authorize { preprocess sql eap } authenticate { Auth-Type CHAP { chap } eap } preacct { preprocess acct_unique files } session { sql }
Les fichiers de configuration de FreeRadius se trouvent dans /etc/freeradius. Commençons par le plus "simple" (en réalité, il n'est pas simple du tout, mais il y a peu de choses à y faire). Aménagez en fonction de vos choix lors de la création de la base. Voici un exemple complet, qui est dépouillé de la partie "accounting" :
sql { driver = "rlm_sql_mysql" server = "localhost" login = "radius" password = "epikoi" radius_db = "radius" acct_table1 = "radacct" acct_table2 = "radacct" postauth_table = "radpostauth" authcheck_table = "radcheck" authreply_table = "radreply" groupcheck_table = "radgroupcheck" groupreply_table = "radgroupreply" usergroup_table = "usergroup" nas_table = "nas" deletestalesessions = yes sqltrace = no sqltracefile = ${logdir}/sqltrace.sql num_sql_socks = 5 connect_failure_retry_delay = 60 sql_user_name = "%{User-Name}" authorize_check_query = "SELECT id, UserName, Attribute, Value, op \ FROM ${authcheck_table} \ WHERE Username = '%{SQL-User-Name}' \ ORDER BY id" authorize_reply_query = "SELECT id, UserName, Attribute, Value, op \ FROM ${authreply_table} \ WHERE Username = '%{SQL-User-Name}' \ ORDER BY id" authorize_group_check_query = "SELECT ${groupcheck_table}.id, \ ${groupcheck_table}.GroupName,${groupcheck_table}.Attribute, \ ${groupcheck_table}.Value,${groupcheck_table}.op \ FROM ${groupcheck_table},${usergroup_table} \ WHERE ${usergroup_table}.Username = '%{SQL-User-Name}' \ AND ${usergroup_table}.GroupName = ${groupcheck_table}.GroupName \ ORDER BY ${groupcheck_table}.id" authorize_group_reply_query = "SELECT ${groupreply_table}.id, \ ${groupreply_table}.GroupName,${groupreply_table}.Attribute, \ ${groupreply_table}.Value,${groupreply_table}.op \ FROM ${groupreply_table},${usergroup_table} \ WHERE ${usergroup_table}.Username = '%{SQL-User-Name}' \ AND ${usergroup_table}.GroupName = ${groupreply_table}.GroupName \ ORDER BY ${groupreply_table}.id" simul_verify_query = "SELECT RadAcctId, AcctSessionId, UserName, \ NASIPAddress, NASPortId, FramedIPAddress, CallingStationId, FramedProtocol \ FROM ${acct_table1} \ WHERE UserName='%{SQL-User-Name}' \ AND AcctStopTime = 0" group_membership_query = "SELECT GroupName FROM ${usergroup_table} \ WHERE UserName='%{SQL-User-Name}'" postauth_query = "INSERT into ${postauth_table} (id, user, pass, reply, date) \ values ('', '%{User-Name}', '%{User-Password:-Chap-Password}', \ '%{reply:Packet-Type}', NOW())" readclients = yes }
Nous avons décidé, en préparant notre système Wi-Fi, d'utiliser EAP-TLS pour l'authentification des utilisateurs. Lors de la création des certificats pour WPA2, nous avons créé :
Nous allons utiliser ici ces deux certificats, qu'il faut placer dans le répertoire /etc/freeradius/certs. Ce répertoire devrait contenir :
/etc/freeradius/certs# ls -l total 12 -rw-r----- 1 root freerad 0 2007-03-12 11:11 dh -rw-r----- 1 root freerad 3242 2007-03-12 15:38 maison.mrs-cert.pem -rw-r----- 1 root freerad 1024 2007-03-12 11:11 random -rw-r----- 1 root freerad 2610 2007-03-12 15:25 root_maison_CA-cacert.pem
Faites attention aux droits d'accès des fichiers de ce répertoire. Il suffit maintenant de modifier eap.conf de la sorte :
eap { default_eap_type = tls timer_expire = 60 ignore_unknown_eap_types = no cisco_accounting_username_bug = no tls { private_key_password = epikoi private_key_file = ${raddbdir}/certs/sysop@maison.mrs-cert.pem certificate_file = ${raddbdir}/certs/sysop@maison.mrs-cert.pem CA_file = ${raddbdir}/certs/root_maison_CA-cacert.pem CA_path = ${raddbdir}/certs/ dh_file = ${raddbdir}/certs/dh random_file = ${raddbdir}/certs/random fragment_size = 1024 include_length = yes check_crl = no } }
N'oublions pas de relancer FreeRadius pour qu'il prenne en compte la nouvelle configuration.
Nous créons un "authenticator" de test dans la table "nas" :
# echo "INSERT INTO nas(nasname,shortname,secret) VALUES ('127.0.0.1','localhost','naspassword');" \ | mysql -u root -p radius
Nous créons un utilisateur de test dans "radcheck" :
# echo "INSERT INTO radcheck(UserName,Attribute,op,Value) VALUES ('test0','User-Password','==','userpassword');" \ | mysql -u root -p radius
Notez que l'on utilise un mot de passe en clair dans la base, ce qui correspondra à un protocole "chap" pour l'authentification.
Enfin, depuis le serveur radius lui-même, qui va pour l'occasion cumuler le rôle d'authenticator, nous utilisons l'outil radtest :
# radtest test0 userpassword 127.0.0.1 0 naspassword
Sending Access-Request of id 146 to 127.0.0.1 port 1812
User-Name = "test0"
User-Password = "userpassword"
NAS-IP-Address = 255.255.255.255
NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=146, length=20
Notre solution fonctionne. Il ne nous reste qu'à ajouter dans la table "nas" nos switchs , nos points d'accès Wi-Fi, et dans la table "radcheck" toutes nos adresses MAC en guise d'utilisateurs pour le réseau filaire ("UserName" et "User-Password" identiques).