I have a configuration which I need, but haven't been able to figure out how to make freeradius do it. I have two users, A and B, both authenticating over wireless using EAP-TLS. User A has a certificate which has been signed by CA X, and B has one signed by CA Y. What I need is to tell freeradius that certificates presented by user A should only be checked against CA X, and similarly B only by Y. Putting both X and Y in the same CA list won't work in this case due to what appears to be a limitation in OpenSSL. I've been over all the existing docs I can find, and I haven't been able any way to do this. Anyone have any suggestion what I might try? -- Frank Sweetser fs at wpi.edu | For every problem, there is a solution that WPI Senior Network Engineer | is simple, elegant, and wrong. - HL Mencken GPG fingerprint = 6174 1257 129E 0D21 D8D4 E8A3 8E39 29E3 E2E8 8CEC
Frank, It is not really a configuration issue, but more an Identity Management issue. It is not common to have a CA per user, but a CA per domain. And per domain you have users. So: User X from domain A has CA 1. User Y from domain B has CA 2. If this is what you are trying to achieve you can simply setup a configuration per domain/realm of these users. Regards, Tom
-----Oorspronkelijk bericht----- Van: freeradius-users-bounces+list=securew2.com@lists.freeradius.org [mailto:freeradius-users-bounces+list=securew2.com@lists.freeradius.org] Namens Frank Sweetser Verzonden: vrijdag 6 juni 2008 20:07 Aan: freeradius-users@lists.freeradius.org Onderwerp: EAP-TLS with different CA per user?
I have a configuration which I need, but haven't been able to figure out how to make freeradius do it.
I have two users, A and B, both authenticating over wireless using EAP- TLS. User A has a certificate which has been signed by CA X, and B has one signed by CA Y.
What I need is to tell freeradius that certificates presented by user A should only be checked against CA X, and similarly B only by Y. Putting both X and Y in the same CA list won't work in this case due to what appears to be a limitation in OpenSSL.
I've been over all the existing docs I can find, and I haven't been able any way to do this. Anyone have any suggestion what I might try?
-- Frank Sweetser fs at wpi.edu | For every problem, there is a solution that WPI Senior Network Engineer | is simple, elegant, and wrong. - HL Mencken GPG fingerprint = 6174 1257 129E 0D21 D8D4 E8A3 8E39 29E3 E2E8 8CEC - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
In our company, we do have certificates signed by multiple Certificate Authorities...but there is a hierarchy. So, some users come in from Domain A (root CA) some come in from Domain B (intermediate CA). So then it's easy....just maintain the CA_path containing the root and any necessary intermediate CAs. On Sat, Jun 7, 2008 at 11:48 AM, SecureW2 (List) <list@securew2.com> wrote:
Frank,
It is not really a configuration issue, but more an Identity Management issue.
It is not common to have a CA per user, but a CA per domain. And per domain you have users.
So:
User X from domain A has CA 1. User Y from domain B has CA 2.
If this is what you are trying to achieve you can simply setup a configuration per domain/realm of these users.
Regards,
Tom
-----Oorspronkelijk bericht----- Van: freeradius-users-bounces+list=securew2.com@lists.freeradius.org [mailto:freeradius-users-bounces+list <freeradius-users-bounces%2Blist>= securew2.com@lists.freeradius.org] Namens Frank Sweetser Verzonden: vrijdag 6 juni 2008 20:07 Aan: freeradius-users@lists.freeradius.org Onderwerp: EAP-TLS with different CA per user?
I have a configuration which I need, but haven't been able to figure out how to make freeradius do it.
I have two users, A and B, both authenticating over wireless using EAP- TLS. User A has a certificate which has been signed by CA X, and B has one signed by CA Y.
What I need is to tell freeradius that certificates presented by user A should only be checked against CA X, and similarly B only by Y. Putting both X and Y in the same CA list won't work in this case due to what appears to be a limitation in OpenSSL.
I've been over all the existing docs I can find, and I haven't been able any way to do this. Anyone have any suggestion what I might try?
-- Frank Sweetser fs at wpi.edu | For every problem, there is a solution that WPI Senior Network Engineer | is simple, elegant, and wrong. - HL Mencken GPG fingerprint = 6174 1257 129E 0D21 D8D4 E8A3 8E39 29E3 E2E8 8CEC - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
SecureW2 (List) wrote:
Frank,
It is not really a configuration issue, but more an Identity Management issue.
It is not common to have a CA per user, but a CA per domain. And per domain you have users.
In general, I certainly agree. The catch is that I'm attempting to handle certs and CAs that are already out on some users machines. Worst case, I can start having everyone update certs as needed, but it would be far less hassle for me to handle it in freeradius.
So:
User X from domain A has CA 1. User Y from domain B has CA 2.
If this is what you are trying to achieve you can simply setup a configuration per domain/realm of these users.
The usernames currently don't have a domain portion. Would it be possible for me to set a default domain for a given username? (The list is small, so would be manageable for me.) And if so, could you give me at least a rough example of how I would set this up? -- Frank Sweetser fs at wpi.edu | For every problem, there is a solution that WPI Senior Network Engineer | is simple, elegant, and wrong. - HL Mencken GPG fingerprint = 6174 1257 129E 0D21 D8D4 E8A3 8E39 29E3 E2E8 8CEC
Frank Sweetser wrote:
The usernames currently don't have a domain portion. Would it be possible for me to set a default domain for a given username? (The list is small, so would be manageable for me.) And if so, could you give me at least a rough example of how I would set this up?
You can configure two different versions of the EAP module. Each one has it's own server cert && CA. Then, in the "authorize" section, do: authorize { ... if (User-Name == "user1") { eap_1 } elsif (User-Name == "user2") { eap_2 } ... } authenticate { ... eap_1 eap_2 ... } That should work. Alan DeKok.
Happy Sunday! Trying to install FR 2.0.4 on my Solaris 10, I'm getting a lot of WARNINGS during ./configure and "make" does nut run til the expected end. I pasted the ./configure warnings at the end. To me, it looks about a general error in my Solaris configuration, because libgdbm, OpenSSL, snmpget, snmpwalk are on the system after the standard installation and after installing coolstack. I've also spamed my PATH with every lib, bin, sbin directories from sfw, coolstack, usr and usr/local, where the needed portions are spread over. I'm able to add options to ./configure like the MySQL path or to disable features, which are not required, like oracle, but there must be a more simple way... I bet. Any hints? How did you do this on Solaris 10? (Solaris 9 with FR 1.0.2 installs fine...) Thank you. Stefan What I did: Solaris 10 Sparc Sun Coolstack (incl MySQL and Perl) gcc 3.4.6 from sunfreeware.com Make 3.8.1 from sunfreeware.com Libiconf 1.11 from sunfreeware.com FR 2.0.4 ./configure These are the warnings: configure: WARNING: snmpget not found - Simultaneous-Use and checkrad.pl may not work configure: WARNING: snmpwalk not found - Simultaneous-Use and checkrad.pl may not work configure: WARNING: pcap library not found, silently disabling the RADIUS sniffer. config.status: WARNING: ./Make.inc.in seems to ignore the --datarootdir setting config.status: WARNING: ./src/include/build-radpaths-h.in seems to ignore the --datarootdir setting chmod: WARNING: can't access check-radiusd-config configure: WARNING: FAILURE: rlm_counter requires: libgdbm. configure: WARNING: FAILURE: rlm_eap_tls requires: OpenSSL. configure: WARNING: FAILURE: rlm_eap_ttls requires: OpenSSL. configure: WARNING: FAILURE: rlm_eap_ikev2 requires: libeap-ikev2 EAPIKEv2/connector.h. configure: WARNING: the TNCS library isn't found! configure: WARNING: FAILURE: rlm_eap_tnc requires: -lTNCS. configure: WARNING: FAILURE: rlm_eap_peap requires: OpenSSL. configure: WARNING: silently not building rlm_ippool. configure: WARNING: FAILURE: rlm_ippool requires: libgdbm. configure: WARNING: neither krb5 'k5crypto' nor 'crypto' libraries are found! configure: WARNING: the comm_err library isn't found! configure: WARNING: FAILURE: rlm_krb5 requires: krb5.h krb5. configure: WARNING: FAILURE: rlm_ldap requires: libldap_r. configure: WARNING: FAILURE: rlm_otp requires: openssl-libs openssl-includes openssl-includes openssl-includes openssl-includes openssl-includes. configure: WARNING: FAILURE: rlm_perl requires: EXTERN.h perl.h libperl.so. configure: WARNING: FAILURE: rlm_python requires: python-binary. configure: WARNING: FAILURE: rlm_sql_iodbc requires: libiodbc isql.h. configure: WARNING: MySQL libraries not found. Use --with-mysql-lib-dir=<path>. configure: WARNING: MySQL headers not found. Use --with-mysql-include-dir=<path>. configure: WARNING: FAILURE: rlm_sql_mysql requires: libmysqlclient_r mysql.h. configure: WARNING: FAILURE: rlm_sql_postgresql requires: libpq-fe.h libpq. configure: WARNING: oracle headers not found. Use --with-oracle-home-dir=<path>. configure: WARNING: FAILURE: rlm_sql_oracle requires: oci.h. configure: WARNING: FAILURE: rlm_sql_unixodbc requires: libodbc sql.h.
Stefan A. wrote:
Happy Sunday! Trying to install FR 2.0.4 on my Solaris 10, I'm getting a lot of WARNINGS during ./configure and "make" does nut run til the expected end.
WARNINGS are OK. They just mean that some optional thing wasn't found. What are the errors from make?
I pasted the ./configure warnings at the end. To me, it looks about a general error in my Solaris configuration, because libgdbm, OpenSSL, snmpget, snmpwalk are on the system after the standard installation and after installing coolstack.
Are they located in places where the linker can C compiler can find them? It doesn't look like it.
I've also spamed my PATH with every lib, bin, sbin directories from sfw, coolstack, usr and usr/local, where the needed portions are spread over.
PATH only affects executables. It doesn't affect include files or libraries.
Any hints? How did you do this on Solaris 10? (Solaris 9 with FR 1.0.2 installs fine...)
My solaris 10 installs go pretty much like any other system. I just make sure that the C compiler can find the include files, and that the linker can find the libraries. Alan DeKok.
Gurus! I still have problems, getting FR 2.0.4 up and running, for days.. Reading hundreds of emails and listings.... I'm lost. Alan, thanks for your reply. I followed your hint and configured using this options: ./configure --with-openssl-libraries=/usr/sfw/lib \ --with-openssl-includes=/usr/sfw/include/openssl \ --with-mysql-dir=/opt/coolstack/mysql \ --with-mysql-lib-dir=/opt/coolstack/mysql/lib/mysql/lib |grep WARNING & The OpenSSL Warnings are gone. I also renamed the src/directories of counter, eap, eap2, ippool, krb5, ldap, opt, pam, perl, python To not use them, because I'll only do accounting into MySQL. Some Warnings are still there: configure: WARNING: snmpget not found - Simultaneous-Use and checkrad.pl may not work configure: WARNING: snmpwalk not found - Simultaneous-Use and checkrad.pl may not work configure: WARNING: pcap library not found, silently disabling the RADIUS sniffer. config.status: WARNING: ./Make.inc.in seems to ignore the --datarootdir setting config.status: WARNING: ./src/include/build-radpaths-h.in seems to ignore the --datarootdir setting chmod: WARNING: can't access check-radiusd-config configure: WARNING: FAILURE: rlm_sql_iodbc requires: libiodbc isql.h. configure: WARNING: MySQL libraries not found. Use --with-mysql-lib-dir=<path>. configure: WARNING: FAILURE: rlm_sql_mysql requires: libmysqlclient_r. configure: WARNING: FAILURE: rlm_sql_postgresql requires: libpq-fe.h libpq. configure: WARNING: oracle headers not found. Use --with-oracle-home-dir=<path>. configure: WARNING: FAILURE: rlm_sql_oracle requires: oci.h. configure: WARNING: FAILURE: rlm_sql_unixodbc requires: libodbc sql.h. (I will take a look for the MySQL warning later, but I'm sure, that the libs are in the directory, given to ./configure) 'make' seems to work fine... Piped it into a file and did not find an error or warning. 'make install' also runs, but shows a lot of warnings similar to this one "libtool: install: warning: relinking `rlm_expiration.la'" 'radiusd -X' just tells: ld.so.1: radiusd: fatal: libgcc_s.so.1: open failed: No such file or directory Killed Coming to that point, it is real frustrating to read:
My solaris 10 installs go pretty much like any other system. I just make sure that the C compiler can find the include files, and that the linker can find the libraries.
What else did you do? I've installed Solaris 10 and Coolstack (the Sun Apache/MySQL/PHP/Perl pack) Then GCC from sunfreeware incl. Libiconv.... The FR 2.0.4 having the above trouble.... Any further ideas? Thank you. Stefan
-----Original Message----- From: freeradius-users-bounces+a.freeradius=premit.de@lists.freeradi us.org [mailto:freeradius-users-bounces+a.freeradius=premit.de@lists. freeradius.org] On Behalf Of Alan DeKok Sent: Sunday, June 08, 2008 6:24 PM To: FreeRadius users mailing list Subject: Re: FR 2.0.4 on Solaris 10 Sparc
Stefan A. wrote:
Happy Sunday! Trying to install FR 2.0.4 on my Solaris 10, I'm getting a lot of WARNINGS during ./configure and "make" does nut run til the expected end.
WARNINGS are OK. They just mean that some optional thing wasn't found.
What are the errors from make?
I pasted the ./configure warnings at the end. To me, it looks about a general error in my Solaris configuration, because libgdbm, OpenSSL, snmpget, snmpwalk are on the system after the standard installation and after installing coolstack.
Are they located in places where the linker can C compiler can find them? It doesn't look like it.
I've also spamed my PATH with every lib, bin, sbin directories from sfw, coolstack, usr and usr/local, where the needed portions are spread over.
PATH only affects executables. It doesn't affect include files or libraries.
Any hints? How did you do this on Solaris 10? (Solaris 9 with FR 1.0.2 installs fine...)
My solaris 10 installs go pretty much like any other system. I just make sure that the C compiler can find the include files, and that the linker can find the libraries.
Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Stefan A. wrote:
I still have problems, getting FR 2.0.4 up and running, for days.. Reading hundreds of emails and listings.... I'm lost.
It's not a FreeRADIUS problem.
I also renamed the src/directories of counter, eap, eap2, ippool, krb5, ldap, opt, pam, perl, python To not use them, because I'll only do accounting into MySQL.
That's unnecessary. Please don't do that.
Some Warnings are still there:
They are WARNINGs, not ERRORs. Ignore them.
(I will take a look for the MySQL warning later, but I'm sure, that the libs are in the directory, given to ./configure)
Or, just edit src/modules/rlm_sql/drivers/rlm_sql_mysql/Makefile The "configure" script is just there to catch the common cases. If it doesn't work, the "Makefile" *is* text, and *can* be edited by hand.
'make install' also runs, but shows a lot of warnings similar to this one "libtool: install: warning: relinking `rlm_expiration.la'"
Again, warnings are not errors.
'radiusd -X' just tells:
ld.so.1: radiusd: fatal: libgcc_s.so.1: open failed: No such file or directory
You've managed to install libgcc in a location where the run-time linker can't find it. This is a gcc/solaris problem. It's NOT a freeradius problem. See "man crle" on Solaris for how to fix it. e.g.: $ crle -l /path/to/directory/containing/libgcc -u If you don't have libgcc.... install it from sunfreeware.
Coming to that point, it is real frustrating to read:
My solaris 10 installs go pretty much like any other system. I just make sure that the C compiler can find the include files, and that the linker can find the libraries.
What else did you do?
I installed libgcc from sunfreeware, gcc, libiconv, and a bunch of other things. I read the documentation on sunfreeware, to see what other packages were needed by the packages I wanted. I downloaded them all, and installed them all.
Any further ideas?
The problems you're running into are strictly Solaris. You would see them if you tried to build *any* Open Source software from the source code. Alan DeKok.
Alan DeKok wrote:
Frank Sweetser wrote:
The usernames currently don't have a domain portion. Would it be possible for me to set a default domain for a given username? (The list is small, so would be manageable for me.) And if so, could you give me at least a rough example of how I would set this up?
You can configure two different versions of the EAP module. Each one has it's own server cert && CA. Then, in the "authorize" section, do:
authorize { ... if (User-Name == "user1") { eap_1 } elsif (User-Name == "user2") { eap_2 } ...
}
authenticate { ... eap_1 eap_2 ... }
That should work.
That looks exactly like what I was looking for - thanks! I'll give this a shot on Monday and report back on how it worked... -- Frank Sweetser fs at wpi.edu | For every problem, there is a solution that WPI Senior Network Engineer | is simple, elegant, and wrong. - HL Mencken GPG fingerprint = 6174 1257 129E 0D21 D8D4 E8A3 8E39 29E3 E2E8 8CEC
Alan DeKok wrote:
Frank Sweetser wrote:
The usernames currently don't have a domain portion. Would it be possible for me to set a default domain for a given username? (The list is small, so would be manageable for me.) And if so, could you give me at least a rough example of how I would set this up?
You can configure two different versions of the EAP module. Each one has it's own server cert && CA. Then, in the "authorize" section, do:
authorize { ... if (User-Name == "user1") { eap_1 } elsif (User-Name == "user2") { eap_2 } ...
}
authenticate { ... eap_1 eap_2 ... }
That should work.
Alan DeKok.
This worked perfectly, Alan. Thanks again! -- Frank Sweetser fs at wpi.edu | For every problem, there is a solution that WPI Senior Network Engineer | is simple, elegant, and wrong. - HL Mencken GPG fingerprint = 6174 1257 129E 0D21 D8D4 E8A3 8E39 29E3 E2E8 8CEC
Background: We're using FreeRADIUS-2.0.3 with an OpenLDAP backend, on two separate systems for authentication and authorization of users to our wireless network and a lesser-used VPN service. I would like to be able to modify the LDAP query filter based on (for example) which NAS device sent the RADIUS request so that (again, for example) a different filter might be used to search for wireless users than for VPN users. In an effort to be able to setup a "dynamic" LDAP query filter, I have tried adding a string-type attribute to our local dictionary file, to hold the filter that would be updated on-the-fly: ATTRIBUTE CU-LDAP-Filter 3000 string The radiusd.conf file then has ldap module instances (one per LDAP server) with the following reference to this attribute: ldap ldap_host1 { server = "ldap_host1" identity = "cn=...,ou=...,dc=concordia,dc=ca" password = "**SANITIZED**" basedn = "ou=people,dc=concordia,dc=ca" filter = "%{CU-LDAP-Filter}" base_filter = "(objectclass=ConcordiaPerson)" ... } ldap ldap_host2 { server = "ldap_host2" identity = "cn=...,ou=...,dc=concordia,dc=ca" password = "**SANITIZED**" basedn = "ou=people,dc=concordia,dc=ca" filter = "%{CU-LDAP-Filter}" base_filter = "(objectclass=ConcordiaPerson)" ... } I'm presently testing with the radeapclient client (on localhost), so am testing with the following configured into sites-enabled/default: authorize { ... switch "%{NAS-IP-Address}" { case 192.168.198.20 { # test update control { CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY1 TRIMMED FOR BREVITY***))" } } case 127.0.0.1 { # test update control { CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY2 TRIMMED FOR BREVITY***))" } } ... case { # default noop } } if ("%{CU-LDAP-Filter}" != "") { redundant-load-balance { ldap_host1 ldap_host2 } } ... } The LDAP query filters, though not included above (these things are quite long and site-specific anyway) are known to work, as they're copied from our currently in-production configuration that is selecting the ldap module instance based on the NAS-IP-Address (ie. if NAS-IP-Address is the VPN server we call the ldap_vpn module which is configured with an appropriate filter, else we call the ldap_wireless module which is also appropriately configured). The present setup works, but based on what I'm reading it would give is a much more flexible and fault-tolerant (and dare-I-say, more manageable?) setup if I could get the LDAP module instances configured into a redundant-load-balance stanza, with a dynamically determined LDAP query filter (so that if one LDAP server is unavailable, one or more others could be tried instead, instead of having a hard-coded query to specific LDAP servers for each service). I hope I'm making sense so far ... The following command is issued to test: radeapclient -x localhost:1815 auth testing123 << END_OF_EAP User-Name = "j_doe" Cleartext-Password = "**SANITIZED**" NAS-IP-Address = 192.168.198.20 NAS-Port-Type = "Wireless-802.11" EAP-Code = Response EAP-Id = 210 EAP-Type-Identity = "j_doe" Message-Authenticator = 0x00 NAS-Port = 0 END_OF_EAP Radiusd, running in debug mode shows the following (config-file parsing output skipped; it is not showing any errors at all, so although the configuration I show above may not be producing the intended result, it at least seems syntactically correct): Listening on authentication address * port 1815 Listening on accounting address * port 1816 Listening on proxy address * port 1817 Ready to process requests. User-Name = "j_doe" NAS-IP-Address = 192.168.198.20 NAS-Port-Type = Wireless-802.11 Message-Authenticator = 0x8499bae7c162d5f0ef2e587fdb9086a0 NAS-Port = 0 EAP-Message = 0x02d200080173796c +- entering group authorize ++[preprocess] returns ok ++[chap] returns noop ++[mschap] returns noop rlm_realm: No '@' in User-Name = "j_doe", looking up realm NULL rlm_realm: No such realm "NULL" ++[suffix] returns noop rlm_eap: EAP packet type response id 210 length 8 rlm_eap: No EAP Start, assuming it's an on-going EAP conversation ++[eap] returns updated ++[unix] returns notfound ++[files] returns noop expand: %{NAS-IP-Address} -> 192.168.198.20 ++- entering switch %{NAS-IP-Address} +++- entering case 192.168.198.20 expand: %{Stripped-User-Name} -> expand: %{User-Name} -> j_doe expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})**LDAP QUERY1 FILTER TRIMMED**) -> (&(cn=j_doe)**LDAP QUERY1 FILTER TRIMMED**) ++++[control] returns noop +++- case 192.168.198.20 returns noop ++- switch %{NAS-IP-Address} returns noop ++? if ("%{CU-LDAP-Filter}" != "") expand: %{CU-LDAP-Filter} -> ? Evaluating ("%{CU-LDAP-Filter}" != "") -> FALSE ++? if ("%{CU-LDAP-Filter}" != "") -> FALSE ++[expiration] returns noop ++[logintime] returns noop rlm_pap: WARNING! No "known good" password found for the user. Authentication may fail because of this. ++[pap] returns noop rad_check_password: Found Auth-Type EAP auth: type "EAP" +- entering group authenticate rlm_eap: EAP Identity rlm_eap: processing type tls rlm_eap_tls: Initiate rlm_eap_tls: Start returned 1 rlm_eap: RT Modif EAP-Type = 21 EAP-LENGTH = 1 ++[eap] returns handled EAP-Message = 0x01d300061520 Message-Authenticator = 0x00000000000000000000000000000000 State = 0x1c870d031c541859b55d17dd8af5914a Finished request 0. Going to the next request Waking up in 4.9 seconds. Cleaning up request 0 ID 232 with timestamp +4 Ready to process requests. Note that of the above, I believe the following is relevant to my question: expand: %{NAS-IP-Address} -> 192.168.198.20 ++- entering switch %{NAS-IP-Address} +++- entering case 192.168.198.20 expand: %{Stripped-User-Name} -> expand: %{User-Name} -> j_doe expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})**LDAP QUERY1 FILTER TRIMMED**) -> (&(cn=j_doe)**LDAP QUERY1 FILTER TRIMMED**) ++++[control] returns noop +++- case 192.168.198.20 returns noop ++- switch %{NAS-IP-Address} returns noop ++? if ("%{CU-LDAP-Filter}" != "") expand: %{CU-LDAP-Filter} -> ? Evaluating ("%{CU-LDAP-Filter}" != "") -> FALSE ++? if ("%{CU-LDAP-Filter}" != "") -> FALSE This corresponds to the following from the "authorize" section in my sites-enabled/default file: switch "%{NAS-IP-Address}" { case 192.168.198.20 { # test update control { CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY TRIMMED FOR BREVITY***))" } } } We see that the line where I intend to assign a value to CU-LDAP-Filter is indeed encountered and the variables referred to in that line are expanded correctly, but it seems as though the assignment to CU-LDAP-Filter isn't done: if ("%{CU-LDAP-Filter}" != "") is evaluated as "FALSE". I suspect that my "update" statement is likely incorrect, since the only mention of it in the debug output is: ++++[control] returns noop Can anyone help me with this? I've read as much of the relevant documentation as I'm aware exists, especially "man unlang" without which I certainly wouldn't have gotten even this far, but I'd be very grateful if someone could point me to further documentation that would help with what I'm trying to do ... Thanks ... -- ---------------------------------------------------------------------- Sylvain Robitaille syl@alcor.concordia.ca Systems and Network analyst Concordia University Instructional & Information Technology Montreal, Quebec, Canada ----------------------------------------------------------------------
man unlang - attribute lists. *** The "<list>:" prefix is optional, and if omitted, is assumed to refer to the "request" list. *** Ivan Kalik Kalik Informatika ISP Dana 9/6/2008, "Sylvain Robitaille" <syl@alcor.concordia.ca> piše:
Background:
We're using FreeRADIUS-2.0.3 with an OpenLDAP backend, on two separate systems for authentication and authorization of users to our wireless network and a lesser-used VPN service. I would like to be able to modify the LDAP query filter based on (for example) which NAS device sent the RADIUS request so that (again, for example) a different filter might be used to search for wireless users than for VPN users.
In an effort to be able to setup a "dynamic" LDAP query filter, I have tried adding a string-type attribute to our local dictionary file, to hold the filter that would be updated on-the-fly:
ATTRIBUTE CU-LDAP-Filter 3000 string
The radiusd.conf file then has ldap module instances (one per LDAP server) with the following reference to this attribute:
ldap ldap_host1 { server = "ldap_host1" identity = "cn=...,ou=...,dc=concordia,dc=ca" password = "**SANITIZED**" basedn = "ou=people,dc=concordia,dc=ca" filter = "%{CU-LDAP-Filter}" base_filter = "(objectclass=ConcordiaPerson)" ... }
ldap ldap_host2 { server = "ldap_host2" identity = "cn=...,ou=...,dc=concordia,dc=ca" password = "**SANITIZED**" basedn = "ou=people,dc=concordia,dc=ca" filter = "%{CU-LDAP-Filter}" base_filter = "(objectclass=ConcordiaPerson)" ... }
I'm presently testing with the radeapclient client (on localhost), so am testing with the following configured into sites-enabled/default:
authorize { ... switch "%{NAS-IP-Address}" { case 192.168.198.20 { # test update control { CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY1 TRIMMED FOR BREVITY***))" } } case 127.0.0.1 { # test update control { CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY2 TRIMMED FOR BREVITY***))" } } ... case { # default noop } }
if ("%{CU-LDAP-Filter}" != "") { redundant-load-balance { ldap_host1 ldap_host2 } } ... }
The LDAP query filters, though not included above (these things are quite long and site-specific anyway) are known to work, as they're copied from our currently in-production configuration that is selecting the ldap module instance based on the NAS-IP-Address (ie. if NAS-IP-Address is the VPN server we call the ldap_vpn module which is configured with an appropriate filter, else we call the ldap_wireless module which is also appropriately configured). The present setup works, but based on what I'm reading it would give is a much more flexible and fault-tolerant (and dare-I-say, more manageable?) setup if I could get the LDAP module instances configured into a redundant-load-balance stanza, with a dynamically determined LDAP query filter (so that if one LDAP server is unavailable, one or more others could be tried instead, instead of having a hard-coded query to specific LDAP servers for each service).
I hope I'm making sense so far ...
The following command is issued to test:
radeapclient -x localhost:1815 auth testing123 << END_OF_EAP User-Name = "j_doe" Cleartext-Password = "**SANITIZED**" NAS-IP-Address = 192.168.198.20 NAS-Port-Type = "Wireless-802.11" EAP-Code = Response EAP-Id = 210 EAP-Type-Identity = "j_doe" Message-Authenticator = 0x00 NAS-Port = 0 END_OF_EAP
Radiusd, running in debug mode shows the following (config-file parsing output skipped; it is not showing any errors at all, so although the configuration I show above may not be producing the intended result, it at least seems syntactically correct):
Listening on authentication address * port 1815 Listening on accounting address * port 1816 Listening on proxy address * port 1817 Ready to process requests. User-Name = "j_doe" NAS-IP-Address = 192.168.198.20 NAS-Port-Type = Wireless-802.11 Message-Authenticator = 0x8499bae7c162d5f0ef2e587fdb9086a0 NAS-Port = 0 EAP-Message = 0x02d200080173796c +- entering group authorize ++[preprocess] returns ok ++[chap] returns noop ++[mschap] returns noop rlm_realm: No '@' in User-Name = "j_doe", looking up realm NULL rlm_realm: No such realm "NULL" ++[suffix] returns noop rlm_eap: EAP packet type response id 210 length 8 rlm_eap: No EAP Start, assuming it's an on-going EAP conversation ++[eap] returns updated ++[unix] returns notfound ++[files] returns noop expand: %{NAS-IP-Address} -> 192.168.198.20 ++- entering switch %{NAS-IP-Address} +++- entering case 192.168.198.20 expand: %{Stripped-User-Name} -> expand: %{User-Name} -> j_doe expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})**LDAP QUERY1 FILTER TRIMMED**) -> (&(cn=j_doe)**LDAP QUERY1 FILTER TRIMMED**) ++++[control] returns noop +++- case 192.168.198.20 returns noop ++- switch %{NAS-IP-Address} returns noop ++? if ("%{CU-LDAP-Filter}" != "") expand: %{CU-LDAP-Filter} -> ? Evaluating ("%{CU-LDAP-Filter}" != "") -> FALSE ++? if ("%{CU-LDAP-Filter}" != "") -> FALSE ++[expiration] returns noop ++[logintime] returns noop rlm_pap: WARNING! No "known good" password found for the user. Authentication may fail because of this. ++[pap] returns noop rad_check_password: Found Auth-Type EAP auth: type "EAP" +- entering group authenticate rlm_eap: EAP Identity rlm_eap: processing type tls rlm_eap_tls: Initiate rlm_eap_tls: Start returned 1 rlm_eap: RT Modif EAP-Type = 21 EAP-LENGTH = 1 ++[eap] returns handled EAP-Message = 0x01d300061520 Message-Authenticator = 0x00000000000000000000000000000000 State = 0x1c870d031c541859b55d17dd8af5914a Finished request 0. Going to the next request Waking up in 4.9 seconds. Cleaning up request 0 ID 232 with timestamp +4 Ready to process requests.
Note that of the above, I believe the following is relevant to my question:
expand: %{NAS-IP-Address} -> 192.168.198.20 ++- entering switch %{NAS-IP-Address} +++- entering case 192.168.198.20 expand: %{Stripped-User-Name} -> expand: %{User-Name} -> j_doe expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})**LDAP QUERY1 FILTER TRIMMED**) -> (&(cn=j_doe)**LDAP QUERY1 FILTER TRIMMED**) ++++[control] returns noop +++- case 192.168.198.20 returns noop ++- switch %{NAS-IP-Address} returns noop ++? if ("%{CU-LDAP-Filter}" != "") expand: %{CU-LDAP-Filter} -> ? Evaluating ("%{CU-LDAP-Filter}" != "") -> FALSE ++? if ("%{CU-LDAP-Filter}" != "") -> FALSE
This corresponds to the following from the "authorize" section in my sites-enabled/default file:
switch "%{NAS-IP-Address}" { case 192.168.198.20 { # test update control { CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY TRIMMED FOR BREVITY***))" } } }
We see that the line where I intend to assign a value to CU-LDAP-Filter is indeed encountered and the variables referred to in that line are expanded correctly, but it seems as though the assignment to CU-LDAP-Filter isn't done: if ("%{CU-LDAP-Filter}" != "") is evaluated as "FALSE".
I suspect that my "update" statement is likely incorrect, since the only mention of it in the debug output is:
++++[control] returns noop
Can anyone help me with this? I've read as much of the relevant documentation as I'm aware exists, especially "man unlang" without which I certainly wouldn't have gotten even this far, but I'd be very grateful if someone could point me to further documentation that would help with what I'm trying to do ...
Thanks ...
-- ---------------------------------------------------------------------- Sylvain Robitaille syl@alcor.concordia.ca
Systems and Network analyst Concordia University Instructional & Information Technology Montreal, Quebec, Canada ---------------------------------------------------------------------- - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Mon, 9 Jun 2008, Ivan Kalik wrote:
man unlang - attribute lists.
*** The "<list>:" prefix is optional, and if omitted, is assumed to refer to the "request" list. ***
Ah yes ... That helps a lot. Thank you. However, having fixed references to %{CU-LDAP-Filter} so they now refer to %{control:CU-LDAP-Filter} (since I've assigned a value to that attribute in an "update control" statement), I see now that it does indeed refer to the value I've set, but by the time that's handed to rlm_ldap, punctuation characters have been replaced with hexadecimal (escape) representations: ... +++- entering case 192.168.198.20 expand: %{Stripped-User-Name} -> expand: %{User-Name} -> j_doe expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(|(memberOf=cn=role_active_emp,ou=portal_role,ou=Groups,dc=concordia,dc=ca)(memberOf=cn=role_faculty,ou=portal_role,ou=Groups,dc=concordia,dc=ca))) -> (&(cn=j_doe)(|(memberOf=cn=role_active_emp,ou=portal_role,ou=Groups,dc=concordia,dc=ca)(memberOf=cn=role_faculty,ou=portal_role,ou=Groups,dc=concordia,dc=ca))) ++++[control] returns noop +++- case 192.168.198.20 returns noop ++- switch %{NAS-IP-Address} returns noop ++? if ("%{control:CU-LDAP-Filter}" != "") expand: %{control:CU-LDAP-Filter} -> (&(cn=j_doe)(|(memberOf=cn=role_active_emp,ou=portal_role,ou=Groups,dc=concordia,dc=ca)(memberOf=cn=role_faculty,ou=portal_role,ou=Groups,dc=concordia,dc=ca))) ? Evaluating ("%{control:CU-LDAP-Filter}" != "") -> TRUE ++? if ("%{control:CU-LDAP-Filter}" != "") -> TRUE ++- entering if ("%{control:CU-LDAP-Filter}" != "") +++- entering redundant-load-balance group redundant-load-balance rlm_ldap: - authorize rlm_ldap: performing user authorization for j_doe expand: %{control:CU-LDAP-Filter} -> \28&\28cn\3dj_doe\29\28|\28memberOf\3dcn\3drole_active_emp\2cou\3dportal_role\2cou\3dGroups\2cdc\3dconcordia\2cdc\3dca\29\28memberOf\3dcn\3drole_faculty\2cou\3dportal_role\2cou\3dGroups\2cdc\3dconcordia\2cdc\3dca\29\29\29 expand: ou=people,dc=concordia,dc=ca -> ou=people,dc=concordia,dc=ca rlm_ldap: ldap_get_conn: Checking Id: 0 rlm_ldap: ldap_get_conn: Got Id: 0 rlm_ldap: attempting LDAP reconnection rlm_ldap: (re)connect to host1:389, authentication 0 rlm_ldap: bind as cn=rad_admin,ou=AdminRoles,dc=concordia,dc=ca/**SANITIZED** to host1:389 rlm_ldap: waiting for bind result ... rlm_ldap: Bind was successful rlm_ldap: performing search in ou=people,dc=concordia,dc=ca, with filter \28&\28cn\3dj_doe\29\28|\28memberOf\3dcn\3drole_active_emp\2cou\3dportal_role\2cou\3dGroups\2cdc\3dconcordia\2cdc\3dca\29\28memberOf\3dcn\3drole_faculty\2cou\3dportal_role\2cou\3dGroups\2cdc\3dconcordia\2cdc\3dca\29\29\29 rlm_ldap: ldap_search() failed: Bad search filter: \28&\28cn\3dj_doe\29\28|\28memberOf\3dcn\3drole_active_emp\2cou\3dportal_role\2cou\3dGroups\2cdc\3dconcordia\2cdc\3dca\29\28memberOf\3dcn\3drole_faculty\2cou\3dportal_role\2cou\3dGroups\2cdc\3dconcordia\2cdc\3dca\29\29\29 rlm_ldap: search failed rlm_ldap: ldap_release_conn: Release Id: 0 ++++[ldap_host1] returns fail ... Notice the "expand: %{control:CU-LDAP-Filter}" line once it's in rlm_ldap. I suspect that this is happening in the update block, but I can't be sure of that (or how to avoid it). I've tried to read all documentation that refers to "update", but haven't yet found any enlightenment. My update block corresponding to the above is (in sites-enabled/default): switch "%{NAS-IP-Address}" { case 192.168.198.20 { # test update control { CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(|(memberOf=cn=role_active_emp,ou=portal_role,ou=Groups,dc=concordia,dc=ca)(memberOf=cn=role_faculty,ou=portal_role,ou=Groups,dc=concordia,dc=ca)))" } } ... } The CU-LDAP-Filter variable is then referenced in the instance(s) of the ldap module configuration: ldap ldap_host1 { ... filter = %{control:CU-LDAP-Filter} ... } Hrmmm ... I see from further reading (man unlang again!) that there is a 253 character limit on the assignment of string values. The above sample is below that limit but the filter values I'm intending to ultimately use will be well beyond that, so this seems like it perhaps isn't the best way to get what I'm after. I'll see if there's some way I could simplify the variable portion of my LDAP search filter, but I'm bothered by the escaping of punctuation characters. Is there a way to "un-escape" those when the variable is referred to later? -- ---------------------------------------------------------------------- Sylvain Robitaille syl@alcor.concordia.ca Systems and Network analyst Concordia University Instructional & Information Technology Montreal, Quebec, Canada ----------------------------------------------------------------------
participants (7)
-
Alan DeKok -
Frank Sweetser -
Ivan Kalik -
Matt Causey -
SecureW2 (List) -
Stefan A. -
Sylvain Robitaille