ldap在开源平台中的应用

  • LDAP结构
  • phpldapadmin导入groupOfUniqueNames
  • ldap的备份迁移恢复(docker部署)
  • Jenkins
  • 配置jenkins的ldap服务
  • Role-Based Strategy
  • Gitlab
  • Self Service Password自助修改密码服务
  • ldap对接jumpserver
  • 对接zabbix
  • 对接npm私有仓库verdaccio
  • 对接YAPI


LDAP结构


简单的人员划分大致如下:

- ou=service
	- ou=jenkins
	- ou=gitlab
	- ou=禅道
	- ou=...
- ou=人事行政
	- ou=人事
		- cn=人员1
		- ...
	- ou=行政
		- cn=人员1
		- ...
- ou=销售运营
	- ou=销售
		- cn=人员1
		- ...
	- ou=运营
		- cn=人员1
		- ...
- ou=研发
	- ou=开发
		- cn=人员1
		- ...
	- ou=测试
		- cn=人员1
		- ...
	- ou=运维
		- cn=人员1
		- ...
- ou=管理层
- ou=试用期
  • 常用结构
  • o:公司
  • c:国家
  • dn: o=company_name,c=China
  • ou:部门
  • 部分划分为:普通职员和管理人员.例如:

    dn: ou=Managers,o=company,c=china
    dn: ou=Employees,o=company,c=china

phpldapadmin导入groupOfUniqueNames

# dn: cn=jumpserver,ou=Group,dc=duanyiwen,dc=com
# objectClass: groupOfUniqueNames
# cn: jumpserver
# description: 堡垒机
# uniqueMember: cn=dyiwen,cn=test,ou=People,dc=duanyiwen,dc=com
# cn=段义文,ou=People,dc=duanyiwen,dc=com

ldap的备份迁移恢复(docker部署)

  • 1.备份
  • a.根据文件备份
volumes:
      - /data/d-server/public/ldap/database:/var/lib/ldap
      - /data/d-server/public/ldap/config:/etc/ldap/slapd.d
  • 定时备份即可tar czvf openldap-backup-`date +%Y_%m_%d_%H_%M`.tar ./database ./config
  • b.ldapsearch命令备份
    查询:docker exec openldap ldapsearch -x -b 'dc=duanyiwen,dc=com' -D "cn=admin,dc=duanyiwen,dc=com" -w 管理员密码 > ldapbackup.ldif-b:查询分支
    备份:docker exec openldap ldapsearch -x -b 'dc=duanyiwen,dc=com' -D "cn=admin,dc=duanyiwen,dc=com" -w 管理员密码 > ldapbackup.ldif
  • 3.清空模拟出错
    ldapdelete -x -D "cn=admin,dc=duanyiwen,dc=com" -w 管理员密码 -r "dc=duanyiwen,dc=com"-r:指定需要删除的分支
  • 4.导入数据
    ldapadd -x -D "cn=admin,dc=duanyiwen,dc=com" -w 管理员密码 -f 备份文件地址 -c-c:连续执行,跳过报错

Jenkins

  • 安装 LDAP 插件
  • LDAP Plugin
  • Role-based Authorization Strategy

配置jenkins的ldap服务

  • Configure Global Security>Access Control>LDAP

    server:ldap服务地址
    root DN:LDAP根DN,配置该项后下面的字段可以省略DN
    User search base:从哪一级下匹配用户
    User search filter:用户搜索过滤语句,我所填写的意思是,搜索研发组下加入jenkins组的用户,用uid替换该用户名称
    (&(uid={0})(memberof=cn=jenkins,ou=group,dc=duanyiwen,dc=com))
    Group search base:组搜索,用户量大后优化查询速度
    Group search filter:组过滤,优化查询速度
    Group memebership:组人员关系
    Manager DN: LDAP管理员账号
    Manager Password:LDAP管理员密码
    Display Name LDAP attribute:用什么属性来展示用户的姓名,我用的是cn,test时可以看到测试日志
    Email Address LDAP attribute: 用什么属性来展示用户的邮箱
    Environment Properties:添加环境变量
    Ignore if Unavailable:加入配置了多个LDAP服务,选中此项,上一个访问LDAP服务发生错误则会跳过继续尝试下一个服务地址
  • 测试配置是否正常

    输入一个你希望其能够登录JENKINS服务的LDAP账号

