您的位置:首页 > 运维架构 > Docker

基于docker的高可用openldap(包含lam-admin网页和sudo,ppolicy模块)

2020-06-21 18:33 85 查看

你好! 这是本人第一次写博客,请大家多多包涵

1.使用并安装docker

安装docker主要分四步,先卸载本机中已经有的docker包,然后下载必要的组件,加入yum源,最后安装docker

sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io

由于国内官网的docker源比较慢,这里采用阿里源,并且关闭防火墙,当然生产环境建议设置ip白名单,ldap默认389端口,ldap-admin使用4389端口

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://vbd65v07.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
firewall-cmd --add-port=389/tcp --permanent
firewall-cmd --add-port=4389/tcp --permanent
sudo systemctl restart firewalld
sudo systemctl restart docker
sudo systemctl enable docker

到了这里docker环境就安装完毕了

2.拉取docker镜像

镜像包涵两个一个是openldap镜像一个是lam-admin图形化的镜像

docker pull osixia/openldap
docker pull ldapaccountmanager/lam

3.接下来就是运行容器了

首先需要设置rsyslog用于记录容器中的日志,用于记录容器状态,和用户访问日志生成的目录保存在宿主机的/var/log/messages下

echo "\$ModLoad imtcp" >> /etc/rsyslog.conf
echo "\$InputTCPServerRun 514" >> /etc/rsyslog.conf
systemctl restart  rsyslog
netstat -ntul |grep 514

执行定时任务对日志进行备份,每个月1号0点0分进行日志备份和清理,备份的目录为/openldap/log

crontab -e
0 0 1 * * root sh /log/copy.sh

echo "0 0 1 * * root sh /log/copy.sh" >> /etc/crontab
mkdir /log
touch /log/copy.sh
cat>/log/copy.sh<<EOF
#!bin/bash
time2=\$(date "+%Y%m%d%H%M.log")
cp /var/log/massage /log/\$time2
rm -f /var/log/massage
find /log/ -mtime +1100 -name "*.log" -exec rm -rf {} \;
systemctl restart  rsyslog
EOF
systemctl enable crond.service
service crond restart
service crond status -l

在第一台机器ldap1.example.com上运行,/openldap目录用于存放日志,数据库和overlay信息。

mkdir /openldap
mkdir /openldap/log
mkdir /openldap/ldap
mkdir /openldap/slapd.d
docker run -v /openldap/slapd.d:/etc/ldap/slapd.d -v /openldap/ldap:/var/lib/ldap -v /openldap/log:/var/log --log-driver syslog --log-opt syslog-address=tcp://127.0.0.1:514 --log-opt tag=ldap1 --name ldap1 --restart=always --hostname ldap1.example.com --add-host ldap1.example.com:192.168.137.128 --add-host ldap2.example.com:192.168.137.129 --env LDAP_ORGANISATION="example" --env LDAP_DOMAIN="example.com" --env LDAP_REPLICATION_HOSTS="#PYTHON2BASH:['ldap://ldap1.example.com','ldap://ldap2.example.com']" --env LDAP_REPLICATION=true --env LDAP_ADMIN_PASSWORD="111111" -p 389:389 --detach osixia/openldap:latest
docker run -d --restart=always --name ldap-account-manager -p 4389:80 --detach ldapaccountmanager/lam:latest

这里的example.com为openldap的域名,111111为admin的密码,192.168.137.129为第二台机器的ip地址用于两台机器的通讯互通。

在第二台机器ldap2.example.com上以同样的方式运行

