Tutorial, HowTo, How-To ...

Ce HowTo est une mise à jour de mon précédent tutorial : Installation de Freeradius sur une Debian Sarge (testing) (freeradius 1.1). Dans la nouvelle version freeradius 2.0.4, les fichiers de configuration ont changé, notamment avec la possibilité de créer des virtualhost (similaire à la configuration de apache2).

N’hésitez pas à m’envoyer un petit mail pour toute remarque et améliorer ce How-To.

Rq : les commentaires dans le code sont en italique : exemple de commentaire

Historique des modifications

  • 11/06/2008 : création du totorial installation freeradius 2.0.4

Installation de Freeradius

# apt-get install freeradius freeradius-utils
# apt-get install freeradius-mysql

Installation de MySQL

# apt-get install mysql-server
# apt-get install mysql-client

Configuration de MySQL

# echo "create database radius;" | mysql -u root -p
# echo "grant all on radius.* to radius@'%' identified by 'motdepasse_sql'; flush privileges;" | mysql -u root -p
# mysql -uroot -p radius < /etc/freeradius/sql/mysql/schema.sql
# mysql -uroot -p radius < /etc/freeradius/sql/mysql/nas.sql

Création de comptes utilisateur

Vous pouvez choisir les méthodes d’authentification CHAP ou PAP. Pour connaître les avantages et inconvénients de chaque méthode, je vous invite à lire la FAQ 5.6.1 de Freeradius.

  • Créer un nouvel utilisateur (Thus0) avec un mot de passe stocké en clair : "motdepasse" (authentification CHAP)
# echo "INSERT INTO radcheck(UserName,Attribute,op,Value) VALUES ('Thus0','Cleartext-Password',':=','motdepasse');" | mysql -u root -p radius
  • Créer un utilisateur (Thus1) avec un mot de passe crypté : "motdepasse" (authentification PAP)
# echo "INSERT INTO radcheck(UserName,Attribute,op,Value) VALUES ('Thus1','Crypt-Password',':=',ENCRYPT('motdepasse')); " | mysql -u root -p radius
# echo "INSERT INTO radcheck(UserName,Attribute,op,Value) VALUES ('Thus1','Auth-Type',':=','Crypt-Local'); " | mysql -u root -p radius

Configuration de Freeradius

  • Modifier le fichier /etc/freeradius/sql.conf
sql {
        database = "mysql"        
        driver = "rlm_sql_${database}"
        server = "localhost"
        login = "radius"
        password = "motdepasse_sql"
        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 = "radusergroup"

        deletestalesessions = yes
       
        sqltrace = no
        sqltracefile = ${logdir}/sqltrace.sql
        num_sql_socks = 5

        connect_failure_retry_delay = 60

        readclients = yes
        nas_table = "nas"

        $INCLUDE sql/${database}/dialup.conf
}
  • Modifier le fichier /etc/freeradius/radiusd.conf : décommenter les 2 lignes suivantes :
        $INCLUDE sql.conf
        $INCLUDE sql/mysql/counter.conf
  • Créer un virtualhost (par ex : radius.foobar.com) : prendre pour exemple, le fichier fourni par defaut et l’activer :
# cd /etc/freeradius/sites-available
# cp default radius.foobar.com
# ln -s etc/freeradius/sites-available/radius.foobar.com /etc/freeradius/sites-enabled/
  • Configurer le virtualhost créé : modifier le fichier /etc/freeradius/sites-available/radius.foobar.com
authorize {
      preprocess
      chap
      suffix
      sql
      expiration
      logintime
      pap
}

authenticate {
      Auth-Type PAP {
               pap
       }
       Auth-Type CHAP {
               chap
       }
       eap
}

preacct {
       preprocess
       acct_unique
       suffix
}

accounting {
       detail
       radutmp
       sql
}

session {
       radutmp
       sql
}

post-auth {
       sql
#       sql_log
       exec
       Post-Auth-Type REJECT {
               attr_filter.access_reject
       }
}

[...]

Test de l’installation de freeradius

- créer un NAS [1] pour tester en local au freeradius : modifier dans le fichier /etc/freeradius/clients.conf le secret partagé entre le NAS et le serveur radius :

client localhost {
      ipaddr = 127.0.0.1
      secret = monsecret_nasradius
      nastype = other
}

- Lancer freeradius en mode console pour voir les messages de debug :

# /etc/init.d/freeradius stop
# freeradius -X
[...]
Debug: Listening on authentication address * port 1812
Debug: Listening on accounting address * port 1813
Debug: Listening on proxy address * port 1814
Debug: Ready to process requests.

