yet ANOTHER EAP-TTLS/PAP with OpenLDAP problem ...

Sylvain Robitaille syl at alcor.concordia.ca
Fri Mar 28 19:59:18 CET 2008


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



More information about the Freeradius-Users mailing list