echo "\$ModLoad imtcp" >> /etc/rsyslog.conf
echo "\$InputTCPServerRun 514" >> /etc/rsyslog.conf
systemctl restart  rsyslog
netstat -ntul |grep 514
mkdir /openldap
mkdir /openldap/log
mkdir /openldap/ldap
mkdir /openldap/slapd.d
docker run -v /openldap/slapd.d:/etc/ldap/slapd.d -v /openldap/ldap:/var/lib/ldap -v /openldap/log:/var/log --name ldap2 --restart=always --log-driver syslog --log-opt syslog-address=tcp://127.0.0.1:514 --log-opt tag=ldap2 --hostname ldap2.example.com --add-host ldap1.example.com:192.168.137.128 --add-host ldap2.example.com:192.168.137.129 --env LDAP_ORGANISATION="example" --env LDAP_DOMAIN="example.com" --env LDAP_REPLICATION_HOSTS="#PYTHON2BASH:['ldap://ldap1.example.com','ldap://ldap2.example.com']" --env LDAP_REPLICATION=true --env LDAP_ADMIN_PASSWORD="111111" -p 389:389 --detach osixia/openldap:latest
docker run -d --restart=always --name ldap-account-manager -p 4389:80 --detach ldapaccountmanager/lam:latest

这里的example.com为openldap的域名,111111为admin的密码,192.168.138.128为第一台机器的ip地址用于两台机器的通讯互通。

到这里就完成了高可用openldap的搭建,接下来就要添加sudo模块和ppolicy模块

4.sudo模块添加

以下内容需要在两台机器上分别执行,本教程以ldap1为例
进入容器

docker exec -it ldap1 /bin/bash

填加sudo的overlay模块

