Refer to http://vuksan.com/linux/dot1x/802-1x-LDAP.html
This HOWTO covers how to set up your OpenLDAP directory to support 802.1x and WPA users. It assumes you have a working LDAP authentication setup ie. you have your e.g. Linux/Windows hosts authenticating against your LDAP database. If that is not so please consult LDAP authentication for Linux/UNIX/Mac OS X.
If you are only looking to authenticate WPA users that are in your OpenLDAP directory you may not need to follow steps in the following section. Following section is only for those people who want to e.g. dynamically assign users to a VLAN using RADIUS FilterID attributes or other RADIUS type of assignments . If you have no need for that please jump directly to OpenLDAP security.
OpenLDAP setup for 802.1x
1. Add the RADIUS schema to your LDAP configuration ie. if you look at the FreeRADIUS distribution you will find following file
RADIUS-LDAPv3.schema.gz
Uncompress it with
gzip -d RADIUS-LDAPv3.schema.gz
Uncompress it with
gzip -d RADIUS-LDAPv3.schema.gz
2. Copy the file to your LDAP schema directory and include it in your slapd.conf ie.
include /etc/ldap/schema/RADIUS-LDAPv3.schema
Make sure you include it on all LDAP servers ie. Master and Slave servers. If you don't your replication may not work if you have schemacheck set to on.
3. I recommend creating a separate LDAP subtree for 802.1x devices ie. unattended machines. This is not required if you want to provide access to all users. If so please go to following step. Otherwise create a subtree called cn=dot1x,dc=cs,dc=school,edu using a following LDIF
dn: cn=dot1x,dc=cs,dc=,dc=edu
objectClass: container
cn: dot1x
structuralObjectClass: container
objectClass: container
cn: dot1x
structuralObjectClass: container
To add this LDIF execute
ldapadd -ZZ -x -h ldap1.school.edu -D 'uid=root,cn=users,dc=cs,dc=school,dc=edu' -W
Then cut and paste the above LDIF.
4. Now you are ready to add 802.1x users. Let's say I have a hostname called myhost that I want to authenticate using 802.1x and password to authenticate is supersecret. You would add LDIF like this
dn: uid=myhost,cn=dot1x,dc=cs,dc=school,dc=edu
objectClass: top
objectClass: radiusprofile
objectClass: inetOrgPerson
cn: myhost
sn: myhost
uid: myhost
description: 802.1x user
radiusFilterId: "Enterasys:version=1:policy=Enterprise User"
userPassword: supersecret
objectClass: top
objectClass: radiusprofile
objectClass: inetOrgPerson
cn: myhost
sn: myhost
uid: myhost
description: 802.1x user
radiusFilterId: "Enterasys:version=1:policy=Enterprise User"
userPassword: supersecret
Please note that userPassword attribute contains an unencrypted password. radiusFilterID is an additional piece of information that can be supplied to the switch. It depends from a switch to switch so check the docs for your switch. For example in this particular case Enterasys switch will assign a policy of "Enterprise User" to machine that authenticates as myhost.
OpenLDAP security
Since userPasswords are shown in clear text and since in general you don't want even password hashes exposed to casual observation you need to limit access to the userPassword attribute. To do so we'll create a separate user who has access to the userPassword attribute.1. Create a user e.g. onex with password oursecret in your LDAP repository
2. Add the necessary access control rules to your slapd.conf or slapd.access.conf. For example I have
access to attrs=userPassword
by dn="uid=onex,cn=users,dc=cs,dc=school,dc=edu" read
by dn="uid=root,cn=users,dc=cs,dc=school,dc=edu" write
by dn="uid=admin,cn=users,dc=cs,dc=school,dc=edu" write
by anonymous auth
by self write
by * none
by dn="uid=onex,cn=users,dc=cs,dc=school,dc=edu" read
by dn="uid=root,cn=users,dc=cs,dc=school,dc=edu" write
by dn="uid=admin,cn=users,dc=cs,dc=school,dc=edu" write
by anonymous auth
by self write
by * none
The above couple lines will allow only root, admin and user themself to read and modify the userPassword attribute for a particular entry. onex user we created will have only read privileges to the attribute.
Note: I tried to even further lock down the access so e.g. onex user could only see cn=dot1x,dc=cs,dc=school,dc=edu subtree however I haven't been successful. I tried adding following above the entry above e.g.
access to dn.sub="cn=dot1x,dc=cs,dc=unm,dc=edu" attrs=userPassword
by dn="uid=onex,cn=users,dc=cs,dc=school,dc=edu" read
by dn="uid=onex,cn=users,dc=cs,dc=school,dc=edu" read
With no success :-(. If you get this working please let me know.
FreeRADIUS setup
Now we need to configure FreeRADIUS to look up users1. In /etc/freeradius/radiusd.conf find the modules {} section. Insert following
ldap ldap_1x {
server = "ldap1.cs.school.edu"
identity = "uid=onex,cn=users,dc=cs,dc=school,dc=edu"
password = "oursecret"
basedn = "dc=cs,dc=school,dc=edu"
base_filter = "(objectclass=radiusprofile)"
start_tls = yes
# This is your Certificate Authority (CA) certificate
tls_cacertfile = /etc/ldap/csca.crt
tls_require_cert = "demand"
# default_profile = "cn=radprofile,ou=dialup,o=My Org,c=UA"
# profile_attribute = "radiusProfileDn"
access_attr = "radiusFilterId"
dictionary_mapping = ${raddbdir}/ldap.attrmap
authtype = ldap
ldap_connections_number = 5
timeout = 4
timelimit = 3
net_timeout = 1
}
server = "ldap1.cs.school.edu"
identity = "uid=onex,cn=users,dc=cs,dc=school,dc=edu"
password = "oursecret"
basedn = "dc=cs,dc=school,dc=edu"
base_filter = "(objectclass=radiusprofile)"
start_tls = yes
# This is your Certificate Authority (CA) certificate
tls_cacertfile = /etc/ldap/csca.crt
tls_require_cert = "demand"
# default_profile = "cn=radprofile,ou=dialup,o=My Org,c=UA"
# profile_attribute = "radiusProfileDn"
access_attr = "radiusFilterId"
dictionary_mapping = ${raddbdir}/ldap.attrmap
authtype = ldap
ldap_connections_number = 5
timeout = 4
timelimit = 3
net_timeout = 1
}
Note: If you don't care about setting up a separate tree for 802.1x users and don't want to add radiusFilterId attribute for all users who need access you can change access_attr to e.g.
access_attr = "uid"
That will allow anyone who has a uid attribute in their LDAP record (all users) to be allowed.
2. Go to
http://tldp.org/HOWTO/html_single/8021X-HOWTO/#confradius
Follow their EAP setup. The main difference is that HOWTO above uses a built-in passwords file instead of LDAP.
3. When you are done we'll just need to add ldap_1x to both authorize and authentication sections ie.
authorize {
preprocess
chap
mschap
suffix
ldap_1x
eap
}
authenticate {
Auth-Type PAP {
pap
}
Auth-Type MS-CHAP {
mschap
}
eap
}
preprocess
chap
mschap
suffix
ldap_1x
eap
}
authenticate {
Auth-Type PAP {
pap
}
Auth-Type MS-CHAP {
mschap
}
eap
}
4. In /etc/freeradius/ldap.attrmap add
checkItem User-Password userPassword
replyItem Tunnel-Type radiusTunnelType
replyItem Tunnel-Medium-Type radiusTunnelMediumType
replyItem Tunnel-Private-Group-Id radiusTunnelPrivateGroupId
replyItem Tunnel-Type radiusTunnelType
replyItem Tunnel-Medium-Type radiusTunnelMediumType
replyItem Tunnel-Private-Group-Id radiusTunnelPrivateGroupId
If you are using Samba and you have NT/LM password hashes you should also change the default mapping for LM-Password and NT-Password to following.
checkItem LM-Password sambaLMPassword
checkItem NT-Password sambaNTPassword
checkItem NT-Password sambaNTPassword
5. Start FreeRADIUS in foreground/debug mode and make sure things work :-)
radiusd -X -f
Different LDAP instances depending on source
Solution is from:http://lists.freeradius.org/archives/freeradius-users/2005/04/frm00783.html
with my own modifications since it didn't work "out-of-the-box"
I'm trying to get ldap instances working on a per client basis. For example, any authentication requests coming from host example1 should be authenticated using the ldap example1 instance, and example2 should be auth'd using the ldap example2 instance.
1) Define multiple ldap instances in the modules section of radiusd.conf, eg
ldap ldap_client1 {
.....
}
ldap ldap_client2 {
.....
}
.....
}
ldap ldap_client2 {
.....
}
2) In the authorize section of radiusd.conf, put e.g.
authorize {
preprocess
chap
mschap
Autz-Type LDAP1 {
ldap_client1
}
Autz-Type LDAP2 {
ldap_client2
}
eap
files
}
preprocess
chap
mschap
Autz-Type LDAP1 {
ldap_client1
}
Autz-Type LDAP2 {
ldap_client2
}
eap
files
}
3) Change the authenticate section e.g.
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
Auth-Type LDAP1 {
ldap_client1
}
Auth-Type LDAP2 {
ldap_client2
}
eap
}
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
Auth-Type LDAP1 {
ldap_client1
}
Auth-Type LDAP2 {
ldap_client2
}
eap
}
3) Then in the users file put ie. default to ldap_client1. Otherwise if client comes from x.x.x.2 authenticate against ldap_client2
DEFAULT Client-IP-Address == "x.x.x.2", Auth-Type := LDAP2, Autz-Type := LDAP2
DEFAULT Auth-Type = "LDAP1"
Fall-Through = Yes
DEFAULT Autz-Type = "LDAP1"
DEFAULT Auth-Type = "LDAP1"
Fall-Through = Yes
DEFAULT Autz-Type = "LDAP1"
4) Please note that if you are doing WPA or 802.1x authentication you should NOT set Auth-Type. Let FreeRADIUS set Auth-Type to EAP. For example if you had an AP doing WPA your configuration would look something like this.
DEFAULT Client-IP-Address == "x.x.x.3", Autz-Type := LDAP2
DEFAULT Auth-Type = "LDAP1"
Fall-Through = Yes
DEFAULT Autz-Type = "LDAP1"
DEFAULT Auth-Type = "LDAP1"
Fall-Through = Yes
DEFAULT Autz-Type = "LDAP1"
EAP-TTLS vs. PEAP
Most clients these days ie. Windows XP and Mac OS X native 802.1x/WPA clients will prefer EAP-PEAP security method. They are fairly similar with the exception that TTLS gives you extra flexibility to specify what kind of authentication to do inside a TLS tunnel ie. PAP, CHAP or MSCHAPv2. Why is that important you ask ? It is important depending what kind of password information you have stored in your LDAP database.- In most cases you will have the MD5 or CRYPT hashes stored in userPassword attribute. If so you will have to use EAP-TTLS with PAP inner tunnel authentication
- If you have NT/LM hashes stored because you e.g. use LDAP as backend to Samba you can use either EAP-TTLS with MSCHAPv2 inner tunnel authentication (this is the default) or EAP-PEAP
- If you have passwords in plain text stored in userPassword you can use whatever authentication method you want ie. EAP-TTLS, EAP-PEAP or EAP-MD5.
- Configure Linux (wpa_supplicant) to use TTLS+PAP for WPA or 802.1x
- Configuring Mac OS X to use TTLS+PAP for WPA or 802.1x
- Configuring Windows (SecureW2) to use TTLS+PAP for WPA or 802.1x
Using PEAP with OpenLDAP
If you do need to use PEAP you will have to add NT/LM hashes to every user record in your LDAP directory. Easiest thing is to follow Samba LDAP set up. For examplehttp://www.ofb.net/~jheiss/samba/ldap.shtml. In short you will have to add the samba schema to your OpenLDAP configuration. Then use smbldap-tools to add necessary samba attributes to a user ie.
smbldap-usermod -a testuser
Once you have that you have to reset users' password with smbldap-passwd since you can't convert CRYPT/MD5 or SHA1 hashes to NT/LM hashes. Also make sure that ldap.attrmap file contains following two lines
checkItem LM-Password sambaLMPassword
checkItem NT-Password sambaNTPassword
checkItem NT-Password sambaNTPassword
Only other gotcha is that you cannot use LDAP bind to authenticate users with PEAP. PEAP will always do MSCHAPv2 authentication in the inner tunnel and RADIUS needs access to NT/LM hashes. Therefore you will need to set up a user that has access to sambaLMPassword and sambaNTPassword attributes. Please check OpenLDAP security at the top of this document ie. you will have to have to modify the permissions entry to read
access to attrs=userPassword,sambaNTPassword,sambaLMPassword
by dn="uid=onex,cn=users,dc=cs,dc=school,dc=edu" read
....
by dn="uid=onex,cn=users,dc=cs,dc=school,dc=edu" read
....
ChilliSpot setup
Above set up will work nicely with ChilliSpot which is a hotspot captive portal. The only difference is that you need to edit the hotspotlogin.cgi if you only have MD5/CRYPT password hashes in the LDAP database. You need to set
# Uncomment the following line if you want to use ordinary user-password
# for radius authentication. Must be used together with $uamsecret.
$userpassword=1;
$uamsecret="testing123";
# for radius authentication. Must be used together with $uamsecret.
$userpassword=1;
$uamsecret="testing123";
In chilli.conf you will need to add the uamsecret that corresponds to the uamsecret above ie.
uamsecret testing123
In this case RADIUS will get password in clear (decoded with shared key) from the Chillispot and attempt LDAP bind. If you have NT/LM password ie. sambaNTpassword and sambaLMpassword attributes you don't have to do above.
Supplicant setup
Xsupplicant
You can get detail instructions on setting up Xsupplicant athttp://tldp.org/HOWTO/html_single/8021X-HOWTO/#xsupplicant
This is the xsupplicant.conf I used. Change items in red to
network_list = default
default_netname = default
first_auth_command = <BEGIN_COMMAND>dhclient %i<END_COMMAND>
logfile = /var/log/xsupplicant.log
allow_interfaces = eth0
default
{
type = wired
allow_types = eap_md5
identity = <BEGIN_ID>myhost<END_ID>
eap-md5 {
username = <BEGIN_UNAME>myhost<END_UNAME>
password = <BEGIN_PASS>supersecret<END_PASS>
}
}
default_netname = default
first_auth_command = <BEGIN_COMMAND>dhclient %i<END_COMMAND>
logfile = /var/log/xsupplicant.log
allow_interfaces = eth0
default
{
type = wired
allow_types = eap_md5
identity = <BEGIN_ID>myhost<END_ID>
eap-md5 {
username = <BEGIN_UNAME>myhost<END_UNAME>
password = <BEGIN_PASS>supersecret<END_PASS>
}
}
WPA Supplicant
You can also use WPA supplicant for both 802.1x wired and Wireless connections. To use wpa_supplicant for wired you have to use version 0.40+ and configure wpa_supplicant as follows
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
ap_scan=0
network={
key_mgmt=IEEE8021X
eap=MD5
identity="XUSERNAME"
password="XPASSWORD"
eapol_flags=0
}
ctrl_interface_group=0
ap_scan=0
network={
key_mgmt=IEEE8021X
eap=MD5
identity="XUSERNAME"
password="XPASSWORD"
eapol_flags=0
}
In some ways working with wpa_supplicant is easier than with Xsupplicant plus you have a single client for both Wired and Wireless connections.
To start it make sure you specify wired driver ie. -Dwired
/opt/wpa_supplicant -B -w -c /etc/wpa_supplicant.conf -i eth0 -Dwired
Enable 802.1x on a Cisco switch
To set up Cisco switch for 802.1x I consulted following documenthttp://www.cisco.com/univercd/cc/td/doc/product/lan/cat2950/1216ea2/scg/swg8021x.htm#60637
In short this is what I did.
1. Enable 802.1x on a Cisco switch. You need to adjust the items in red to your own configuration
Switch# configure terminal
Switch(config)# aaa new-model
Switch(config)# aaa authorization network radius
Switch(config)# aaa authentication login admins local
Switch(config)# aaa authentication dot1x default group radius
Switch(config)# username admin password A-very-long-password
Switch(config)# dot1x system-auth-control
Switch(config)# radius-server host 192.168.1.38 auth-port 1812 acct-port 1813 key testing123
Switch(config)# end
Switch(config)# aaa new-model
Switch(config)# aaa authorization network radius
Switch(config)# aaa authentication login admins local
Switch(config)# aaa authentication dot1x default group radius
Switch(config)# username admin password A-very-long-password
Switch(config)# dot1x system-auth-control
Switch(config)# radius-server host 192.168.1.38 auth-port 1812 acct-port 1813 key testing123
Switch(config)# end
After you are done doing this when you try to log back into the switch you will be prompted for a username and password. The same username and password are the ones you specified under username and password. Make sure that the shared secret (key) for the radius server corresponds to the entry in clients.conf in FreeRADIUS configuration.
2. To configure a particular port for 802.1x use following
Switch(config)# interface fastethernet0/1
Switch(config-if)# dot1x port-control auto
Switch(config-if)# end
Switch(config-if)# dot1x port-control auto
Switch(config-if)# end
3. If you have multiple hosts behind a port ie. there is a switch connected to a port you need to enable following when configuring an interface
Switch(config)# interface fastethernet0/1
Switch(config-if)# dot1x port-control auto
Switch(config-if)# dot1x multiple-hosts
Switch(config-if)# dot1x port-control auto
Switch(config-if)# dot1x multiple-hosts
4. If you are happy with the config make sure to copy the running config into the startup config ie.
Switch#copy running-config startup-config
Dynamically assigning VLANs on Cisco switches (NOT YET FULLY TESTED)
Now that you got 802.1x going you can dynamically assign users to a VLAN depending on how they authenticate. Please make sure that you added the proper mappings in the ldap.attrmap. If you did all you have to do is add these attributes to users/machines LDAP record ie. if you want to assign user to VLAN 2 you would add something like this
radiusTunnelMediumType: IEEE-802
radiusTunnelType: VLAN
radiusTunnelPrivateGroupId: 2
radiusTunnelType: VLAN
radiusTunnelPrivateGroupId: 2
or fully
dn: uid=myhost,cn=dot1x,dc=cs,dc=school,dc=edu
objectClass: top
objectClass: radiusprofile
objectClass: inetOrgPerson
cn: myhost
sn: myhost
uid: myhost
description: 802.1x user
radiusFilterId: "Enterasys:version=1:policy=Enterprise User"
userPassword: supersecretradiusTunnelMediumType: IEEE-802
radiusTunnelType: VLAN
radiusTunnelPrivateGroupId: 2
objectClass: top
objectClass: radiusprofile
objectClass: inetOrgPerson
cn: myhost
sn: myhost
uid: myhost
description: 802.1x user
radiusFilterId: "Enterasys:version=1:policy=Enterprise User"
userPassword: supersecretradiusTunnelMediumType: IEEE-802
radiusTunnelType: VLAN
radiusTunnelPrivateGroupId: 2
Troubleshooting
1. My Cisco switch doesn't seem to be authenticating and I have set it up to point to the RADIUS server.Make sure you are have actually enabled dot1x ie.
Switch#show dot1x
Sysauthcontrol = Enabled
Dot1x Protocol Version = 1
Dot1x Oper Controlled Directions = Both
Dot1x Admin Controlled Directions = Both
Sysauthcontrol = Enabled
Dot1x Protocol Version = 1
Dot1x Oper Controlled Directions = Both
Dot1x Admin Controlled Directions = Both
Sysauthcontrol needs to show Enabled. If it doesn't make sure you enable it. Please check this step.
2. I am attempting PEAP authentication but I am getting
rlm_mschap: Told to do MS-CHAPv2 for xxx with NT-Password
"FAILED: No NT/LM-Password".
"FAILED: No NT/LM-Password".
This can be due to following reasons
- You do not have NT/LM hashes stored in the LDAP database. Your LDAP directory has to have samba schema included in the configuration and NTPassword and LMPassword attributes populated for the user. Those are different than the userPassword attribute. There are two solutions to this problem
- Use TTLS with PAP inner tunnel authentication. To do so you will have to configure your clients.
- Populate NTPassword and LMPassword hashes by using e.g. smbldap-tools. You will not be able to convert your existing UNIX hashes to NT/LM.
- RADIUS user does not have access to NT/LM hashes. You can check here on how to enable that. Attributes you need access to are NTPassword and LMPassword.
0 comments
Post a Comment