freeIPA的会包含下面2个组件:

  • LDAP Server - based on the 389 project (LDAP) http://directory.fedoraproject.org/wiki/Main_Page

  • KDC - based on MIT Kerberos implementation http://k5wiki.kerberos.org/wiki/Main_Page

注意LDAP Server用的不是openLDAP,而是RedHat自己的389 Project。我们知道只要向freeIPA添加一次用户,后续可以使用同一套账户、密码通过LDAP、kerberos、linux认证,那么后台是怎么实现的呢?

先说结论:kerberos的数据存储在LDAP上,在做kerberos认证时,会去LDAP取所需要的用户信息,然后自己再去做认证。

对于kerberos来说,唯一的配置只有/etc/krb5.conf这1个:

[dbmodules]
  IEEVEE.COM = {
    db_library = ipadb.so
  }

kerberos允许使用自定义存储后端,只要实现了kdb_vftabl这个结构体就行。ipadb.so即为freeIPA提供的存储后端,其源码在daemon/ipa-kdb里,相关代码可以参见kdb_function_table

我比较关心kerberos是怎么跟LDAP交互的,下面挨个问题解答。

1、跟LDAP的连接是怎么建立的?

kerberos跟LDAP在同一台机器上,二者之间的连接并非我预想的是ldapi://hostname:port这种形式,而是ldapi:///var/run/slapd-IEEVEE-COM.socket这种形式,具体代码可以参见ipadb_realm_to_ldapi_uriipadb_get_connection。LDAPI使用了IPC通信,通过slapd-xx.socket允许不同进程间通信,相关信息可以参考RedHat的介绍。LDAPI方式比普通LDAP更快,更安全。

Inter-process communication (IPC) is a way for separate processes on a Unix machine or a network to communicate directly with each other. LDAPI allows LDAP connections to run over IPC connections, meaning that LDAP operations can run over Unix sockets. These connections are much faster and more secure than regular LDAP connections.

2、kinit时是怎么通过LDAP认证的?

ipadb.so中会先构造下面的filter条件,然后调用ldap_search_ext_s去LDAP查询符合要求的entry。

 #define PRINC_SEARCH_FILTER "(&(|(objectclass=krbprincipalaux)" \
                                 "(objectclass=krbprincipal))" \
                                 "(krbprincipalname=%s))"

ipadb_parse_ldap_entry中会解析LDAP返回的entry,并填到返回给kerberos的krb5_db_entry结构中,该结构中包含principal的密码,kerberos拿到后用来检查用户输入的密码是否正确。

LDAP entry中包含krbPrincipalKey和krbExtraData字段,但我拿不准哪个字段存储了kerberos用户的密码。从代码上来看应该是krbPrincipalKey,但是我从LDAP admin tool去看LDAP数据的时候,这个字段是空的。望赐教。

我的理解:kerberos只是用LDAP来做database,其认证过程还是自己来做的,这一点需要和LDAP认证区分开来。一般来说LDAP除了可以做DB,还有更主要的是其LDAP认证功能。LDAP认证可以分为两层:上层是LDAPserver,下层是LDAP DB,LDAP server会从LDAP DB取数据,然后根据用户提供的密码去bind(即认证),最终返回认证结果,从这个角度来看kerberos和LDAP Server的角色类似。

3、添加用户时,在kerberos上有什么动作吗?还是只是在LDAP上增加信息。

从WEB页面上添加用户时,走的是user.py/user_add,在这里面会设置很多该entry的LDAP属性,但不涉及密码(事实上这个时候密码是随机的/MAGIC_VALUE)。之后修改密码需要走“reset password”,这时会调用password.py/passwd去修改,之后会调用ipa_kdb.c/ipadb_change_pwd,生成新密码后再调用ipadb_put_principal写到LDAP上去。

这段代码看的不是很清楚,很多地方模模糊糊。

另,linux上有类似source insight的工具吗?vim+ctags+cscope用的很不熟练。

参考:

MIT Kerberos Documentation Database administration

Configuring Kerberos with OpenLDAP back-end

freeIPA: Kerberos

freeIPA: Directory Server

Extending FreeIPA

LDAP服务器的概念和原理简单介绍

使用 LDAP + Kerberos 实现集中用户认证及授权系统