# WPA Enterprise w/ FreeRadius [Solved]

## moszern

Hello, 

I'm wondering if anyone else has tried to setup a simple user/pass authentication for wireless using FreeRadius.  PEAP w/ TLS or something of the sort is nice and secure but having to put a certificate on each laptop is a pain. 

What I'm looking for is a secure yet simple way for users to have to type in a user/pass when they try to connect to an AP.  I've got the ap using a radius now and the radius has a sql database we use for other authentication.  Have I overlooked a simple way to do this?  All options in XP seem to require a certificate.

Thanks!Last edited by moszern on Mon Jul 31, 2006 1:51 pm; edited 1 time in total

----------

## pharoh

I am not sure about XP but I know one of the guys here did it on Windows Mobile via the certchk.exe utility.

----------

## odessit

I have PEAP working with FreeRADIUS for WPA and a users file (not MySQL)

To get XP working without certificates I unchecked  "Validate Server Certificate" (not a very good idea BTW, but it works).

----------

## moszern

 *Quote:*   

> I have PEAP working with FreeRADIUS for WPA and a users file (not MySQL)
> 
> To get XP working without certificates I unchecked "Validate Server Certificate" (not a very good idea BTW, but it works).

 

Thanks for the replies!

odessit Would you mind posting your radiusd.conf?

----------

## odessit

This is my FreeRadius config file for PEAP authentication.

I sanitized it from many # to save space. 

BTW - where you see references to crashing server - it was not related to rad config. 

Good Luck