Role-Based Strategy

  • 打开功能
    JenkinsConfigure-Global Security-Access Control-Authorization
  • jira接入ldap后管理员没有权限登录 ldap管理员dn_php


  • 配置用户权限划分
    Manage and Assign Roles
  • jira接入ldap后管理员没有权限登录 ldap管理员dn_Group_02

  • Manage Roles:管理用户,事实上可看作设置用户组
    Assign Roles:分配用户,将用户分配到用户组中
    Role Strategy Macros:用的少
  • 管理用户
    我装的插件是老版的

    举例:大致就分为3个组
  • 全局配置
  • admin:管理员组(全局管理权限)
  • dev_roles:开发组(全局读权限)
  • test_roles:测试组(全局读权限)
  • 项目配置
    test_roles:测试项目分组,正则(?i)test-.*?,让处于该组中的人员能够查看到以test-(忽略大小写)开头的项目,并具有相关配置权限
  • 分配角色

    解释:让duanyiwen具有全局管理权限,test1具有全局测试项目的查看权限,xiaohong具有全局开发项目的查看权限。
    具体项目分组,让xiaohong加入test组,可以查看管理以test开头的项目。同理可以做其他分组配置。

Gitlab


  • 配置
GITLAB_OMNIBUS_CONFIG: |
          gitlab_rails['ldap_enabled'] = true
          gitlab_rails['ldap_servers'] = YAML.load <<-'EOS'
            main:
              lable: 'LDAP'
              host: openldap
              port: 389
              uid: 'cn'
              method: 'plain'
              bind_dn: "cn=admin,dc=duanyiwen,dc=com"
              password: '*******'
              allow_username_or_email_login: false
              base: 'ou=研发,dc=duanyiwen,dc=com'
              user_filter: 'memberof=cn=gitlab,ou=service,dc=duanyiwen,dc=com'
              attributes:
                username: ['uid']
                email: ['mail']
                first_name: 'sn'
          EOS

比较重要的属性:
uid:'cn':该字段用来规定gitlab的登录用户名,‘cn’,‘sn’,‘uid’ 等都可以
base:ou=研发,dc=duanyiwen,dc=com:即匹配ldap中研发目录下的用户
user_filter: memberof=cn=gitlab,ou=group,dc=duanyiwen,dc=com:即匹配加入了gitlab组的用户

  • 测试命令:
#内容编辑完成之后,需要使用命令配置重置
gitlab-ctl reconfigure
#重启服务
gitlab-ctl restart
#测试获取AD域用户列表:
sudo gitlab-rake gitlab:ldap:check

Self Service Password自助修改密码服务

  • 资源地址

官网:https://ltb-project.org/doku.php
官网下载:http://ltb-project.org/wiki/download
github:http://ltb-project.org/wiki/download

  • 安装
  • 配置Self Service Password的yum仓库源,如下:
cat >> /etc/yum.repos.d/ltb-project.repo << “EOF”

[ltb-project-noarch]

name=LTB project packages (noarch)

baseurl=https://ltb-project.org/rpm/$releasever/noarch

enabled=1

gpgcheck=0

gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-LTB-	project

EOF

yum -y install self-service-password
  • 或直接yum安装:

yum install php70-ldap.x86_64 -y(版本尽量大于5.3,否则会提示更新php程序)

yum install httpd -y

  • 查询安装地址
    rpm -ql self-service-password

/etc/httpd/conf.d/self-service-password.conf

/usr/share/self-service-password

/usr/share/self-service-password/conf
/usr/share/self-service-password/conf/config.inc.php

/usr/share/self-service-password/css

/usr/share/self-service-password/css/bootstrap-theme.css.map

  • 配置
  • 配置apache
