Hi All, I've been following Thomas Glanzmann's work on sms/email otp with freeradius and can see it could REALLY save our organisation a lot of money (we're using securid tokens exclusively ATM). I'm trying to work out something to suit us and at the same time be helpful to others into making something useful, not that I'm a coder particularly. Can I just ask if anyone has any ideas about implementing a beginning process like this; Authorization : - Check user is in an ldap group "allowed" to do otp; using the files, and ldap modules. I'm thinking pass back the phone number for sms from the ldap module, and place in a custom attribute. Ok on that bit Authentication: - Assuming user has a phone number in ldap and is allowed to do OTP, and if the request is new and, they authenticate, then we want to generate an OTP and store it. I guess the generation *could* be done in exec or perl modules quite easily or using xlat, but not sure how to do it using that. Then the user, otp failed attempts and maybe lock state are stored, preferably in a sql table. If request isn't new, how many tries have they already had? - The ordering is the tricky thing here - we need to authenticate the user before an otp is generated, then challenge against that otp, incrementing the failure count if the auth fails and then rechallenging up to the failure limit and then setting auth-type if we pass the user. I can't do unlang in the authentication phase and presumably the post auth section may not be the place to do all these other checks and sql bits. I can see why it's perhaps easier to do all this in exec or perl modules and just return an exit code, but I'd like to see if it can all be done within FR. Once the challenge fails, we need to prompt again until the retry limit.. - At some point we need to return control variables from the to determine the account lock state and failed attempts if the user fails and then revisits the NAS - from the SQL module, where I'd like to see the session data stored. I guess this is possible but am not 100% on how it's done. These are just ramblings. I'd forgive people for just ignoring this post, but hopefully someone is interested enough to get something like this working - it's a great cheap way of 2 factor authentication and it'd be nice not to have to go and buy software to do this. I know Thomas Glanzmann has already got this going with rlm_perl and the smsotp module methods using a file based db, but I'd like to see ldap authorization and variable passback (phone numbers/ email addresses if using email OTP) filling an sql DB, or maybe rlm_cache (of which I've no knowledge and I think is experimental?) for storage of variables. Also some post auth sql storage of cumulative sessions, failed attempts etc, if possible all using FR natively without perl/exec etc, which wouldn't be too difficult. Am I dreaming or can this be done completely within FR without using perl/exec/..? Cheers Andy
Hello, I don't know why I can't make my authentication working with Juniper secure access I have a user +----+----------+--------------------+------------+----+ | id | username | attribute | value | op | +----+----------+--------------------+------------+----+ | 9 | t2 | Cleartext-Password | passsecret | == | +----+----------+--------------------+------------+----+ Command line authentication works # radtest t2 passsecret 127.0.0.1 1812 testing1234 PPP 192.168.1.1 I entered the Juniper device in clients.conf client mag.mydomain.com { ipaddr = 192.168.1.2 secret = mykey shortname = mag require_message_authenticator = no nastype = other # localhost isn't usually a NAS... } I entered that same key in the Juniper secure access configuration The complete debug output is below, does anyone see something that could explain why it doesn't work ? It says: [pap] WARNING! No "known good" password found for the user. Authentication may fail because of this. However, the password is good !!! rad_recv: Access-Request packet from host 192.168.1.2 port 65218, id=236, length=132 NAS-Identifier = "mag" User-Name = "t2" User-Password = "passsecret" Tunnel-Client-Endpoint:0 = "192.168.1.3" NAS-IP-Address = 192.168.1.2 NAS-Port = 0 Acct-Session-Id = "t2(Group XXXX)\"Sun Sep 16 01:43:02 2012\"VVZatHVK" # Executing section authorize from file /etc/raddb/sites-enabled/default +- entering group authorize {...} ++[preprocess] returns ok ++[chap] returns noop ++[mschap] returns noop ++[digest] returns noop [suffix] No '@' in User-Name = "t2", looking up realm NULL [suffix] No such realm "NULL" ++[suffix] returns noop [eap] No EAP-Message, not doing EAP ++[eap] returns noop [files] users: Matched entry DEFAULT at line 202 ++[files] returns ok [sql] expand: %{User-Name} -> t2 [sql] sql_set_user escaped user --> 't2' rlm_sql (sql): Reserving sql socket id: 3 [sql] 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 = 't2' ORDER BY id rlm_sql_mysql: query: SELECT id, username, attribute, value, op FROM radcheck WHERE username = 't2' ORDER BY id [sql] expand: SELECT groupname FROM radusergroup WHERE username = '%{SQL-User-Name}' ORDER BY priority -> SELECT groupname FROM radusergroup WHERE username = 't2' ORDER BY priority rlm_sql_mysql: query: SELECT groupname FROM radusergroup WHERE username = 't2' ORDER BY priority rlm_sql (sql): Released sql socket id: 3 [sql] User t2 not found ++[sql] returns notfound ++[expiration] returns noop ++[logintime] returns noop [pap] WARNING! No "known good" password found for the user. Authentication may fail because of this. ++[pap] returns noop ERROR: No authenticate method (Auth-Type) found for the request: Rejecting the user Failed to authenticate the user. expand: Host %n -> Host 192.168.1.2 Login incorrect: [t2/passsecret] (from client mag port 0) Host 192.168.1.2 Using Post-Auth-Type Reject # Executing group from file /etc/raddb/sites-enabled/default +- entering group REJECT {...} [attr_filter.access_reject] expand: %{User-Name} -> t2 attr_filter: Matched entry DEFAULT at line 11 ++[attr_filter.access_reject] returns updated Delaying reject of request 5 for 1 seconds Going to the next request Waking up in 0.9 seconds. Sending delayed reject for request 5 Sending Access-Reject of id 236 to 192.168.1.2 port 65218 Waking up in 4.9 seconds. Cleaning up request 5 ID 236 with timestamp +1809 Ready to process requests.
On Sun, Sep 16, 2012 at 7:00 AM, Mik J <mikydevel@yahoo.fr> wrote:
Hello,
I don't know why I can't make my authentication working with Juniper secure access
I have a user +----+----------+--------------------+------------+----+ | id | username | attribute | value | op | +----+----------+--------------------+------------+----+ | 9 | t2 | Cleartext-Password | passsecret | == | +----+----------+--------------------+------------+----+
Change the op to ":=" ... which you should've seen if you read the included doc/rlm_sql -- Fajar
De : Fajar A. Nugraha <list@fajar.net>
On Sun, Sep 16, 2012 at 7:00 AM, Mik J <mikydevel@yahoo.fr> wrote:
Hello,
I don't know why I can't make my authentication working with Juniper secure access
I have a user +----+----------+--------------------+------------+----+ | id | username | attribute | value | op | +----+----------+--------------------+------------+----+ | 9 | t2 | Cleartext-Password | passsecret | == | +----+----------+--------------------+------------+----+
Change the op to ":="
... which you should've seen if you read the included doc/rlm_sql
Thank you for your answer Fajar, it helped although the authentication is not fully functional. For now I'll read again the documentation.
De : Mik J <mikydevel@yahoo.fr> De : Fajar A. Nugraha <list@fajar.net>
On Sun, Sep 16, 2012 at 7:00 AM, Mik J <mikydevel@yahoo.fr> wrote:
Hello,
I don't know why I can't make my authentication working with
Juniper secure access
I have a user +----+----------+--------------------+------------+----+ | id | username | attribute | value | op | +----+----------+--------------------+------------+----+ | 9 | t2 | Cleartext-Password | passsecret | == | +----+----------+--------------------+------------+----+
Change the op to ":="
... which you should've seen if you read the included doc/rlm_sql
Thank you for your answer Fajar, it helped although the authentication is not fully functional. For now I'll read again the documentation.
So here's what the documentation says: == "Attribute == Value": As a check item, it matches if the named attribute is present in the request, AND has the given value. =>>> In my case, I wanted to compare the password sent by the Juniper device to the entry in the radcheck table. If the login and password matches then the check is positive. So the documentation seems to say that it should work with "==" or I don't understand. := "Attribute := Value": Always matches as a check item, and replaces in the configuration items any attribute of the same name. If no attribute of that name appears in the request, then this attribute is added.
On Sun, Sep 16, 2012 at 3:09 PM, Mik J <mikydevel@yahoo.fr> wrote:
So here's what the documentation says:
== "Attribute == Value": As a check item, it matches if the named attribute is present in the request, AND has the given value. =>>> In my case, I wanted to compare the password sent by the Juniper device to the entry in the radcheck table. If the login and password matches then the check is positive. So the documentation seems to say that it should work with "==" or I don't understand.
No, that's not how it works. If you want to check for other attributes (e.g. bind a user to a particular Calling-Station-Id), you can use "==". But not for password. More details below.
:= "Attribute := Value": Always matches as a check item, and replaces in the configuration items any attribute of the same name. If no attribute of that name appears in the request, then this attribute is added.
If you've read doc/rlm_sql, like I suggested, you would've seen examples of what entry goes where. This is a start. Once that works, you can read other docs to find out what they mean. Regarding user-password, it's somewhat special. Old version of FR manpage (e.g. http://swoolley.org/man.cgi/5/users) actually suggest using "==". Don't use those, as they're outdated. A good explanation on how it should be is included in the current version of FR. For example, if you run "man 5 users" on up-to-date installation, you'd see this snippet: " EXAMPLES bob Cleartext-Password := "hello" Requests containing the User-Name attribute, with value "bob", will be authenticated using the "known good" password "hello". There are no reply items, so the reply will be empty. " "known good password' is a configuration item ("control item" is probably a better term). It tells the server "this is what the correct password for the user is". You need to use ":=", because you're NOT directly comparing it to User-Password in incoming request. The password that user sends might be in the form of User-Password attribute (in which case the content will be the same as cleartext-password that you store in the db), or they might come in different form (e.g. Chap-Password). Since it might be different, you can't compare it directly (thus, you can't use "=="). Instead, you need to tell the server what the correct password is (with ":=" and the attribute Cleartext-Password), and the server will then perform the necessary processing, and then compare it to whatever attribute the client sends. Does that (simplified) explanation make sense? -- Fajar
----- Mail original -----
De : Fajar A. Nugraha <list@fajar.net> À : Mik J <mikydevel@yahoo.fr>; FreeRadius users mailing list <freeradius-users@lists.freeradius.org> Cc : Envoyé le : Dimanche 16 septembre 2012 10h35 Objet : Re: Authentication with Juniper SA
On Sun, Sep 16, 2012 at 3:09 PM, Mik J <mikydevel@yahoo.fr> wrote:
So here's what the documentation says:
== "Attribute == Value": As a check item, it matches if the named attribute is present in the request, AND has the given value. =>>> In my case, I wanted to compare the password sent by the Juniper device to the entry in the radcheck table. If the login and password matches then the check is positive. So the documentation seems to say that it should work with "==" or I don't understand.
No, that's not how it works.
If you want to check for other attributes (e.g. bind a user to a particular Calling-Station-Id), you can use "==". But not for password. More details below.
:= "Attribute := Value": Always matches as a check item, and
replaces in the configuration items any attribute of the same name. If no attribute of that name appears in the request, then this attribute is added.
If you've read doc/rlm_sql, like I suggested, you would've seen examples of what entry goes where. This is a start. Once that works, you can read other docs to find out what they mean.
Regarding user-password, it's somewhat special. Old version of FR manpage (e.g. http://swoolley.org/man.cgi/5/users) actually suggest using "==". Don't use those, as they're outdated. A good explanation on how it should be is included in the current version of FR. For example, if you run "man 5 users" on up-to-date installation, you'd see this snippet:
" EXAMPLES
bob Cleartext-Password := "hello"
Requests containing the User-Name attribute, with value "bob", will be authenticated using the "known good" password "hello". There are no reply items, so the reply will be empty. "
"known good password' is a configuration item ("control item" is probably a better term). It tells the server "this is what the correct password for the user is". You need to use ":=", because you're NOT directly comparing it to User-Password in incoming request.
The password that user sends might be in the form of User-Password attribute (in which case the content will be the same as cleartext-password that you store in the db), or they might come in different form (e.g. Chap-Password). Since it might be different, you can't compare it directly (thus, you can't use "=="). Instead, you need to tell the server what the correct password is (with ":=" and the attribute Cleartext-Password), and the server will then perform the necessary processing, and then compare it to whatever attribute the client sends.
Does that (simplified) explanation make sense?
Hello Fajar, This is very clear now. My freeradius version is not so new (2.1.12) Thank you very much for this explanation. Have a nice week end
On Sun, Sep 16, 2012 at 4:20 PM, Mik J <mikydevel@yahoo.fr> wrote:
The password that user sends might be in the form of User-Password attribute (in which case the content will be the same as cleartext-password that you store in the db), or they might come in different form (e.g. Chap-Password). Since it might be different, you can't compare it directly (thus, you can't use "=="). Instead, you need to tell the server what the correct password is (with ":=" and the attribute Cleartext-Password), and the server will then perform the necessary processing, and then compare it to whatever attribute the client sends.
Does that (simplified) explanation make sense?
Hello Fajar, This is very clear now. My freeradius version is not so new (2.1.12)
2.1.12 is actually new-enough, in that many distro still ships with it, and it also needs "Cleartext-Password :=" instead of "==". There's a know security issue with anything under 2.2.0 though, so if you're using anything older make sure the fix is backported (e.g. if you're using debian/ubuntu make sure you use 2.1.12+dfsg-1.1). Ask your distro support/forum/list for details. Also, just in case I wasn't clear, you can still use "==" in newer versions of FR (and you probably need to, for some situations). The exception is only for user password, where you should use "Cleartext-Password :=" instead of "User-Password ==". -- Fajar
participants (3)
-
Fajar A. Nugraha -
Franks Andy (RLZ) IT Systems Engineer -
Mik J