```
##

## radiusd.conf -- FreeRADIUS server configuration file.

##

prefix = /usr

exec_prefix = ${prefix}

sysconfdir = /etc

localstatedir = /var

sbindir = ${exec_prefix}/sbin

logdir = ${localstatedir}/log/radius

raddbdir = ${sysconfdir}/raddb

radacctdir = ${logdir}/radacct

#  Location of config and logfiles.

confdir = ${raddbdir}

run_dir = ${localstatedir}/run/radiusd

#

#  The logging messages for the server are appended to the

#  tail of this file.

#

log_file = ${logdir}/radius.log

#

# libdir: Where to find the rlm_* modules.

#

#   This should be automatically set at configuration time.

#

libdir = ${exec_prefix}/lib

#  pidfile: Where to place the PID of the RADIUS server.

#

pidfile = ${run_dir}/radiusd.pid

# user/group: The name (or #number) of the user/group to run radiusd as.

user = radiusd

group = radiusd

#  max_request_time: The maximum time (in seconds) to handle a request.

#

max_request_time = 5

#  delete_blocked_requests: If the request takes MORE THAN 'max_request_time'

#  to be handled, then maybe the server should delete it.

#

#  If you're running in threaded, or thread pool mode, this setting

#  should probably be 'no'.  Setting it to 'yes' when using a threaded

#  server MAY cause the server to crash!

#

delete_blocked_requests = no

#  cleanup_delay: The time to wait (in seconds) before cleaning up

#  a reply which was sent to the NAS.

#

#  Useful range of values: 2 to 10

#

# EDIT - I AM MAKING IT ZERO TO TRY TO ISOLATE THE PROBLEM WITH

# CRASHING SERVER AFTER IT GETS "INVALID PASSWORD" TOO MANY TIMES

cleanup_delay = 0

# EDIT - I AM MAKING IT 128 TO TRY TO ISOLATE THE PROBLEM WITH

# CRASHING SERVER AFTER IT GETS "INVALID PASSWORD"

#  16384 == 64 clients. Currently we have 32 clients.

max_requests = 32768

#  bind_address:  Make the server listen on a particular IP address, and

#  send replies out from that address.  This directive is most useful

#  for machines with multiple IP addresses on one interface.

#

#  It can either contain "*", or an IP address, or a fully qualified

#  Internet domain name.  The default is "*"

#

#  As of 1.0, you can also use the "listen" directive.  See below for

#  more information.

#

bind_address = 1.1.1.1

#  port: Allows you to bind FreeRADIUS to a specific port.

#  The port is defined here to be 0 so that the server will pick up

#  the machine's local configuration for the radius port, as defined

#  in /etc/services.

port = 0

#  hostname_lookups: Log the names of clients or just their IP addresses

hostname_lookups = no

#  Core dumps are a bad thing.  This should only be set to 'yes'

#  if you're debugging a problem with the server.

#

#  allowed values: {no, yes}

#

allow_core_dumps = no

#  Regular expressions

#

#  These items are set at configure time.  If they're set to "yes",

#  then setting them to "no" turns off regular expression support.

#

#  If they're set to "no" at configure time, then setting them to "yes"

#  WILL NOT WORK.  It will give you an error.

#

regular_expressions     = yes

extended_expressions    = yes

#  Log the full User-Name attribute, as it was found in the request.

#

# allowed values: {no, yes}

#

log_stripped_names = no

#  Log authentication requests to the log file.

#

#  allowed values: {no, yes}

#

log_auth = yes

#  Log passwords with the authentication requests.

#  log_auth_badpass  - logs password if it's rejected

#  log_auth_goodpass - logs password if it's correct

#

#  allowed values: {no, yes}

#

log_auth_badpass = yes

log_auth_goodpass = no

# usercollide:  Turn "username collision" code on and off.  See the

# "doc/duplicate-users" file

usercollide = no

# lower_user / lower_pass:

# Lower case the username/password "before" or "after"

# attempting to authenticate.

lower_user = no

lower_pass = no

# nospace_user / nospace_pass:

#

#  Some users like to enter spaces in their username or password

#  incorrectly.  To save yourself the tech support call, you can

#  eliminate those spaces here:

#

# Default is 'no' (don't remove spaces)

# Valid values = "before" / "after" / "no" (explanation above)

#

nospace_user = no

nospace_pass = no

#  The program to execute to do concurrency checks.

checkrad = ${sbindir}/checkrad

# SECURITY CONFIGURATION

#

#  There may be multiple methods of attacking on the server.  This

#  section holds the configuration items which minimize the impact

#  of those attacks

#

security {

        max_attributes = 200

        reject_delay = 2

        status_server = no

}

# PROXY CONFIGURATION

#

proxy_requests  = no

#$INCLUDE  ${confdir}/proxy.conf

# CLIENTS CONFIGURATION

#

#  Client configuration is defined in "clients.conf".

#

#  The 'clients.conf' file contains all of the information from the old

#  'clients' and 'naslist' configuration files.  We recommend that you

#  do NOT use 'client's or 'naslist', although they are still

#  supported.

#

#  Anything listed in 'clients.conf' will take precedence over the

#  information from the old-style configuration files.

#

$INCLUDE  ${confdir}/clients.conf

# SNMP CONFIGURATION

#

snmp    = no

#$INCLUDE  ${confdir}/snmp.conf

# THREAD POOL CONFIGURATION

#

thread pool {

        #  Number of servers to start initially --- should be a reasonable

        #  ballpark figure.

        start_servers = 5

        #  Limit on the total number of servers running.

        #

        max_servers = 64

        #  Server-pool size regulation.  Rather than making you guess

        #  how many servers you need, FreeRADIUS dynamically adapts to

        #  the load it sees, that is, it tries to maintain enough

        #  servers to handle the current load, plus a few spare

        #  servers to handle transient load spikes.

        #

        min_spare_servers = 3

        max_spare_servers = 10

        #  There may be memory leaks or resource allocation problems with

        #  the server.  If so, set this value to 300 or so, so that the

        #  resources will be cleaned up periodically.

        #

        #  This should only be necessary if there are serious bugs in the

        #  server which have not yet been fixed.

        #

        #  '0' is a special value meaning 'infinity', or 'the servers never

        #  exit'

        #EDIT - changed it from 0 to 500 to help with crashing

        max_requests_per_server = 500

}

# MODULE CONFIGURATION

#

#  The names and configuration of each module is located in this section.

#

#  After the modules are defined here, they may be referred to by name,

#  in other sections of this configuration file.

#

modules {

       

$INCLUDE ${confdir}/eap.conf

        # Microsoft CHAP authentication

        #

        #  This module supports MS-CHAP and MS-CHAPv2 authentication.

        #  It also enforces the SMB-Account-Ctrl attribute.

        #

        mschap {

                #

                #  As of 0.9, the mschap module does NOT support

                #  reading from /etc/smbpasswd.

                #

                #  If you are using /etc/smbpasswd, see the 'passwd'

                #  module for an example of how to use /etc/smbpasswd

                # authtype value, if present, will be used

                # to overwrite (or add) Auth-Type during

                # authorization. Normally should be MS-CHAP

                authtype = MS-CHAP

                # if use_mppe is not set to no mschap will

                # add MS-CHAP-MPPE-Keys for MS-CHAPv1 and

                # MS-MPPE-Recv-Key/MS-MPPE-Send-Key for MS-CHAPv2

                #

                use_mppe = no

                # if mppe is enabled require_encryption makes

                # encryption moderate

                #

                require_encryption = yes

                # require_strong always requires 128 bit key

                # encryption

                #

                require_strong = yes

                # Windows sends us a username in the form of

                # DOMAIN\user, but sends the challenge response

                # based on only the user portion.  This hack

                # corrects for that incorrect behavior.

                #EDIT - changed it for Giant

                with_ntdomain_hack = yes

                # The module can perform authentication itself, OR

                # use a Windows Domain Controller.  This configuration

                # directive tells the module to call the ntlm_auth

                # program, which will do the authentication, and return

                # the NT-Key.  Note that you MUST have "winbindd" and

                # "nmbd" running on the local machine for ntlm_auth

                # to work.  See the ntlm_auth program documentation

                # for details.

                #

                # Be VERY careful when editing the following line!

                #

                #ntlm_auth = "/path/to/ntlm_auth --request-nt-key --username=%{Stripped-User-Name:-%{User-Name:-None}} --challenge=%{mschap:Challenge:-00} --nt-response=%{mschap:NT-Response:-00}"

        }

        #  'username@realm'

        #

        realm suffix {

                format = suffix

                delimiter = "@"

                ignore_default = no

                ignore_null = no

        }

        #  A simple value checking module

        #

        checkval {

                # The attribute to look for in the request

                item-name = Calling-Station-Id

                # The attribute to look for in check items. Can be multi valued

                check-name = Calling-Station-Id

                # The data type. Can be

                # string,integer,ipaddr,date,abinary,octets

                data-type = string

                # If set to yes and we dont find the item-name attribute in the

                # request then we send back a reject

                # DEFAULT is no

                #notfound-reject = no

        }

       

        # Preprocess the incoming RADIUS request, before handing it off

        # to other modules.

       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 = yes

        }

        # Livingston-style 'users' file

        #

        files {

                usersfile = ${confdir}/users

                acctusersfile = ${confdir}/acct_users

                preproxy_usersfile = ${confdir}/preproxy_users

                compat = no

        }

        # Write a detailed log of all accounting records received.

        #

        detail {

                detailfile = ${radacctdir}/%{Client-IP-Address}/detail-%Y%m%d

                detailperm = 0600

        }

 

        #

        #  Create a unique accounting session Id.  Many NASes re-use

        #  or repeat values for Acct-Session-Id, causing no end of

        #  confusion.

        #

        #  This module will add a (probably) unique session id

        #  to an accounting packet based on the attributes listed

        #  below found in the packet.  See doc/rlm_acct_unique for

        #  more information.

        #

        acct_unique {

                key = "User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port"

        }

        #  Write a 'utmp' style file, of which users are currently

        #  logged in, and where they've logged in from.

        #

        #  This file is used mainly for Simultaneous-Use checking,

        #  and also 'radwho', to see who's currently logged in.

        #

        radutmp {

                #  Where the file is stored.  It's not a log file,

                #  so it doesn't need rotating.

                filename = ${logdir}/radutmp

                username = %{User-Name}

                case_sensitive = yes

                check_with_nas = yes

                perm = 0600

                callerid = "yes"

        }

        # "Safe" radutmp - does not contain caller ID, so it can be

        # world-readable, and radwho can work for normal users, without

        # exposing any information that isn't already exposed by who(1).

        #

        # This is another 'instance' of the radutmp module, but it is given

        # then name "sradutmp" to identify it later in the "accounting"

        # section.

        radutmp sradutmp {

                filename = ${logdir}/sradutmp

                perm = 0644

                callerid = "no"

        }

        # attr_filter - filters the attributes received in replies from

        # proxied servers, to make sure we send back to our RADIUS client

        # only allowed attributes.

        attr_filter {

                attrsfile = ${confdir}/attrs

        }

        #  counter module:

        #  This module takes an attribute (count-attribute).

        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

        }

        #

        #  This module is an SQL enabled version of the counter module.

        #

       sqlcounter dailycounter {

                counter-name = Daily-Session-Time

                check-name = Max-Daily-Session

                sqlmod-inst = sql

                key = User-Name

                reset = daily

                # This query properly handles calls that span from the

                # previous reset period into the current period but

                # involves more work for the SQL server than those

                # below

                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

                # This query properly handles calls that span from the

                # previous reset period into the current period but

                # involves more work for the SQL server than those

                # below

                query = "SELECT SUM(AcctSessionTime - \

                 GREATEST((%b - UNIX_TIMESTAMP(AcctStartTime)), 0)) \

                 FROM radacct WHERE UserName='%{%k}' AND \

                 UNIX_TIMESTAMP(AcctStartTime) + AcctSessionTime > '%b'"

        }

        #

        # The "always" module is here for debugging purposes. Each

        # instance simply returns the same result, always, without

        # doing anything.

        always fail {

                rcode = fail

        }

        always reject {

                rcode = reject

        }

        always ok {

                rcode = ok

                simulcount = 0

                mpp = no

        }

        #

        #  The 'expression' module currently has no configuration.

        #

        expr {

        }

        #

        #  The 'digest' module currently has no configuration.

        #

        #  "Digest" authentication against a Cisco SIP server.

        #  See 'doc/rfc/draft-sterman-aaa-sip-00.txt' for details

        #  on performing digest authentication for Cisco SIP servers.

        #

        digest {

        }

        #

        #  Execute external programs

        #

       

        exec {

                wait = yes

                input_pairs = request

        }

        #

        #  This is a more general example of the execute module.

        #

        #  This one is called "echo".

        #

        #  Attribute-Name = `%{echo:/path/to/program args}`

        #

        #  If you wish to execute an external program in more than

        #  one section (e.g. 'authorize', 'pre_proxy', etc), then it

        #  is probably best to define a different instance of the

        #  'exec' module for every section.

        #

        exec echo {

                #  Wait for the program to finish.

                wait = yes

                #

                #  The name of the program to execute, and it's

                #  arguments.  Dynamic translation is done on this

                #  field, so things like the following example will

                #  work.

                #

                program = "/bin/echo %{User-Name}"

                #

                #  The attributes which are placed into the

                #  environment variables for the program.

                #

                input_pairs = request

                #

                #  Where to place the output attributes (if any) from

                #  the executed program.  The values allowed, and the

                #  restrictions as to availability, are the same as

                #  for the input_pairs.

                #

                output_pairs = reply

      }

        #  Do server side ip pool management. Should be added in post-auth and

        #  accounting sections.

        #

        #  The module also requires the existance of the Pool-Name

        #  attribute. That way the administrator can add the Pool-Name

        #  attribute in the user profiles and use different pools

        #  for different users. The Pool-Name attribute is a *check* item not

        #  a reply item.

        #

        # Example:

        # radiusd.conf: ippool students { [...] }

        # users file  : DEFAULT Group == students, Pool-Name := "students"

        #

        # ********* IF YOU CHANGE THE RANGE PARAMETERS YOU MUST *********

        # ********* THEN ERASE THE DB FILES                     *********

        #

        ippool main_pool {

                #  range-start,range-stop: The start and end ip

                #  addresses for the ip pool

                range-start = 192.168.1.1

                range-stop = 192.168.3.254

                #  netmask: The network mask used for the ip's

                netmask = 255.255.255.0

                #  cache-size: The gdbm cache size for the db

                #  files. Should be equal to the number of ip's

                #  available in the ip pool

                cache-size = 800

                # session-db: The main db file used to allocate ip's to clients

                session-db = ${raddbdir}/db.ippool

                # ip-index: Helper db index file used in multilink

                ip-index = ${raddbdir}/db.ipindex

                # override: Will this ippool override a Framed-IP-Address already set

                override = no

                # maximum-timeout: If not zero specifies the maximum time in seconds an

                # entry may be active. Default: 0

                maximum-timeout = 0

        }

}

# Instantiation

#

instantiate {

        exec

        expr

}

#  Authorization. First preprocess (hints and huntgroups files),

#  then realms, and finally look in the "users" file.

authorize {

        preprocess

        mschap

        suffix

        eap

        files

}

#  Authentication.

authenticate {

         Auth-Type MS-CHAP {

               mschap

          }

         #

         #  Allow EAP authentication.

         eap

}

#

#  Pre-accounting.  Decide which accounting type to use.

#

preacct {

        preprocess

        acct_unique

        files

}

#

#  Accounting.  Log the accounting data.

#

accounting {

        #

        #  Create a 'detail'ed log of the packets.

        #  Note that accounting requests which are proxied

        #  are also logged in the detail file.

        detail

        radutmp

}

#  Session database, used for checking Simultaneous-Use. Either the radutmp

#  or rlm_sql module can handle this.

#  The rlm_sql module is *much* faster

session {

        radutmp

        #

        #  See "Simultaneous Use Checking Querie" in sql.conf

#       sql

}

#  Post-Authentication

#  Once we KNOW that the user has been authenticated, there are

#  additional steps we can take.

post-auth {

      

}

#

#  When the server decides to proxy a request to a home server,

#  the proxied request is first passed through the pre-proxy

#  stage.  This stage can re-write the request, or decide to

#  cancel the proxy.

#

#  Only a few modules currently have this method.

#

pre-proxy {

#       attr_rewrite

        #  Uncomment the following line if you want to change attributes

        #  as defined in the preproxy_users file.

#       files

        #  If you want to have a log of packets proxied to a home

        #  server, un-comment the following line, and the

        #  'detail pre_proxy_log' section, above.

#       pre_proxy_log

}

#

#  When the server receives a reply to a request it proxied

#  to a home server, the request may be massaged here, in the

#  post-proxy stage.

#

post-proxy {

        eap

}
```

----------

## moszern

odessit  thanks for the help!  That works great.  

For anyone reading this later, I was able to get freeradius working with this config for both a users file and mysql database(with a few minor changes) provided the mysql passwords were NOT encrypted.  Once I encrypt them PEAP breaks.  So this setup will work for cleartext only apparently.  Unless someone knows a way around this?

----------

## odessit

no probs, I think encryption/decryption within MySQL is the function of the database yay/nay? (although I would not mind encryption of the users file)

btw - if it is solved - edit the title of the original post and put [SOLVED] infront of it

----------