cat /etc/httpd/conf.d/self-service-password.conf

-----------------------------------
NameVirtualHost *
<VirtualHost *>
    	ServerName ssp.example.com

    	DocumentRoot /usr/share/self-service-password
    	DirectoryIndex index.php

    	AddDefaultCharset UTF-8
    	<Directory "/usr/share/self-service-password">
            	AllowOverride None
            	Require all granted
    	</Directory>
    	LogLevel warn
    	ErrorLog /var/log/httpd/ssp_error_log
    	CustomLog /var/log/httpd/ssp_access_log combined
</VirtualHost>
  • 官方配置样板

apache:https://ltb-project.org/documentation/self-service-password/1.2/config_apache
nginx:https://ltb-project.org/documentation/self-service-password/1.2/config_nginx

  • Self Service Password配置文件

官方帮助文档

https://ltb-project.org/documentation/self-service-password/1.2/config_ldaphttps://ltb-project.org/documentation/self-service-password/1.2/start

cat vim /usr/share/self-service-password/conf/config.inc.php
#######LDAP配置
 26 # Debug mode
27 # true: log and display any errors or warnings (use this in configuration/testing)
28 # false: log only errors and do not display them (use this in production)
29 $debug = true;
30 
31 # LDAP
################ldap服务地址
32 $ldap_url = "ldap://192.168.78.13:389";
################ldap是否开启ssl/tsl
33 $ldap_starttls = false;
############ldap管理员账号
34 $ldap_binddn = "cn=admin,dc=duanyiwen,dc=com";
###########ldap管理员密码
35 $ldap_bindpw = "xxxxxxxx";
##########开始获取用户的根节点
36 $ldap_base = "dc=duanyiwen,dc=com";
#########以什么属性做为登录账号
37 $ldap_login_attribute = "uid";
########以什么属性作为用户全称
38 $ldap_fullname_attribute = "cn";
########ldap过滤语句
39 $ldap_filter = "(&(objectClass=inetOrgPerson)($ldap_login_attribute={login}))";
######邮箱设置
175 $mail_address_use_ldap = false;
176 # Who the email should come from
177 $mail_from = "dyiwen@aliyun.com";
178 $mail_from_name = "企业账号密码重置";
179 $mail_signature = "";
180 # Notify users anytime their password is changed
181 $notify_on_change = true;
182 # PHPMailer configuration (see https://github.com/PHPMailer/PHPMailer)
183 $mail_sendmailpath = '/usr/sbin/sendmail';
184 $mail_protocol = 'smtp';                                                                                                                                                  
185 $mail_smtp_debug = 0;
186 $mail_debug_format = 'html';
187 $mail_smtp_host = 'smtp.aliyun.com';
188 $mail_smtp_auth = true;
189 $mail_smtp_user = 'dyiwen@aliyun.com';
190 $mail_smtp_pass = 'xxxxxxxx';
191 $mail_smtp_port = 465;
192 $mail_smtp_timeout = 30;
193 $mail_smtp_keepalive = false;
##########重点字段,默认tls,会引发php的bug,注意改为ssl
194 $mail_smtp_secure = 'ssl';
195 $mail_contenttype = 'text/plain';
196 $mail_wordwrap = 0;
197 $mail_charset = 'utf-8';
198 $mail_priority = 3;
199 $mail_newline = PHP_EOL;
  • 启动服务
    systemctl restart httpd
  • 查看日志
    tail -f /var/log/httpd/*_log
  • 可以用我做的镜像
version: '3.1'
services:
  ldap_pwc:
    restart: always
    image: registry.cn-hangzhou.aliyuncs.com/dyiwen/ldap:self-service-password
    container_name: ldap_pwc
    ports:
      - 80:80
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - /data/docker/compose_file_management/conf:/home/web/conf
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "1"

dockerfile脚本命令

#重启,停止php-fpm
INT, TERM 立刻终止
QUIT 平滑终止
USR1 重新打开日志文件
USR2 平滑重载所有worker进程并重新载入配置和二进制模块
例如:
kill -USR2 42891

我的git地址https://gitee.com/dyiwen/compose_file_management/tree/self-password-web

ldap对接jumpserver

jira接入ldap后管理员没有权限登录 ldap管理员dn_git_03


这里的一个坑即是用户memberof过滤语句,官网没有示例,和其他开源平台的过滤语法又不相同,需要按照我这里的格式(&(uid=%(user)s)(memberof=cn=jumpserver,ou=Group,dc=xxx,dc=xxx))这样去写,可以匹配。

  • ldap认证源码分析
.....
    def get_search_filter_extra(self):
        extra = ''
        if self.search_users:
            mapping_username = self.config.attr_map.get('username')
            for user in self.search_users:
                extra += '({}={})'.format(mapping_username, user)
            return '(|{})'.format(extra)
        if self.search_value:
            for attr in self.config.attr_map.values():
                extra += '({}={})'.format(attr, self.search_value)
            return '(|{})'.format(extra)
        return extra

    def get_search_filter(self):
        search_filter = self.config.search_filter % {'user': '*'}
        search_filter_extra = self.get_search_filter_extra()
        if search_filter_extra:
            search_filter = '(&{}{})'.format(search_filter, search_filter_extra)
        return search_filter

    def search_user_entries_ou(self, search_ou, paged_cookie=None):
        search_filter = self.get_search_filter()
        attributes = list(self.config.attr_map.values())
        self.connection.search(
            search_base=search_ou, search_filter=search_filter,
            attributes=attributes, paged_size=self._paged_size,
            paged_cookie=paged_cookie
        )
.....

事实上关键就在这个地方search_filter = self.config.search_filter % {'user': '*'},等同于search_filter = "(&(uid=%(user)s)(memberof=cn=jumpserver,ou=Group,dc=xxxx,dc=xxx))" % {"user":"*"},self.search_usersself.search_value初始化为NONE,看不出来是用来干嘛的。

  • 多用户OU过滤可以这样写
ou=jumpserver,dc=jumpserver,dc=org | ou=user,dc=jumpserver,dc=org | ou=xxx,dc=jumpserver,dc=org

对接zabbix

zabbix集成ldap只是使用了ldap的密码验证功能,ldap和zabbix平台上均需要创建同名用户

jira接入ldap后管理员没有权限登录 ldap管理员dn_ldap_04

对接npm私有仓库verdaccio

auth:
  ldap:
    type: ldap
    client_options:
      url: "ldap://172.xx.x.1:389"
      # Only required if you need auth to bind
      adminDn: "cn=admin,dc=dyiwen,dc=com"
      adminPassword: "dyiwen123"
      # Search base for users
      searchBase: "cn=产品研发,ou=People,dc=dyiwen,dc=com"
      searchFilter: "(&(uid={{username}})(memberof=cn=verdaccio,ou=Group,dc=dyiwen,dc=com))"
      # If you are using groups, this is also needed
      groupDnProperty: 'uid'
      groupSearchBase: 'cn=verdaccio,ou=Group,dc=dyiwen,dc=com'
      # If you have memberOf support on your ldap
      #searchAttributes: ['*', 'memberOf']
      searchAttributes: ['memberOf']
      # Else, if you don't (use one or the other):
      #groupSearchFilter: '(memberUid={{uid}})'
      #
      # Optional, default false.
      # If true, then up to 100 credentials at a time will be cached for 5 minutes.
      cache: false
      # Optional
      reconnect: true

# a list of other known repositories we can talk to
uplinks:
  npmjs:
    url: http://registry.npm.taobao.org/
    #url: https://registry.npmjs.org/

对接YAPI

"ldapLogin": {
    "enable": true,
    "server": "ldap://127.0.0.1",
    "baseDn": "CN=admin,DC=duanyiwen,DC=com",
    "bindPassword": "xxxxxxxx",
    "searchDn": "CN=产品研发,OU=People,DC=duanyiwen,DC=com",
    "searchStandard": "uid",
    "emailKey": "uid",
    "usernameKey": "cn"
  }