- Utiliser l’outil radtest : la syntaxe est de la forme : radtest utilisateur mot_de_passe_utilisateur ip_serveur_radius numero_port_NAS secret_partage_NAS_radius

  • Test avec le compte Thus0
$ radtest Thus0 motdepasse 127.0.0.1 0 monsecret_nasradius
Sending Access-Request of id 95 to 127.0.0.1:1812
       User-Name = "Thus0"
       User-Password = "motdepasse"
       NAS-IP-Address = localhost
       NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=95, length=20

Vous devriez avoir une réponse Access-Accept si tout est bien configuré !

Dans les messages de debug de freeradius, vous devriez également voir les lignes suivantes :

[...]
rad_recv: Access-Request packet from host 127.0.0.1 port 2152, id=165, length=57
       User-Name = "Thus0"
       User-Password = "motdepasse"
       NAS-IP-Address = XXX.XXX.XXX.XXX
       NAS-Port = 0
+- entering group authorize
++[preprocess] returns ok
++[chap] returns noop
   rlm_realm: No '@' in User-Name = "Thus0", looking up realm NULL
   rlm_realm: No such realm "NULL"
++[suffix] returns noop
 rlm_eap: No EAP-Message, not doing EAP
++[eap] returns noop
       expand: %{User-Name} -> Thus0
rlm_sql (sql): sql_set_user escaped user --> 'Thus0'
rlm_sql (sql): Reserving sql socket id: 0
       expand: SELECT id, username, attribute, value, op           FROM radcheck           WHERE username = '%{SQL-User-Name}'           ORDER BY id -> SELECT id, username, attribute, value, op           FROM radcheck           WHERE username = 'Thus0'           ORDER BY id
rlm_sql (sql): User found in radcheck table
       expand: SELECT id, username, attribute, value, op           FROM radreply           WHERE username = '%{SQL-User-Name}'           ORDER BY id -> SELECT id, username, attribute, value, op           FROM radreply           WHERE username = 'Thus0'           ORDER BY id
       expand: SELECT groupname           FROM radusergroup           WHERE username = '%{SQL-User-Name}'           ORDER BY priority -> SELECT groupname           FROM radusergroup           WHERE username = 'Thus0'           ORDER BY priority
rlm_sql (sql): Released sql socket id: 0
++[sql] returns ok
++[expiration] returns noop
++[logintime] returns noop
++[pap] returns updated
 rad_check_password:  Found Auth-Type
auth: type "PAP"
+- entering group PAP
rlm_pap: login attempt with password "motdepasse"
rlm_pap: Using clear text password "motdepasse"
rlm_pap: User authenticated successfully
++[pap] returns ok
Login OK: [Thus0/motdepasse] (from client localhost port 0)
+- entering group post-auth
rlm_sql (sql): Processing sql_postauth
       expand: %{User-Name} -> Thus0
rlm_sql (sql): sql_set_user escaped user --> 'Thus0'
       expand: %{User-Password} -> motdepasse
       expand: INSERT INTO radpostauth                           (username, pass, reply, authdate)                           VALUES (                           '%{User-Name}',                           '%{%{User-Password}:-%{Chap-Password}}',                           '%{reply:Packet-Type}', '%S') -> INSERT INTO radpostauth                           (username, pass, reply, authdate)                           VALUES (                           'Thus0',                           'motdepasse',                           'Access-Accept', '2008-06-11 21:26:19')
rlm_sql (sql) in sql_postauth: query is INSERT INTO radpostauth                           (username, pass, reply, authdate)                           VALUES (                           'Thus0',                           'motdepasse',                           'Access-Accept', '2008-06-11 21:26:19')
rlm_sql (sql): Reserving sql socket id: 4
rlm_sql (sql): Released sql socket id: 4
++[sql] returns ok
++[exec] returns noop
Sending Access-Accept of id 165 to 127.0.0.1 port 2152
Finished request 2.
Going to the next request
Waking up in 4.9 seconds.
Cleaning up request 2 ID 165 with timestamp +1366
Ready to process requests.

Vous devriez avoir une ligne du type Sending Access-Accept of id 228 to 127.0.0.1:51428 si tout est bien configuré !

  • Test avec le compte Thus1
$ radtest Thus1 motdepasse 127.0.0.1 0 monsecret_nasradius
Sending Access-Request of id 132 to 127.0.0.1 port 1812
       User-Name = "Thus1"
       User-Password = "motdepasse"
       NAS-IP-Address = 130.98.172.108
       NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=132, length=20

