From: Alan T. DeKok Date: Tue, 27 Aug 2019 13:26:30 +0000 (-0400) Subject: more cleanups and split authentication into its own page X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26d91fbb4832e2411528a82d18d431c03984ea8a;p=thirdparty%2Ffreeradius-server.git more cleanups and split authentication into its own page --- diff --git a/doc/antora/modules/howto/nav.adoc b/doc/antora/modules/howto/nav.adoc index 44dab169856..0e68c2cc313 100644 --- a/doc/antora/modules/howto/nav.adoc +++ b/doc/antora/modules/howto/nav.adoc @@ -5,6 +5,9 @@ *** xref:modules/expiration.adoc[Expiration] *** xref:modules/krb5.adoc[Krb5] *** xref:modules/ldap.adoc[LDAP] +**** xref:modules/ldap_docker.adoc[Docker] +**** xref:modules/ldap_search.adoc[Testing with ldapsearch] +**** xref:modules/ldap_authentication.adoc[Authenticating Users with LDAP] *** xref:modules/mschap.adoc[MS-CHAP] *** xref:modules/pam.adoc[PAM] *** xref:modules/passwd.adoc[Passwd] diff --git a/doc/antora/modules/howto/pages/modules/ldap.adoc b/doc/antora/modules/howto/pages/modules/ldap.adoc index 700ba0e639e..38f5e2fcf31 100644 --- a/doc/antora/modules/howto/pages/modules/ldap.adoc +++ b/doc/antora/modules/howto/pages/modules/ldap.adoc @@ -39,70 +39,55 @@ following recommendations for LDAP "best practices" security. * Create a dedicated account for use by FreeRADIUS -* Ensure that this account is a not an administrator +* Ensure that this account does not have administrator access * Ensure that this account is read-only, and has no write permissions -* Start by using 'simple authentication' (instead of - https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer[SASL] - SASL should be attempted only after 'simple authentication' has been - verified to wrork. +* Start by using 'simple authentication' instead of + https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer[SASL]. + The SASL protocol should be attempted only after 'simple + authentication' has been verified to work. * Use TLS for connecting between FreeRADIUS and the LDAP server. See - the `tls` sub-section of the default `ldap` module. + the `tls` sub-section of the default `ldap` module for instructions * When storing RADIUS user profiles (quotas, `Simultaneous-Use` flags, -access time restrictions, etc) in LDAP, the LDAP schema -`doc/schemas/ldap/openldap/freeradius.schema` must be imported first -into the LDAP server. - -=== Authentication - -There are several authentication flows you can use depending on your environment: - - * user attempts to authenticate sending a plaintext password (ie. PAP or EAP-TTLS/PAP) - ** FreeRADIUS reads and uses the LDAP `userPassword` (or `ntPassword`) attributes to perform authentication against; `userPassword` may be hashed (recommended at https://openldap.org/doc/admin24/security.html#Password%20Storage[least using SSHA]) - ** you can attempt to LDAP bind as that user; this is possibly slower than the `userPassword` method - * user attempts to authenticate sending a hashed password (ie. MSCHAPv2 or EAP-{PEAP,TTLS}/MSCHAPv2) - ** FreeRADIUS reads and uses the LDAP `userPassword` attribute which *must* contain a plaintext password - ** if MSCHAPv2 is being used, you need to store and make available an LDAP `ntPassword` attribute in the user object - -These are technical limitations not of FreeRADIUS but in the components required to be able to authenticate any user. - -Picking up from where we left off with the `ldapsearch` test above, if `userPassword` is returned: - - * if the value is not prepended with `{...}` - ** your LDAP server stores plaintext passwords - ** provides the greatest flexibility to use MSCHAPv2 and other hashing authentication mechanisms in your RADIUS packets - * if the value is prepended with `{...}` (for example `{SSHA}`) - ** you *must* use PAP (or EAP-TTLS/PAP) in your RADIUS packets to authenticate your users - -*N.B.* LDAP attribute names (such as `userPassword`) may be appended -with `::` (two colons rather than one) to indicate a binary value and -the value will be the https://en.wikipedia.org/wiki/Base64[base64] -representation of the actual value, which you can decode using -`printf "%s" "VALUE" | base64 -d` to inspect - -If `userPassword` is not returned then permissions for the credentials -used need to be adjusted so that it is accessible. If this is not -feasible and/or possible you *must* use PAP (or EAP-TTLS/PAP) in your -RADIUS packets so that you can use an LDAP bind to authenticate your -users. - -You may notice that by using PAP (or EAP-TTLS/PAP) in your RADIUS -requests will work will all LDAP environments regardless of how -passwords have been stored. - -You will need to balance the implications of sending RADIUS packets -containing plaintext passwords (though EAP-TTLS/PAP makes the risk -similar to HTTPS) over the wire with, or in addition to, storing -plaintext passwords in LDAP. - -Ultimately the decision is yours though it may have already been -decided by your LDAP administrator. If the LDAP `userPassword` -attribute is unavailable or does not contain a plaintext password you -have no option but to use PAP (or EAP-TTLS/PAP) in your RADIUS -requests. + access time restrictions, etc) in LDAP, the LDAP schema + `doc/schemas/ldap/openldap/freeradius.schema` must first be imported + into the LDAP server. + +== Authentication + +The LDAP module can be used by FreeRADIUS to read passwords order to +xref:modules/ldap_authentication.adoc[authenticate] users. Please be +aware the FreeRADIUS is an _authentication server_, and LDAP is a +_database_. This separation of roles means that FreeRADIUS supports +multiple kinds of authentication protocols such as `PAP`, `CHAP`, +`MS-CHAP`, etc. An LDAP database supports only one authentication +method: "bind as user". This authentication method is compatible only +with PAP. + +Our recommendation is to use LDAP as a database. FreeRADIUS should +read the "known good" password from LDAP, and then use that +information to authenticate the user. It is almost always wrong to +use the LDAP "bind as user" method for authenticating users. + +The only caveat to the above recommendation is Active Directory. For +"security" reasons, Active Directory will not return the "known good" +password to FreeRADIUS over a standard LDAP query. Therefore when +Active Directory is used, the choices are: + +PAP:: +Use "bind as user" + +MS-CHAP:: +Use xref:raddb:mods-available/ntlm_auth.adoc[`ntlm`] or xref:raddb:mods-available/winbind.adoc[`winbind`]. + +Due to the limitations of Active Directory, There are unfortunately no +other possible choices. + +Please see the xref:modules/ldap_authentication.adoc[LDAP +authentication] page for more information on authenticating users with LDAP. === Authorization diff --git a/doc/antora/modules/howto/pages/modules/ldap_authentication.adoc b/doc/antora/modules/howto/pages/modules/ldap_authentication.adoc new file mode 100644 index 00000000000..94cfaeab611 --- /dev/null +++ b/doc/antora/modules/howto/pages/modules/ldap_authentication.adoc @@ -0,0 +1,104 @@ += Authenticating Users with LDAP + +The LDAP module supports a few different kinds of authentication +flows. + +PAP:: +The user supplies a `User-Password` (plaintext or EAP-TTLS/PAP) ++ +FreeRADIUS reads the "known good" password from LDAP, and compares +that to what the user entered. + +Bind as user:: +The user supplies a `User-Password` (plaintext or EAP-TTLS/PAP) ++ +FreeRADIUS uses that password to "bind as the user" to LDAP, using the +supplied `User-Name` and `User-Password. If the bind is successfull, +the user is authenticated. Otherwise, authentication fails. + +CHAP:: +The user supplies a `CHAP` password attribute/ ++ +FreeRADIUS reads the "known good" password from LDAP in cleartext, and +compares that to what the user entered. + +MS-CHAP:: +The user supplies a `MS-CHAP` password attribute. ++ +FreeRADIUS reads the "known good" password from LDAP in cleartext, or +as an NT hash, and compares that to what the user entered. + +== Caveats + +There are some major caveats with the above authentication flows. The +first is that we *strongly recommend* against using "bind as user". +This process is slow, and causes unnecessary churn in the connections +used to contact the LDAP server. Further, the "bind as user" process +works _only_ when a `User-Password attribute exists in the request. +If any other authentication type is used in the request, then the +"bind as user" _will not work_. There is no amount of "fixing" things +or configuration changes which will make it work. + +The second caveat is that the `CHAP` authentication type works _only_ +when a "clear text" password is stored in the LDAP database. The +`CHAP` calclulations are designed around having access to the "clear +text" password. It is impossible to use any "encrypted" or "hashed" +passwords with `CHAP`. + +The third caveat is that the `MS-CHAP` authentication type works +_only_ when a "clear text" password or "NT hashed" passwords which are +stored in the LDAP database. The `MS-CHAP` calclulations are designed +around having access to "known good" passwords in those formats. It +is impossible to use any other kind of "encrypted" or "hashed" +passwords with `MS-CHAP`. + +The final caveat is that when the LDAP database contains "encrypted" +or "hashed" passwords, the _only_ authentication type which is +compatible with those passwords is PAP. i.e. when the `User-Password` +is supplied to FreeRADIUS. + +For recommendations on password storage in LDAP, please see the LDAP +https://openldap.org/doc/admin24/security.html#Password%20Storage[password +storage] page. Please note that the recommendations there are made +for LDAP security, and pay no attention to the caveats described +above. When both RADIUS and LDAP are used together, then the +requirements of _both_ systems must be met in order for them to work +together. In many cases, a naive approach to LDAP security will +prevent RADIUS from working. In those cases, the only solutions are +to give up on using RADIUS, or to relax the security requirements on +LDAP. + +Picking up from where we left off with the `ldapsearch` test above, if `userPassword` is returned: + + * if the value is not prepended with `{...}` + ** your LDAP server stores plaintext passwords + ** provides the greatest flexibility to use MSCHAPv2 and other hashing authentication mechanisms in your RADIUS packets + * if the value is prepended with `{...}` (for example `{SSHA}`) + ** you *must* use PAP (or EAP-TTLS/PAP) in your RADIUS packets to authenticate your users + +*N.B.* LDAP attribute names (such as `userPassword`) may be appended +with `::` (two colons rather than one) to indicate a binary value and +the value will be the https://en.wikipedia.org/wiki/Base64[base64] +representation of the actual value, which you can decode using +`printf "%s" "VALUE" | base64 -d` to inspect + +If `userPassword` is not returned then permissions for the credentials +used need to be adjusted so that it is accessible. If this is not +feasible and/or possible you *must* use PAP (or EAP-TTLS/PAP) in your +RADIUS packets so that you can use an LDAP bind to authenticate your +users. + +You may notice that by using PAP (or EAP-TTLS/PAP) in your RADIUS +requests will work will all LDAP environments regardless of how +passwords have been stored. + +You will need to balance the implications of sending RADIUS packets +containing plaintext passwords (though EAP-TTLS/PAP makes the risk +similar to HTTPS) over the wire with, or in addition to, storing +plaintext passwords in LDAP. + +Ultimately the decision is yours though it may have already been +decided by your LDAP administrator. If the LDAP `userPassword` +attribute is unavailable or does not contain a plaintext password you +have no option but to use PAP (or EAP-TTLS/PAP) in your RADIUS +requests.