HW4
LDAP Server
LDAP server IP:
192.168.14.8
Workstation IP:192.168.14.9
- Install packages
sudo apt update
sudo apt install slapd ldap-utils rsyslog sudo-ldap
- Trust the certs
sudo vim /usr/local/share/ca-certificates/ldap.crt
sudo update-ca-certificates
- Cert & key permission
-rw------- 1 openldap openldap 1704 May 14 14:05 ldap.key
-rw-r--r-- 1 openldap openldap 3160 May 14 14:05 ldap.pem
- Configure LDAPS
sudo dpkg-reconfigure slapd
vim /etc/ldap/ldaps.ldif
# dn: cn=config
# changetype: modify
# add: olcTLSCACertificateFile
# olcTLSCACertificateFile: /etc/ssl/certs/ca-certificates.crt
# -
# add: olcTLSCertificateKeyFile
# olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap.key
# -
# add: olcTLSCertificateFile
# olcTLSCertificateFile: /etc/ldap/ssl/ldap.pem
ldapmodify -Y EXTERNAL -H ldapi:/// -f ldaps.ldif
- LDAPS and force TLS search
sudo vim /etc/default/slapd
# SLAPD_SERVICES="ldapi:/// ldaps:///"
- Set ou
vim /etc/ldap/baseou.ldif
# dn: ou=People,dc=14,dc=nasa
# objectClass: organizationalUnit
# ou: People
# dn: ou=Group,dc=14,dc=nasa
# objectClass: organizationalUnit
# ou: Group
# dn: ou=Ppolicy,dc=14,dc=nasa
# objectClass: organizationalUnit
# ou: Ppolicy
# dn: ou=SUDOers,dc=14,dc=nasa
# objectClass: organizationalUnit
# ou: SUDOers
# dn: ou=Fortune,dc=14,dc=nasa
# objectClass: organizationalUnit
# ou: Fortune
ldapadd -x -H ldapi:/// -D "cn=admin,dc=14,dc=nasa" -W -f baseou.ldif
- Set groups
vim /etc/ldap/group.ldif
# dn: cn=ta,ou=Group,dc=14,dc=nasa
# objectClass: posixGroup
# cn: ta
# gidNumber: 10000
# dn: cn=stu,ou=Group,dc=14,dc=nasa
# objectClass: posixGroup
# cn: stu
# gidNumber: 20000
ldapadd -x -H ldapi:/// -D cn=admin,dc=14,dc=nasa -W -f group.ldif
- Add sudoer schema
sudo vim /etc/ldap/schema/sudo.ldif
# dn: cn=sudo,cn=schema,cn=config
# objectClass: olcSchemaConfig
# cn: sudo
# olcAttributeTypes: {0}( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
# olcAttributeTypes: {1}( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
# olcAttributeTypes: {2}( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
# olcAttributeTypes: {3}( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s) impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
# olcAttributeTypes: {4}( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
# olcAttributeTypes: {5}( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
# olcAttributeTypes: {6}( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
# olcAttributeTypes: {7}( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Start of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
# olcAttributeTypes: {8}( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'End of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
# olcAttributeTypes: {9}( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an integer to order the sudoRole entries' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
# olcObjectClasses: {0}( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' DESC 'Sudoer Entries' SUP top STRUCTURAL MUST cn MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $ description ) )
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/sudo.ldif
- Set sudoer
vim /etc/ldap/sudoer.ldif
# dn: cn=ta,ou=SUDOers,dc=14,dc=nasa
# objectClass: sudoRole
# cn: ta
# sudoUser: %ta
# sudoHost: ALL
# sudoCommand: ALL
# dn: cn=stu,ou=SUDOers,dc=14,dc=nasa
# objectClass: sudoRole
# cn: stu
# sudoUser: %stu
# sudoHost: ALL
# sudoCommand: /usr/bin/ls
ldapadd -x -H ldapi:/// -D cn=admin,dc=14,dc=nasa -W -f sudoer.ldif
- Get hash password
slappasswd -s {your_password}
# {SSHA}cRlbt/snhxEwgG56xKCqjWLY0zZZclNU
- Add ldap publickey schema
vim /etc/ldap/schema/openssh-lpk.ldif
# dn: cn=openssh-lpk,cn=schema,cn=config
# objectClass: olcSchemaConfig
# cn: openssh-lpk
# olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DESC 'OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
# olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' DESC 'OpenSSH LPK objectclass' SUP top AUXILIARY MUST ( sshPublicKey $ uid ) )
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/openssh-lpk.ldif
- Set user
vim /etc/ldap/users.ldif
# dn: uid=generalta,ou=People,dc=14,dc=nasa
# objectClass: posixAccount
# objectClass: ldapPublicKey
# objectClass: account
# cn: generalta
# uid: generalta
# uidNumber: 10000
# gidNumber: 10000
# homeDirectory: /home/generalta
# loginShell: /bin/bash
# userPassword: {SSHA}cRlbt/snhxEwgG56xKCqjWLY0zZZclNU
# sshPublicKey: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFfg2DMY3DfBBvZCnqN8Az5tUnVQca+qXkJ9HceOcRAy 2025-na-hw4
# dn: uid=stu14,ou=People,dc=14,dc=nasa
# objectClass: posixAccount
# objectClass: ldapPublicKey
# objectClass: account
# cn: stu14
# uid: stu14
# uidNumber: 20014
# gidNumber: 20000
# homeDirectory: /home/stu14
# loginShell: /bin/bash
# userPassword: {SSHA}cRlbt/snhxEwgG56xKCqjWLY0zZZclNU
# sshPublickey: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFfg2DMY3DfBBvZCnqN8Az5tUnVQca+qXkJ9HceOcRAy 2025-na-hw4
ldapadd -x -H ldapi:/// -D cn=admin,dc=14,dc=nasa -W -f users.ldif
- ACL
vim /etc/ldap/access.ldif
# dn: olcDatabase={1}mdb,cn=config
# changetype: modify
# replace: olcAccess
# olcAccess: to attrs=userPassword
# by dn.exact="uid=generalta,ou=People,dc=14,dc=nasa" =mwscdx
# by self write
# by anonymous auth
# by * none
# olcAccess: to attrs=loginShell,sshPublicKey
# by dn.exact="cn=admin,dc=14,dc=nasa" manage
# by dn.exact="uid=generalta,ou=People,dc=14,dc=nasa" manage
# by self write
# by * read
# olcAccess: to dn.subtree="ou=People,dc=14,dc=nasa"
# by dn.exact="cn=admin,dc=14,dc=nasa" manage
# by dn.exact="uid=generalta,ou=People,dc=14,dc=nasa" manage
# by * read
# olcAccess: to dn.subtree="ou=Group,dc=14,dc=nasa"
# by dn.exact="cn=admin,dc=14,dc=nasa" manage
# by dn.exact="uid=generalta,ou=People,dc=14,dc=nasa" manage
# by * read
# olcAccess: to attrs=shadowLastChange
# by self write
# by * read
# olcAccess: to *
# by * read
ldapmodify -Y EXTERNAL -H ldapi:/// -f access.ldif
- Modify some entry (e.g. password)
vim modify.ldif
# dn: uid=generalta,ou=People,dc=14,dc=nasa
# changetype: modify
# replace: userPassword
# userPassword: {SSHA}cRlbt/snhxEwgG56xKCqjWLY0zZZclNU
sudo ldapmodify -x -H ldapi:/// -D cn=admin,dc=14,dc=nasa -W -f modify.ldif
- Install ppolicy module (source)
sudo apt install libpwquality-dev cracklib-runtime libdb-dev
apt-get source slapd
cd openldap-2.5.13+dfsg
./configure
make depend
vim /etc/ldap/pwquality.conf
# minlen = 8
# minclass = 3
cd /tmp
git clone https://github.com/isarandi/openldap-check-pwquality.git
cd openldap-check-pwquality
sudo make install LDAP_SRC=/root/openldap-2.5.13+dfsg CONFIG_PATH=/etc/ldap/pwquality.conf LDAP_LIBDIR=/usr/lib/ldap
cd /tmp
git clone https://github.com/cracklib/cracklib.git
cd cracklib/words
make
sudo cp cracklib-words /etc/cracklib/
sudo sed -i 's/cracklib_dictpath_src=""/cracklib_dictpath_src="\/etc\/cracklib\/cracklib-words"/' /etc/cracklib/cracklib.conf
sudo update-cracklib
sudo cp /var/cache/cracklib/cracklib_dict* /etc/ldap/
echo 'dictpath = /etc/ldap/cracklib_dict' | sudo tee -a /etc/ldap/pwquality.conf
ls /usr/lib/ldap/check_pwquality.so
- log
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats config acl args trace
EOF
- Password policy
ldapadd -Y EXTERNAL -H ldapi:/// <<EOF
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: ppolicy.la
EOF
vim /etc/ldap/overlay.ldif
# dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
# objectClass: olcOverlayConfig
# objectClass: olcPPolicyConfig
# olcOverlay: ppolicy
# olcPPolicyDefault: cn=default,ou=Ppolicy,dc=14,dc=nasa
ldapadd -Y EXTERNAL -H ldapi:/// -f overlay.ldif
vim /etc/ldap/ppolicy.ldif
# dn: cn=default,ou=Ppolicy,dc=14,dc=nasa
# objectClass: organizationalRole
# objectClass: pwdPolicy
# objectClass: pwdPolicyChecker
# cn: default
# pwdAttribute: userPassword
# pwdAllowUserChange: TRUE
# pwdMinLength: 8
# pwdInHistory: 1
# pwdCheckQuality: 2
# pwdCheckModule: check_pwquality.so
ldapadd -x -H ldapi:/// -D "cn=admin,dc=14,dc=nasa" -W -f ppolicy.ldif
vim /etc/ldap/modify.ldif
# dn: uid=generalta,ou=People,dc=14,dc=nasa
# changetype: modify
# add: pwdPolicySubentry
# pwdPolicySubentry: cn=default,ou=Ppolicy,dc=14,dc=nasa
# dn: uid=stu14,ou=People,dc=14,dc=nasa
# changetype: modify
# add: pwdPolicySubentry
# pwdPolicySubentry: cn=default,ou=Ppolicy,dc=14,dc=nasa
ldapmodify -x -H ldapi:/// -D cn=admin,dc=14,dc=nasa -W -f modify.ldif
- Test
slappasswd -s {yourPassword}
vim /etc/ldap/test.ldif
# dn: uid=test,ou=People,dc=14,dc=nasa
# objectClass: posixAccount
# objectClass: account
# cn: test
# uid: test
# uidNumber: 30000
# gidNumber: 10000
# homeDirectory: /home/test
# loginShell: /bin/bash
# userPassword: {SSHA}cKTeeev5+wQNgO1+Z4y9NDUqYVuCAW4/
ldapadd -x -H ldapi:/// -D uid=generalta,ou=People,dc=14,dc=nasa -W -f test.ldif
vim /etc/ldap/modify.ldif
# dn: uid=test,ou=People,dc=14,dc=nasa
# changetype: modify
# replace: userPassword
# userPassword: {SSHA}cKTeeev5+wQNgO1+Z4y9NDUqYVuCAW4/
ldapmodify -x -H ldapi:/// -D uid=generalta,ou=People,dc=14,dc=nasa -W -f modify.ldif
- Add ObjectClass
fortune
vim /etc/ldap/schema/fortune.ldif
# dn: cn=fortune,cn=schema,cn=config
# objectClass: olcSchemaConfig
# cn: fortune
# olcAttributeTypes: {0}( 2.25.20250524.1.1 NAME 'author' DESC 'author' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch ORDERING caseIgnoreOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
# olcAttributeTypes: {1}( 2.25.20250524.1.2 NAME 'id' DESC 'id' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
# olcObjectClasses: {0}( 2.25.20250524.2.1 NAME 'fortune' DESC 'fortune' SUP top STRUCTURAL MUST cn MAY ( author $ id $ description ) )
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/fortune.ldif
ldapsearch -H ldapi:/// -Y EXTERNAL -b cn={6}fortune,cn=schema,cn=config
- Convert yml to ldif
import yaml
with open('hw4fortunes.yml', 'r') as file:
entries = yaml.safe_load(file)
with open('hw4fortunes.ldif', 'w') as ldif:
for entry in entries:
id_value = entry.get('ID')
author = entry.get('Author')
description = entry.get('Description')
dn = f"dn: cn=fortune-{id_value},ou=Fortune,dc=14,dc=nasa\n"
obj_classes = "objectClass: fortune\nobjectClass: top\n"
cn = f"cn: fortune-{id_value}\n"
author_field = f"author: {author}\n"
id_field = f"id: {id_value}\n"
description_field = f"description: {description}\n"
ldif_entry = dn + obj_classes + cn + author_field + id_field + description_field + "\n"
ldif.write(ldif_entry)
ldapadd -H ldapi:/// -x -D "cn=admin,dc=14,dc=nasa" -W -f hw4fortunes.ldif
- sssvlv
ldapadd -Y EXTERNAL -H ldapi:/// <<EOF
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: sssvlv.la
EOF
vim /etc/ldap/sssvlv.ldif
# dn: olcOverlay=sssvlv,olcDatabase={1}mdb,cn=config
# objectClass: olcOverlayConfig
# objectClass: olcSssVlvConfig
# olcOverlay: sssvlv
# olcSssVlvMax: 10
# olcSssVlvMaxKeys: 5
ldapadd -Y EXTERNAL -H ldapi:/// -f sssvlv.ldif
ldapsearch -Y EXTERNAL -H ldapi:/// -b "ou=fortune,dc=14,dc=nasa"
Bonus - Mail server
- Setting
sudo apt-get update
sudo apt-get install postfix-ldap dovecot-ldap
sudo vim /etc/dovecot/conf.d/10-auth.conf
# !include auth-ldap.conf.ext
sudo vim /etc/dovecot/conf.d/auth-ldap.conf.ext
# passdb {
# driver = ldap
# args = /etc/dovecot/dovecot-ldap.conf.ext
# }
# userdb {
# driver = ldap
# args = /etc/dovecot/dovecot-ldap.conf.ext
# }
sudo vim /etc/dovecot/dovecot-ldap.conf.ext
# hosts = ldap.14.nasa:636
# dn = cn=admin,dc=14,dc=nasa
# dnpass = 0000
# base = ou=People,dc=14,dc=nasa
# scope = subtree
# auth_bind = yes
# ldap_version = 3
# user_attrs = homeDirectory=home,uidNumber=uid,gidNumber=gid
# user_filter = (&(objectClass=posixAccount)(uid=%u))
# pass_filter = (&(objectClass=posixAccount)(uid=%u))
sudo vim /etc/postfix/main.cf
# smtpd_sender_login_maps = hash:/etc/postfix/login_maps, ldap:/etc/postfix/ldap.cf
vim /etc/postfix/ldap.cf
# server_host = ldap.14.nasa:636
# search_base = ou=People,dc=14,dc=nasa
# version = 3
sudo systemctl restart postfix
sudo systemctl restart dovecot
- Restart service & Check the config
slaptest -u
sudo systemctl restart slapd
sudo slapcat -n 0
ldapsearch -H ldapi:/// -Y EXTERNAL -b "cn=config" -LLL -Q -s base
ldapsearch -H ldapi:/// -x -b "dc=14,dc=nasa"
ldapsearch -H ldapi:/// -x -b "dc=14,dc=nasa" ou
ldapsearch -H ldapi:/// -x -b "ou=People,dc=14,dc=nasa"
LDAP client
5E842AEEEDB8F6EA8857E6D1FB72E76E
- Trust the certs
sudo vim /usr/local/share/ca-certificates/ldap.crt
sudo update-ca-certificates
sudo apt install sssd libnss-sss libsss-sudo libpam-sss sssd-ldap ldap-utils -y
sudo vim /etc/sssd/sssd.conf
# [sssd]
# services = nss, pam, sudo
# config_file_version = 2
# domains = ldap
# [nss]
# default_shell = /bin/bash
# [domain/ldap]
# id_provider = ldap
# auth_provider = ldap
# chpass_provider = ldap
# access_provider = ldap
# ldap_uri = ldaps://ldap.14.nasa
# ldap_tls_cacert = /etc/ssl/certs/ca-certificates.crt
# ldap_search_base = dc=14,dc=nasa
# ldap_user_shell = loginShell
# ldap_sudo_search_base = ou=SUDOers,dc=14,dc=nasa
# ldap_user_ssh_public_key = sshPublicKey
# ldap_user_object_class = posixAccount
# ldap_group_object_class = posixGroup
# ldap_user_home_directory = homeDirectory
# ldap_access_order = filter
# ldap_access_filter = (|(gidNumber=10000)(gidNumber=20000))
sudo chmod 600 /etc/sssd/sssd.conf
sudo vim /etc/nsswitch.conf
sudo pam-auth-update --enable mkhomedir
sudo vim /etc/pam.d/common-session
# session required pam_mkhomedir.so skel=/etc/skel umask=077
sudo vim /etc/ssh/sshd_config
# AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
# AuthorizedKeysCommandUser nobody
sudo systemctl enable sssd
sudo systemctl restart sssd
sudo systemctl restart sshd
sudo systemctl status sssd
