Freeradius and PHP auth script
Asked Answered
W

2

9

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...

Whitebeam answered 3/3, 2012 at 0:33 Comment(0)
Q
18

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

Queenqueena answered 14/12, 2012 at 0:17 Comment(7)
Hi, how can be this changed to read also more attributes than Accept or Reject ? Thanks.Brunobruns
Keep in mind @CarcaBot that you will need both scripts running in order to do two things. 1) Return Accept or Reject . 2) Send the attributes . Both are required to make this work.Queenqueena
Shouldn't you rather say Auth-Type == Accept?Urien
Does this require any other configuration? Using yourscript.php with just one line ( echo "Accept"; ) I get ERROR: Expecting output ... Expecting operator; ERROR: Program returned code (0) and output 'Accept', and then it rejects.Thompkins
This is now from almost 1 year and a half ago, this method could be deprecated by now. However, just outputting "Accept" should work considering you're specifying: "Auth-Type := Accept" in the control, which should be valid, unless it was deprecated in newer versions.Queenqueena
anyone can repost what files must i change, i'm still got error "/etc/freeradius/users[74]: Parse error (check) for entry Exec-Program-Wait: Invalid vendor name in attribute name "" and error "Errors reading /etc/freeradius/users"Catton
How can you filter this just for PAP (not mschap)?Demolish
D
-1

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"
    }
  }
Discontinuity answered 5/10, 2016 at 8:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.