通过命令行管理用户分组备份等工作
# 1,基础部署
通过如下脚本一键启动 ldap 服务端以及管理端。
cat start.sh
#!/bin/bash -e
SERVICE=ldap-service
HOST_NAME=ldap-server
LDAP_DOMAIN=eryajf.net
LDAP_DC=eryajf
LDAP_DC_ORG=net
NETWORK_ADAPTER=eth0
PASSWORD=123465
OPENLDAP="1.3.0"
PHPLDAPADMIN="0.9.0"
HTTPS_PORT=88
OPENLDAP_PORT=389
docker run \
-p ${OPENLDAP_PORT}:389 \
--name ${SERVICE} \
--hostname ${HOST_NAME} \
--env LDAP_ORGANISATION="WPT-Group" \
--env LDAP_DOMAIN=${LDAP_DOMAIN} \
--env LDAP_ADMIN_PASSWORD=${PASSWORD} \
--detach osixia/openldap:${OPENLDAP}
docker run \
-p ${HTTPS_PORT}:80 \
--name ${SERVICE}-admin \
--hostname ${HOST_NAME}-admin \
--link ${SERVICE}:${HOST_NAME} \
--env PHPLDAPADMIN_LDAP_HOSTS=${HOST_NAME} \
--env PHPLDAPADMIN_HTTPS=false \
--detach \
osixia/phpldapadmin:${PHPLDAPADMIN}
sleep 1
echo "-----------------------------------"
PHPLDAP_IP=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" ${SERVICE})
docker exec ${SERVICE} ldapsearch -x -H ldap://${PHPLDAP_IP}:389 -b "dc=${LDAP_DC},dc=${LDAP_DC_ORG}" -D "cn=admin,dc=${LDAP_DC},dc=${LDAP_DC_ORG}" -w ${PASSWORD}
echo "-----------------------------------"
PUB_IP=$(ifconfig ${NETWORK_ADAPTER} |grep "inet"|awk '{print $2}')
echo "Go to: https://${PUB_IP}:${HTTPS_PORT}"
echo "Login DN: cn=admin,dc=${LDAP_DC},dc=${LDAP_DC_ORG}"
echo "Password: ${PASSWORD}"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
这个脚本会创建一个 ldap 服务,并创建一个 admin 用户,启动之后,访问 10.3.0.42:88
,输入用户名密码,得到如下效果:
现在还是一穷二白,什么都没有的状态,接下来,就要进入正式操作了,从创建第一个用户开始,一步一步往前操作。
# 2,创建两个基本组织
ldap 本质上就是轻量目录协议,那么接下来创建的东西也都可以按目录层级的概念来理解,现在需要先创建两个最外层目录,一个作为人员的所有代理目录,一个作为分组的目录,创建方式如下:
注意需要进入到ldap-server的容器内部执行如下命令
cat << EOF | ldapadd -x -D "cn=admin,dc=eryajf,dc=net" -w 123465
dn: ou=People,dc=eryajf,dc=net
objectClass: organizationalUnit
ou: people
dn: ou=Group,dc=eryajf,dc=net
objectClass: organizationalUnit
ou: group
EOF
2
3
4
5
6
7
8
9
操作过程如下:
$ docker exec -it ldap-service bash
root@ldap-server:/# cat << EOF | ldapadd -x -D "cn=admin,dc=eryajf,dc=net" -w 123465
> dn: ou=People,dc=eryajf,dc=net
> objectClass: organizationalUnit
> ou: people
>
> dn: ou=Group,dc=eryajf,dc=net
> objectClass: organizationalUnit
> ou: group
> EOF
adding new entry "ou=People,dc=eryajf,dc=net"
adding new entry "ou=Group,dc=eryajf,dc=net"
2
3
4
5
6
7
8
9
10
11
12
13
如果没有报错,则说明创建成功了,这个时候可以去看一下页面上的情况:
可以看到刚刚说明的创建两个最外层目录已经完成了。
如果报错如下信息:
ldapadd: attributeDescription "dn": (possible missing newline after line 5, entry "ou=People,dc=eryajf,dc=net"?)
adding new entry "ou=People,dc=eryajf,dc=net"
ldap_add: Type or value exists (20)
additional info: objectClass: value #0 provided more than once
2
3
4
这种报错有两种可能,一种是的确里边有了对应记录,我们可以查一下,是否有ou=People,dc=eryajf,dc=net
这条记录,如果没有,那么应该就是另外一种情况:从上边复制下来的配置中间少了一个换行,每个独立的条目之间应该以换行隔开
。
# 3,创建用户
有一些操作是创建一些模拟用户,比较不给力,这里直接模拟真实,创建三个用户,操作如下。
创建一个liqilong用户:
cat << EOF | ldapadd -x -D cn=admin,dc=eryajf,dc=net -w 123465
dn: uid=liqilong,ou=People,dc=eryajf,dc=net
uid: liqilong
cn: liqilong
sn: liqilong
displayName: liqilong
objectClass: posixAccount
objectClass: top
objectClass: person
objectClass: shadowAccount
objectClass: inetOrgPerson
gecos: System Manager
loginShell: /bin/bash
homeDirectory: /home/liqilong
userPassword: liqilong
uidNumber: 1000
gidNumber: 1009
mobile: 15638888888
mail: liqilong@eryajf.net
postalAddress: Hangzhou
EOF
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
创建一个zhangsan用户
cat << EOF | ldapadd -x -D cn=admin,dc=eryajf,dc=net -w 123465
dn: uid=zhangsan,ou=People,dc=eryajf,dc=net
uid: zhangsan
cn: zhangsan
sn: zhangsan
displayName: zhangsan
objectClass: posixAccount
objectClass: top
objectClass: person
objectClass: shadowAccount
objectClass: inetOrgPerson
gecos: System Manager
loginShell: /bin/bash
homeDirectory: /home/zhangsan
userPassword: zhangsan
uidNumber: 1000
gidNumber: 1009
mobile: 15638888888
mail: zhangsan@eryajf.net
postalAddress: Hangzhou
EOF
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
创建一个zhaosi用户:
cat << EOF | ldapadd -x -D cn=admin,dc=eryajf,dc=net -w 123465
dn: uid=zhaosi,ou=People,dc=eryajf,dc=net
uid: zhaosi
cn: zhaosi
sn: zhaosi
displayName: zhaosi
objectClass: posixAccount
objectClass: top
objectClass: person
objectClass: shadowAccount
objectClass: inetOrgPerson
gecos: System Manager
loginShell: /bin/bash
homeDirectory: /home/zhaosi
userPassword: zhaosi
uidNumber: 1000
gidNumber: 1009
mobile: 15638888888
mail: zhaosi@eryajf.net
postalAddress: Hangzhou
EOF
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
注意这里为了变更全局的内容方便,用户名密码是一致的。
# 4,创建组
组的概念帮助我们大大减轻很多人员权限配置的工作量,它是与用户平行的目录等级,至于创建什么样的组,以哪个维度进行划分,都是可以的,只要实际需求合理,都是可以的。
这里就以常见配置环境中的分组维度,分如下几个组:
cat << EOF | ldapadd -x -D cn=admin,dc=eryajf,dc=net -w 123465
dn: cn=ops,ou=Group,dc=eryajf,dc=net
cn: ops
gidNumber: 66
objectClass: top
objectClass: posixGroup
dn: cn=dev,ou=Group,dc=eryajf,dc=net
cn: dev
gidNumber: 66
objectClass: top
objectClass: posixGroup
dn: cn=jenkins,ou=Group,dc=eryajf,dc=net
cn: jenkins
gidNumber: 66
objectClass: top
objectClass: posixGroup
EOF
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
创建了三个组,两个是组织上的概念,一个是应用层面的概念,创建之后效果如下:
# 5,各就各位
前边已经创建了一些用户, 一些组,现在就来对这些用户进行分组,我称之为各就各位。
通过如下方式可以将一个用户加入到某个组内:
cat << EOF | ldapmodify -x -D cn=admin,dc=eryajf,dc=net -w 123465
dn: cn=ops,ou=Group,dc=eryajf,dc=net
changetype: modify
add: memberuid
memberuid: liqilong
dn: cn=ops,ou=Group,dc=eryajf,dc=net
changetype: modify
add: memberuid
memberuid: zhaosi
EOF
2
3
4
5
6
7
8
9
10
11
如上意思表示将 liqilong
和 zhaosi
加入到 ops 这个组,操作之后现在可以看下 web 页面:
可以看到用户已经在对应组内了,这个时候如果需要添加更多用户,可以直接通过下边 add value
进行添加。
到现在,基本上的用户日常管理都差不多都介绍到了,接下来介绍一下数据的备份问题。
# 6,备份的操作
备份是非常有必要的,任何一个说备份没必要的,都不必与他抬杠。
ldap 通过 slapcat 命令进行备份,可以在容器内部执行,但是如果我们想将备份的指令放入到定时任务的话,就需要通过如下方式进行备份了:
mkdir /data/ldap/bak
docker exec -it ldap-service /bin/bash -c 'slapcat -v -l 20191220.ldif'
docker cp ldap-service:/20191220.ldif /data/ldap/bak
docker exec -it ldap-service /bin/bash -c 'rm -f /20191220.ldif'
2
3
4
这样就把备份之后的文件放置到宿主机上了。
如果 cat 一下文件的内容,发现都是定义各个角色的语句,这个语句是完整版的,可以通过如下操作进行精简。
先指定过滤策略:
$ cat > openldap-backup.synax << EOF
/^creatorsName: /d
/^modifiersName: /d
/^modifyTimestamp: /d
/^structuralobjectClass: /d
/^createTimestamp: /d
/^entryUUID: /d
/^entryCSN: /d
EOF
2
3
4
5
6
7
8
9
然后通过 sed 对文件进行处理:
cat 20191220.ldif | sed -f openldap-backup.synax > new.ldif
[root@ops-eryajf-test-2 bak]$cat 20191220.ldif | wc -l
178
[root@ops-eryajf-test-2 bak]$cat new.ldif | wc -l
118
2
3
4
5
这个时候,有了备份文件在手,就算直接把 ldap 给干了,也不用发愁,因为随时可以通过备份文件进行恢复。刚刚已经写了如何通过命令行备份,那么放入定时任务就不赘述了。
# 7,恢复演练
未经恢复测试的备份都不能叫完整的备份。
现在直接将 docker 启动的两个容器干掉,因为并没有将数据目录往外挂载,所以再次启动的时候数据将会清空,一切都回到第一步时候的状态。
现在就利用刚刚保留的备份来进行一波恢复。
先将备份文件拷贝到容器之内:
docker cp new.ldif ldap-service:/opt
接着进入容器进行恢复,这个时候发现报了错:
ldapadd -x -D "cn=admin,dc=eryajf,dc=net" -w 123465 -f new.ldif
adding new entry "dc=eryajf,dc=net"
ldap_add: Constraint violation (19)
additional info: structuralObjectClass: no user modification allowed
2
3
4
这是因为存在一些系统规则,如下操作去掉这些规则:
$ cat >slapcat.regex <<EOF
/^creatorsName: /d
/^createTimestamp: /d
/^modifiersName: /d
/^modifyTimestamp: /d
/^structuralObjectClass: /d
/^entryUUID: /d
/^entryCSN: /d
EOF
2
3
4
5
6
7
8
9
过滤规则,重写文件内容:
cat new.ldif | sed -f slapcat.regex > neww.ldif
然后进行恢复,发现又报错了:
ldapadd -x -D "cn=admin,dc=eryajf,dc=net" -w 123465 -f neww.ldif
adding new entry "dc=eryajf,dc=net"
ldap_add: Already exists (68)
2
3
这个报错说有内容已经存在了,我们应该想起一开始启动的时候创建了 admin 这个用户,所以备份文件里边就应该去掉,现在编辑一下备份文件,将头上的内容删除:
head -15 new.ldif
dn: dc=eryajf,dc=net
objectClass: top
objectClass: dcObject
objectClass: organization
o: WPT-Group
dc: eryajf
structuralObjectClass: organization
dn: cn=admin,dc=eryajf,dc=net
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e1NTSEF9amplNk43SVp3VkFSSkRRM01pUCszbGU3RURqNVFSMEg=
structuralObjectClass: organizationalRole
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
这部分删除之后,再次导入,发现执行成功了:
ldapadd -x -D "cn=admin,dc=eryajf,dc=net" -w 123465 -f neww.ldif
adding new entry "ou=People,dc=eryajf,dc=net"
adding new entry "ou=Group,dc=eryajf,dc=net"
adding new entry "uid=liqilong,ou=People,dc=eryajf,dc=net"
adding new entry "uid=zhangsan,ou=People,dc=eryajf,dc=net"
adding new entry "uid=zhaosi,ou=People,dc=eryajf,dc=net"
adding new entry "cn=ops,ou=Group,dc=eryajf,dc=net"
adding new entry "cn=dev,ou=Group,dc=eryajf,dc=net"
adding new entry "cn=jenkins,ou=Group,dc=eryajf,dc=net"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
再到界面刷一下,看到数据恢复到了干掉之前的样子了。
到这里,基本上 ldap 相关的日常使用管理就足够了。