Question

I'm trying to authenticate freeradius users against a PHP script, with no success. I've been trying for hours to config this right, and all the threads I found with Google are either deadlinked or obsolete...

radiusd.conf

prefix = /usr
exec_prefix = /usr
sysconfdir = /etc
localstatedir = /var
sbindir = ${exec_prefix}/sbin
logdir = /var/log/freeradius
raddbdir = /etc/freeradius
radacctdir = ${logdir}/radacct

#  Name of the running server
name = freeradius

#  Location of config and logfiles.
confdir = ${raddbdir}
run_dir = ${localstatedir}/run/${name}

# Should likely be ${localstatedir}/lib/radiusd
db_dir = ${raddbdir}

libdir = /usr/lib/freeradius

pidfile = ${run_dir}/${name}.pid

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

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

#  cleanup_delay: The time to wait (in seconds) before cleaning up
#  a reply which was sent to the NAS.
cleanup_delay = 5

#  max_requests: The maximum number of requests which the server keeps
#  track of.  This should be 256 multiplied by the number of clients.
#  e.g. With 4 clients, this number should be 1024.
max_requests = 1024

#  listen: Make the server listen on a particular IP address, and send
#  replies out from that address. This directive is most useful for
#  hosts with multiple IP addresses on one interface.
listen {
    type = auth
    ipaddr = *
    port = 0
}

#  This second "listen" section is for listening on the accounting
#  port, too.
listen {
    ipaddr = *
    port = 0
    type = acct
}

hostname_lookups = no
allow_core_dumps = no
regular_expressions = yes
extended_expressions    = yes

log {
    destination = files
    file = ${logdir}/radius.log
    syslog_facility = daemon
    stripped_names = no
    auth = no
    auth_badpass = no
    auth_goodpass = no
}

checkrad = ${sbindir}/checkrad

security {
    max_attributes = 200
    reject_delay = 1
    status_server = yes
}

proxy_requests  = off

# CLIENTS CONFIGURATION
client 0.0.0.0/0 {
    secret = secret
    shortname = wireless
}

# THREAD POOL CONFIGURATION
thread pool {
    start_servers = 5
    max_servers = 32
    min_spare_servers = 3
    max_spare_servers = 10
    max_requests_per_server = 0
}

# MODULE CONFIGURATION
modules {
    $INCLUDE ${confdir}/modules/
    $INCLUDE eap.conf
}

# Instantiation
instantiate {
    exec
    expr
    expiration
    logintime
}

$INCLUDE policy.conf

$INCLUDE sites-enabled/

modules/exec

exec {
    wait = yes 
    program = "/usr/bin/php -f /usr/local/auth.php %{User-Name} %{User-Password}"
    input_pairs = request 
    output_pairs = reply
    shell_escape = yes
}

sites-available/default

authorize {
    preprocess
    exec
    chap
    suffix
    files
    expiration
    logintime
    pap
}

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


preacct {
    preprocess
    acct_unique
    suffix
    files
}

accounting {
    detail
    radutmp
    exec
    attr_filter.accounting_response
}

session {
    radutmp
}

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

pre-proxy {
}

post-proxy {
}

Although I have no idea what to put in the users file...

Was it helpful?

Solution

It's actually quite easy. Remove everything you did and start over.

Go into your sites-enabled/default file.

Go into the authorize directive and add this code in. Replace yourscript.php with the proper script. Make sure the user radiusd has access to run the script.

authorize{
    update control { 
        Auth-Type := `/usr/bin/php -f /etc/raddb/yourscript.php '%{User-Name}' '%{User-Password}' '%{Client-IP-Address}'`
    }

Make sure your script echoes "Accept" or "Reject" without the quotations. This should authentication your user.

Since someone requested how to pull attributes -

Open up the /etc/raddb/users file and update the following-

DEFAULT Auth-Type = Accept
Exec-Program-Wait = "/usr/bin/php -f  /etc/raddb/yourscript.php '%{User-Name}' '%{User-Password}' '%{Client-IP-Address}'"

Essentially you're telling it if the Auth-Type is Accept to execute the following script and pull the attributes. Make sure your PHP script just echos out the attributes. Depending on the vendor, the attributes will obviously be different.

Edits-

  • Added attributes information

  • Added '%{Client-IP-Address}' to specify the device the user is trying to connect to

OTHER TIPS

I try custom script in Python and PHP,
and find out the Freeradius' Auth-Type will always be 'Auth-Reject'
when the script has a non-zero return code.

So I use "echo" in PHP and "print" in Python replace return code.

like this in PHP

if(isUserValid($user['username'], $user['password'])) {
  // do nothing
  echo 'correct string';
} else {
  echo 'incorrect string';
}
return 0 //OR not return anything

or in Python

if(login success):
  print "correct string"
else:
  print "incorrect string"

then use the string to determine login success or fail in FreeRadius

  if (Tmp-String-0 == 'correct string') {
    update control {
      Auth-type := Accept
    }
    update reply{
      reply-message += "password correct"
    }
  }
  else {
    reject
    update reply{
      reply-message += "password incorrect"
    }
  }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top