Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP

Intro
You guessed correctly. This is yet another article on how to setup FreeRADIUS to do 802.1x authentication. Why am I doing another? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up another page here. This was also expedited by user in the #FreeRADIUS channel looking to do the same, but as I as posting configs, it wasn't helping. So, without further ado, I give you my guide on setting up FreeRADIUS pulling it's information from an LDAP backend.

What does this page assume?

 * You have a working OpenLDAP setup.
 * There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
 * Passwords are stored in plain text
 * You have configured your end devices (or will once FreeRADIUS is setup).
 * In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
 * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from (http://www.cacert.org CACert). I do recommend them, especially if you can get assured.

My testing environment

 * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
 * While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
 * FreeRADIUS was emerged with the following USE line:
 * USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
 * You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
 * I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me.
 * SSL Cert from CACert (needs to be known who the CA is when configuring it).

The Files

 * All files are referenced from /etc/raddb/

clients.conf

 * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32.

eap.conf

 * Under EAP {}:
 * default_eap_type = peap
 * Under TLS {}:
 * This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
 * pem_file_type = yes -- This is an addition
 * certdir = /etc/ssl/ _wildcard -- This is where I store the wildcard cert mentioned above
 * cadir = /etc/ssl/certs -- since CACert is included in the system CAs
 * #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
 * private_key_file = ${certdir}/ _wildcard.key
 * certificate_file = ${certdir}/ _wildcard.crt
 * CA_file = ${cadir}/cacert.org.pem
 * #CA_path = ${cadir} -- Commented out, maybe this is fine?
 * Under peap {}:
 * use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this

ldap.attrmap

 * Added: checkItem      Cleartext-Password                   userPassword
 * I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.

modules/ldap

 * Under ldap {}:
 * server = "server.domain.com" -- set to your LDAP Server
 * identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
 * password = "MyradiusUserPassword"
 * basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
 * #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
 * Under tls {}:
 * start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
 * cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
 * require_cert  = "demand" -- Uncomment
 * access_attr_used_for_allow = yes -- Uncomment
 * set_auth_type = no -- Uncommented and changed

modules/mschap

 * Under mschap {}:
 * authtype = MS-CHAP -- Addition
 * use_mppe = yes -- Uncommented and changed
 * require_encryption = yes -- Uncommented
 * require_strong = yes -- Uncommented
 * with_ntdomain_hack = yes -- Uncommented and changed


 * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)

sites-enabled/default

 * Under authorize {}:
 * #chap -- Commented
 * #digest -- Commented
 * #suffix -- Commented
 * ntdomain -- Uncommented
 * ldap -- Uncommented
 * #pap -- Commented
 * Under authenticate {}:
 * #Auth-Type CHAP {} -- Section commented
 * #digest -- Commented
 * #unix -- Commented

sites-enabled/inner-tunnel

 * Under server inner-tunnel {}:
 * #listen {} -- Commented listen block
 * Under authorize {}:
 * unix -- Uncommented - Old?
 * #suffix -- Commented
 * ntdomain -- Uncommented
 * ldap -- Uncommented