SLIDE 1 1
SER Authentication with Radius and LDAP
Nimal Ratnayake
<nimalr@learn.ac.lk>
Lanka Education and Research Network (LEARN) and Department of Electrical & Electronic Engineering, University of Peradeniya
SLIDE 2 2
SER Authentication
- Checks whether the provided password is correct
- Local users
– Added using serctl command line utility serctl add <username> <passwd> <email>
– Need a proper database for persistence
- Users defined in MySQL database
– Existing directory can be exported to MySQL – Need to export whenever directory is modified
– SER authenticates via Radius – Radius gets directory data from LDAP server – Useful for implementing SIP.EDU
SLIDE 3 3
Digest Authentication
- SIP server/proxy challenges UA
– 401 Unauthorized – 407 Proxy authentication required – Challenge includes realm and nonce – realm is normally set to the SIP domain
– Get the password from user – Compute MD5 hash of user:realm:password (This is called HA1) – UA computes the response as the MD5 hash of HA1, nonce and some other info – Sends response, nonce etc to SIP server/proxy
SLIDE 4 4
Digest Authentication (ctd)
– Creates a Radius Access-Request packet and sends to Radius server
– Computes the HA1 and then response
- Radius server must know users cleartext password
- r HA1 (already computed)
– Looks up the LDAP database for the user's password
- Bind to the LDAP directory tree
- Search the LDAP directory tree for users password
– Must authenticate itself to the LDAP server – Sends an Access-Accept or Access-Reject packet to SER
SLIDE 5 5
Digest Authentication (ctd)
– Sends OK to UA if authenticated – Sends Unauthorized if not authenticated
SLIDE 6 6
Software components
– Enable radius module when compiling
- Radius client (radiusclient-ng 0.3.2)
– SER talks to the Radius server using radiusclient
- Radius server (freeradius 1.0.5r3)
– In our case running on the same machine
- LDAP server (openldap server 2.2.3)
– In our case running on the same machine – Already populated LDAP Directory
- This presentation will focus on
– SER and FreeRadius configuration
SLIDE 7 7
SER Configuration
– Load the auth_radius module in addition to auth module – Set parameters for the module
- radius_config and service_type parameters
– Use radius_www_authorize and radius_proxy_authorize instead of www_authorize and proxy_authorize
- They take only one parameter instead of two for
www_authorize and proxy_authorize
SLIDE 8 8
SER Configuration Example
loadmodule "/usr/local/lib/ser/modules/auth.so" loadmodule "/usr/local/lib/ser/modules/auth_radius.so" ..... modparam("auth_radius", "radius_config", "/etc/ser/radiusclient.conf") modparam("auth_radius", "service_type", 15) ..... if (!radius_www_authorize("pdn.ac.lk")) { www_challenge("pdn.ac.lk", "0"); break; }; ..... if (!radius_proxy_authorize("pdn.ac.lk")) { proxy_challenge("pdn.ac.lk", "0"); break; }; ......
SLIDE 9 9
Radiusclient configuration
- Add Radius server name or IP address in file
/etc/ser/radiusclient.conf authserver localhost
acctserver localhost
- Add the shared secret in file
/etc/radiusclient-ng/servers localhost testing123
- Append contents of /etc/ser/dictionary.ser to file
/etc/radiusclient-ng/dictionary cat /etc/ser/dictionary.ser >> /etc/radiusclient-ng/dictionary
SLIDE 10 10
Radius server configuration
- Add radius client name/IP in file /etc/raddb/clients
client 127.0.0.1 { secret testing123 }
- Include the SER dictionary by adding the following in
the file /etc/raddb/dictionary $INCLUDE /etc/ser/dictionary.ser
modules { .... ldap { // ldap config goes here } } // end of modules
SLIDE 11
11
Radius server configuration example
ldap { server = "localhost" identity = "cn=root,dc=pdn,dc=ac,dc=lk" password = tops3cr3t basedn = "ou=People,dc=pdn,dc=ac,dc=lk" filter = "(uid=%u)" ..... password_attribute = userPassword ..... }
SLIDE 12 12
LDAP configuration
– Directory tree structure – LDAP permissions are important
- Before searching LDAP directory, Radius server
needs to bind to some location on the LDAP tree
– Configuration parameter identity
identity = "cn=root,dc=pdn,dc=ac,dc=lk"
- From the bind location, you must have permission to
read/authenticate againt the location you are searching
– Configuration parameter basedn
basedn = "ou=People,dc=pdn,dc=ac,dc=lk" filter = "(uid=%u)"
SLIDE 13
13
Sample LDAP configuration
access to dn.base="" by * read access to attr=userPassword by self write by anonymous auth by dn.base="cn=root,dc=pdn,dc=ac,dc=lk" write by * none access to * by self write by anonymous auth by dn.base="cn=root,dc=pdn,dc=ac,dc=lk" write by dn.one="ou=Servers,dc=pdn,dc=ac,dc=lk" read by * none
SLIDE 14 14
Debugging
– Run radiusd in debug mode /usr/sbin/radiusd -X
- Use radtest utility to test
– First try with a user defined in /etc/raddb/users
test Auth-Type := Local, User-Password := "test"
– Try HTTP Digest authentication with the same user
test Auth-Type := Digest, User-Password := "test" Reply-Message = "Hello, test with digest"
– May need some entries in /etc/raddb/hints to map user test@localhost to just test
SLIDE 15
15
Sample Radius debug output
rad_recv: Access-Request packet from host 127.0.0.1:56217, id=200, length=194 User-Name = "nimalr@pdn.ac.lk" Digest-Attributes = 0x0a086e696d616c72 Digest-Attributes = 0x010b70646e2e61632e6c6b Digest-Attributes = 0x022a343364343237316338643065323534376466383230303939656 43639646434323464373337383663 Digest-Attributes = 0x040f7369703a70646e2e61632e6c6b Digest-Attributes = 0x030a5245474953544552 Digest-Response = "df07d6bf3e4e0c78a04e597d430bc12e" Service-Type = Sip-Session Sip-Uri-User = "nimalr" NAS-IP-Address = 127.0.0.1 NAS-Port = 5060
SLIDE 16 16
Sample Radius debug output (2)
modcall: entering group authorize for request 0 modcall[authorize]: module "preprocess" returns ok for request 0 modcall[authorize]: module "chap" returns noop for request 0 modcall[authorize]: module "mschap" returns noop for request 0 rlm_digest: Converting Digest-Attributes to something sane... Digest-User-Name = "nimalr" Digest-Realm = "pdn.ac.lk" Digest-Nonce = "43d4271c8d0e2547df820099ed69dd424d73786c" Digest-URI = "sip:pdn.ac.lk" Digest-Method = "REGISTER"
SLIDE 17 17
Sample Radius debug output (3)
rlm_digest: Converting Digest-Attributes to something sane... Digest-User-Name = "nimalr" Digest-Realm = "pdn.ac.lk" Digest-Nonce = "43d4271c8d0e2547df820099ed69dd424d73786c" Digest-URI = "sip:pdn.ac.lk" Digest-Method = "REGISTER"
.....
SLIDE 18 18
Sample Radius debug output (3)
rlm_ldap: - authorize
rlm_ldap: performing user authorization for nimalr radius_xlat: '(uid=nimalr)' radius_xlat: 'ou=People,dc=pdn,dc=ac,dc=lk' ..... rlm_ldap: attempting LDAP reconnection rlm_ldap: (re)connect to localhost:389, authentication 0 rlm_ldap: bind as cn=root,dc=pdn,dc=ac,dc=lk/tops3cr3t to localhost:389 rlm_ldap: waiting for bind result ... rlm_ldap: Bind was successful ..... rlm_ldap: performing search in ou=People,dc=pdn,dc=ac,dc=lk, with filter (uid=nimalr) rlm_ldap: Added password BlahBlah in check items
SLIDE 19
19
Sample Radius debug output (4)
modcall: group authorize returns ok for request 0 rad_check_password: Found Auth-Type DIGEST auth: type "digest" Processing the authenticate section of radiusd.conf modcall: entering group authenticate for request 0 A1 = nimalr:pdn.ac.lk:BlahBlah A2 = REGISTER:sip:pdn.ac.lk KD = 2fc2286e2c035f42ef4c0d077751ca09:43d4271c8d0e2547df820099 ed69dd424d73786c:4ea8a5db028bb11e4698dcaef8f4c6d9 modcall[authenticate]: module "digest" returns ok for request 0 modcall: group authenticate returns ok for request 0 Sending Access-Accept of id 200 to 127.0.0.1:56217
SLIDE 20 20
LDAP and SIP.EDU
- Incoming request INVITE nimalr@pdn.ac.lk
- Lookup LDAP directory for PBX extension of nimalr
- If found append the new URL to the list of URLs
if ((method=="INVITE") & (uri=~ "sip:[a-z]{3,}@pdn.ac.lk")) { if (exec_dset("/usr/local/sbin/sipldap")) { log(1," sipldap lookup successful"); append_branch(); revert_uri(); }; };
- If the call is not answered, can use LDAP directory to
forward the call to mobile
SLIDE 21 21
LDAP lookup script
#!/usr/local/bin/bash LDAP_SERV="localhost" LDAP_BIND="cn=auth,ou=Servers,dc=pdn,dc=ac,dc=lk" LDAP_BINDPW="SvrS3cr3" LDAP_BASE="ou=People,dc=pdn,dc=ac,dc=lk" EMAIL=$(echo ${1} | cut -d: -f2) USERID=$(echo $EMAIL | sed -e "s/@pdn.ac.lk//") ....... # search LDAP directory if [ -z "${PHONE}" ]; then PHONE=$(ldapsearch -LLL -x -h ${LDAP_SERV} -D ${LDAP_BIND} -w ${LDAP_BINDPW} -b ${LDAP_BASE} uid=${USERID} telephoneNumber | grep -i telephoneNumber | cut -d' ' -f2 | tr -d '-') fi .......
SLIDE 22 22
LDAP lookup script (ctd)
# print out original unmodified URI if nothing found,
if [ -z "${PHONE}" -o "${PHONE}" = "none" ]; then echo "${1}" exit 1; else echo "sip:${PHONE}@192.248.40.59" exit 0; fi