วันนี้เราจะเรียนรู้การใช้ dockerfile สร้าง image ชื่อ openldap เพื่อใช้เป็น LDAP database
ผมทดสอบด้วย Oracle VM VirtualBox เป็น VM ที่ตั้งค่า Network adapter เป็นแบบ NAT network ที่ติดตั้ง Ubuntu 16.04 และ docker เรียบร้อยแล้ว ในตัวอย่างนี้ผมตั้งชื่อ host ว่า ldap.example.com โดยแก้ไขที่ไฟล์ /etc/hosts และ /etc/hostname ให้เรียบร้อย แล้วรีบูตเครื่องด้วย
ผมจะขอแยกขั้นตอนออกเป็น 3 ขั้นตอนหลัก คือ 1.ขั้นตอนเตรียมไฟล์ที่เกี่ยวข้องซึ่งรวมไฟล์ ldif ด้วย 2.ขั้นตอนสร้างไฟล์ dockerfile และ 3.ขั้นตอนการรัน container
1.ขั้นตอนเตรียมไฟล์ที่เกี่ยวข้อง
สร้างไดเรกทอรีของ image ที่เราจะสร้าง
$ mkdir openldap
สร้างไดเรกทอรีที่เก็บไฟล์ ldif (โครงสร้าง และ ตัวอย่างข้อมูล)
$ cd openldap $ mkdir src
สร้างไฟล์ ./src/create-schema.ldif ด้วยเอติเตอร์ที่ถนัด เช่น vi หรือ nano ก็ได้
$ vi ./src/create-schema.ldif # Starter kit for create user in domain dc=example,dc=com # Create 1st tree OU=groups dn: ou=groups,dc=example,dc=com objectClass: organizationalUnit ou: groups # Create sub tree OU=execs,OU=groups dn: ou=execs,ou=groups,dc=example,dc=com objectClass: organizationalUnit ou: execs # Create sub tree OU=staffs,OU=groups dn: ou=staffs,ou=groups,dc=example,dc=com objectClass: organizationalUnit ou: staffs # Create sub tree OU=students,OU=groups dn: ou=students,ou=groups,dc=example,dc=com objectClass: organizationalUnit ou: students # Create 2nd tree OU=people dn: ou=people,dc=example,dc=com objectClass: organizationalUnit ou: people
สร้างไฟล์ ssl.ldif
$ vi src/ssl.ldif dn: cn=config changetype: modify add: olcTLSCipherSuite olcTLSCipherSuite: NORMAL - add: olcTLSCRLCheck olcTLSCRLCheck: none - add: olcTLSVerifyClient olcTLSVerifyClient: never - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/certs/ldap-ca-cert.pem - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/private/ldap-ca-key.pem
สร้างไฟล์ ./src/create-users.ldif
$ vi ./src/create-users.ldif # Create 1 user in tree OU=execs,OU=groups dn: cn=nana,ou=execs,ou=groups,dc=example,dc=com objectClass: inetOrgPerson uid: nana sn: Na givenName: Na cn: nana displayName: Na Na userPassword: 123456 mail: nana@example.com # Create 2 users in tree OU=staffs,OU=groups dn: cn=koko,ou=staffs,ou=groups,dc=example,dc=com objectClass: inetOrgPerson uid: koko sn: Ko givenName: Ko cn: koko displayName: Ko Ko userPassword: 123456 mail: koko@example.com dn: cn=momo,ou=staffs,ou=groups,dc=example,dc=com objectClass: inetOrgPerson uid: momo sn: Mo givenName: Mo cn: momo displayName: Mo Mo userPassword: 123456 mail: momo@example.com # Create 2 users in tree OU=people dn: cn=lala,ou=people,dc=example,dc=com objectClass: inetOrgPerson uid: lala sn: La givenName: La cn: lala displayName: La La userPassword: 123456 mail: lala@example.com dn: cn=lulu,ou=people,dc=example,dc=com objectClass: inetOrgPerson uid: lulu sn: Lu givenName: Lu cn: lulu displayName: Lu Lu userPassword: 123456 mail: lulu@example.com
สร้างไฟล์ ./src/create-students.ldif
$ vi ./src/create-students.ldif # Create 2 students in tree OU=students,OU=groups dn: cn=5310110293,ou=students,ou=groups,dc=example,dc=com objectClass: inetOrgPerson uid: 5310110293 sn: 5310110293 givenName: somsak cn: 5310110293 displayName: somsak somsaknaja userPassword: 123456 mail: 5310110293@example.com dn: cn=5410110308,ou=students,ou=groups,dc=example,dc=com objectClass: inetOrgPerson uid: 5410110308 sn: 5410110308 givenName: somsri cn: 5410110308 displayName: somsri somsrisiya userPassword: 123456 mail: 5410110308@example.com
ต่อไปเป็นการเตรียม self-signed certificate เพื่อให้ใช้งาน LDAPS ได้
$ sudo apt install ssl-cert $ mkdir cert $ cp /etc/ssl/certs/ssl-cert-snakeoil.pem cert/ldap-ca-cert.pem $ sudo cp /etc/ssl/private/ssl-cert-snakeoil.key cert/ldap-ca-key.pem $ sudo chmod +r cert/ldap-ca-key.pem
2.ขั้นตอนสร้างไฟล์ dockerfile
ตอนนี้ก็มาถึงขั้นตอนการเขียน dockerfile ด้วยเอดิเตอร์ที่ถนัดเช่น vi หรือ nano ก็ได้
$ vi dockerfile # Composer: Comments FROM ubuntu:16.04 # Change apt source RUN sed -i 's/\/us.archive/\/th.archive/g' /etc/apt/sources.list && \ sed -i 's/\/archive/\/th.archive/g' /etc/apt/sources.list # Update ubuntu, then install packages RUN apt-get update && \ echo 'slapd slapd/root_password password 123456' | debconf-set-selections && \ echo 'slapd slapd/root_password_again password 123456' | debconf-set-selections && \ echo "slapd slapd/internal/adminpw password 123456" |debconf-set-selections && \ echo "slapd slapd/internal/generated_adminpw password 123456" |debconf-set-selections && \ echo "slapd slapd/password2 password 123456" |debconf-set-selections && \ echo "slapd slapd/password1 password 123456" |debconf-set-selections && \ echo "slapd slapd/domain string example.com" |debconf-set-selections && \ echo "slapd shared/organization string example" |debconf-set-selections && \ echo "slapd slapd/backend string HDB" |debconf-set-selections && \ echo "slapd slapd/purge_database boolean true" |debconf-set-selections && \ echo "slapd slapd/move_old_database boolean true" |debconf-set-selections && \ echo "slapd slapd/allow_ldap_v2 boolean false" |debconf-set-selections && \ echo "slapd slapd/no_configuration boolean false" |debconf-set-selections && \ DEBIAN_FRONTEND=noninteractive apt install -y slapd # LDAP utils, self-signed certificates RUN apt-get install -y ldap-utils ssl-cert # Timezone Asia/Bangkok RUN apt-get install -y tzdata && \ ln -sf /usr/share/zoneinfo/Asia/Bangkok /etc/localtime && \ dpkg-reconfigure -f noninteractive tzdata # Cleaning RUN apt-get autoremove -y && apt-get clean -y # LDAP COPY ./src/*.ldif /tmp/ ## Schema only, no user. RUN service slapd start && \ ldapadd -H ldapi:/// -f /tmp/create-schema.ldif -x -D "cn=admin,dc=example,dc=com" -w 123456 ## Schema and add users. ## RUN service slapd start && \ ## ldapadd -H ldapi:/// -f /tmp/create-schema.ldif -x -D "cn=admin,dc=example,dc=com" -w 123456 && \ ## ldapadd -H ldapi:/// -f /tmp/create-users.ldif -x -D "cn=admin,dc=example,dc=com" -w 123456 && \ ## ldapadd -H ldapi:/// -f /tmp/create-students.ldif -x -D "cn=admin,dc=example,dc=com" -w 123456 EXPOSE 389 #CMD slapd -h 'ldap:///' -g openldap -u openldap -d 0 # # LDAPS COPY ./cert/ldap-ca-cert.pem /etc/ssl/certs/ COPY ./cert/ldap-ca-key.pem /etc/ssl/private/ RUN chgrp ssl-cert /etc/ssl/private/ldap-ca-key.pem && \ chmod g+r /etc/ssl/private/ldap-ca-key.pem && \ adduser openldap ssl-cert RUN echo 'SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"' >> /etc/default/slapd && \ echo 'TLS_REQCERT never' >> /etc/ldap/ldap.conf RUN service slapd start && \ ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/ssl.ldif -v EXPOSE 636 ##CMD slapd -h 'ldaps:///' -g openldap -u openldap -d 0 CMD RUN ulimit -n 1024 CMD /usr/sbin/slapd -h 'ldap:/// ldaps:/// ldapi:///' -g openldap -u openldap -d 0
3.ขั้นตอนการรัน container
สร้าง image ด้วยคำสั่งนี้
$ docker build -t openldap .
รัน container และ ตรวจสอบ ด้วยคำสั่งนี้
$ docker run -d -p 636:636 -p 389:389 --name openldap openldap $ docker ps
อธิบายได้ดังนี้ container จะรันแบบ detach (-d) เปิด port 636 และ 389 ตั้งชื่อ(–name) ว่า openldap และรันจาก image ชื่อ openldap
ทดสอบการนำเข้าข้อมูล ซึ่งเราจะใช้เครื่องที่กำลังทำอยู่นี้เป็น ldap client ไม่ต้องไปหาอีกเครื่องก็ได้ โดยเพิ่มแพ็กเกจ ldap-utils
$ sudo apt install ldap-utils
ทดสอบการเพิ่มตัวอย่างข้อมูล โดยเลือกใช้ port 389 (LDAP)
$ ldapadd -H ldap://ldap.example.com -f ./src/create-users.ldif -x -D "cn=admin,dc=example,dc=com" -w 123456
ทดสอบการเพิ่มตัวอย่างข้อมูล โดยเลือกใช้ port 636 (LDAPS)
$ ldapadd -H ldaps://ldap.example.com -f ./src/create-students.ldif -x -D "cn=admin,dc=example,dc=com" -w 123456
จะพบข้อความว่า
ldap_sasl_bind(SIMPLE): Can’t contact LDAP server (-1)
ให้ทำคำสั่ง 2 บรรทัดข้างล่างนี้ เพื่อเพิ่ม certificate จาก LDAP server แล้วลองคำสั่งนั้นอีกครั้งจะทำได้
$ openssl s_client -connect ldap.example.com:636 -showcerts </dev/null 2>/dev/null | openssl x509 -outform PEM | sudo tee /usr/local/share/ca-certificates/ldap.example.com.crt $ sudo update-ca-certificates
ทดสอบค้นหาข้อมูล
$ ldapsearch -xLLL -b "dc=example,dc=com" uid=lulu $ ldapsearch -xLLL -b "dc=example,dc=com" uid=5310110293
ลบ container
$ docker stop openldap $ docker rm openldap
เรื่องสุดท้ายของบล็อกในวันนี้คือ ต้องการเก็บตัวอย่างข้อมูลที่เพิ่มไว้จะทำอย่างไร ทำได้โดยการสร้างที่เก็บ persistent data แบบ named volume โดยที่ oldata สำหรับข้อมูล และ olconfig สำหรับไฟล์คอนฟิกกูเรชัน
$ docker volume create oldata oldata $ docker volume create olconfig olconfig
เช็คดูรายการ volume
$ docker volume ls DRIVER VOLUME NAME local olconfig local oldata
รัน container (เขียนคำสั่งให้อยู่ในบรรทัดเดียว)
$ docker run -d -p 636:636 -p 389:389 --name openldap --volume oldata:/var/lib/ldap --volume olconfig:/etc/ldap/slapd.d openldap
อธิบายได้ดังนี้ container จะรันแบบ detach (-d) เปิด port 636 และ 389 ตั้งชื่อ(–name) ว่า openldap เก็บข้อมูลไว้นอก container เอาไว้ที่ volume ชื่อ oldata ที่ mapped ไปยัง /var/lib/ldap ใน container กับ olconfig ที่ mapped ไปยัง /etc/ldap/slapd.d ใน container และรันจาก image ชื่อ openldap
เพิ่มข้อมูลตัวอย่าง
$ ldapadd -H ldaps://ldap.example.com -f ./src/create-students.ldif -x -D "cn=admin,dc=example,dc=com" -w 123456
ค้นหาข้อมูล
$ ldapsearch -xLLL -b "dc=example,dc=com" uid=5310110293
ลบ container เมื่อจะไม่ใช้งานแล้ว
$ docker stop openldap $ docker rm openldap
หลังจากลบ container ข้อมูลของเราจะยังคงอยู่ในที่เก็บข้อมูลแบบ volume อยู่ที่ path /var/lib/docker/volumes
ในตอนต่อไปจะเป็นการสร้าง dockerfile เพื่อรัน phpldapadmin ใช้ในการเข้า admin ผ่านหน้าเว็บเพจ