apt-get install -y slapd ldap-utils krb5-kdc-ldap
打造统一的 Kerberos 和 OpenLDAP 服务
背景
什么是 LDAP,它用来做什么?
LDAP 是轻量目录访问协议,英文全称是 Lightweight Directory Access Protocol,一般都简称为 LDAP。它是基于 X.500 标准的,但是简单多了并且可以根据需要定制。与 X.500 不同,LDAP 支持 TCP/IP,这对访问 Internet 是必须的。LDAP 的核心规范在 RFC 中都有定义,所有与 LDAP 相关的 RFC 都可以在 LDAPman RFC 网页中找到。LDAP 最新的 RFC 规范文档是 『RFC 4511 Lightweight Directory Access Protocol (LDAP): The Protocol』。
什么是 Kerberos,它用来做什么?
Kerberos 这一名词来源于希腊神话『三个头的狗--地狱之门守护者』系统设计上采用客户端/服务器结构与 DES 加密技术,并且能够进行相互认证,即客户端和服务器端均可对对方进行身份认证。可以用于防止窃听、防止 replay 攻击、保护数据完整性等场合,是一种应用对称密钥体制进行密钥管理的系统。
Kerberos 是一种网络认证协议,其设计目标是通过密钥系统为客户机/服务器应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据。在以上情况下, Kerberos 作为一种可信任的第三方认证服务,是通过传统的密码技术(如:共享密钥)执行认证服务的。
使用Kerberos时,一个客户端需要经过三个步骤来获取服务:
-
认证:客户端向认证服务器发送一条报文,并获取一个含时间戳的 Ticket-Granting Ticket(TGT)。
-
授权:客户端使用 TGT 向 Ticket-Granting Server(TGS)请求一个服务 Ticket。
-
服务请求:客户端向服务器出示服务 Ticket,以证实自己的合法性。该服务器提供客户端所需服务,在 Hadoop 应用中,服务器可以是 namenode 或 jobtracker。
为此,Kerberos 需要 The Key Distribution Centers(KDC)来进行认证。KDC 只有一个 Master,可以带多个 slaves 机器。slaves 机器仅进行普通验证。Mater 上做的修改需要自动同步到 slaves。
另外,KDC 需要一个 admin,来进行日常的管理操作。这个 admin 可以通过远程或者本地方式登录。
什么是 SASL?
简单认证和安全层(Simple Authentication and Security Layer),也是一套 RFC 定义的标准。它的核心思想是把用户认证和安全传输从应用程序中隔离出来。像 SMTP 协议在定义之初都没有考虑到用户认证等问题,现在 SMTP 可以配置使用 SASL 来完成这方面的工作。
SASL支持多种认证方法,比如:
-
ANONYMOUS:无需认证。
-
PLAIN:明文密码方式(cleartext password)
-
DIGEST-MD5:HTTP Digest 兼容的安全机制,基于 MD5,可以提供数据的安全传输层。这个是方便性和安全性结合得最好的一种方式。也是默认的方式。
-
GSSAPI:Generic Security Services Application Program Interface
GSSAPI 本身是一套 API,由 IETF 标准化,其最主要也是著名的实现是基于 Kerberos 的,所以一般说到 GSSAPI 都暗指 Kerberos 实现。
-
EXTERNAL:认证已经在环境中实现了,比如 SSL/TLS, IPSec。
我们的目标是什么?
LDAP 作为存储,Kerberos 作为网络认证协议。都是标准协议,有的系统支持 LDAP,有的系统支持 Kerberos,如果将二者打通的话,可以做到一套数据,多种认证方式,适配能力会更强。
OpenLDAP 服务器
安装 OpenLDAP 服务器
配置 OpenLDAP
使用 OpenLDAP 作为 Kerberos 存储的数据库,需要将 kerberos.schema
添加到 OpenLDAP 的 cn=config
树中。
-
新增配置文件
schema_convert.conf
,输入下面的内容。include /etc/ldap/schema/core.schema include /etc/ldap/schema/collective.schema include /etc/ldap/schema/corba.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/duaconf.schema include /etc/ldap/schema/dyngroup.schema include /etc/ldap/schema/inetorgperson.schema include /etc/ldap/schema/java.schema include /etc/ldap/schema/misc.schema include /etc/ldap/schema/nis.schema include /etc/ldap/schema/openldap.schema include /etc/ldap/schema/ppolicy.schema include /etc/ldap/schema/kerberos.schema
-
创建临时目录,用来存放 LDIF 文件
mkdir /tmp/ldif_output
-
使用
slapcat
命令转换上面指定的 schema 文件slapcat -f schema_convert.conf -F /tmp/ldif_output -n0 -s \ "cn={12}kerberos,cn=schema,cn=config" > /tmp/cn=kerberos.ldif
-
修改生成的
/tpm/cn\=kerberos.ldif
文件,找到并修改下面的两行:dn: cn=kerberos,cn=schema,cn=config ... cn: kerberos
另外,还需要移除位于文件末位的下面几行:
structuralObjectClass: olcSchemaConfig entryUUID: 18ccd010-746b-102d-9fbe-3760cca765dc creatorsName: cn=config createTimestamp: 20090111203515Z entryCSN: 20090111203515.326445Z#000000#000#000000 modifiersName: cn=config modifyTimestamp: 20090111203515Z
-
使用
slapadd
命令加载新的 schemaldapadd -Q -Y EXTERNAL -H ldapi:/// -f /tmp/cn\=kerberos.ldif
-
为
krbPrincipalName
属性增加索引ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF dn: olcDatabase={1}hdb,cn=config add: olcDbIndex olcDbIndex: krbPrincipalName eq,pres,sub EOF
-
最后,更新访问控制清单(ACL)
ldapmodify -Q -Y EXTERNAL -H ldapi:/// Enter LDAP Password: dn: olcDatabase={1}hdb,cn=config replace: olcAccess olcAccess: to attrs=userPassword,shadowLastChange,krbPrincipalKey by dn="cn=admin,dc=example,dc=com" write by anonymous auth by self write by * none - add: olcAccess olcAccess: to dn.base="" by * read - add: olcAccess olcAccess: to * by dn="cn=admin,dc=example,dc=com" write by * read modifying entry "olcDatabase={1}hdb,cn=config"
Kerberos 安装
krb5-user krb5-kdc krb5-admin-server krb5-kdc-ldap
配置
Note
|
以 7V1.NET 域名为例。 |
-
在配置文件
/etc/krb5.conf
中增加[dbmodules]
小节,加入一下内容:在/etc/krb5.conf
中添加的内容[dbmodules] openldap_ldapconf = { db_library = kldap ldap_kdc_dn = "$ldap_kdc_dn" # this object needs to have read rights on # the realm container, principal container and realm sub-trees ldap_kadmind_dn = "$ldap_kadmind_dn" # this object needs to have read and write rights on # the realm container, principal container and realm sub-trees ldap_service_password_file = $ldap_service_password_file ldap_servers = ldap://$LDAP_HOST ldap_conns_per_server = 5 }
Note-
$ldap_kdc_dn
指的是『KDC』服务将采用哪个 OpenLDAP DN与 OpenLDAP 服务通信。 -
$ldap_kadmind_dn
指的是『KADMIND』服务将采用哪个 OpenLDAP DN与 OpenLDAP 服务通信。 -
$ldap_service_password_file
表示存储 OpenLDAP DN 密码的文件路径。 -
$LDAP_HOST
表示 OpenLDAP 的服务器地址。
-
-
在
/etc/krb5.conf
的[realms]
小节中将特定的『REALM』(如 7V1.NET)的database_module
设置为刚才添加的openldap_ldapconf
。[realms] 7V1.NET = { kdc = $KDC_ADDRESS admin_server = $KDC_ADDRESS default_domain = $DOMAIN_REALM database_module = openldap_ldapconf }
-
使用 kdb5_ldap_util 命令来初始化 Kerberos 数据库
为 OpenLDAP DN 生成密码文件kdb5_ldap_util -D $ADMIN_DN -w $ADMIN_PW stashsrvpw -f $ldap_service_password_file $ADMIN_DN
创建 Kerberos 数据库kdb5_ldap_util -D $ADMIN_DN -w $ADMIN_PW create -subtrees $DOMAIN_DN -r $KRB5REALM -s
Tip
|
小提示
|
saslauthd
安装
saslauthd 需要和 OpenLDAP 装在同一台机器上。
配置 saslauthd
-
修改配置文件
/etc/default/saslauthd
START=yes DESC="SASL Authentication Daemon" NAME="saslauthd" MECHANISMS="kerberos5" MECH_OPTIONS="" THREADS=5 OPTIONS="-c -m /var/run/saslauthd"
-
添加账号 『openldap』、『sasl』,赋予合适的权限
sudo adduser openldap sasl
-
为本机生成 Kerberos Principal,并授权
kadmin.local -q "ank -randkey host/`hostname`" kadmin.local -q "ktadd host/`hostname`"
-
测试
testsaslauthd -u username -p password
配置 OpenLDAP 和 Kerberos
-
需要先把
/etc/krb5.conf
拷一份到 OpenLDAP 服务器。任何 Kerberos 的客户端机器都需要配置文件
/etc/krb5.conf
。 -
在 Kerberos 中为 OpenLDAP 服务器添加 Principal。
kadmin.local -q "ank -randkey ldap/`hostname`" kadmin.local -q "ktadd ldap/`hostname`"
-
新增
/etc/ldap/sals2/slapd.conf
,增加下面内容:pwcheck_method: saslauthd mech_list: gs2-krb5 gssapi plain
-
修改
/etc/ldap/ldap.conf
,增加下面内容:SASL_MECH GSSAPI
-
重启 OpenLDAP 服务器。
-
为 LDAP 用户设置密码
ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF dn: ${USER_DN} changetype: modify replace: userPassword userPassword:: `echo -n {SASL}[email protected]|base64` EOF
Tip采用 SASL 授权后,OpenLDAP 的 userPassword
字段实际上是 『[email protected]』 的 base64编码,如:echo -n {SASL}[email protected]|base64
。
Docker
这么复杂的操作,好痛苦,怎么破?别怕,我们有 Docker 大法。
OpenLDAP 篇
-
从 github 上将 docker-openldap 克隆下来,执行构建命令
docker build -t lifei/openldap .
。 -
使用新构建的镜像来启动一个容器,
docker run --name=openldap -d lifei/openldap
, 就这样一个名为『openldap』的 OpenLDAP 服务容器就启起来了。 -
进入这个镜像进行配置,执行命令
docker exec -it openldap bash
,进入 bash。 -
这个镜像采用环境变量作为配置项,先准备如下面的内容:
export NAME=7v1 export DOMAIN_DN=dc=7v1,dc=net export ADMIN_DN=cn=admin,$DOMAIN_DN export ADMIN_PW=1234 export KRB5REALM=7V1.NET export DOMAIN_REALM=7v1.net
以上变量含义比较清晰,就不再解释了。
-
执行 OpenLDAP 的初始化命令
openldap-init.sh
,OpenLDAP 服务就按照上面的配置初始化好了。 -
若 Kerberos 想使用 OpenLDAP 作为后端存储,则只需执行 Kerberos 初始化命令,
kerberos-init.sh
,Kerberos 所需要的设置也配置完毕了。 -
未完待续,等 Kerberos 配置完毕后,再来配置使用 Kerberos 作为 OpenLDAP 的认证。
Kerberos 篇
-
从 github 上将 docker-kerberos 克隆下来,执行构建命令
docker build -t lifei/kerberos .
。 -
使用新构建的镜像来启动一个容器,
docker run --link openldap:openldap --name=kerberos -d lifei/kerberos
,就这样一个名为『kerberos』容器就启起来了,但是与上面的『openldap』容器不同,此时的 Kerberos 服务还未启动。 -
进入这个镜像进行配置,执行命令
docker exec -it kerberos bash
,进入 bash。 -
这个镜像同样采用环境变量作为配置项,先准备如下面的内容:
export DOMAIN_DN=dc=7v1,dc=net export ADMIN_DN=cn=admin,$DOMAIN_DN export ADMIN_PW=1234 export KRB5REALM=7V1.NET export DOMAIN_REALM=7v1.net export LDAP_HOST=openldap
-
执行初始化命令
kerberos-init.sh
,键入『Master Key』的密码两次,Kerberos 环境就配置完了。 -
若想让 OpenLDAP 使用 Kerberos 作为验证方法的话,在执行
kadmin.local -q "ank root/admin"
,键入密码,生成一个可以使用 kadmin 命令的账号,下文的krb5-init.sh
会用到这个账号。
OpenLDAP使用Kerberos作为验证方法
-
在 openldap 容器中设置环境命令
export KDC_ADDRESS=kerberos容器的IP
。 -
执行
krb5-init.sh
,初始化krb5.conf
文件并为 OpenLDAP 服务器生成两个 principal。 -
重启 openldap 容器,创建测试账号
smith
# openldap容器中执行 UID=smith && ldapadd -x -D $ADMIN_DN -w $ADMIN_PW <<EOF dn: ou=people,$DOMAIN_DN objectClass: organizationalUnit ou: people dn: cn=$UID,ou=people,$DOMAIN_DN objectclass: inetOrgPerson sn: $UID uid: $UID userpassword: {SASL}$UID@$KRB5REALM description: $UID ou: people EOF kadmin -q "ank smith" ldapwhoami -x -D cn=smith,ou=people,$DOMAIN_DN -W
参考资料:
-
http://www.math.ucla.edu/~jimc/documents/ldap/kerberos-ldap-1202.html
-
http://www.math.ucla.edu/~jimc/documents/ldap/ldap-setup-1202.html
-
http://labs.opinsys.com/blog/2010/03/16/openldap-authentication-with-kerberos-backend-using-sasl/
-
http://www.rjsystems.nl/en/2100-kerberos-openldap-provider.php
-
http://web.mit.edu/kerberos/krb5-1.13/doc/admin/conf_ldap.html