LDAP

作者: Nick_4438 | 来源:发表于2021-11-27 16:06 被阅读0次

    什么是LDAP

    LDAP(Light Directory Access Portocol),它是基于X.500标准的轻量级目录访问协议。该协议可以提供目录服务。LDAP可以类比成为一个树形的数据库。其试用于更新少,读取多的场景,在软件系统中通常用来做一个统一的用户、组织管理。

    基本概念

    • DN (distinguished name),可以理解成为LDAP中各个资源定位的ID,类似于文件路径,这个路径通常包含DC (Domain Component)、OU (Organizational Unit)、CN (Common Name)
    • DC (Domain Component),域名元素,通常是树形的根位置
    • OU (Organizational Unit),组织单元,
    • CM(common name),对象属性的通用名
    • o (Organization Name),
    • uid(userid),

    LDAP的结构

    image.png

    在这里,我们举一个公司的例子,如上所示。

    • DN(Distinguished Name),数据的唯一标识,树形结构每个节点都有自己的唯一标识,如上图:
      • XXX集团 DN: dc=xxx集团,dc=com ,这是该树的根节点
      • 集团总部DN: dc=集团总部,dc=xxx集团,dc=com , 该节点的DN包含【 XXX集团 DN】的DN,所以可以看出这是【 XXX集团 DN】的子节点
      • 牛A公司DN: dc=牛A公司,dc=xxx集团,dc=com
      • 牛A公司研发部 DN: ou=研发部,ou=牛A公司,dc=xxx集团,dc=com
      • 牛A公司研发部 李四DN: cn=李四,cn=研发部,ou=牛A公司,dc=xxx集团,dc=com

    容器openladp使用

    • 启动 openldap
    # 挂载目录运行
    docker run -itd -p 389:389 --name openldap \
    -v /opt/data/ldap/database:/var/lib/ldap \
    -v /opt/data/ldap/config:/etc/openldap/slapd.d \
    --env LDAP_ORGANISATION="xyz" \
    --env LDAP_DOMAIN="xyz.com" \
    --env LDAP_ADMIN_PASSWORD="qiu11211" \
    --detach osixia/openldap:1.5.0
    # 测试,不挂载目录
    docker run -itd -p 389:389 --name openldap \
    --env LDAP_ORGANISATION="xyz" \
    --env LDAP_DOMAIN="xyz.com" \
    --env LDAP_ADMIN_PASSWORD="qiu11211" \
    --detach osixia/openldap:1.5.0
    

    配置LDAP组织者:LDAP_ORGANISATION
    配置LDAP域:LDAP_DOMAIN
    配置LDAP密码:LDAP_ADMIN_PASSWORD
    默认登录用户名:admin

    • 启动phpldapadmin,其中10.54.16.23为openldap的启动IP
    docker run -p 6443:443 \
            --env PHPLDAPADMIN_LDAP_HOSTS=192.168.3.156 \
            --detach osixia/phpldapadmin:0.9.0
    
    login DN :cn=admin,dc=xyz,dc=com
    Password: qiu11211
    
    • 可以自页面上创建操作节点

    导入

    在PHPLDAPadmin上可以导入组织架构,如下是一个例子:


    image.png
    dn: dc=gdy, dc=com 
    dc: gdy  
    objectClass: top  
    objectClass: domain  
     
    dn: ou=people, dc=gdy, dc=com 
    ou: people  
    objectClass: top  
    objectClass: organizationalUnit  
     
    dn: ou=group, dc=gdy, dc=com 
    ou: group  
    objectClass: top  
    objectClass: organizationalUnit  
    
    

    列子代码

    • 登录验证LDAP
    package main
    
    import (
        "fmt"
        "github.com/go-ldap/ldap/v3"
    )
    
    func main() {
        con, err := LoginBind("admin","qiu11211")
        fmt.Println(con.IsClosing())
        if err != nil {
            fmt.Println("V")
            fmt.Println(err)
        }
        fmt.Println("Exit")
    }
    // LoginBind  connection ldap server and binding ldap server
    func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
        l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
        if err != nil {
            fmt.Errorf("conect error",err)
            return nil, err
        }
        _, err = l.SimpleBind(&ldap.SimpleBindRequest{
            Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
            Password: ldapPassword,
        })
        if err != nil {
            fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
            return nil, err
        }
        fmt.Println(ldapUser,"登录成功")
        return l, nil
    }
    
    • 添加用户例子
    package main
    
    import (
        "fmt"
        "github.com/go-ldap/ldap/v3"
    )
    type User struct {
        username    string
        password    string
        telephone   string
        emailSuffix string
        snUsername  string
        uid         string
        gid         string
    }
    
    func main() {
        fmt.Println("hello 1")
        con, err := LoginBind("admin","qiu11211")
        fmt.Println(con.IsClosing())
        if err != nil {
            fmt.Println("V")
            fmt.Println(err)
        }
        //1. add user
        var user User
        user.username="nick"
        user.password="admin123"
        user.snUsername="nick"
        user.uid="1000"
        user.gid="1000"
        user.emailSuffix="@qq.com"
        if err=user.addUser(con);err!=nil{
            fmt.Println(err)
        }
        fmt.Println("exit")
    
        //1. add user
        //var user1 User
        //user1.username="邱家洪"
        //user1.password="admin123"
        //user1.snUsername="邱家洪"
        //user1.uid="1000"
        //user1.gid="1000"
        //user1.emailSuffix="@qq.com"
        //if err=user1.addUser(con);err!=nil{
        //  fmt.Println(err)
        //}
    
    }
    // LoginBind  connection ldap server and binding ldap server
    func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
        l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
        //l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", 389))
        if err != nil {
            fmt.Errorf("conect error",err)
            return nil, err
        }
        _, err = l.SimpleBind(&ldap.SimpleBindRequest{
            Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
            Password: ldapPassword,
        })
        if err != nil {
            fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
            return nil, err
        }
        fmt.Println(ldapUser,"登录成功")
        return l, nil
    }
    func (user *User) addUser(conn *ldap.Conn) error {
        ldaprow := ldap.NewAddRequest(fmt.Sprintf("cn=%s,dc=demo,dc=com", user.username), nil)
        ldaprow.Attribute("userPassword", []string{user.password})
        ldaprow.Attribute("homeDirectory", []string{fmt.Sprintf("/home/%s", user.username)})
        ldaprow.Attribute("cn", []string{user.username})
        ldaprow.Attribute("uid", []string{user.username})
        ldaprow.Attribute("objectClass", []string{"shadowAccount", "posixAccount", "account"})
        ldaprow.Attribute("uidNumber", []string{"2201"})
        ldaprow.Attribute("gidNumber", []string{"2201"})
        ldaprow.Attribute("loginShell", []string{"/bin/bash"})
    
        if err := conn.Add(ldaprow); err != nil {
            return err
        }
        return nil
    }
    
    
    • 删除用户
    package main
    
    import (
        "fmt"
        "github.com/go-ldap/ldap/v3"
    )
    type User struct {
        username    string
        password    string
        telephone   string
        emailSuffix string
        snUsername  string
        uid         string
        gid         string
    }
    func main() {
        fmt.Println("hello 1")
        con, err := LoginBind("admin","qiu11211")
        fmt.Println(con.IsClosing())
        if err != nil {
            fmt.Println("V")
            fmt.Println(err)
        }
        var user User
        user.username="marionxue"
        if err:=user.delUser(con);err!=nil{
            fmt.Println("用户删除失败")
        }
        fmt.Println(user.username,"用户删除成功!")
    }
    // LoginBind  connection ldap server and binding ldap server
    func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
        l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
        //l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", 389))
        if err != nil {
            fmt.Errorf("conect error",err)
            return nil, err
        }
        _, err = l.SimpleBind(&ldap.SimpleBindRequest{
            Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
            Password: ldapPassword,
        })
        if err != nil {
            fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
            return nil, err
        }
        fmt.Println(ldapUser,"登录成功")
        return l, nil
    }
    
    func (user *User) delUser(conn *ldap.Conn) error{
        ldaprow := ldap.NewDelRequest(fmt.Sprintf("cn=%s,dc=demo,dc=com",user.username),nil)
    
        if err:= conn.Del(ldaprow);err!=nil{
            return err
        }
        return nil
    }
    
    
    • 遍历所有用户
    package main
    
    import (
        "fmt"
        "github.com/go-ldap/ldap/v3"
        "strings"
    )
    type User struct {
        username    string
        password    string
        telephone   string
        emailSuffix string
        snUsername  string
        uid         string
        gid         string
    }
    
    func main() {
        fmt.Println("hello 1")
        con, err := LoginBind("admin","qiu11211")
        fmt.Println(con.IsClosing())
        if err != nil {
            fmt.Println("V")
            fmt.Println(err)
        }
        //2. 遍历用户
        employees, err := GetEmployees(con)
        if err != nil {
            fmt.Println(err)
        }
        for _, employe := range employees {
            fmt.Println(employe)
        }
    }
    // LoginBind  connection ldap server and binding ldap server
    func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
        l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
        //l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", 389))
        if err != nil {
            fmt.Errorf("conect error",err)
            return nil, err
        }
        _, err = l.SimpleBind(&ldap.SimpleBindRequest{
            Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
            Password: ldapPassword,
        })
        if err != nil {
            fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
            return nil, err
        }
        fmt.Println(ldapUser,"登录成功")
        return l, nil
    }
    
    
    func GetEmployees(con *ldap.Conn) ([]string, error) {
        var employees []string
        sql := ldap.NewSearchRequest("dc=demo,dc=com",
            ldap.ScopeWholeSubtree,
            ldap.NeverDerefAliases,
            0,
            0,
            false,
            "(objectClass=*)",
            []string{"dn", "cn", "objectClass"},
            nil)
    
        cur, err := con.Search(sql)
        if err != nil {
            return nil, err
        }
    
        if len(cur.Entries) > 0 {
            for _, item := range cur.Entries {
                cn := item.GetAttributeValues("cn")
                for _, iCn := range cn {
                    employees = append(employees, strings.Split(iCn, "[")[0])
                }
            }
            return employees, nil
        }
        return nil, nil
    }
    
    
    • 添加组
    package main
    
    import (
        "fmt"
        "github.com/go-ldap/ldap/v3"
    )
    type Group struct {
        username    string
    }
    
    func main() {
        fmt.Println("hello 1")
        con, err := LoginBind("admin","qiu11211")
        fmt.Println(con.IsClosing())
        if err != nil {
            fmt.Println("V")
            fmt.Println(err)
        }
        //1. add user
        var g Group
        g.username="crqu"
        if err=g.addGroup(con);err!=nil{
            fmt.Println(err)
        }
        fmt.Println("exit")
    
    }
    // LoginBind  connection ldap server and binding ldap server
    func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
        l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
        if err != nil {
            fmt.Errorf("conect error",err)
            return nil, err
        }
        _, err = l.SimpleBind(&ldap.SimpleBindRequest{
            Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
            Password: ldapPassword,
        })
        if err != nil {
            fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
            return nil, err
        }
        fmt.Println(ldapUser,"登录成功")
        return l, nil
    }
    //dn: ou=crqu,dc=demo,dc=com
    //objectclass: organizationalUnit
    //ou: crqu
    func (group *Group) addGroup(conn *ldap.Conn) error {
        ldaprow := ldap.NewAddRequest(fmt.Sprintf("ou=%s,dc=demo,dc=com", group.username), nil)
        ldaprow.Attribute("objectClass", []string{"organizationalUnit"})
        ldaprow.Attribute("ou", []string{group.username})
        if err := conn.Add(ldaprow); err != nil {
            return err
        }
        return nil
    }
    
    
    • 在新的组上面添加用户,含密码
    package main
    
    import (
        "fmt"
        "github.com/go-ldap/ldap/v3"
    )
    type User struct {
        username    string
    }
    
    func main() {
        fmt.Println("hello 1")
        con, err := LoginBind("admin","qiu11211")
        fmt.Println(con.IsClosing())
        if err != nil {
            fmt.Println("V")
            fmt.Println(err)
        }
        //1. add user
        var g User
        g.username="ming"
        if err=g.addUser(con);err!=nil{
            fmt.Println(err)
        }
        fmt.Println("exit")
    
    }
    // LoginBind  connection ldap server and binding ldap server
    func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
        l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
        if err != nil {
            fmt.Errorf("conect error",err)
            return nil, err
        }
        _, err = l.SimpleBind(&ldap.SimpleBindRequest{
            Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
            Password: ldapPassword,
        })
        if err != nil {
            fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
            return nil, err
        }
        fmt.Println(ldapUser,"登录成功")
        return l, nil
    }
    //dn: cn=nick,ou=crqu,dc=demo,dc=com
    //cn: nick
    //givenname: nick
    //objectclass: inetOrgPerson
    //objectclass: top
    //sn: nick
    func (group *User) addUser(conn *ldap.Conn) error {
        ldaprow := ldap.NewAddRequest(fmt.Sprintf("cn=%s,ou=crqu,dc=demo,dc=com", group.username), nil)
        ldaprow.Attribute("objectClass", []string{"inetOrgPerson","top"})
        ldaprow.Attribute("cn", []string{group.username})
        ldaprow.Attribute("givenname", []string{group.username})
        ldaprow.Attribute("sn", []string{group.username})
        // hua
        ldaprow.Attribute("userpassword", []string{"{MD5}pP2/vmpo8KAIjC2YxkRzEQ=="})
        if err := conn.Add(ldaprow); err != nil {
            return err
        }
        return nil
    }
    
    

    相关文章

      网友评论

          本文标题:LDAP

          本文链接:https://www.haomeiwen.com/subject/clafxrtx.html