cat<<EOF|ldapadd -Y EXTERNAL -H ldapi:///
dn: cn=sudo,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: sudo
olcAttributeTypes: {0}( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s
) who may  run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5Substrin
gsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {1}( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s
) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5Substring
sMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {2}( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Com
mand(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4
.1.1466.115.121.1.26 )
olcAttributeTypes: {3}( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(
s) impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3
.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {4}( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Opti
ons(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466
.115.121.1.26 )
olcAttributeTypes: {5}( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'U
ser(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.
1466.115.121.1.26 )
olcAttributeTypes: {6}( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC '
Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.
1.1466.115.121.1.26 )
olcAttributeTypes: {7}( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'S
tart of time interval for which the entry is valid' EQUALITY generalizedTim
eMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.12
1.1.24 )
olcAttributeTypes: {8}( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'En
d of time interval for which the entry is valid' EQUALITY generalizedTimeMa
tch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1
.24 )
olcAttributeTypes: {9}( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an i
nteger to order the sudoRole entries' EQUALITY integerMatch ORDERING intege
rOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
olcObjectClasses: {0}( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' DESC 'Sudoer
Entries' SUP top STRUCTURAL MUST cn MAY ( sudoUser $ sudoHost $ sudoCommand
$ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ su
doNotBefore $ sudoNotAfter $ description ) )
EOF

添加sudo功能

cat<<EOF|ldapadd -x -W -D "cn=admin,dc=example,dc=com"
dn: ou=SUDOers,dc=example,dc=com
ou: SUDOers
objectClass: top
objectClass: organizationalUnit

dn: cn=defaults,ou=SUDOers,dc=example,dc=com
objectClass: sudoRole
cn: defaults
sudoOption: requiretty
sudoOption: !visiblepw
sudoOption: always_set_home
sudoOption: env_reset
sudoOption: env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
sudoOption: env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
sudoOption: env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
sudoOption: env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
sudoOption: env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
sudoOption: secure_path = /sbin:/bin:/usr/sbin:/usr/bin
sudoOption: logfile = /var/log/sudo
EOF

并输入admin的密码111111,最后添加一个sudo的目录。用户为800001,之后用户可以用图形化的方法更改

cat<<EOF|ldapadd -x -W -D "cn=admin,dc=example,dc=com"
dn: cn=sudo_ops_role,ou=SUDOers,dc=example,dc=com
objectClass: sudoRole
cn: sudo_ops_role
sudoOption: !authenticate
sudoRunAsUser: root
sudoCommand: ALL
sudoHost: ALL
sudoUser: 800001
EOF

5.ppolicy密码模块

由于默认的ldap密码策略无法满足苛刻的生产环境于是乎需要添加ppolicy模块

cat<<EOF|ldapmodify -Y EXTERNAL -H ldapi:///
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: ppolicy.la
EOF

cat<<EOF|ldapmodify -Y EXTERNAL -H ldapi:///
dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
changeType: add
objectClass: olcOverlayConfig
objectClass: olcPPolicyConfig
olcOverlay: ppolicy
olcPPolicyDefault: cn=default,ou=ppolicy,dc=example,dc=com
olcPPolicyHashCleartext: TRUE
EOF

创建默认策略

cat<<EOF|ldapadd -x -W -D "cn=admin,dc=example,dc=com"
dn: ou=ppolicy,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: ppolicy

dn: cn=default,ou=ppolicy,dc=example,dc=com
cn: default
objectClass: top
objectClass: device
objectClass: pwdPolicy
objectClass: pwdPolicyChecker
pwdAllowUserChange: TRUE
pwdAttribute: userPassword
pwdCheckQuality: 2
pwdExpireWarning: 604800
pwdFailureCountInterval: 0
pwdGraceAuthnLimit: 5
pwdInHistory: 5
pwdLockout: TRUE
pwdLockoutDuration: 600
pwdMaxAge: 0
pwdMaxFailure: 5
pwdMinAge: 0
pwdMinLength: 8
pwdMustChange: FALSE
pwdSafeModify: FALSE
pwdCheckModule: check_password.so
EOF

添加密码审计功能

cat << EOF | ldapadd -Y EXTERNAL -H ldapi:///
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: auditlog

dn: olcOverlay=auditlog,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcAuditLogConfig
olcAuditlogFile: /var/log/slapd/auditlog.log
EOF

cat << EOF | ldapmodify -c -Y EXTERNAL -Q -H ldapi:///
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by dn="cn=admin,dc=example,dc=com" write by anonymous auth by * read
olcAccess: {1}to * by self write by dn="cn=admin,dc=example,dc=com" write by * read
EOF

至此就完成了服务器端的搭建接下来,就来介绍一下lam-admin的web管理

6.客户端访问 (对应客户端服务的ip+端口)

http://127.0.0.1:4389
登录前请进行相关设置,请参考以下设置规则

(1)先进行登录前的设置,点击右上角 LAM configuration 菜单进行设置

(2)点击 Edit server profiles 菜单,进行相关设置, 默认密码为 lam

(3)设置对应服务端IP和LDAP域名(IP为容器对应容器IP,内网ip:192.168.44.147或者公网IP,验证数据同步时,设置不同容器IP连接即可,LDAP域名要和容器运行时候设置 LDAP_DOMAIN 一致,格式为 dc=example,dc=com),和客户端管理员用户(默认admin)

(4)默认初始化两个组(这个可以不设置,注意格式为:ou=people,dc=example,dc=com ,ou可以自定义,dc要和容器运行时候设置 LDAP_DOMAIN 一致)

(5)点击模块设置建议勾选memberUid不然设置用户组时会报错

(6)设置完成后,进入首页进行登录,密码为容器运行时候设置 LDAP_ADMIN_PASSWORD 密码 111111

到这里服务器端配置就全部做完了,至于访问控制部分,建议还是通过堡垒机的方式去管理,经过测试目前有两种方式能通过openldap进行访问控制(基于主机名和基于用户组)。
基于主机名的话1.动态host经过测试有,host添加组后,由于bug无法成功同步到人。2.静态host的方式在实际管理起来过于复杂。
基于用户组的话一旦发生团队变动(合并或解散)时,需要更改所有服务器的客户端的配置,上千台生产服务器去动风险太大,不建议采用。
而通过堡垒机管理的话只需要在客户机上access文件上指定堡垒机的ip即可,省下的交给堡垒机即可。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: