Mastering Go-LDAP: Connect, Manage, and Secure LDAP with Go
Learn how to use the Go‑ldap library to connect to an LDAP server, set up a Docker‑based LDAP environment, and perform core operations such as creating, listing, deleting users and checking weak passwords, complete with full code examples and optimization tips.
1 Go Connect LDAP Service
Use the go-ldap package, which implements LDAP v3 functions such as connecting, adding, deleting, and modifying user entries, and supports conditional searches.
2 Download
go get github.com/go-ldap/ldap/v3
go get github.com/wxnacy/wgo/arraysDocumentation can be found at gopkg.in/[email protected]#section-readme.
3 Prepare LDAP Environment
Run a temporary LDAP instance with docker‑compose:
version: "3"
services:
ldap:
image: osixia/openldap:latest
container_name: openldap
hostname: openldap
restart: always
environment:
- "LDAP_ORGANISATION=devopsman"
- "LDAP_DOMAIN=devopsman.cn"
- "LDAP_BASE_DN=dc=devopsman,dc=cn"
- "LDAP_ADMIN_PASSWORD=admin123"
ports:
- 389:389
- 636:636Modify environment variables as needed. The image can be found on hub.docker.com.
4 GO‑LDAP Example
Create User
Use Add and NewAddRequest to create a user. First bind to the server with an account that has creation rights.
// LoginBind connection ldap server and binding ldap server
func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
l, err := ldap.DialURL(ldapURL)
if err != nil {
return nil, err
}
_, err = l.SimpleBind(&ldap.SimpleBindRequest{
Username: fmt.Sprintf("cn=%s,dc=devopsman,dc=cn", ldapUser),
Password: ldapPassword,
})
if err != nil {
fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
return nil, err
}
fmt.Println(ldapUser, "登录成功")
return l, nil
}Define a User struct with required fields.
type User struct {
username string
password string
telephone string
emailSuffix string
snUsername string
uid string
gid string
}Implement addUser using NewAddRequest.
func (user *User) addUser(conn *ldap.Conn) error {
ldaprow := ldap.NewAddRequest(fmt.Sprintf("cn=%s,dc=devopsman,dc=cn", 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
}Instantiate User and call addUser.
func main() {
con, err := LoginBind("admin", "admin123")
fmt.Println(con.IsClosing())
if err != nil {
fmt.Println("V")
fmt.Println(err)
}
var user User
user.username = "marionxue"
user.password = "admin123"
user.snUsername = "Marionxue"
user.uid = "1000"
user.gid = "1000"
user.emailSuffix = "@qq.com"
if err = user.addUser(con); err != nil {
fmt.Println(err)
}
fmt.Println(user.username, "创建完成!")
}Running the program creates the user.
List Users
Reuse LoginBind and implement GetEmployees to search the directory.
func GetEmployees(con *ldap.Conn) ([]string, error) {
var employees []string
sql := ldap.NewSearchRequest(
"dc=devopsman,dc=cn",
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
}Print the retrieved usernames.
func main() {
con, err := LoginBind("admin", "admin123")
if err != nil {
fmt.Println("V")
fmt.Println(err)
}
employees, err := GetEmployees(con)
if err != nil {
fmt.Println(err)
}
for _, employe := range employees {
fmt.Println(employe)
}
}Delete User
Implement delUser using NewDelRequest.
// delUser 删除用户
func (user *User) delUser(conn *ldap.Conn) error {
ldaprow := ldap.NewDelRequest(fmt.Sprintf("cn=%s,dc=devopsman,dc=cn", user.username), nil)
if err := conn.Del(ldaprow); err != nil {
return err
}
return nil
}Call delUser in main after binding.
func main() {
con, err := LoginBind("admin", "admin123")
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, "用户删除成功!")
}Weak Password Check
Because LDAP does not store passwords in plain text, a dictionary‑based login attempt can identify weak passwords.
func CheckPassword(employe string) {
// 遍历的弱密码字典
f, err := os.Open("~/dict.txt")
if err != nil {
fmt.Println("reading dict.txt error: ", err)
}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
weakpassword := scanner.Text()
_, err := LoginBind(employe, weakpassword)
if err == nil {
fmt.Println(employe + " 使用的密码为: " + weakpassword)
}
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
fmt.Println(employe + " check have already finished. and the password is stronger well.")
}Combine enumeration and checking, skipping whitelisted accounts.
func main() {
con, err := LoginBind("admin", "admin123")
if err != nil {
fmt.Println("V")
fmt.Println(err)
}
employees, err := GetEmployees(con)
if err != nil {
fmt.Println(err)
}
Whitelist := []string{"zhangsan", "lisi"}
for _, employe := range employees {
fmt.Println("Starting check: ", employe)
if index := arrays.ContainsString(Whitelist, employe); index == -1 {
CheckPassword(employe)
} else {
fmt.Println(employe + " in whitelist. skiping...")
}
}
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
