Borne d'accès avec authentification

Radius et un annuaire LDAP

Comptabilité Radius

Hostapd contactant Freeradius avec LDAP



Nous voulons avoir une borne wifi qui fasse du WPA-Enterprise (WPA TKIP ou CCMP)

                                     module EAP-TLS          module LDAP
 Client WIFI ) ) ) ) ( ( ( Borne AP<--------------->Radius<--------------->LDAP
             requête       IP1        négociation     IP2    négociation   IP3
          <----------------> ^        Hachage du       |     Hachage du
               connexion     |        mot de passe   <-|->   mot de passe
                             |        envoyé par le    |     envoyé par 
                             |        client WIFI      |     LDAP
                             --------------OK-----comparaison-----OK-----------------> BDD radius MySQL---->radacct
                                                       |
                                                     pasOK
                                                 pas de réponse
                          \______________________________________________________/
                                    Si c'est la même machine : IP1=IP2=IP3

Auth: Login OK: [lolo/<via Auth-Type = EAP>] (from client private-network-2 port 0 via TLS tunnel)

Ce tutoriel fonctionne sur les distributions suivantes:



Ce guide a été fait avec une Debian Etch. (personnellement)

Afin que ce guide corresponde totalement à votre environnement, je vous conseille de modifier le niveau de priorité de Debconf. Sur la nouvelle debian Etch et sur Ubuntu le niveau de Debconf est à « Élevé ». Ce qui réduit sensiblement le nombre de questions qui vous ai posé lors de l'installation d'un paquet. On va donc changer le niveau à « Intermédiaire » voir à « basse » pour controler un maximum.

Pour cela tapez en root : # dpkg-reconfigure debconf

Choisissez "Dialogue" puis « Intermédiaire » ou « basse »


Je vous conseille grandement d'utiliser le même mot de passe que celui de votre utilisateur root à chaque fois q'on vous demande un mot de passe. Cela évitera les erreurs !!

Installation

Il vous faut récupérer le source de freeradius ! En effet un problème de licence d'un des modules de freeradius (rlm_eap_tls) fait que celui-ci ne se trouve pas dans le paquet officiel !

ftp://ftp.freeradius.org/pub/freeradius/freeradius-server-2.1.1.tar.gz

ou ici pou ceux qui veulent ce documenter. http://freeradius.org/download.html

Je passe les détails de la compilation en dehors du fait qu'il faut :

apt-get install openssl libssl-dev libldap2-dev g++ build-essential debian-builder libgdbm-dev

Les versions de ces paquets sont/seront ceux de Debian stable Etch au moment de votre installation. (Aujourd'hui 01/09/2008).

libssl-dev et openssl 0.9.8c-4etch3

Il se configure assez bien si vous lancez :

$ ./configure --prefix=/usr --libdir=/usr/lib --with-experimental-modules
$ make
$ su
password: 
# make install

(--with-experimental-modules sera très utile pour le radius accounting)

Cela installera, les exécutables dans /usr/bin, les fichiers de configurations dans /usr/etc, les journaux dans /usr/log/raddb.

Tests

Vous pouvez dès à présent tester le serveur freeradius avec la ligne de commande suivante :

Attention : Lors du premier lancement il y a création des certificats. Ce sont ceux par défaut. Ils se trouvent dans /usr/etc/raddb/certs. Ils sont utilisés dans le fichier modules/inner-eap.

# radiusd -X
FreeRADIUS Version 2.1.1, for host i686-pc-linux-gnu, built on Sep 30 2008 at 07:25:52
Copyright (C) 1999-2008 The FreeRADIUS server project and contributors.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
You may redistribute copies of FreeRADIUS under the terms of the
GNU General Public License v2.
Starting - reading configuration files ...
including configuration file /usr//etc/raddb/radiusd.conf
including configuration file /usr//etc/raddb/proxy.conf
including configuration file /usr//etc/raddb/clients.conf
including files in directory /usr//etc/raddb/modules/
including configuration file /usr//etc/raddb/modules/sradutmp
including configuration file /usr//etc/raddb/modules/passwd
including configuration file /usr//etc/raddb/modules/files
including configuration file /usr//etc/raddb/modules/exec
including configuration file /usr//etc/raddb/modules/always
including configuration file /usr//etc/raddb/modules/policy
including configuration file /usr//etc/raddb/modules/logintime
including configuration file /usr//etc/raddb/modules/detail
including configuration file /usr//etc/raddb/modules/checkval
including configuration file /usr//etc/raddb/modules/linelog
including configuration file /usr//etc/raddb/modules/ippool
including configuration file /usr//etc/raddb/modules/chap
including configuration file /usr//etc/raddb/modules/preprocess
including configuration file /usr//etc/raddb/modules/expr
including configuration file /usr//etc/raddb/modules/digest
including configuration file /usr//etc/raddb/modules/smbpasswd
including configuration file /usr//etc/raddb/modules/pam
including configuration file /usr//etc/raddb/modules/echo
including configuration file /usr//etc/raddb/modules/sql_log
including configuration file /usr//etc/raddb/modules/ldap
including configuration file /usr//etc/raddb/modules/etc_group
including configuration file /usr//etc/raddb/modules/unix
including configuration file /usr//etc/raddb/modules/radutmp
including configuration file /usr//etc/raddb/modules/pap
including configuration file /usr//etc/raddb/modules/inner-eap
including configuration file /usr//etc/raddb/modules/realm
including configuration file /usr//etc/raddb/modules/mschap
including configuration file /usr//etc/raddb/modules/detail.example.com
including configuration file /usr//etc/raddb/modules/wimax
including configuration file /usr//etc/raddb/modules/detail.log
including configuration file /usr//etc/raddb/modules/acct_unique
including configuration file /usr//etc/raddb/modules/attr_filter
including configuration file /usr//etc/raddb/modules/mac2vlan
including configuration file /usr//etc/raddb/modules/attr_rewrite
including configuration file /usr//etc/raddb/modules/krb5
including configuration file /usr//etc/raddb/modules/expiration
including configuration file /usr//etc/raddb/modules/counter
including configuration file /usr//etc/raddb/modules/mac2ip
including configuration file /usr//etc/raddb/eap.conf
including configuration file /usr//etc/raddb/sql.conf
including configuration file /usr//etc/raddb/sql/mysql/dialup.conf
including configuration file /usr//etc/raddb/sql/mysql/counter.conf
including configuration file /usr//etc/raddb/policy.conf
including files in directory /usr//etc/raddb/sites-enabled/
including configuration file /usr//etc/raddb/sites-enabled/default
including configuration file /usr//etc/raddb/sites-enabled/inner-tunnel
including dictionary file /usr//etc/raddb/dictionary
main {
        prefix = "/usr/"
        localstatedir = "/usr//var"
        logdir = "/usr//var/log/radius"
        libdir = "/usr/lib"
        radacctdir = "/usr//var/log/radius/radacct"
        hostname_lookups = no
        max_request_time = 30
        cleanup_delay = 5
        max_requests = 1024
        allow_core_dumps = no
        pidfile = "/usr//var/run/radiusd/radiusd.pid"
        checkrad = "/usr//sbin/checkrad"
        debug_level = 0
        proxy_requests = yes
 log {
        stripped_names = yes
        auth = yes
        auth_badpass = yes
        auth_goodpass = yes
 }
 security {
        max_attributes = 200
        reject_delay = 1
        status_server = yes
 }
}
 client localhost {
        ipaddr = 127.0.0.1
        require_message_authenticator = no
        secret = "!unmotdepassefort!"
        nastype = "other"
 }
 client 0.0.0.0/0 {
        require_message_authenticator = no
        secret = "!unmotdepasseencoreplusfort!"
        shortname = "private-network-2"
 }
radiusd: #### Loading Realms and Home Servers ####
 proxy server {
        retry_delay = 5
        retry_count = 3
        default_fallback = no
        dead_time = 120
        wake_all_if_all_dead = no
 }
 home_server localhost {
        ipaddr = 127.0.0.1
        port = 1812
        type = "auth"
        secret = "!unmotdepassefort!"
        response_window = 20
        max_outstanding = 65536
        zombie_period = 40
        status_check = "status-server"
        ping_interval = 30
        check_interval = 30
        num_answers_to_alive = 3
        num_pings_to_alive = 3
        revive_interval = 120
        status_check_timeout = 4
 }
 home_server_pool my_auth_failover {
        type = fail-over
        home_server = localhost
 }
 realm example.com {
        auth_pool = my_auth_failover
 }
 realm LOCAL {
 }
radiusd: #### Instantiating modules ####
 instantiate {
 Module: Linked to module rlm_exec
 Module: Instantiating exec
  exec {
        wait = no
        input_pairs = "request"
        shell_escape = yes
  }
 Module: Linked to module rlm_expr
 Module: Instantiating expr
 Module: Linked to module rlm_expiration
 Module: Instantiating expiration
  expiration {
        reply-message = "Password Has Expired  "
  }
 Module: Linked to module rlm_logintime
 Module: Instantiating logintime
  logintime {
        reply-message = "You are calling outside your allowed timespan  "
        minimum-timeout = 60
  }
 }
radiusd: #### Loading Virtual Servers ####
server inner-tunnel {
 modules {
 Module: Checking authenticate {...} for more modules to load
 Module: Linked to module rlm_pap
 Module: Instantiating pap
  pap {
        encryption_scheme = "auto"
        auto_header = no
  }
 Module: Linked to module rlm_chap
 Module: Instantiating chap
 Module: Linked to module rlm_mschap
 Module: Instantiating mschap
  mschap {
        use_mppe = yes
        require_encryption = no
        require_strong = no
        with_ntdomain_hack = no
  }
 Module: Linked to module rlm_unix
 Module: Instantiating unix
  unix {
        radwtmp = "/usr//var/log/radius/radwtmp"
  }
 Module: Linked to module rlm_ldap
 Module: Instantiating ldap
  ldap {
        server = "debian"
        port = 389
        password = "!lemotdepassedeladminldap!"
        identity = "cn=admin,dc=DOMAIN,dc=local"
        net_timeout = 1
        timeout = 4
        timelimit = 3
        tls_mode = no
        start_tls = no
        tls_require_cert = "allow"
   tls {
        start_tls = no
        require_cert = "allow"
   }
        basedn = "dc=DOMAIN,dc=local"
        filter = "(uid=%{Stripped-User-Name:-%{User-Name}})"
        base_filter = "(objectclass=radiusprofile)"
        password_attribute = "userPassword"
        auto_header = no
        access_attr = "dialupAccess"
        access_attr_used_for_allow = yes
        groupname_attribute = "cn"
        groupmembership_filter = "(|(&(objectClass=GroupOfNames)(member=%{Ldap-UserDn}))(&(objectClass=GroupOfUniqueNames)(uniquemember=%{Ldap-UserDn})))"
        dictionary_mapping = "/usr//etc/raddb/ldap.attrmap"
        ldap_debug = 0
        ldap_connections_number = 5
        compare_check_items = no
        do_xlat = yes
        set_auth_type = yes
  }
rlm_ldap: Registering ldap_groupcmp for Ldap-Group
rlm_ldap: Registering ldap_xlat with xlat_name ldap
rlm_ldap: reading ldap<->radius mappings from file /usr//etc/raddb/ldap.attrmap
rlm_ldap: LDAP radiusCheckItem mapped to RADIUS $GENERIC$
rlm_ldap: LDAP radiusReplyItem mapped to RADIUS $GENERIC$
rlm_ldap: LDAP radiusAuthType mapped to RADIUS Auth-Type
rlm_ldap: LDAP radiusSimultaneousUse mapped to RADIUS Simultaneous-Use
rlm_ldap: LDAP radiusCalledStationId mapped to RADIUS Called-Station-Id
rlm_ldap: LDAP radiusCallingStationId mapped to RADIUS Calling-Station-Id
rlm_ldap: LDAP lmPassword mapped to RADIUS LM-Password
rlm_ldap: LDAP ntPassword mapped to RADIUS NT-Password
rlm_ldap: LDAP sambaLmPassword mapped to RADIUS LM-Password
rlm_ldap: LDAP sambaNtPassword mapped to RADIUS NT-Password
rlm_ldap: LDAP dBCSPwd mapped to RADIUS LM-Password
rlm_ldap: LDAP acctFlags mapped to RADIUS SMB-Account-CTRL-TEXT
rlm_ldap: LDAP radiusExpiration mapped to RADIUS Expiration
rlm_ldap: LDAP radiusNASIpAddress mapped to RADIUS NAS-IP-Address
rlm_ldap: LDAP radiusServiceType mapped to RADIUS Service-Type
rlm_ldap: LDAP radiusFramedProtocol mapped to RADIUS Framed-Protocol
rlm_ldap: LDAP radiusFramedIPAddress mapped to RADIUS Framed-IP-Address
rlm_ldap: LDAP radiusFramedIPNetmask mapped to RADIUS Framed-IP-Netmask
rlm_ldap: LDAP radiusFramedRoute mapped to RADIUS Framed-Route
rlm_ldap: LDAP radiusFramedRouting mapped to RADIUS Framed-Routing
rlm_ldap: LDAP radiusFilterId mapped to RADIUS Filter-Id
rlm_ldap: LDAP radiusFramedMTU mapped to RADIUS Framed-MTU
rlm_ldap: LDAP radiusFramedCompression mapped to RADIUS Framed-Compression
rlm_ldap: LDAP radiusLoginIPHost mapped to RADIUS Login-IP-Host
rlm_ldap: LDAP radiusLoginService mapped to RADIUS Login-Service
rlm_ldap: LDAP radiusLoginTCPPort mapped to RADIUS Login-TCP-Port
rlm_ldap: LDAP radiusCallbackNumber mapped to RADIUS Callback-Number
rlm_ldap: LDAP radiusCallbackId mapped to RADIUS Callback-Id
rlm_ldap: LDAP radiusFramedIPXNetwork mapped to RADIUS Framed-IPX-Network
rlm_ldap: LDAP radiusClass mapped to RADIUS Class
rlm_ldap: LDAP radiusSessionTimeout mapped to RADIUS Session-Timeout
rlm_ldap: LDAP radiusIdleTimeout mapped to RADIUS Idle-Timeout
rlm_ldap: LDAP radiusTerminationAction mapped to RADIUS Termination-Action
rlm_ldap: LDAP radiusLoginLATService mapped to RADIUS Login-LAT-Service
rlm_ldap: LDAP radiusLoginLATNode mapped to RADIUS Login-LAT-Node
rlm_ldap: LDAP radiusLoginLATGroup mapped to RADIUS Login-LAT-Group
rlm_ldap: LDAP radiusFramedAppleTalkLink mapped to RADIUS Framed-AppleTalk-Link
rlm_ldap: LDAP radiusFramedAppleTalkNetwork mapped to RADIUS Framed-AppleTalk-Network
rlm_ldap: LDAP radiusFramedAppleTalkZone mapped to RADIUS Framed-AppleTalk-Zone
rlm_ldap: LDAP radiusPortLimit mapped to RADIUS Port-Limit
rlm_ldap: LDAP radiusLoginLATPort mapped to RADIUS Login-LAT-Port
rlm_ldap: LDAP radiusReplyMessage mapped to RADIUS Reply-Message
conns: 0x81694c0
 Module: Linked to module rlm_eap
 Module: Instantiating eap
  eap {
        default_eap_type = "md5"
        timer_expire = 60
        ignore_unknown_eap_types = no
        cisco_accounting_username_bug = no
        max_sessions = 2048
  }
 Module: Linked to sub-module rlm_eap_md5
 Module: Instantiating eap-md5
 Module: Linked to sub-module rlm_eap_leap
 Module: Instantiating eap-leap
 Module: Linked to sub-module rlm_eap_gtc
 Module: Instantiating eap-gtc
   gtc {
        challenge = "Password: "
        auth_type = "PAP"
   }
 Module: Linked to sub-module rlm_eap_tls
 Module: Instantiating eap-tls
   tls {
        rsa_key_exchange = no
        dh_key_exchange = yes
        rsa_key_length = 512
        dh_key_length = 512
        verify_depth = 0
        pem_file_type = yes
        private_key_file = "/usr//etc/raddb/certs/server.pem"
        certificate_file = "/usr//etc/raddb/certs/server.pem"
        CA_file = "/usr//etc/raddb/certs/ca.pem"
        private_key_password = "whatever"
        dh_file = "/usr//etc/raddb/certs/dh"
        random_file = "/usr//etc/raddb/certs/random"
        fragment_size = 1024
        include_length = yes
        check_crl = no
        cipher_list = "DEFAULT"
        make_cert_command = "/usr//etc/raddb/certs/bootstrap"
    cache {
        enable = no
        lifetime = 24
        max_entries = 255
    }
   }
 Module: Linked to sub-module rlm_eap_ttls
 Module: Instantiating eap-ttls
   ttls {
        default_eap_type = "md5"
        copy_request_to_tunnel = no
        use_tunneled_reply = no
        virtual_server = "inner-tunnel"
   }
 Module: Linked to sub-module rlm_eap_peap
 Module: Instantiating eap-peap
   peap {
        default_eap_type = "mschapv2"
        copy_request_to_tunnel = no
        use_tunneled_reply = no
        proxy_tunneled_request_as_eap = yes
        virtual_server = "inner-tunnel"
   }
 Module: Linked to sub-module rlm_eap_mschapv2
 Module: Instantiating eap-mschapv2
   mschapv2 {
        with_ntdomain_hack = no
   }
 Module: Checking authorize {...} for more modules to load
 Module: Linked to module rlm_realm
 Module: Instantiating suffix
  realm suffix {
        format = "suffix"
        delimiter = "@"
        ignore_default = no
        ignore_null = no
  }
 Module: Linked to module rlm_files
 Module: Instantiating files
  files {
        usersfile = "/usr//etc/raddb/users"
        acctusersfile = "/usr//etc/raddb/acct_users"
        preproxy_usersfile = "/usr//etc/raddb/preproxy_users"
        compat = "no"
  }
 Module: Checking session {...} for more modules to load
 Module: Linked to module rlm_radutmp
 Module: Instantiating radutmp
  radutmp {
        filename = "/usr//var/log/radius/radutmp"
        username = "%{User-Name}"
        case_sensitive = yes
        check_with_nas = yes
        perm = 384
        callerid = yes
  }
 Module: Checking post-proxy {...} for more modules to load
 Module: Checking post-auth {...} for more modules to load
 Module: Linked to module rlm_attr_filter
 Module: Instantiating attr_filter.access_reject
  attr_filter attr_filter.access_reject {
        attrsfile = "/usr//etc/raddb/attrs.access_reject"
        key = "%{User-Name}"
  }
 }
}
 modules {
 Module: Checking authenticate {...} for more modules to load
 Module: Checking authorize {...} for more modules to load
 Module: Linked to module rlm_preprocess
 Module: Instantiating preprocess
  preprocess {
        huntgroups = "/usr//etc/raddb/huntgroups"
        hints = "/usr//etc/raddb/hints"
        with_ascend_hack = no
        ascend_channels_per_line = 23
        with_ntdomain_hack = no
        with_specialix_jetstream_hack = no
        with_cisco_vsa_hack = no
        with_alvarion_vsa_hack = no
  }
 Module: Checking preacct {...} for more modules to load
 Module: Linked to module rlm_acct_unique
 Module: Instantiating acct_unique
  acct_unique {
        key = "User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port"
  }
 Module: Checking accounting {...} for more modules to load
 Module: Linked to module rlm_detail
 Module: Instantiating detail
  detail {
        detailfile = "/usr//var/log/radius/radacct/%{Client-IP-Address}/detail-%Y%m%d"
        header = "%t"
        detailperm = 384
        dirperm = 493
        locking = no
        log_packet_header = no
  }
 Module: Instantiating attr_filter.accounting_response
  attr_filter attr_filter.accounting_response {
        attrsfile = "/usr//etc/raddb/attrs.accounting_response"
        key = "%{User-Name}"
  }
 Module: Checking session {...} for more modules to load
 Module: Checking post-proxy {...} for more modules to load
 Module: Checking post-auth {...} for more modules to load
 }
radiusd: #### Opening IP addresses and Ports ####
listen {
        type = "auth"
        ipaddr = *
        port = 0
}
listen {
        type = "acct"
        ipaddr = *
        port = 0
}
Listening on authentication address * port 1812
Listening on accounting address * port 1813
Listening on proxy address * port 1814
Ready to process requests.

Votre serveur Radius écoute et attend !

Configuration de Freeradius

Nous allons modifier quelques fichiers : clients.conf, radiusd.conf, modules/ldap, site-enabled/default, site-enabled/inner-tunnel.

Tout d'abord le fichier clients.conf :

client localhost {
           # Cette partie permet l'authentification de la borne
           # au près du service Radius si la borne est sur la
           # même machine.
        ipaddr = 127.0.0.1
        secret = !unmotdepassefort!
        require_message_authenticator = no
        shortname = localhost
        #
        # The nastype tells 'checkrad.pl' which NAS-specific method to
        #  use to query the NAS for simultaneous use.
        #
        #  Permitted NAS types are:
        #
        #       cisco
        #       computone
        #       livingston
        #       max40xx
        #       multitech
        #       netserver
        #       pathras
        #       patton
        #       portslave
        #       tc
        #       usrhiper
        #       other           # for all other types

        #
        nastype = other # localhost isn't usually a NAS...
}

client adrIP/mask {
           # Cette partie permet l'authentification de la borne
           # au près du service Radius si la borne est sur l'
           # adresse réseau adrIP/mask.
        secret          = !unmotdepassefort!
        shortname       = private-network-2 # un nom quelconque de ce réseau
}



Le fichier radiusd.conf :

Nous allons modifier que la partie « journaux ».

#
#  Logging section.  The various "log_*" configuration items
#  will eventually be moved here.
#
log {
.... bla bla ...
        #
        stripped_names = yes

        #  Log authentication requests to the log file.
        #
        #  allowed values: {no, yes}
        #
        auth = yes

        #  Log passwords with the authentication requests.
        #  auth_badpass  - logs password if it's rejected
        #  auth_goodpass - logs password if it's correct
        #
        #  allowed values: {no, yes}
        #
        auth_badpass = yes
        auth_goodpass = yes
}



Le fichier modules/ldap :

ldap {
        #
        #  Note that this needs to match the name in the LDAP
        #  server certificate, if you're using ldaps.
        server = "nomdhote"
        identity = "cn=admin,dc=DOMAIN,dc=local"
        password = !motdepasseadminldap!
        basedn = "dc=DOMAIN,dc=local"
        filter = "(&(uid=%{Stripped-User-Name:-%{User-Name}})(dialupAccess=yes))"
        #base_filter = "(objectclass=radiusprofile)"

.... bla bla ....
        # default_profile = "cn=radprofile,ou=dialup,dc=dom-sln,dc=local"
        # profile_attribute = "radiusProfileDn"
        access_attr = "dialupAccess"
           # Cet attribut LDAP nous permettra de filtrer les utilisateurs autorisés
           # ou pas ! Si dialupAccess alors autorisés, sinon pas !
           # Là il vous faudra ajouter cet attribut à chaque compte utilisateur, 
           # de l'annuaire, autorisé à se connecter à la borne
           # J'essayerais par les groupes ! ;) Voir plus bas !

        # Mapping of RADIUS dictionary attributes to LDAP
.... bla bla ...
        password_attribute = userPassword
        #  Un-comment the following to disable Novell
.... bla bla ....
}



Le fichier site-enabled/default :

Nous modifions la partie « authorize », « authenticate » et « accounting».

authorize {
.... bla bla ....
        #
        #  Look in an SQL database.  The schema of the database
        #  is meant to mirror the "users" file.
        #
        #  See "Authorization Queries" in sql.conf
        sql
.... bla bla ....
        #
        #  The ldap module will set Auth-Type to LDAP if it has not
        #  already been set
        ldap

.... bla bla ....
}

.....

authenticate {
.... bla bla ....
        # Uncomment it if you want to use ldap for authentication
        #
        # Note that this means "check plain-text password against
        # the ldap database", which means that EAP won't work,
        # as it does not supply a plain-text password.
        Auth-Type LDAP {
                ldap
        }

        #
        #  Allow EAP authentication.
        eap
}
accounting {
.... bla bla ....
#
        #  Log traffic to an SQL database.
        #
        #  See "Accounting queries" in sql.conf
        sql

        #
        #  Instead of sending the query to the SQL server,
        #  write it into a log file.
        #
        sql_log
.... bla bla ....
}

Le fichier sites-enabled/inner-tunnel :

Nous modifions la partie « autorize » et « authenticate ».

authorize {
.... bla bla ....
        #
        #  The ldap module will set Auth-Type to LDAP if it has not
        #  already been set
        ldap
.... bla bla ....
        #
        # Use the checkval module
        checkval
.... bla bla ....
}


.... bla bla ....

authenticate {
.... bla bla ....
        # Uncomment it if you want to use ldap for authentication
        #
        # Note that this means "check plain-text password against
        # the ldap database", which means that EAP won't work,
        # as it does not supply a plain-text password.
        Auth-Type LDAP {
                ldap
        }

        #
        #  Allow EAP authentication.
        eap
}



Normalement votre serveur Radius est près... Vous devriez pouvoir lancer radius -X, pour vérifier les alertes !



Installation

Vous pouvez suivre le tutos rapide : http://www.system-linux.net/config/access-point/

Il faut installer les mêmes paquets...

Configuration de la borne AP

Le fichier /etc/hostapd/hostapd.conf :

interface=nominterface (eth0, ath0, ra0, etc...)
ssid=VotreESSID
driver=votrepilote (madwifi, ndiswrapper, wext, wired, etc...)
logger_syslog=-1
logger_syslog_level=4
logger_stdout=--1
logger_stdout_level=4
debug=4
ctrl_interface_group=0

# Comment gérer les adresses MAC (adresse Hardware des cartes réseaux)
# C'est une sécurité qui peut facilement être contournée, mais est
# néanmoins pratique, car elle est facile à mettre en place
# En effet, hostAPd va vérifier l'adresse MAC de la carte Wifi qui fait une
# demande d'accès et pourra alors, sur cette seule adresse, soit continuer le
# processus d'identification, soit s'arrêter et refuser la carte.
# Les paramètres possibles sont les suivants :
# 0 : Tout accepter à moins qu'elle ne soit dans la liste noire
# 1 : Tout refuser, à moins qu'elle ne soit dans la liste blanche
# 2 : Vérifier l'adresse auprès d'un serveur RADIUS (honnêtement, pour son réseau local, ça ne sert à rien)
# Le meilleur paramètre pour commencer est 1. Ça réduit de beaucoup les risques de piratage.
macaddr_acl=2
#deny_mac_file=/etc/hostapd/hostapd.deny
#accept_mac_file=/etc/hostapd/hostapd.accept

ieee8021x=1
own_ip_addr= adrIP
nas_identifier=nomdhote
auth_server_addr= adrIP
auth_server_port=1812
auth_server_shared_secret=!unmotdepassefort!
acct_server_addr= adrIP
acct_server_port=1813
acct_server_shared_secret=!unmotdepassefort!
radius_acct_interim_interval=6

wpa=3
wpa_key_mgmt=WPA-EAP
wpa_pairwise=TKIP CCMP
wpa_group_rekey=300
wpa_gmk_rekey=6400

Création du script de lancement de la borne AP

Comme dans le tutos http://www.system-linux.net/config/access-point/

Nous créons un script bash qui lancera les commandes de destruction, construction, configuration et de paramètres de la borne AP. Ce script sera dans /etc/init.d

#!/bin/sh

# Création de la carte ath0 et du point d'accès debian-AP
echo "Création de la carte ath0 et du point d'accès debian-AP";

ifconfig NomCarte down;
wlanconfig NomCarte destroy;
wlanconfig NomCarte create wlandev wifi0 wlanmode ap;
echo "Veuillez patienter...";
sleep 2;
echo "Activation de ath0";

ifconfig NomCarte mtu 1492 adrIP netmask mask up;
kill `pidof radiusd`;
radiusd;
killall hostapd;
/usr/sbin/hostapd -B -P /var/run/hostapd.pid -dd -K -t /etc/hostapd/hostapd.conf.wpa2-enterprise;

echo "Veuillez patienter...";
sleep 1;
echo "Mise en place des options du point d'accès debian-AP";
iwconfig NomCarte key restricted;
iwconfig NomCarte nickname "unNickName";

echo "Veuillez patienter...";
sleep 1;
echo "Mise en place des options DHCP";
/etc/init.d/dhcp3-server restart;

echo "Veuillez patienter...";
sleep 1;
iwconfig NomCarte channel VotreCanal;

echo "Veuillez patienter...";
sleep 1;
echo "Mise en place du routage NAT internet";
echo 1 > /proc/sys/net/ipv4/ip_forward;
iptables -t nat -A POSTROUTING -o NomCarteInternet -j MASQUERADE;
/etc/init.d/samba restart;



Configuration du serveur DHCP

Le fichier se trouve : /etc/dhcpd3/dhcpd.conf

ddns-update-style none;
option domain-name "DOMAIN.local";

default-lease-time 600;
max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

# wifi
subnet adrIPrz netmask mask {
        range IP1 IP2;
        option domain-name-servers IPDNS1, IPDNS2, IPDNS3;
        option routers adrIP;
        option broadcast-address adrIPbroadcast;
        default-lease-time 600;
        max-lease-time 7200;
}



Nous devons ajouté l' ObjectClass = radiusProfile à nos comptes utilisateurs. Pour cela au par avant il faut ajouter le schéma Radius à notre annuaire.

Le schéma se trouve dans : /làoùvousavezdécompressélesource/freeradius-server-$version/doc/examples/openldap.schema.

Renommez le en freeradius.schema et mettez le dans /etc/ldap/schema(*).

Et ajouter l'attribut « dialupAccess », j'ai mis la valeur « yes », mais peu importe.

Faites le avec phpLDAPadmin ou ApacheDirectoryStudio.

(*) : Le schéma fourni avec les sources de Freeradius fixe le nombre de valeur à une pour « radiusCallingStation ». Cet attribut peut-être excessivement utile, en effet on y met l'adresse physique de la machine (00-1A-70-AE-D4-53). Et il est plus souple de constater qu'un compte peut avoir besoin de se connecter à partir d'une machine qui ne soit pas la sienne ! Il faut modifier le fichier freeradius.schema :

attributetype
   ( 1.3.6.1.4.1.3317.4.3.1.7
      NAME 'radiusCallingStationId'
      DESC ''
      EQUALITY caseIgnoreIA5Match
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
      SINGLE-VALUE
   )

en

attributetype
   ( 1.3.6.1.4.1.3317.4.3.1.7
      NAME 'radiusCallingStationId'
      DESC ''
      EQUALITY caseIgnoreIA5Match
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   )



J'ai aussi modifié le script perl smbldap-useradd pour ajouter cet attribut.

Modifiez cette partie à partir de la ligne 310 :

En :

# USER ACCOUNT
# add posix account first
my $add;
# if AIX account, inetOrgPerson obectclass can't be used
if (defined($Options{'b'})) {
        $add = $ldap_master->add ("uid=$userName,$config{usersdn}",
                                     attr => [
                                              'objectclass' => ['top','person', 'organizationalPerson', 'posixAccount','shadowAccount'],
                                              'cn'   => "$userCN",
                                              'sn'   => "$userSN",
                                              'uid'   => "$userName",
                                              'uidNumber'   => "$userUidNumber",
                                              'gidNumber'   => "$userGidNumber",
                                              'homeDirectory'   => "$userHomeDirectory",
                                              'loginShell'   => "$config{userLoginShell}",
                                              'gecos'   => "$config{userGecos}",
                                              'userPassword'   => "{crypt}x",
                                              'dialupAccess'   => "yes",
                                              'radiusCallingStationId'  => "00-00-00-00-00-00",
                                              'radiusFramedIPAddress'   => "10.3.1.X",
                                              'radiusFramedIPNetmask'   => "255.255.255.0",
                                              'radiusFramedProtocol'    => "PPP",
                                              'radiusFramedRouting'     => "None",
                                              'radiusServiceType'       => "Framed-User"
                                             ]
                                );
} else {
        $add = $ldap_master->add ("uid=$userName,$config{usersdn}",
                                     attr => [
                                              'objectclass' => ['top','person', 'organizationalPerson', 'inetOrgPerson','posixAccount','shadowAccount','radiusProfile'],
                                              'cn'   => "$userCN",
                                              'sn'   => "$userSN",
                                              'givenName'   => "$givenName",
                                              'uid'   => "$userName",
                                              'uidNumber'   => "$userUidNumber",
                                              'gidNumber'   => "$userGidNumber",
                                              'homeDirectory'   => "$userHomeDirectory",
                                              'loginShell'   => "$config{userLoginShell}",
                                              'gecos'   => "$config{userGecos}",
                                              'userPassword'   => "{crypt}x",
                                              'dialupAccess'   => "yes",
                                              'radiusCallingStationId'  => "00-00-00-00-00-00",
                                              'radiusFramedIPAddress'   => "10.3.1.X",
                                              'radiusFramedIPNetmask'   => "255.255.255.0",
                                              'radiusFramedProtocol'    => "PPP",
                                              'radiusFramedRouting'     => "None",
                                              'radiusServiceType'       => "Framed-User"
                                             ]
                                );
}
$add->code && warn "failed to add entry: ", $add->error ;

Nous pouvons aussi si c'est votre politique de connexion, n'accepter la connexions de un-tel que par telle machine.

Nous pouvons évaluer la valeur de l'attribut LDAP « radiusCallingStationId » à celui de Radius « Calling-Station-Id », qui représente l'adresse physique de la machine. Ainsi la machine « 00-1f-3c-ab-10-8c » peut-être associée à « User » en ajoutant dans LDAP dans le compte « User » l'attribut «  radiusCallingStationId= 00-1f-3c-ab-10-8c ».

Il suffit de dé-commenter dans les fichier site-enabled/default et site-enabled/inner-tunnel la ligne :

# checkval

J'ai tenté rapidement de faire un tuto simple, style copier/coller, pour n'aller qu'a l'essentiel !

Mais je vous recommande de vous documenter ! Vous trouverez ici et là des tutos qui vous indiquent de mettre dans le fichier « users » la valeur :

DEFAULT Auth-Type == LDAP
        Fall-Through = 0

Ceci est faux comme le dit le développeur principale de Freeradius !

http://readlist.com/lists/lists.freeradius.org/freeradius-users/2/10880.html

http://deployingradius.com/documents/protocols/oracles.html

http://deployingradius.com/blog/



Linux :









































































Windows XP (SP2/SP3) :

















































































































































Radius offre la possibilité de faire de la comptabilité (appelé accounting). En effet on peut enregistrer un certain nombre de données informatives telles que :

L'heure de connexion, l'identifiant, par quel NAS (borne), le nombre d'octets entrants/sortants, etc...

Ceci peut-être pratique si vous avez à facturer ou tout simplement compter les connexions !

Pour cela rien de plus simple(*).

  1. Création d'une base de données avec les tables.

  2. Modification de la configuration Radius et redémarrage de celui-ci.

Création de la base :

Création de la base de données « radius » :

# mysql -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 173
Server version: 5.0.32-Debian_7etch6-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.01 sec)

mysql> quit
Bye



Dans le répertoire d'installation de radius et mysql, il y a un fcihier /usr/etc/raddb/sql/mysql/schema.sql, nous allons l'utiliser pour créer les tables, etc...

# mysql -p radius < /usr/etc/raddb/sql/mysql/schema.sql
Enter password:


Deux tables nous intéresserons : radpostauth et radacct.


Modification de Radius :

Nous allons modifier le fichier site-enable/default


Dans la partie « accounting » : concerne la table « radacct »

accounting  {
...
        #
        #  Log traffic to an SQL database.
        #
        #  See "Accounting queries" in sql.conf
        sql
...
}



Dans la partie « post-auth» : concerne la table « radpostauth »

post-auth {
...
        #
        #  After authenticating the user, do another SQL query.
        #
        #  See "Authentication Logging Queries" in sql.conf
        sql
...
}


(*) : Oui pourquoi cette étoile...

Et bien voilà, le rien de plus simple a durée 5-6 jours, en effet dans le hostapd.conf j'avais renseigné deux fois la même variable impliquant l'oublie d'une autre !

La variable renseignée deux fois était : auth_server_shared_secret

Au lieu de renseigner auth_server_shared_secret et acct_server_shared_secret !!!

Il n'y avait donc pas de valeur pour celle-ci, donc pas d' « accounting » !!!! :-/


Remarque : l'accounting ne sert pas à grand chose si, personne n'a accès aux données.


Pour cela nous allons installer un serveur web avec les modules PHP et MySQL :

# apt-get install apache2-mpm-prefork php5-mysql php5-ldap libapache2-mod-php5

Redémarrez apache : #/etc/init.d/apache2 restart


Les pages apache sont mises dans /var/www. Nous allons donc créer un répertoire "radius" pour y placer les pages "accounting". Ce répertoire doit être en lecture pour le processus d'apache tournant sous "www-data".


# mkdir /var/www/radius
# chmod 755 /var/www/radius


Nous allons créer trois pages PHP :

- page de connexion à MySQL pour la base de données "radius".

- page d'entré récapitulant toutes les sessions radius et de sélection des utilisateurs.

- page de résultats de la sélection.


La page de connexion BDD config.inc.db.php :

<?php
// L'hôte sur le quel est la base de donn?e
$host="localhost";
// Le login superuser de MySQL
$user="root";
// Son mots de passe
$pass="motdepasseadminmysql";
// Le nom de la base de données
$DB="radius";


// Connexion à MySQL sur $host
$message = "&#233;chec de la connexion.<br>";
$message = $message . "Le serveur est inaccessible, ou le service de base de données est arrêtée ...<br>";
$message = $message . "Veuillez contacter l'administrateur<br>";
$message = $message;
$link = mysql_connect($host, $user, $pass) or die($message);

// S?lection de la base $DB
$message = "&#233;chec de la base de données.<br>";
$message = $message . "La base de donn?es est inaccessible...<br>";
$message = $message . "Veuillez contacter l'administrateur<br>";
$message = $message;
$sel = mysql_select_db($DB) or die($message);
?>


La page par défaut index.php :

<?php
// // Connexion la base de donnée
include ("conf.inc.db.php");

// La requète
$sql = "SELECT * FROM radacct ORDER BY radacctid DESC";
?>
<body bgcolor="#B4B3C6">
<h1><p align=center><strong><u>Radius Accounting</u></strong></p></h1>
<?PHP
$req = mysql_query($sql) or die('Requ&#232;te mal formulï&#233;e');

echo "<table border='1' align='center' bgcolor='#ADADAD'><tbody bgcolor='Gray'>";
echo "<tr bgcolor='Silver'>";
echo "<td>Identifiant Comptable</td>";
echo "<td>Nom utilisateur</td>";
echo "<td>KOctets entr&#233;s</td>";
echo "<td>KOctets sortis</td>";
echo "<td>Heure et date d&#233;but</td>";
echo "<td>Heure et date fin</td>";
echo "</tr>";

while($data = mysql_fetch_assoc($req))
     {
$koin=round (intval  ($data['acctinputoctets'])/1024, 2); //plus agréable en Ko
$koout=round (intval  ($data['acctoutputoctets'])/1024, 2); //plus agréable en Ko
if ($data['acctstoptime']=='') {
$data['acctstoptime']="<font color='Red'>Session en cours</font>";
}
        echo "<tr bgcolor='#00C0C0'>";
        echo "<td>".$data['radacctid']."</td>";
        echo "<td>".$data['username']."</td>";
        echo "<td>".$koin."</td>";
        echo "<td>".$koout."</td>";
        echo "<td>".$data['acctstarttime']."</td>";
        echo "<td>".$data['acctstoptime']."</td>";
        echo "</tr>";
     }
echo "</tbody></table>";
?>
<br><br>
<center>
Choisissez un utilisateur : 
<FORM method="POST" action="resultat.php" name="formulaire" class="txt">
<SELECT name="username">
                <?PHP
                $sql = 'SELECT DISTINCT username from radacct ORDER by username';
                $req = mysql_query($sql) or die('Requ&#232;te mal formulï&#233;e');
                //echo '<option></option>';
                while($data = mysql_fetch_assoc($req))
                {
                if ($data['username'] != "") {
                        echo "<option value=\"".htmlentities($data['username'])."\">".htmlentities($data['username'])."</option>";
                }
                }
                ?>
</select>
<INPUT type="submit" name="recherche" value="Afficher">
</FORM>
</center>
</body>


La page de résultats resultat.php :

<?php
// // Connexion la base de donnée
include ("conf.inc.db.php");

// Réccupération des variable postées
$username = $_POST['username'];
?>
<body bgcolor="#B4B3C6">
<h1><p align=center><strong><u>Radius Accounting</u></strong></p></h1>
<?PHP
$sql = "SELECT * FROM radacct WHERE username='$username'";
$req = mysql_query($sql) or die('Requ&#232;te mal formulï&#233;e 1');

echo "<table border='1' align='center' bgcolor='#ADADAD'><tbody bgcolor='Gray'>";
echo "<tr bgcolor='Silver'>";
echo "<td>Identifiant Comptable</td>";
echo "<td>Nom utilisateur</td>";
echo "<td>KOctets entr&#233;s</td>";
echo "<td>KOctets sortis</td>";
echo "<td>Heure et date d&#233;but</td>";
echo "<td>Heure et date fin</td>";
echo "</tr>";

while($data = mysql_fetch_assoc($req))
     {
$koin=round (intval  ($data['acctinputoctets'])/1024, 2);
$koout=round (intval  ($data['acctoutputoctets'])/1024, 2);
if ($data['acctstoptime']=='') {
$data['acctstoptime']="<font color='Red'>Session en cours</font>";
}
        echo "<tr bgcolor='#00C0C0'>";
        echo "<td>".$data['radacctid']."</td>";
        echo "<td>".$data['username']."</td>";
        echo "<td>".$koin."</td>";
        echo "<td>".$koout."</td>";
        echo "<td>".$data['acctstarttime']."</td>";
        echo "<td>".$data['acctstoptime']."</td>";
        echo "</tr>";
     }
echo "</tbody></table>";
?>
<br><br>
<center>
Choisissez un utilisateur : 
<FORM method="POST" action="resultat.php" name="formulaire" class="txt">
<SELECT name="username">
                <?PHP
                $sql = 'SELECT DISTINCT username from radacct ORDER by username';
                $req = mysql_query($sql) or die('Requ&#232;te mal formulï&#233;e');
                //echo '<option></option>';
                while($data = mysql_fetch_assoc($req))


                {
                if ($data['username'] != "") {
                        echo "<option value=\"".htmlentities($data['username'])."\">".htmlentities($data['username'])."</option>";
                }
                }
                ?>
</select>
<INPUT type="submit" name="recherche" value="Afficher">
</FORM>
</center>
<br><br>
<center>
<FORM method="POST" action="index.php">
<INPUT type="submit" name="reset" value="Revenir">
</FORM>
</center>
</body>


Ce qui devrait donner :

La page par défaut :


























La page résultats :





























Creative Commons : CopyNoRight or CopyLeft



Creative Commons License
Authentification Radius et LDAP by Laurent Besson est mis à disposition selon les termes de la licence Creative Commons Paternité-Pas d'Utilisation Commerciale-Partage des Conditions Initiales à l'Identique 2.0 France.