I've been working on this for a while, and have yet to find a way to configure this correctly, despite lots of reading through the mailing list archives, documentation included with FreeRADIUS, and third-party documentation. In fact, I've been trying to get this working for years with older versions of FreeRADIUS, and have succeeded only with FreeRADIUS<=1.1.6, using configurations that readers of this list are repeatedly told not to use (such as setting Auth-Type in the users file). [ASIDE] With the older versions of FreeRADIUS we're having performance problems with the authentication. Research on this list has uncovered no end of responses that such problems are normally caused by the back-end, not radiusd, but our backend (OpenLDAP) responds to an identical query as that sent by radius in approximately 6ms (7ms when it's slow), yet radiusd is still not responding after 30 seconds. We have thousands of users trying to use our service simultaneously, through hundreds of wireless access points. I would be willing to accept that the configuration I'm using (setting Auth-Type in users) causes radiusd to perform poorly, but that this isn't radiusd's "fault", since it's an un-advised configuration, but I just don't see that the problem we're seeing there is because the backend is slow to respond. Regardless of the cause here, I decided to upgrade to FreeRADIUS-2.0.3, hoping that a) I could get that configured according in a recommended way to accomplish what I want, and b) that this would result in better performance than we're seeing now. Getting TTLS/PAP/OpenLDAP working correctly with FreeRADIUS-2.0.3 is the problem I'd like to solve from this message. [/ASIDE] Converting from a working, though technically incorrect configuration to a "correct" configuration hasn't been particularly easy, but I believe I've accomplished that, with very little change to the default configurations (unified context diffs of my configurations against the defaults are appended below my signature for completeness). What I have seems to pass tests that have been recommended as "get these working before moving on", but I can't seem to figure out how to get from here to being able to unleash my access points on this and have successful authentications. I see (from -X output) that the TTLS tunnel is successfully built (that seems to be several steps), a query against LDAP for authorization (and to retrieve the user's encypted password) succeeds, but when the request finally gets to the authentication, radiusd reports: ... rlm_ldap: performing user authorization for j_doe expand: %{Stripped-User-Name} -> expand: %{User-Name} -> j_doe expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(search filter trimmed for brevity)) -> (&(cn=j_doe)(search filter trimmed for brevity)) 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: performing search in ou=people,dc=concordia,dc=ca, with filter (&(cn=j_doe)(search filter trimmed for brevity)) rlm_ldap: Added User-Password = {SSHA}*SANITIZED*e2E52K+sO/SC+wvE*SANITIZED*== in check items rlm_ldap: looking for check items in directory... rlm_ldap: looking for reply items in directory... rlm_ldap: user j_doe authorized to use remote access rlm_ldap: ldap_release_conn: Release Id: 0 ++[ldap] returns ok ++[expiration] returns noop ++[logintime] returns noop ++[pap] returns noop WARNING: You set Proxy-To-Realm = LOCAL, but it is a LOCAL realm! Cancelling invalid proxy request. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!! Replacing User-Password in config items with Cleartext-Password. !!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!! Please update your configuration so that the "known good" !!! !!! clear text password is in Cleartext-Password, and not in User-Password. !!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! auth: type Local auth: user supplied User-Password does NOT match local User-Password auth: Failed to validate the user. Login incorrect: [j_doe/*SANITIZED*] (from client wireless-mcconnell port 0) TTLS: Got tunneled Access-Reject rlm_eap: Handler failed in EAP/ttls rlm_eap: RT Modif EAP-Type = 0 EAP-LENGTH = 0 rlm_eap: Failed in EAP select ++[eap] returns invalid auth: Failed to validate the user. Login incorrect: [j_doe/<via Auth-Type = EAP>] (from client wireless-mcconnell port 5800234 cli 0019.d290.6e22) Found Post-Auth-Type Reject +- entering group REJECT expand: %{User-Name} -> j_doe attr_filter: Matched entry DEFAULT at line 11 ++[attr_filter.access_reject] returns updated Delaying reject of request 8 for 1 seconds Going to the next request Waking up in 0.9 seconds. ... Now, of the above, beside the fact that the authentication failed when I believe it should have succeeded, I'm concerned about two items. First: WARNING: You set Proxy-To-Realm = LOCAL, but it is a LOCAL realm! Cancelling invalid proxy request. Is this caused by the following in raddb/sites-*/inner-tunnel? # If you want the inner tunnel request to be proxied, delete # the next few lines. # update control { Proxy-To-Realm := LOCAL } Do I worry about it, or just accept that radiusd cancels the request? Second: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!! Replacing User-Password in config items with Cleartext-Password. !!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!! Please update your configuration so that the "known good" !!! !!! clear text password is in Cleartext-Password, and not in User-Password. !!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! The text "User-Password" appears in exactly the following places in my raddb directory (not counting comment lines): ./attrs.pre-proxy: User-Password =* ANY, ./sql/mysql/dialup.conf: '%{%{User-Password}:-%{Chap-Password}}', \ ./sql/postgresql/dialup.conf: VALUES ('%{User-Name}', '%{%{User-Password}:-Chap-Password}', '%{reply:Packet-Type}', NOW())" These files are as shipped with FreeRADIUS-2.0.3. I'm trying to get this done with minimal change to the default configuration, since it appears that's what is expected. Which of the above needs to change? (attrs.pre-proxy?) The above issues of course still don't address what I see as the real problem: Login incorrect: [j_doe/*SANITIZED*] ... Somebody please tell me where I should be looking to make this work correctly. I can run the new server on an alternate port for the preliminary tests, such as using radtest against a user in LDAP (success), and radeapclient against a user in the users file (success using md5 as the default_eap_type, but not ttls), but I can't seem to get a successful test (using ttls; the passwords in LDAP aren't plain-text so md5 won't work for testing that) with radeapclient against a user in LDAP, or successful authentication when running in place of our current in-production RADIUS server. radtest against user in LDAP: radtest j_doe '*SANITIZED*' localhost:1814 1 testing123 User-Name = "syl" User-Password = "*SANITIZED*" NAS-IP-Address = 192.168.7.47 NAS-Port = 1 Older versions of radtest would report receiving "Access-Accept", while this one silently exists. However, radiusd in this case says: Ready to process requests. User-Name = "j_doe" User-Password = "*SANITIZED*" NAS-IP-Address = 192.168.7.47 NAS-Port = 1 +- 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: No EAP-Message, not doing EAP ++[eap] returns noop ++[unix] returns notfound ++[files] returns noop rlm_ldap: - authorize rlm_ldap: performing user authorization for j_doe expand: %{Stripped-User-Name} -> expand: %{User-Name} -> j_doe expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(search filter trimmed for brevity)) -> (&(cn=j_doe)(search filter trimmed for brevity)) 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 localhost boris:389, authentication 0 rlm_ldap: bind as cn=iits_neg,ou=AdminRoles,dc=concordia,dc=ca/*SANITIZED* to localhost boris: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 (&(cn=j_doe)(search filter trimmed for brevity)) rlm_ldap: Added User-Password = {SSHA}*SANITIZED*QDmffXBQkU42Wt9x*SANITIZED*== in check items rlm_ldap: looking for check items in directory... rlm_ldap: looking for reply items in directory... rlm_ldap: user j_doe authorized to use remote access rlm_ldap: ldap_release_conn: Release Id: 0 ++[ldap] returns ok ++[expiration] returns noop ++[logintime] returns noop ++[pap] returns updated rad_check_password: Found Auth-Type auth: type "PAP" +- entering group PAP rlm_pap: login attempt with password "*SANITIZED*" rlm_pap: Using SSHA encryption. rlm_pap: Normalizing SSHA1-Password from base64 encoding rlm_pap: User authenticated successfully ++[pap] returns ok Login OK: [j_doe/*SANITIZED*] (from client localhost port 1) Finished request 0. Going to the next request Ok, good ... radeapclient against a user listed in the users file still performs the ldap query for authorization (I actually don't want that; I'd like the users file to over-ride the LDAP listing, if an entry is matched in the users file), but then seems to stop short of setting up the TTLS tunnel and performing any authentication: radeapclient says: +++> About to send encoded packet: 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 <+++ EAP decoded packet: Service-Type = Dialout-Framed-User EAP-Message = 0x01d300061520 Message-Authenticator = 0x796172e3b17c8b07c0409d2a811f0996 State = 0x99802cfd9953395efbafe88eb97f8c71 EAP-Id = 211 EAP-Code = Request EAP-Type-LEAP = 0x20 ^^^^ ???? I don't want LEAP! Where did it get this from? Radiusd says: rlm_ldap: performing search in ou=people,dc=concordia,dc=ca, with filter (&(cn=syl)(search filter trimmed for brevity)) rlm_ldap: Added User-Password = {SSHA}*SANITIZED*QDmffXBQkU42Wt9x*SANITIZED*== in check items rlm_ldap: looking for check items in directory... rlm_ldap: looking for reply items in directory... rlm_ldap: user syl authorized to use remote access rlm_ldap: ldap_release_conn: Release Id: 0 ++[ldap] returns ok ++[expiration] returns noop ++[logintime] returns noop rlm_pap: Found existing Auth-Type, not changing it. ++[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 Service-Type = Dialout-Framed-User EAP-Message = 0x01d300061520 Message-Authenticator = 0x00000000000000000000000000000000 State = 0x99802cfd9953395efbafe88eb97f8c71 Finished request 2. Going to the next request Waking up in 4.9 seconds. Cleaning up request 2 ID 243 with timestamp +465 Ready to process requests. I'm certainly prepared to be told that I'm doing it wrong, but in that case, I'd sure like to know WHAT I'm doing wrong, because I believe I've followed documented instructions completely, and haven't strayed any further than necessary from the default configuration as shipped with FreeRADIUS-2.0.3. Can someone please tell me where I should be looking? As promised, the unified context diff of my configuration against the default is appended below my signature. -- ---------------------------------------------------------------------- Sylvain Robitaille syl@alcor.concordia.ca Systems and Network analyst Concordia University Instructional & Information Technology Montreal, Quebec, Canada ---------------------------------------------------------------------- diff -ur raddb/clients.conf ../root-freeradius-2.0.3/etc/raddb/clients.conf --- raddb/clients.conf 2008-02-13 04:41:14.000000000 -0500 +++ ../root-freeradius-2.0.3/etc/raddb/clients.conf 2008-03-28 11:11:49.000000000 -0500 @@ -227,3 +227,96 @@ # secret = testing123 # } #} + +client hostname.concordia.ca { + secret = *SANITIZED* + shortname = LOCAL/LOCALTEST +} ### more entries in the same format, for other RADIUS clients ### diff -ur raddb/eap.conf ../root-freeradius-2.0.3/etc/raddb/eap.conf --- raddb/eap.conf 2008-02-26 04:32:29.000000000 -0500 +++ ../root-freeradius-2.0.3/etc/raddb/eap.conf 2008-03-28 12:15:53.000000000 -0500 @@ -27,7 +27,7 @@ # then that EAP type takes precedence over the # default type configured here. # - default_eap_type = md5 + default_eap_type = ttls # A list is maintained to correlate EAP-Response # packets with EAP-Request packets. After a @@ -145,7 +145,7 @@ cadir = ${confdir}/certs private_key_password = whatever - private_key_file = ${certdir}/server.pem + private_key_file = /public/apache/ssl/netnames-1_private.pem # If Private key & Certificate are located in # the same file, then private_key_file & @@ -157,7 +157,7 @@ # only the server certificate, but ALSO all # of the CA certificates used to sign the # server certificate. - certificate_file = ${certdir}/server.pem + certificate_file = /public/apache/ssl/netnames-1.pem # Trusted Root CA list # @@ -174,7 +174,7 @@ # not use client certificates, and you do not want # to permit EAP-TLS authentication, then delete # this configuration item. - CA_file = ${cadir}/ca.pem + CA_file = /public/apache/ssl/cacert.pem # # For DH cipher suites to work, you have to --- raddb/radiusd.conf 2008-03-27 12:42:15.000000000 -0500 +++ ../root-freeradius-2.0.3/etc/raddb/radiusd.conf 2008-03-28 13:27:03.000000000 -0500 @@ -56,13 +56,13 @@ sysconfdir = ${prefix}/etc localstatedir = ${prefix}/var sbindir = /local/pkg/freeradius/root-freeradius-2.0.3/bin -logdir = ${localstatedir}/log/radius +logdir = ${localstatedir}/log raddbdir = ${sysconfdir}/raddb radacctdir = ${logdir}/radacct # Location of config and logfiles. confdir = ${raddbdir} -run_dir = ${localstatedir}/run/radiusd +run_dir = ${localstatedir}/run # Should likely be ${localstatedir}/lib/radiusd db_dir = $(raddbdir) @@ -134,8 +134,8 @@ # that the debugging mode server is running as a user that can read the # shadow info, and the user listed below can not. # -#user = nobody -#group = nobody +user = nul-rad +group = nul-rad # max_request_time: The maximum time (in seconds) to handle a request. # @@ -191,7 +191,7 @@ # # Useful range of values: 256 to infinity # -max_requests = 1024 +max_requests = 262144 # listen: Make the server listen on a particular IP address, and send # replies out from that address. This directive is most useful for @@ -239,7 +239,8 @@ # Allowed values are: # integer port number (1812) # 0 means "use /etc/services for the proper port" - port = 0 + #port = 0 + port = 1814 # Some systems support binding to an interface, in addition # to the IP address. This feature isn't strictly necessary, @@ -274,7 +275,8 @@ listen { ipaddr = * # ipv6addr = :: - port = 0 + #port = 0 + port = 1815 type = acct # interface = eth0 # clients = per_socket_clients @@ -361,7 +363,7 @@ # # allowed values: {no, yes} # - auth = no + auth = yes # Log passwords with the authentication requests. # auth_badpass - logs password if it's rejected @@ -592,7 +594,7 @@ # with the correct value. It will also automatically handle # Base-64 encoded data, hex strings, and binary data. pap { - auto_header = no + auto_header = yes } # CHAP module @@ -737,12 +739,14 @@ # # Note that this needs to match the name in the LDAP # server certificate, if you're using ldaps. - server = "ldap.your.domain" - #identity = "cn=admin,o=My Org,c=UA" - #password = mypass - basedn = "o=My Org,c=UA" - filter = "(uid=%{Stripped-User-Name:-%{User-Name}})" - #base_filter = "(objectclass=radiusprofile)" + server = "localhost another_host" + identity = "cn=iits_neg,ou=AdminRoles,dc=concordia,dc=ca" + password = "*SANITIZED*" + basedn = "ou=people,dc=concordia,dc=ca" + #filter = "(cn=%{%{Stripped-User-Name}:-%{User-Name}})" + filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(search filter trimmed for brevity))" + + base_filter = "(objectclass=ConcordiaPerson)" # How many connections to keep open to the LDAP server. # This saves time over opening a new LDAP socket for @@ -820,7 +825,8 @@ # Novell may require TLS encrypted sessions before returning # the user's password. # - # password_attribute = userPassword + password_attribute = userPassword + password_radius_attribute = "SSHA-Password" # Un-comment the following to disable Novell # eDirectory account policy check and intruder diff -ur raddb/sites-available/default ../root-freeradius-2.0.3/etc/raddb/sites-available/default --- raddb/sites-available/default 2008-01-17 01:42:07.000000000 -0500 +++ ../root-freeradius-2.0.3/etc/raddb/sites-available/default 2008-03-28 10:14:12.000000000 -0500 @@ -132,7 +132,7 @@ # # The ldap module will set Auth-Type to LDAP if it has not # already been set -# ldap + ldap # # Enforce daily limits on time spent logged in. @@ -243,9 +243,9 @@ # Note that this means "check plain-text password against # the ldap database", which means that EAP won't work, # as it does not supply a plain-text password. -# Auth-Type LDAP { -# ldap -# } + Auth-Type LDAP { + ldap + } # # Allow EAP authentication. diff -ur raddb/sites-available/inner-tunnel ../root-freeradius-2.0.3/etc/raddb/sites-available/inner-tunnel --- raddb/sites-available/inner-tunnel 2008-02-26 04:32:29.000000000 -0500 +++ ../root-freeradius-2.0.3/etc/raddb/sites-available/inner-tunnel 2008-03-28 11:05:55.000000000 -0500 @@ -113,7 +113,7 @@ # # The ldap module will set Auth-Type to LDAP if it has not # already been set -# ldap + ldap # # Enforce daily limits on time spent logged in. @@ -201,9 +201,9 @@ # Note that this means "check plain-text password against # the ldap database", which means that EAP won't work, # as it does not supply a plain-text password. -# Auth-Type LDAP { -# ldap -# } + Auth-Type LDAP { + ldap + } # # Allow EAP authentication. diff -ur raddb/sites-enabled/default ../root-freeradius-2.0.3/etc/raddb/sites-enabled/default --- raddb/sites-enabled/default 2008-01-17 01:42:07.000000000 -0500 +++ ../root-freeradius-2.0.3/etc/raddb/sites-enabled/default 2008-03-28 10:14:12.000000000 -0500 @@ -132,7 +132,7 @@ # # The ldap module will set Auth-Type to LDAP if it has not # already been set -# ldap + ldap # # Enforce daily limits on time spent logged in. @@ -243,9 +243,9 @@ # Note that this means "check plain-text password against # the ldap database", which means that EAP won't work, # as it does not supply a plain-text password. -# Auth-Type LDAP { -# ldap -# } + Auth-Type LDAP { + ldap + } # # Allow EAP authentication. diff -ur raddb/users ../root-freeradius-2.0.3/etc/raddb/users --- raddb/users 2007-10-23 09:41:23.000000000 -0400 +++ ../root-freeradius-2.0.3/etc/raddb/users 2008-03-28 12:04:13.000000000 -0500 @@ -201,3 +201,343 @@ # Service-Type = Administrative-User # On no match, the user is denied access. + +# Wireless WDS: +username1 Auth-Type := EAP, Cleartext-Password := "*SANITIZED*" + Service-Type = Outbound-User + +# 2008/03/12 Sylvain Robitaille: for testing: +j_doe Cleartext-Password := "*SANITIZED*" + Service-Type = Outbound-User + #### Lots more in the same format, plus some of this type: + +# 2008/03/19 Sylvain Robitaille: copyright violation +blocked_user Calling-Station-ID == "0019.7e70.cdf9", Auth-Type := Reject + Reply-Message = "This system is blocked from our network ...." + +# Wireless (expect to need to list each access point) +DEFAULT NAS-Port-Type == Wireless-802.11 + Service-Type = Outbound-User +# Autz-Type := wireless +# Autz-Type := wireless, +# Fall-Through = Yes +# +#DEFAULT NAS-Port-Type == Wireless-802.11, EAP-Message !* "Matches if not EAP" +# Auth-Type := wireless + +#DEFAULT EAP-Type == EAP-TTLS, Proxy-To-Realm := LOCAL + +# On no match, the user is denied access.