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
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
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
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
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
With no success :-(. If you get this working please let me know.
FreeRADIUS
setup
Now we need to configure FreeRADIUS to look up users
1. 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
}
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
}
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
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
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 {
.....
}
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
}
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
}
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"
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"
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.
If you have case 1. here is how to set up your clients for EAP-TTLS
with PAP.
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 example
http://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
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
....
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";
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 at
http://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>
}
}
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
}
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 document
http://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
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
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
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
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:
supersecret
radiusTunnelMediumType:
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 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".
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.
Author:
Vladimir Vuksan
E-mail
me
Contributors: Michael Schwartzkopff (Cisco VLAN assignment)