I wanted to test the MAC authentication bypass mechanism as an alternative to switchport configuration using snmp when re-imaging computers in an 802.1x network. According to the Cisco documentation that requires an LDAP server to hold the MAC addresses of the computers, and an LDAP client program to add the MAC addresses and modify the group information.
Since re-imaging is an automated operation there would be no way to enter an LDAP password. I didn’t want to hard code the password into the client or a script. That left me with two options to investigate, certificate based authentication or kerberos. From the title of the post it should be obvious that I wasn’t brave enough to try kerberos.
Materials:
- ADIOS 4.12 Linux Boot CD, containing OpenLDAP 2.2.13 and Cyrus SASL 2.1.19
- Spare computer that will boot the CD.
- Certificates – Self-signed CA certificate, server certifcate and client certificate. See this post for more information on generating self-signed certificates.
The important configuration file for OpenLDAP is /etc/openldap/slapd.conf, as shown in listing 2. The important lines for certificate authentication are shown below. Note the sasl-regexp can be difficult to get right. The cn of my client certificate contains spaces, which caused the slapd.conf to fail verification. I tried using \s to match the spaces but eventually had to fall back to “.”
#Trusted CA certificates
TLSCACertificateFile /media/usb/ldap/Acme/cacert.pem
#Server certificate file
TLSCertificateFile /media/usb/ldap/Acme/ldap.pem
#Server certificate key file
TLSCertificateKeyFile /media/usb/ldap/Acme/ldap.pem
#Force Openldap to ask for a client certificate
TLSVerifyClient try
#Map the certifcate dn to the openldap dn
#Note that sasl-regexp became authz-regexp in version 2.3
sasl-regexp
cn=LDAP.Server.Manager
cn=Manager,dc=acme,dc=com,dc=au
#set openldap logging level to debug
loglevel -1
The ldap client configuration file is .ldaprc and is usually located in the home directory of the user. Listing 1 shows a .ldaprc file’s contents. Note the lines beginning with TLS specifying the acceptable CA certificates and the certificate and keyfile to be used for authentication, and SASL_MECH to specify EXTERNAL (TLS client certificate) authentication.
We can check that everything is configured correctly by performing a search. The -ZZ option forces the use of TLS and requires it to be successful.
[adios@adios-bootcd ~]$ ldapsearch -ZZ -h ldap.acme.com.au -b “” -s base +
Enter PEM pass phrase:clientcertpassword
SASL/EXTERNAL authentication started
SASL username: emailAddress=ldapmanager@acme.com.au,CN=LDAP Server Manager,O=Acme Pty Ltd,L=Brisbane,ST=Queensland,C=AU
SASL SSF: 0
# extended LDIF
….
supportedSASLMechanisms: PLAIN
supportedSASLMechanisms: LOGIN
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: CRAM-MD5
supportedSASLMechanisms: EXTERNAL
subschemaSubentry: cn=Subschema
# search result
search: 3
result: 0 Success
# numResponses: 2
# numEntries: 1
Now we can attempt to add entries to the ldap database. The contents of default.ldif are shown in listing 3.
[adios@adios-bootcd ~]$ ldapadd -ZZ -h ldap.acme.com.au -f /media/usb/ldap/conf/default.ldif
Enter PEM pass phrase:
SASL/EXTERNAL authentication started
SASL username: emailAddress=ldapmanager@acme.com.au,CN=LDAP Server Manager,O=Acme Pty Ltd,L=Brisbane,ST=Queensland,C=AU
SASL SSF: 0
adding new entry “dc=acme,dc=com,dc=au”
adding new entry “cn=Manager,dc=acme,dc=com,dc=au”
adding new entry “cn=Barbara Jensen,dc=acme,dc=com,dc=au”
adding new entry “ou=MAB Segment, dc=acme,dc=com,dc=au”
adding new entry “ou=MAC Addresses, ou=MAB Segment, dc=acme,dc=com,dc=au”
adding new entry “ou=MAC Groups, ou=MAB Segment, dc=acme,dc=com,dc=au”
adding new entry “cn=acctsprn,ou=MAC Addresses, ou=MAB Segment, dc=acme, dc=com, dc=au”
adding new entry “cn=printgroup,ou=MAC Groups, ou=MAB Segment, dc=acme, dc=com,dc=au”
Listing 1 .ldaprc
#
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never
HOST 127.0.0.1
BASE dc=acme,dc=com,dc=au
#URI ldaps://ldap.acme.com.au:636/
SASL_MECH EXTERNAL
TLS_CERT /media/usb/ldap/Acme/ldapmgr.pem
TLS_KEY /media/usb/ldap/Acme/ldapmgrkey.pem
TLS_CACERT /media/usb/ldap/Acme/cacert.pem
Listing 2 slapd.conf
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
# Allow LDAPv2 client connections. This is NOT the default.
allow bind_v2
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org
pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args
# Load dynamic backend modules:
# modulepath /usr/sbin/openldap
# moduleload back_bdb.la
# moduleload back_ldap.la
# moduleload back_ldbm.la
# moduleload back_passwd.la
# moduleload back_shell.la
# The next three lines allow use of TLS for encrypting connections using a
# dummy test certificate which you can generate by changing to
# /usr/share/ssl/certs, running "make slapd.pem", and fixing permissions on
# slapd.pem so that the ldap user or group can read it. Your client software
# may balk at self-signed certificates, however.
# TLSCACertificateFile /usr/share/ssl/certs/ca-bundle.crt
# TLSCertificateFile /usr/share/ssl/certs/slapd.pem
# TLSCertificateKeyFile /usr/share/ssl/certs/slapd.pem
TLSCACertificateFile /media/usb/ldap/Acme/cacert.pem
TLSCertificateFile /media/usb/ldap/Acme/ldap.pem
TLSCertificateKeyFile /media/usb/ldap/Acme/ldap.pem
TLSVerifyClient try
# Sample security restrictions
# Require integrity protection (prevent hijacking)
# Require 112-bit (3DES or better) encryption for updates
# Require 63-bit encryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64
# Sample access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
# Directives needed to implement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
# access to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!
#######################################################################
# ldbm and/or bdb database definitions
#######################################################################
database bdb
suffix "dc=acme,dc=com,dc=au"
rootdn "cn=Manager,dc=acme,dc=com,dc=au"
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
# rootpw secret
# rootpw {crypt}ijFYNcSNctBYg
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory /var/lib/ldap
# Indices to maintain for this database
index objectClass eq,pres
index ou,cn,mail,surname,givenname eq,pres,sub
index uidNumber,gidNumber,loginShell eq,pres
index uid,memberUid eq,pres,sub
index nisMapName,nisMapEntry eq,pres,sub
# Replicas of this database
#replogfile /var/lib/ldap/openldap-master-replog
#replica host=ldap-1.example.com:389 starttls=critical
# bindmethod=sasl saslmech=GSSAPI
# authcId=host/ldap-master.example.com@EXAMPLE.COM
sasl-regexp
cn=LDAP.Server.Manager
cn=Manager,dc=acme,dc=com,dc=au
loglevel -1
Listing 3 – default.ldif
dn: dc=acme,dc=com,dc=au
objectClass: dcObject
objectClass: organization
objectClass: top
o: acme
dc: acme
dn: cn=Manager,dc=acme,dc=com,dc=au
objectclass: organizationalRole
cn: Manager
dn: cn=Barbara Jensen,dc=acme,dc=com,dc=au
objectclass: person
cn: Barbara Jensen
cn: Babs Jensen
sn: Jensen
userPassword: superstr0ngpassw0rd
dn: ou=MAB Segment, dc=acme,dc=com,dc=au
ou: MAB Segment
objectClass: top
objectClass: organizationalUnit
description: MAC Authentication Bypass Sub-Tree
dn: ou=MAC Addresses, ou=MAB Segment, dc=acme,dc=com,dc=au
ou: MAC Addresses
objectClass: top
objectClass: organizationalUnit
dn: ou=MAC Groups, ou=MAB Segment, dc=acme,dc=com,dc=au
ou: MAC Groups
objectClass: top
objectClass: organizationalUnit
dn: cn=acctsprn,ou=MAC Addresses, ou=MAB Segment, dc=acme, dc=com, dc=au
objectClass: top
objectClass: device
objectClass: ieee802Device
macAddress: 00:21:5a:5f:91:c9
cn: acctsprn
dn: cn=printgroup,ou=MAC Groups, ou=MAB Segment, dc=acme, dc=com, dc=au
objectClass: top
objectClass: groupofuniquenames
description: group of delimited MAC Addresses
uniqueMember: cn=acctsprn,ou=MAC Addresses, ou=MAB Segment, dc=acme, dc=com, dc=au
cn: printgroup