---
# System prepended metadata

title: 2. Config OpenLdap Master-Master
tags: [LDAP-Series, ' Configure', ' Tutorial']

---

---
slideOptions:
  transition: slide
  theme: night
tags: LDAP-Series, Configure, Tutorial
type: 
title: 2. Config OpenLdap Master-Master
---
<style>
    .reveal section img {
        background: transparent!important;
        border: none!important;
        box-shadow: none!important;
    }
</style>

# Cấu hình triển khai OpenLdap theo mô hình Master-Master

## Tổng quan
Tài liệu này hướng dẫn cấu hình openLdap theo mô hình Master-Master. Mô hình Master-Master áp dụng trong trường hợp tải cao khi yêu cầu ghi vào openLdap nhiều trong khi mô hình Master-Slave thì chỉ có thể ghi vào một node duy nhất là node Master. Với mô hình Master-Master, dữ liệu có thể ghi vào bất cứ node nào. Đây là mô hình nhằm cải thiện hiệu năng WRITE vào openLdap tăng tính sẵn sàng cho dịch vụ
    
![](https://i.imgur.com/V0WDcm2.png)

----

## Chuẩn bị
- Cài trên 2 server tương đương với 2 node với cấu hình như sau:
    - <b>Node 1:</b>
    > HostName: ldap-01(Master)
    > CPU: 2 cores
    > Ram: 2Gb
    > Disk: 30Gb
    > Network: eth0: Network access (192.168.1.18)
    - <b>Node 2:</b>
    > HostName: ldap-02(Master)
    > CPU: 2 cores
    > Ram: 2Gb
    > Disk: 30Gb
    > Network: eth0: Network access (192.168.1.19)

----

## Cài đặt

### Cài đặt OpenLdap
- Cài đặt OpenLdap theo hướng dẫn tại đây: [Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-openldap-and-phpldapadmin-on-ubuntu-16-04) | [Windows](https://www.maxcrc.de/userbooster/)

----

### Cấu hình bổ sung tại tất cả các node
- Bước 1: Kích hoạt <b><i>module syncprov</i></b>
```ssh
cat > mod_syncprov.ldif << EOF
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib64/openldap
olcModuleLoad: syncprov.la
EOF

ldapadd -Y EXTERNAL -H ldapi:/// -f mod_syncprov.ldif
```
Kết quả:
```ssh
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=module,cn=config"
```
- Bước 2: Cho phép <b><i>module syncprov</i></b> hoạt động trên DB LDAP
```ssh
cat > syncprov.ldif << EOF
dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpSessionLog: 100
EOF

ldapadd -Y EXTERNAL -H ldapi:/// -f syncprov.ldif
```
Kết quả:
```ssh
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "olcOverlay=syncprov,olcDatabase={2}hdb,cn=config"
```
----

### Cấu hình node Master01
<b><u>Lưu ý:</u></b>
    - Trong mô hình mình có 2 node, Master-01 (Ip: 192.168.1.18) và Master-02 (Ip: 192.168.1.19)
    - Tại Node Master-01 sẽ khai báo cấu hình cho phép nhân bản dữ liệu lên node Master-02(master02.ldif)
    - Tại Node Master-02 sẽ khai báo cấu hình cho phép nhân bản dữ liệu lên node Master-01(master01.ldif)
    
<b><u>Lưu ý file cấu hình:</u></b>
- <b>`olcServerID`</b>: Phải là duy nhất định danh cho node openLdap. Với <b>Master-01</b>, ta sẽ định nghĩa là <b><i>`oclServerID: 1`</i></b>, với <b>Master-02</b>, ta sẽ định nghĩa là <b><i>`oclServerID: 2`</i></b>

<b><u>Cấu hình:</u></b>
```ssh
cat > master02.ldif << EOF
dn: cn=config
changetype: modify
replace: olcServerID
olcServerID: 1

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001
  provider=ldap://192.168.1.18:389/
  bindmethod=simple
  binddn="cn=Manager,dc=nhanhoa,dc=local"
  credentials=*****
  searchbase="dc=nhanhoa,dc=local"
  scope=sub
  schemachecking=on
  type=refreshAndPersist
  retry="30 5 300 3"
  interval=00:00:05:00
-
add: olcMirrorMode
olcMirrorMode: TRUE

dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
EOF

ldapmodify -Y EXTERNAL -H ldapi:/// -f master96.ldif
```
Kết quả:
```ssh
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"

modifying entry "olcDatabase={2}hdb,cn=config"

adding new entry "olcOverlay=syncprov,olcDatabase={2}hdb,cn=config"
```
----

### Cấu hình node Master02
<b><u>Lưu ý:</u></b>
    - Trong mô hình mình có 2 node, Master-01 (Ip: 192.168.1.18) và Master-02 (Ip: 192.168.1.19)
    - Tại Node Master-01 sẽ khai báo cấu hình cho phép nhân bản dữ liệu lên node Master-02(master02.ldif)
    - Tại Node Master-02 sẽ khai báo cấu hình cho phép nhân bản dữ liệu lên node Master-01(master01.ldif)
    
<b><u>Lưu ý file cấu hình:</u></b>
- <b>`olcServerID`</b>: Phải là duy nhất định danh cho node openLdap. Với <b>Master-01</b>, ta sẽ định nghĩa là <b><i>`oclServerID: 1`</i></b>, với <b>Master-02</b>, ta sẽ định nghĩa là <b><i>`oclServerID: 2`</i></b>

<b><u>Cấu hình:</u></b>
```ssh
cat > master01.ldif << EOF
dn: cn=config
changetype: modify
replace: olcServerID
olcServerID: 2

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001
  provider=ldap://192.168.1.19:389/
  bindmethod=simple
  binddn="cn=Manager,dc=nhanhoa,dc=local"
  credentials=*****
  searchbase="dc=nhanhoa,dc=local"
  scope=sub
  schemachecking=on
  type=refreshAndPersist
  retry="30 5 300 3"
  interval=00:00:05:00
-
add: olcMirrorMode
olcMirrorMode: TRUE

dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
EOF

ldapmodify -Y EXTERNAL -H ldapi:/// -f master96.ldif
```
Kết quả:
```ssh
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"

modifying entry "olcDatabase={2}hdb,cn=config"

adding new entry "olcOverlay=syncprov,olcDatabase={2}hdb,cn=config"
```
----

## Kết quả

### Trên node Master-01
Thêm dữ liệu vào node Master-01
```ssh
echo '
dn: ou=Tests,dc=nhanhoa,dc=local
ou: Tests
objectclass: organizationalUnit' > test_structure.ldif

ldapadd -x -D cn=Manager,dc=nhanhoa,dc=local -W -f test_structure.ldif
```
Kết quả:
```ssh
adding new entry "ou=Tests,dc=nhanhoa,dc=local"
```
Kiểm tra dữ liệu trên node Master-02
```ssh
ldapsearch -x -h 192.168.1.19 -b "dc=nhanhoa,dc=local" -s sub "(objectclass=person)"
```
Kết quả:
```ssh
[root@ldap_02 ~]# ldapsearch -x -h 192.168.1.19 -b "dc=nhanhoa,dc=local" -s sub "(objectclass=organizationalUnit)"
# extended LDIF
#
# LDAPv3
# base <dc=nhanhoa,dc=local> with scope subtree
# filter: (objectclass=organizationalUnit)
# requesting: ALL
#

# People, nhanhoa.local
dn: ou=People,dc=nhanhoa,dc=local
objectClass: organizationalUnit
ou: People

# Group, nhanhoa.local
dn: ou=Group,dc=nhanhoa,dc=local
objectClass: organizationalUnit
ou: Group

# Tests, nhanhoa.local
dn: ou=Tests,dc=nhanhoa,dc=local
ou: Tests
objectClass: organizationalUnit

# search result
search: 2
result: 0 Success

# numResponses: 4
# numEntries: 3
```
----

### Trên node Master-02
Thêm dữ liệu vào node Master-02
```ssh
echo '
dn: cn=thanhbaba,ou=Tests,dc=nhanhoa,dc=local
objectClass: person
objectClass: inetOrgPerson
mail: thanhbaba@test.com
userPassword:: b3BlbnN0YWNr
cn: thanhbaba
sn: thanhbaba' > user_test_thanhbaba.ldif

ldapadd -x -D cn=Manager,dc=nhanhoa,dc=local -W -f user_test_thanhbaba.ldif
```
Kết quả:
```ssh
adding new entry "cn=thanhbaba,ou=Tests,dc=nhanhoa,dc=local"
```
Kiểm tra dữ liệu trên node Master-01
```ssh
[root@ldap_01 ~]# ldapsearch -x -h 192.168.1.18 -b "dc=nhanhoa,dc=local" -s sub "(objectclass=person)"
# extended LDIF
#
# LDAPv3
# base <dc=nhanhoa,dc=local> with scope subtree
# filter: (objectclass=person)
# requesting: ALL
#

# thanhbaba, Tests, nhanhoa.local
dn: cn=thanhbaba,ou=Tests,dc=nhanhoa,dc=local
objectClass: person
objectClass: inetOrgPerson
mail: thanhbaba@test.com
cn: thanhbaba
sn: thanhbaba

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
```
Kết quả:
```ssh
[root@ldap_01 ~]# ldapsearch -x -h 192.168.1.18 -b "dc=nhanhoa,dc=local" -s sub "(objectclass=organizationalUnit)"
# extended LDIF
#
# LDAPv3
# base <dc=nhanhoa,dc=local> with scope subtree
# filter: (objectclass=organizationalUnit)
# requesting: ALL
#

# People, nhanhoa.local
dn: ou=People,dc=nhanhoa,dc=local
objectClass: organizationalUnit
ou: People

# Group, nhanhoa.local
dn: ou=Group,dc=nhanhoa,dc=local
objectClass: organizationalUnit
ou: Group

# Tests, nhanhoa.local
dn: ou=Tests,dc=nhanhoa,dc=local
ou: Tests
objectClass: organizationalUnit

# search result
search: 2
result: 0 Success

# numResponses: 4
# numEntries: 3
```
----

### Tắt node Master-01, ghi dữ liệu vào Master-02
Tại node Master-01
```ssh
[root@ldap_01 ~]# init 0
```
Tại node Master-02
```ssh
echo '
dn: cn=thanhbaba2,ou=Tests,dc=nhanhoa,dc=local
objectClass: person
objectClass: inetOrgPerson
mail: thanhbaba2@test.com
userPassword:: b3BlbnN0YWNr
cn: thanhbaba2
sn: thanhbaba2' > user_test_thanhbaba2.ldif

ldapadd -x -D cn=Manager,dc=nhanhoa,dc=local -W -f user_test_thanhbaba2.ldif
```
Kết quả:
```ssh
adding new entry "cn=thanhbaba2,ou=Tests,dc=nhanhoa,dc=local"
```
Kiểm tra:
```ssh
[root@ldap_01 ~]# ldapsearch -x -h 10.10.10.96 -b "dc=nhanhoa,dc=local" -s sub "(cn=thanhbaba2)"
# extended LDIF
#
# LDAPv3
# base <dc=nhanhoa,dc=local> with scope subtree
# filter: (cn=thanhbaba2)
# requesting: ALL
#

# thanhbaba2, Tests, nhanhoa.local
dn: cn=thanhbaba2,ou=Tests,dc=nhanhoa,dc=local
objectClass: person
objectClass: inetOrgPerson
mail: thanhbaba2@test.com
cn: thanhbaba2
sn: thanhbaba2

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
```
----

### Bật node Master-01, kiểm tra dữ liệu đồng bộ
```ssh
[root@ldap_01 ~]# ldapsearch -x -h 192.168.1.18 -b "dc=nhanhoa,dc=local" -s sub "(cn=thanhbaba2)"
# extended LDIF
#
# LDAPv3
# base <dc=nhanhoa,dc=local> with scope subtree
# filter: (cn=thanhbaba2)
# requesting: ALL
#

# thanhbaba2, Tests, nhanhoa.local
dn: cn=thanhbaba2,ou=Tests,dc=nhanhoa,dc=local
objectClass: person
objectClass: inetOrgPerson
mail: thanhbaba2@test.com
cn: thanhbaba2
sn: thanhbaba2

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
```
----

## Tổng kết
Như vậy trong bài viết này mình đã triển khai mô hình LDAP Master-Master. Tuy nhiên còn một mô hình triển khai LDAP phổ biến khác đó là mô hình LDAP Master-Slave. Vậy sự khác nhau giữa hai mô hình này là thế nào? Cách triển khai ra sao? Lợi ích của mô hình Masterr-Slave đem lại là gì? Mời các bạn theo dõi bài viết tiếp theo của mình.