In this blog, we’ll look at how to setup and troubleshoot the Percona PAM authentication plugin.
We occasionally get requests from our support clients on how to get Percona Server for MySQL to authenticate with an external authentication service via LDAP or Active Directory. However, we normally do not have access to client’s infrastructure to help troubleshoot these cases. To help them effectively, we need to setup a testbed to reproduce their issues and guide them on how to get authentication to work. Fortunately, we only need to install Samba to provide an external authentication service for both LDAP and AD.
In this article, I will show you how to (a) compile and install Samba, (b) create a domain environment with Samba, (c) add users and groups to this domain and (d) get Percona Server to use these accounts for authentication via LDAP. In my follow-up article, I will discuss how to get MySQL to authenticate credentials with Active Directory.
My testbed environment consists of two machines
Samba PDC
OS: CentOS 7
IP Address: 172.16.0.10
Hostname: samba-10.example.com
Domain name: EXAMPLE.COM
DNS: 8.8.8.8(Google DNS), 8.8.4.4(Google DNS), 172.16.0.10(Samba)
Firewall: none
Percona Server 5.7 with LDAP authentication
OS: CentOS 7
IP Address: 172.16.0.20
Hostname: ps-ldap-20.example.com
and have several users and groups:
Domain Groups and Users
Support: jericho, jervin and vishal
DBA: sidd, paul and arunjith
Search: ldap
We will install an NTP client on the Samba PDC/samba-10.example.com machine because time synchronization is a requirement for domain authentication. We will also compile and install Samba from source because the Samba implementation in the official repository doesn’t include the Active Directory Domain Controller role. Hence, samba-tool is not included in the official repository. For our testbed, we need this tool because it makes it easier to provision a domain and manage users and groups. So, for CentOS 7, you can either build from source or use a trusted 3rd party build of Samba (as discussed in Samba’s wiki).
For more information, please read Setting up Samba as an Active Directory Domain Controller as well.
|
1 |
[root@samba-10 ~]# yum -y install ntp<br>* * *<br>Installed:<br> ntp.x86_64 0:4.2.6p5-25.el7.centos.1 <br><br>Dependency Installed:<br> autogen-libopts.x86_64 0:5.18-5.el7 ntpdate.x86_64 0:4.2.6p5-25.el7.centos.1 <br><br>[root@samba-10 ~]# ntpdate 0.centos.pool.ntp.org<br> 7 Apr 06:06:07 ntpdate[9788]: step time server 202.90.132.242 offset 0.807640 sec<br>[root@samba-10 ~]# systemctl enable ntpd.service<br>Created symlink from /etc/systemd/system/multi-user.target.wants/ntpd.service to /usr/lib/systemd/system/ntpd.service.<br>[root@samba-10 ~]# systemctl start ntpd.service |
|
1 |
[root@samba-10 ~]# yum -y install gcc perl python-devel gnutls-devel libacl-devel openldap-devel<br>* * *<br>Installed:<br> gcc.x86_64 0:4.8.5-11.el7 gnutls-devel.x86_64 0:3.3.24-1.el7 libacl-devel.x86_64 0:2.2.51-12.el7 openldap-devel.x86_64 0:2.4.40-13.el7 perl.x86_64 4:5.16.3-291.el7 python-devel.x86_64 0:2.7.5-48.el7 <br><br>Dependency Installed:<br> cpp.x86_64 0:4.8.5-11.el7 cyrus-sasl.x86_64 0:2.1.26-20.el7_2 cyrus-sasl-devel.x86_64 0:2.1.26-20.el7_2 glibc-devel.x86_64 0:2.17-157.el7_3.1 <br> glibc-headers.x86_64 0:2.17-157.el7_3.1 gmp-devel.x86_64 1:6.0.0-12.el7_1 gnutls-c++.x86_64 0:3.3.24-1.el7 gnutls-dane.x86_64 0:3.3.24-1.el7 <br> kernel-headers.x86_64 0:3.10.0-514.10.2.el7 ldns.x86_64 0:1.6.16-10.el7 libattr-devel.x86_64 0:2.4.46-12.el7 libevent.x86_64 0:2.0.21-4.el7 <br> libmpc.x86_64 0:1.0.1-3.el7 libtasn1-devel.x86_64 0:3.8-3.el7 mpfr.x86_64 0:3.1.1-4.el7 nettle-devel.x86_64 0:2.7.1-8.el7 <br> p11-kit-devel.x86_64 0:0.20.7-3.el7 perl-Carp.noarch 0:1.26-244.el7 perl-Encode.x86_64 0:2.51-7.el7 perl-Exporter.noarch 0:5.68-3.el7 <br> perl-File-Path.noarch 0:2.09-2.el7 perl-File-Temp.noarch 0:0.23.01-3.el7 perl-Filter.x86_64 0:1.49-3.el7 perl-Getopt-Long.noarch 0:2.40-2.el7 <br> perl-HTTP-Tiny.noarch 0:0.033-3.el7 perl-PathTools.x86_64 0:3.40-5.el7 perl-Pod-Escapes.noarch 1:1.04-291.el7 perl-Pod-Perldoc.noarch 0:3.20-4.el7 <br> perl-Pod-Simple.noarch 1:3.28-4.el7 perl-Pod-Usage.noarch 0:1.63-3.el7 perl-Scalar-List-Utils.x86_64 0:1.27-248.el7 perl-Socket.x86_64 0:2.010-4.el7 <br> perl-Storable.x86_64 0:2.45-3.el7 perl-Text-ParseWords.noarch 0:3.29-4.el7 perl-Time-HiRes.x86_64 4:1.9725-3.el7 perl-Time-Local.noarch 0:1.2300-2.el7 <br> perl-constant.noarch 0:1.27-2.el7 perl-libs.x86_64 4:5.16.3-291.el7 perl-macros.x86_64 4:5.16.3-291.el7 perl-parent.noarch 1:0.225-244.el7 <br> perl-podlators.noarch 0:2.5.1-3.el7 perl-threads.x86_64 0:1.87-4.el7 perl-threads-shared.x86_64 0:1.43-6.el7 unbound-libs.x86_64 0:1.4.20-28.el7 <br> zlib-devel.x86_64 0:1.2.7-17.el7 <br><br>Complete! |
|
1 |
[root@samba-10 ~]# yum -y install wget<br>* * *<br>[root@samba-10 ~]# wget https://www.samba.org/samba/ftp/samba-latest.tar.gz <br>* * *<br>2017-04-07 06:16:59 (337 KB/s) - 'samba-latest.tar.gz' saved [21097045/21097045]<br>[root@samba-10 ~]# tar xzf samba-latest.tar.gz <br>[root@samba-10 ~]# cd samba-4.6.2/<br>[root@samba-10 samba-4.6.2]# ./configure --prefix=/opt/samba<br>Checking for program gcc or cc : /usr/bin/gcc <br>Checking for program cpp : /usr/bin/cpp <br>Checking for program ar : /usr/bin/ar <br>Checking for program ranlib : /usr/bin/ranlib <br>* * *<br>Checking compiler for PIE support : yes <br>Checking compiler for full RELRO support : yes <br>Checking if toolchain accepts -fstack-protector : yes <br>'configure' finished successfully (39.119s)<br>[root@samba-10 samba-4.6.2]# make<br>WAF_MAKE=1 python ./buildtools/bin/waf build<br>Waf: Entering directory `/root/samba-4.6.2/bin'<br>symlink: tevent.py -> python/tevent.py<br>* * *<br>[3773/3775] Linking default/source3/modules/libvfs_module_acl_xattr.so<br>[3774/3775] Linking default/source3/modules/libvfs_module_shadow_copy.so<br>[3775/3775] Linking default/source3/modules/libvfs_module_dirsort.so<br>Waf: Leaving directory `/root/samba-4.6.2/bin'<br>'build' finished successfully (6m58.144s)<br>[root@samba-10 samba-4.6.2]# make install<br>WAF_MAKE=1 python ./buildtools/bin/waf install<br>Waf: Entering directory `/root/samba-4.6.2/bin'<br>* creating /opt/samba/etc<br>* creating /opt/samba/private<br>* * *<br>* installing bin/default/source3/nmbd/nmbd.inst as /opt/samba/sbin/nmbd<br>* installing bin/default/file_server/libservice_module_s3fs.inst.so as /opt/samba/lib/service/s3fs.so<br>Waf: Leaving directory `/root/samba-4.6.2/bin'<br>'install' finished successfully (1m44.377s) |
Please take note that when I downloaded Samba, the latest version was 4.6.2. If you have a problem with compiling the latest version of Samba, try using version 4.6.2.
|
1 |
[root@samba-10 samba-4.6.2]# echo "PATH=/opt/samba/sbin:/opt/samba/bin:/usr/sbin:/usr/bin" >> /etc/environment <br>[root@samba-10 samba-4.6.2]# PATH=/opt/samba/sbin:/opt/samba/bin:/usr/sbin:/usr/bin<br>[root@samba-10 samba-4.6.2]# which samba-tool<br>/opt/samba/bin/samba-tool |
|
1 |
[root@samba-10 samba-4.6.2]# echo "[Unit]<br>Description=Samba PDC<br>After=syslog.target network.target <br><br>[Service]<br>Type=forking<br>PIDFile=//opt/samba/var/run/samba.pid<br>ExecStart=/opt/samba/sbin/samba -D<br>ExecReload=/usr/bin/kill -HUP $MAINPID<br>ExecStop=/usr/bin/kill $MAINPID<br><br>[Install]<br>WantedBy=multi-user.target" > /etc/systemd/system/samba.service<br>[root@samba-10 samba-4.6.2]# systemctl enable samba.service<br>Created symlink from /etc/systemd/system/multi-user.target.wants/samba.service to /etc/systemd/system/samba.service. |
|
1 |
[root@samba-10 samba-4.6.2]# rm -f /etc/krb5.conf<br>[root@samba-10 samba-4.6.2]# cd<br>[root@samba-10 ~]# |
Realm: EXAMPLE.COM
Domain: EXAMPLE
Server Role: dc(domain controller)
DNS backend: SAMBA_INTERNAL
DNS forwarder IP address: 8.8.8.8
You will also need to supply the Administrator password. This account is used to join a workstation or server to a domain:
|
1 |
[root@samba-10 ~]# samba-tool domain provision<br>Realm [EXAMPLE.ORG]: EXAMPLE.COM<br> Domain [EXAMPLE]: EXAMPLE<br> Server Role (dc, member, standalone) [dc]: dc<br> DNS backend (SAMBA_INTERNAL, BIND9_FLATFILE, BIND9_DLZ, NONE) [SAMBA_INTERNAL]: SAMBA_INTERNAL<br> DNS forwarder IP address (write 'none' to disable forwarding) [8.8.8.8]: 8.8.8.8<br>Administrator password: <br>Retype password: <br>Looking up IPv4 addresses<br>Looking up IPv6 addresses<br>No IPv6 address will be assigned<br>Setting up secrets.ldb<br>Setting up the registry<br>Setting up the privileges database<br>Setting up idmap db<br>Setting up SAM db<br>Setting up sam.ldb partitions and settings<br>Setting up sam.ldb rootDSE<br>Pre-loading the Samba 4 and AD schema<br>Adding DomainDN: DC=example,DC=com<br>Adding configuration container<br>Setting up sam.ldb schema<br>Setting up sam.ldb configuration data<br>Setting up display specifiers<br>Modifying display specifiers<br>Adding users container<br>Modifying users container<br>Adding computers container<br>Modifying computers container<br>Setting up sam.ldb data<br>Setting up well known security principals<br>Setting up sam.ldb users and groups<br>Setting up self join<br>Adding DNS accounts<br>Creating CN=MicrosoftDNS,CN=System,DC=example,DC=com<br>Creating DomainDnsZones and ForestDnsZones partitions<br>Populating DomainDnsZones and ForestDnsZones partitions<br>Setting up sam.ldb rootDSE marking as synchronized<br>Fixing provision GUIDs<br>A Kerberos configuration suitable for Samba AD has been generated at /opt/samba/private/krb5.conf<br>Once the above files are installed, your Samba4 server will be ready to use<br>Server Role: active directory domain controller<br>Hostname: samba-10<br>NetBIOS Domain: EXAMPLE<br>DNS Domain: example.com<br>DOMAIN SID: S-1-5-21-1337223342-1741564684-602463608 |
Please take note that if you get the error below, it’s likely due to not removing the existing /etc/krb5.conf before using samba-tool:
|
1 |
ERROR(ldb): uncaught exception - operations error at ../source4/dsdb/samdb/ldb_modules/password_hash.c:2820<br> File "/opt/samba/lib64/python2.7/site-packages/samba/netcmd/__init__.py", line 176, in _run<br> return self.run(*args, **kwargs)<br> File "/opt/samba/lib64/python2.7/site-packages/samba/netcmd/domain.py", line 471, in run<br> nosync=ldap_backend_nosync, ldap_dryrun_mode=ldap_dryrun_mode)<br> File "/opt/samba/lib64/python2.7/site-packages/samba/provision/__init__.py", line 2175, in provision<br> skip_sysvolacl=skip_sysvolacl)<br> File "/opt/samba/lib64/python2.7/site-packages/samba/provision/__init__.py", line 1787, in provision_fill<br> next_rid=next_rid, dc_rid=dc_rid)<br> File "/opt/samba/lib64/python2.7/site-packages/samba/provision/__init__.py", line 1447, in fill_samdb<br> "KRBTGTPASS_B64": b64encode(krbtgtpass.encode('utf-16-le'))<br> File "/opt/samba/lib64/python2.7/site-packages/samba/provision/common.py", line 55, in setup_add_ldif<br> ldb.add_ldif(data, controls)<br> File "/opt/samba/lib64/python2.7/site-packages/samba/__init__.py", line 225, in add_ldif<br> self.add(msg, controls) |
You could also get an error if you entered a simple password for the Administrator account.
|
1 |
[root@samba-10 ~]# ln -s /opt/samba/private/krb5.conf /etc |
|
1 |
[root@samba-10 ~]# systemctl start samba.service<br> |
|
1 |
[root@samba-10 ~]# yum -y install net-tools<br>* * *<br>[root@samba-10 ~]# netstat -tapn<br>Active Internet connections (servers and established)<br>Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name <br>tcp 0 0 0.0.0.0:464 0.0.0.0:* LISTEN 13296/samba <br>tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN 13302/samba <br>tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 875/sshd <br>tcp 0 0 0.0.0.0:88 0.0.0.0:* LISTEN 13296/samba <br>tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1327/master <br>tcp 0 0 0.0.0.0:636 0.0.0.0:* LISTEN 13294/samba <br>tcp 0 0 0.0.0.0:445 0.0.0.0:* LISTEN 13307/smbd <br>tcp 0 0 0.0.0.0:1024 0.0.0.0:* LISTEN 13291/samba <br>tcp 0 0 0.0.0.0:1025 0.0.0.0:* LISTEN 13291/samba <br>tcp 0 0 0.0.0.0:3268 0.0.0.0:* LISTEN 13294/samba <br>tcp 0 0 0.0.0.0:3269 0.0.0.0:* LISTEN 13294/samba <br>tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN 13294/samba <br>tcp 0 0 0.0.0.0:135 0.0.0.0:* LISTEN 13291/samba <br>tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN 13307/smbd |
Now that Samba is running we can add users and groups, and assign users to groups with samba-tool.
|
1 |
[root@samba-10 ~]# samba-tool group add support<br>Added group support<br>[root@samba-10 ~]# samba-tool group add dba<br>Added group dba<br>[root@samba-10 ~]# samba-tool group add search<br>Added group search |
|
1 |
[root@samba-10 ~]# samba-tool user create jericho<br>New Password: <br>Retype Password: <br>User 'jericho' created successfully<br>[root@samba-10 ~]# samba-tool user create jervin<br>New Password: <br>Retype Password: <br>User 'jervin' created successfully<br>[root@samba-10 ~]# samba-tool user create vishal<br>New Password: <br>Retype Password: <br>User 'vishal' created successfully<br>[root@samba-10 ~]# samba-tool user create sidd<br>New Password: <br>Retype Password: <br>User 'sidd' created successfully<br>[root@samba-10 ~]# samba-tool user create paul<br>New Password: <br>Retype Password: <br>User 'paul' created successfully<br>[root@samba-10 ~]# samba-tool user create arunjith<br>New Password: <br>Retype Password: <br>User 'arunjith' created successfully<br>[root@samba-10 ~]# samba-tool user create ldap<br>New Password: <br>Retype Password: <br>User 'ldap' created successfully |
|
1 |
[root@samba-10 ~]# samba-tool group addmembers support jericho,jervin,vishal<br>Added members to group support<br>[root@samba-10 ~]# samba-tool group addmembers dba sidd,paul,arunjith<br>Added members to group dba<br>[root@samba-10 ~]# samba-tool group addmembers search ldap<br>Added members to group search |
|
1 |
[root@samba-10 ~]# samba-tool user list<br>Administrator<br>arunjith<br>jericho<br>jervin<br>krbtgt<br>vishal<br>Guest<br>ldap<br>paul<br>sidd<br>[root@samba-10 ~]# samba-tool group list<br>Allowed RODC Password Replication Group<br>Enterprise Read-Only Domain Controllers<br>Denied RODC Password Replication Group<br>Pre-Windows 2000 Compatible Access<br>Windows Authorization Access Group<br>Certificate Service DCOM Access<br>Network Configuration Operators<br>Terminal Server License Servers<br>Incoming Forest Trust Builders<br>Read-Only Domain Controllers<br>Group Policy Creator Owners<br>Performance Monitor Users<br>Cryptographic Operators<br>Distributed COM Users<br>Performance Log Users<br>Remote Desktop Users<br>Account Operators<br>Event Log Readers<br>RAS and IAS Servers<br>Backup Operators<br>Domain Controllers<br>Server Operators<br>Enterprise Admins<br>Print Operators<br>Administrators<br>Domain Computers<br>Cert Publishers<br>DnsUpdateProxy<br>Domain Admins<br>Domain Guests<br>Schema Admins<br>Domain Users<br>Replicator<br>IIS_IUSRS<br>DnsAdmins<br>Guests<br>Users<br>support<br>search<br>dba<br>[root@samba-10 ~]# samba-tool group listmembers support<br>jervin<br>jericho<br>vishal<br>[root@samba-10 ~]# samba-tool group listmembers dba<br>arunjith<br>sidd<br>paul<br>[root@samba-10 ~]# samba-tool group listmembers search<br>ldap |
For more information on using samba-tool, just run samba-tool --help.
We will be using the machine ps-ldap-20.example.com to offer MySQL service with LDAP authentication via Percona PAM. If you’re not familiar with Percona PAM, please have a look at this before moving forward.
At this point, our Samba service is running with users, groups and memberships added. We can now query Samba via LDAP ports 389 and 636. We will configure the server to do LDAP lookups when searching for users and groups. This is necessary because we use the name service to validate group membership. We will then install Percona Server for MySQL and configure our PAM plugin to use nss-pam-ldapd to authenticate to LDAP. Finally, we will test LDAP authentication on Percona Server for MySQL using a regular user and proxy user.
|
1 |
[root@ps-20 ~]# yum -y install nss-pam-ldapd<br> |
|
1 |
[root@ps-20 ~]# echo "uid nslcd<br>gid ldap<br>pagesize 1000<br>referrals off<br>idle_timelimit 800<br>filter passwd (&(objectClass=user)(objectClass=person)(!(objectClass=computer)))<br>map passwd uid sAMAccountName<br>map passwd uidNumber objectSid:S-1-5-21-1337223342-1741564684-602463608<br>map passwd gidNumber objectSid:S-1-5-21-1337223342-1741564684-602463608<br>map passwd homeDirectory "/home/$cn"<br>map passwd gecos displayName<br>map passwd loginShell "/bin/bash"<br>filter group (|(objectClass=group)(objectClass=person))<br>map group gidNumber objectSid:S-1-5-21-1337223342-1741564684-602463608<br>uri ldaps://172.16.0.10<br>base dc=example,dc=com<br>tls_reqcert never<br>binddn cn=ldap,cn=Users,dc=example,dc=com<br>bindpw MyLdapPasswordDontCopyIt2017" > /etc/nslcd.conf |
As you can see above, this config contains LDAP settings, mapping custom LDAP attributes, and LDAP credentials. The value of objectSid was taken from “DOMAIN SID” that was generated when I created a new domain. So, be sure to use the value of “DOMAIN SID” generated on your end. Otherwise, your LDAP queries will not match any record. However, if you’re authenticating from an existing Windows AD server, you can obtain the value of “DOMAIN SID” by running “Get-ADDomain”. Also, you can take a look at this link to get to know more about other configurations for nslcd.conf.
Find:
passwd: files sss
shadow: files sss
group: files sss
Replace with:
passwd: files sss ldap
shadow: files sss ldap
group: files sss ldap
|
1 |
[root@ps-20 ~]# nslcd -d<br>nslcd: DEBUG: add_uri(ldaps://172.16.0.10)<br>nslcd: DEBUG: ldap_set_option(LDAP_OPT_X_TLS_REQUIRE_CERT,0)<br>nslcd: version 0.8.13 starting<br>nslcd: DEBUG: unlink() of /var/run/nslcd/socket failed (ignored): No such file or directory<br>nslcd: DEBUG: initgroups("nslcd",55) done<br>nslcd: DEBUG: setgid(55) done<br>nslcd: DEBUG: setuid(65) done<br>nslcd: accepting connections |
|
1 |
[root@ps-20 ~]# id jervin<br>uid=1107(jervin) gid=1107(jervin) groups=1107(jervin),1103(support)<br>[root@ps-20 ~]# id paul<br>uid=1110(paul) gid=1110(paul) groups=1110(paul),1104(dba)<br>[root@ps-20 ~]# getent passwd<br>root:x:0:0:root:/root:/bin/bash<br>bin:x:1:1:bin:/bin:/sbin/nologin<br>daemon:x:2:2:daemon:/sbin:/sbin/nologin<br>adm:x:3:4:adm:/var/adm:/sbin/nologin<br>lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin<br>sync:x:5:0:sync:/sbin:/bin/sync<br>shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown<br>halt:x:7:0:halt:/sbin:/sbin/halt<br>mail:x:8:12:mail:/var/spool/mail:/sbin/nologin<br>operator:x:11:0:operator:/root:/sbin/nologin<br>games:x:12:100:games:/usr/games:/sbin/nologin<br>ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin<br>nobody:x:99:99:Nobody:/:/sbin/nologin<br>avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin<br>systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin<br>systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin<br>dbus:x:81:81:System message bus:/:/sbin/nologin<br>polkitd:x:997:995:User for polkitd:/:/sbin/nologin<br>tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin<br>postfix:x:89:89::/var/spool/postfix:/sbin/nologin<br>sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin<br>user:x:1000:1000:user:/home/user:/bin/bash<br>mysql:x:27:27:Percona Server:/var/lib/mysql:/bin/false<br>nscd:x:28:28:NSCD Daemon:/:/sbin/nologin<br>nslcd:x:65:55:LDAP Client User:/:/sbin/nologin<br>Administrator:*:500:500::/home/Administrator:/bin/bash<br>arunjith:*:1111:1111::/home/arunjith:/bin/bash<br>jericho:*:1106:1106::/home/jericho:/bin/bash<br>jervin:*:1107:1107::/home/jervin:/bin/bash<br>krbtgt:*:502:502::/home/krbtgt:/bin/bash<br>vishal:*:1108:1108::/home/vishal:/bin/bash<br>Guest:*:501:501::/home/Guest:/bin/bash<br>ldap:*:1112:1112::/home/ldap:/bin/bash<br>paul:*:1110:1110::/home/paul:/bin/bash<br>sidd:*:1109:1109::/home/sidd:/bin/bash |
If you take a look at the nslcd terminal again, you will see that it’s trying to resolve the user and group identification with LDAP searches:
|
1 |
* * *<br>nslcd: [7b23c6] <passwd=1107> DEBUG: ldap_simple_bind_s("cn=ldap,cn=Users,dc=example,dc=com","***") (uri="ldaps://172.16.0.10")<br>nslcd: [7b23c6] <passwd=1107> DEBUG: ldap_result(): CN=jervin,CN=Users,DC=example,DC=com<br>nslcd: [7b23c6] <passwd=1107> DEBUG: ldap_result(): end of results (1 total)<br>nslcd: [3c9869] DEBUG: connection from pid=10468 uid=0 gid=0<br>nslcd: [3c9869] <passwd=1107> DEBUG: myldap_search(base="dc=example,dc=com", filter="(&(&(objectClass=user)(objectClass=person)(!(objectClass=computer)))(objectSid=�1�5�0�0�0�0�0�515�0�0�0ae68b44f�c2bce6778dde8...<br>* * *<br>nslcd: [5558ec] <passwd="paul"> DEBUG: myldap_search(base="dc=example,dc=com", filter="(&(&(objectClass=user)(objectClass=person)(!(objectClass=computer)))(sAMAccountName=paul))")<br>nslcd: [5558ec] <passwd="paul"> DEBUG: ldap_result(): CN=paul,CN=Users,DC=example,DC=com<br>nslcd: [5558ec] <passwd="paul"> DEBUG: ldap_result(): end of results (1 total)<br>* * *<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: myldap_search(base="dc=example,dc=com", filter="(&(objectClass=user)(objectClass=person)(!(objectClass=computer)))")<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): CN=Administrator,CN=Users,DC=example,DC=com<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): CN=arunjith,CN=Users,DC=example,DC=com<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): CN=jericho,CN=Users,DC=example,DC=com<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): CN=jervin,CN=Users,DC=example,DC=com<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): CN=krbtgt,CN=Users,DC=example,DC=com<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): CN=vishal,CN=Users,DC=example,DC=com<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): CN=Guest,CN=Users,DC=example,DC=com<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): CN=ldap,CN=Users,DC=example,DC=com<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): CN=paul,CN=Users,DC=example,DC=com<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): CN=sidd,CN=Users,DC=example,DC=com<br>nslcd: [e2a9e3] <passwd(all)> DEBUG: ldap_result(): end of results (10 total) |
Now that we know nslcd is working, shut it down by running “Ctrl-C”.
|
1 |
[root@ps-20 ~]# systemctl start nslcd.service<br>[root@ps-20 ~]# systemctl enable nslcd.service<br>Created symlink from /etc/systemd/system/multi-user.target.wants/nslcd.service to /usr/lib/systemd/system/nslcd.service. |
|
1 |
[root@ps-20 ~]# rpm -Uvh https://www.percona.com/redir/downloads/percona-release/redhat/percona-release-0.1-4.noarch.rpm<br>Retrieving https://www.percona.com/redir/downloads/percona-release/redhat/percona-release-0.1-4.noarch.rpm<br>Preparing... ################################# [100%]<br>Updating / installing...<br> 1:percona-release-0.1-4 ################################# [100%]<br><br>[root@ps-20 ~]# yum -y install Percona-Server-server-57<br>* * *<br>[root@ps-20 ~]# mysqld --initialize-insecure --user=mysql<br>[root@ps-20 ~]# systemctl start mysqld.service<br>[root@ps-20 ~]# systemctl enable mysqld.service<br>Created symlink from /etc/systemd/system/mysql.service to /usr/lib/systemd/system/mysqld.service.<br>Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld.service to /usr/lib/systemd/system/mysqld.service. |
|
1 |
[root@ps-20 ~]# mysql -uroot<br>mysql> SET PASSWORD=PASSWORD('MyNewAndImprovedPassword'); |
|
1 |
mysql> delete from mysql.user where user='';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> INSTALL PLUGIN auth_pam SONAME 'auth_pam.so';<br>Query OK, 0 rows affected (0.01 sec)<br><br>mysql> INSTALL PLUGIN auth_pam_compat SONAME 'auth_pam_compat.so';<br>Query OK, 0 rows affected (0.00 sec)<br> |
|
1 |
auth required pam_ldap.so<br>account required pam_ldap.so |
|
1 |
mysql> CREATE USER jervin@'%' IDENTIFIED WITH auth_pam;<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> GRANT ALL PRIVILEGES ON support.* TO jervin@'%';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> FLUSH PRIVILEGES;<br>Query OK, 0 rows affected (0.00 sec) |
|
1 |
[root@ps-20 ~]# mysql -u jervin<br>Password: <br>Welcome to the MySQL monitor. Commands end with ; or g.<br>Your MySQL connection id is 22<br>Server version: 5.7.17-13 Percona Server (GPL), Release 13, Revision fd33d43<br><br>Copyright (c) 2009-2016 Percona LLC and/or its affiliates<br>Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.<br><br>Oracle is a registered trademark of Oracle Corporation and/or its<br>affiliates. Other names may be trademarks of their respective<br>owners.<br><br>Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.<br><br>mysql> SHOW GRANTS;<br>+-----------------------------------------------------+<br>| Grants for jervin@% |<br>+-----------------------------------------------------+<br>| GRANT USAGE ON *.* TO 'jervin'@'%' |<br>| GRANT ALL PRIVILEGES ON `support`.* TO 'jervin'@'%' |<br>+-----------------------------------------------------+<br>2 rows in set (0.00 sec) |
It works! However, if you have 100 support users who have the same MySQL privileges, creating 100 MySQL users is tedious and can be difficult to maintain. If belonging to a group has certain MySQL privileges, setup proxy users instead to map a user’s privilege to its defined group. We will implement this for both dba and support users in the next step.
For now, delete the user we just created:
|
1 |
mysql> DROP USER jervin@'%';<br>Query OK, 0 rows affected (0.00 sec) |
|
1 |
mysql> CREATE USER ''@'' IDENTIFIED WITH auth_pam as 'mysqld,support=support_users,dba=dba_users';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> CREATE USER support_users@'%' IDENTIFIED BY 'some_password';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> CREATE USER dba_users@'%' IDENTIFIED BY 'some_password';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> GRANT ALL PRIVILEGES ON support.* TO support_users@'%';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> GRANT ALL PRIVILEGES ON *.* TO dba_users@'%';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> GRANT PROXY ON support_users@'%' TO ''@'';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> GRANT PROXY ON dba_users@'%' TO ''@'';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> FLUSH PRIVILEGES;<br>Query OK, 0 rows affected (0.00 sec) |
To know more about setting up proxy users, see this article written by Stephane.
|
1 |
[root@ps-20 ~]# mysql -ujericho -p<br>Enter password: <br>Welcome to the MySQL monitor. Commands end with ; or g.<br>Your MySQL connection id is 25<br>Server version: 5.7.17-13 Percona Server (GPL), Release 13, Revision fd33d43<br><br>Copyright (c) 2009-2016 Percona LLC and/or its affiliates<br>Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.<br><br>Oracle is a registered trademark of Oracle Corporation and/or its<br>affiliates. Other names may be trademarks of their respective<br>owners.<br><br>Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.<br><br>mysql> SELECT user(), current_user(), @@proxy_user;<br>+-------------------+-----------------+--------------+<br>| user() | current_user() | @@proxy_user |<br>+-------------------+-----------------+--------------+<br>| jericho@localhost | support_users@% | ''@'' |<br>+-------------------+-----------------+--------------+<br>1 row in set (0.00 sec)<br><br>mysql> SHOW GRANTS;<br>+------------------------------------------------------------+<br>| Grants for support_users@% |<br>+------------------------------------------------------------+<br>| GRANT USAGE ON *.* TO 'support_users'@'%' |<br>| GRANT ALL PRIVILEGES ON `support`.* TO 'support_users'@'%' |<br>+------------------------------------------------------------+<br>2 rows in set (0.00 sec)<br><br>mysql> quit<br>Bye<br>[root@ps-20 ~]# mysql -upaul -p<br>Enter password: <br>Welcome to the MySQL monitor. Commands end with ; or g.<br>Your MySQL connection id is 27<br>Server version: 5.7.17-13 Percona Server (GPL), Release 13, Revision fd33d43<br><br>Copyright (c) 2009-2016 Percona LLC and/or its affiliates<br>Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.<br><br>Oracle is a registered trademark of Oracle Corporation and/or its<br>affiliates. Other names may be trademarks of their respective<br>owners.<br><br>Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.<br><br>mysql> SELECT user(), current_user(), @@proxy_user;<br>+----------------+----------------+--------------+<br>| user() | current_user() | @@proxy_user |<br>+----------------+----------------+--------------+<br>| paul@localhost | dba_users@% | ''@'' |<br>+----------------+----------------+--------------+<br>1 row in set (0.00 sec)<br><br>mysql> SHOW GRANTS;<br>+------------------------------------------------+<br>| Grants for dba_users@% |<br>+------------------------------------------------+<br>| GRANT ALL PRIVILEGES ON *.* TO 'dba_users'@'%' |<br>+------------------------------------------------+<br>1 row in set (0.00 sec) |
As you can see, they did inherit the MySQL privileges of their groups.
To be honest, setting up Percona PAM with LDAP can be challenging if you add this functionality with existing infrastructure. But hopefully, by setting this up in a lab environment from scratch, and doing some tests, you’ll be confident enough to incorporate this feature in production environments.
Resources
RELATED POSTS