Vous devriez avoir une réponse Access-Accept si tout est bien configuré !

Dans les messages de debug de freeradius, vous devriez également voir les lignes suivantes :

[...]
rad_recv: Access-Request packet from host 127.0.0.1 port 2135, id=97, length=57
       User-Name = "Thus1"
       User-Password = "motdepasse"
       NAS-IP-Address = XXX.XXX.XXX.XXX
       NAS-Port = 0
+- entering group authorize
++[preprocess] returns ok
++[chap] returns noop
   rlm_realm: No '@' in User-Name = "Thus1", looking up realm NULL
   rlm_realm: No such realm "NULL"
++[suffix] returns noop
 rlm_eap: No EAP-Message, not doing EAP
++[eap] returns noop
       expand: %{User-Name} -> Thus1
rlm_sql (sql): sql_set_user escaped user --> 'Thus1'
rlm_sql (sql): Reserving sql socket id: 4
       expand: SELECT id, username, attribute, value, op           FROM radcheck           WHERE username = '%{SQL-User-Name}'           ORDER BY id -> SELECT id, username, attribute, value, op           FROM radcheck           WHERE username = 'Thus1'           ORDER BY id
rlm_sql (sql): User found in radcheck table
       expand: SELECT id, username, attribute, value, op           FROM radreply           WHERE username = '%{SQL-User-Name}'           ORDER BY id -> SELECT id, username, attribute, value, op           FROM radreply           WHERE username = 'Thus1'           ORDER BY id
       expand: SELECT groupname           FROM radusergroup           WHERE username = '%{SQL-User-Name}'           ORDER BY priority -> SELECT groupname           FROM radusergroup           WHERE username = 'Thus1'           ORDER BY priority
rlm_sql (sql): Released sql socket id: 4
++[sql] returns ok
++[expiration] returns noop
++[logintime] returns noop
rlm_pap: Found existing Auth-Type, not changing it.
++[pap] returns noop
 rad_check_password:  Found Auth-Type Crypt-Local
auth: type Crypt
Login OK: [Thus1/motdepasse] (from client localhost port 0)
+- entering group post-auth
rlm_sql (sql): Processing sql_postauth
       expand: %{User-Name} -> Thus1
rlm_sql (sql): sql_set_user escaped user --> 'Thus1'
       expand: %{User-Password} -> motdepasse
       expand: INSERT INTO radpostauth                           (username, pass, reply, authdate)                           VALUES (                           '%{User-Name}',                           '%{%{User-Password}:-%{Chap-Password}}',                           '%{reply:Packet-Type}', '%S') -> INSERT INTO radpostauth                           (username, pass, reply, authdate)                           VALUES (                           'Thus1',                           'motdepasse',                           'Access-Accept', '2008-06-11 21:03:52')
rlm_sql (sql) in sql_postauth: query is INSERT INTO radpostauth                           (username, pass, reply, authdate)                           VALUES (                           'Thus1',                           'motdepasse',                           'Access-Accept', '2008-06-11 21:03:52')
rlm_sql (sql): Reserving sql socket id: 3
rlm_sql (sql): Released sql socket id: 3
++[sql] returns ok
++[exec] returns noop
Sending Access-Accept of id 97 to 127.0.0.1 port 2135
Finished request 0.
Going to the next request
  • Si tout fonctionne (Access-Accept reçu), vous pouvez arrêter freeradius, en tapant Ctr+C puis relancer freeradius en tâche de fond :
# /etc/init.d/freeradius start

Installation de freeradius-dialupadmin

# apt-get install libapache2-mod-php5
# apt-get install freeradius-dialupadmin

[à compléter]

  • Vérifier le fichier /etc/php5/conf.d/mysql.ini
  • Vérifier le support des fichiers .php3 par php5 : fichier /etc/apache2/mods-available/php5.conf
<IfModule mod_php5.c>
 AddType application/x-httpd-php .php .phtml .php3
 AddType application/x-httpd-php-source .phps
</IfModule>
  • Activer php5 dans apache2
# a2enmod php5

- Rq : si vous avez une erreur "mktime() ===> "Warning : mktime() expects parameter 1 to be long, string given in /usr/share/freeradius-dialupadmin/lib/functions.php3", remplacer dans ce fichier les lignes en question :

$timest = mktime($time[0],$time[1],time[2],$day[1],$day[2],$day[0]) ;

par

$timest = mktime($time[0] ?"":0,$time[1],$time[2],$day[1],$day[2],$day[0]) ;

[1] Network Access Server