TurnKey Linux Virtual Appliance Library

TKLPatch for OpenLDAP [UPDATED 20-09-2010]

Hi everyone. LDAP for me is like DNS, one of those complex topics I prefer to be far away. Anyway, I do cross with ldap servers on my job, so I think this TKLPatch will be usefull. On to details:

 

Features:

OpenLDAP server
TLS-SSL enabled
Custom ldap-setup script to create initial root of DIT based on your domain and organization name, with standard organizational units people, groups and machines. Also lets you setup replication if you need it. 
ldapscripts installed and configured (convenience)
phpldapadmin installed and configured (convenience)
[Added 20/09/2010] Official webmin module for openldap-server to manage openldap from within webmin
Default admin password: turnkey
 
* This is a custom script that ask your domain and organization name, an then:
  - Modifies and loads a customized backend and frontend templates ldif.
  - Configure ldapscripts settings to point to your dn.
  - Configure phpldapadmin to point to your dn.
  - Also, if replication is needed, it will ask you for details to set this server as provider or consumer and sets tls-enabled replication between servers. More details down this thread.
 
Configurations for this appliance where taken from Ubuntu OpenLDAP Server Official Documentation
 

What it does:

 
1. Updates package information
apt-get update
 
2. Sets Hostname to ldap.
HOSTNAME=ldap
echo "$HOSTNAME" > /etc/hostname
sed -i "s|127.0.1.1 \(.*\)|127.0.1.1 $HOSTNAME|" /etc/hosts
hostname ldap
3. Install required packages (update: added apparmor-profiles apparmor gnutls-bin)
[Updated 20/09/2010] - Added webmin-ldap-server libnet-ldap-perl packages. 
install slapd ldap-utils ldapscripts apache2 apache2-mpm-prefork apache2-utils apache2.2-bin apache2.2-common libapache2-mod-php5 libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap php5-common php5-ldap ssl-cert apparmor-profiles apparmor gnutls-bin webmin-ldap-server libnet-ldap-perl
 
4. Add initial ldap schemas: minimum required for openldap to work.
 
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif
 
4.5 (updated) Set info for self signed certificates (generated using gnutls)
	echo "cn = Turnkeylinux Appliances" > /etc/ssl/ca.info
echo "ca" >> /etc/ssl/ca.info
echo "cert_signing_key" >> /etc/ssl/ca.info
echo "organization = Turnkeylinux Appliances" > /etc/ssl/ldap.info
echo "cn = ldap" >> /etc/ssl/ldap.info
echo "tls_www_server" >> /etc/ssl/ldap.info
echo "encryption_key" >> /etc/ssl/ldap.info
echo "signing_key" >> /etc/ssl/ldap.info
4.6 (Updated) Generate self signed certificates
	certtool --generate-privkey > /etc/ssl/private/cakey.pem
certtool --generate-self-signed --load-privkey /etc/ssl/private/cakey.pem --template /etc/ssl/ca.info --outfile /etc/ssl/certs/cacert.pem
certtool --generate-privkey > /etc/ssl/private/ldap_slapd_key.pem
certtool --generate-certificate --load-privkey /etc/ssl/private/ldap_slapd_key.pem --load-ca-certificate /etc/ssl/certs/cacert.pem --load-ca-privkey /etc/ssl/private/cakey.pem --template /etc/ssl/ldap.info --outfile /etc/ssl/certs/ldap_slapd_cert.pem
 
5. Activate TLS and SSL: The first line modifies cn=config to add the location of the ssl certificates. Adds ldaps protocol to /etc/default/slapd. Adds the openldap user to the ssl-cert group so that it can read the certificates.
 
ldapmodify -Y EXTERNAL -H ldapi:/// -f /src/tls-ssl.ldif
sed -i 's|SLAPD_SERVICES="ldap:/// ldapi:///"|SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"|' /etc/default/slapd
adduser openldap ssl-cert
service slapd restart
 
6. Configure ldapscripts password. The dn configuration is handled by the ldapsetinitialdn script. So here we simply set the password to 'turnkey' which is the default for admin in this appliance.
 
sh -c "echo -n 'turnkey' > /etc/ldapscripts/ldapscripts.passwd"
sudo chmod 400 /etc/ldapscripts/ldapscripts.passwd
 
7. Download and install phpldapadmin. Self signed certificate of the ppa fails, so the --no-check-certificate option is used.
 
wget http://launchpad.net/~ubuntu-security-proposed/+archive/ppa/+build/17449... --no-check-certificate
dpkg -i phpldapadmin_1.2.0.5-1ubuntu1.10.04.1_all.deb
8. Activate phpldapadmin site for http and https. Config files are overlayed. Finally stop services.
a2enmod ssl
a2dissite default
a2ensite phpldapadmin
a2ensite phpldapadmin-ssl
service apache2 stop
service slapd stop
 
9. Clean apt cache
cleanup_apt
 

ldap-setup script

20/09/2010 - Added 

 

echo "Configuring Webmin Module"
# Set pass in webmin module
sed -i -r "s/pass=.*/pass=$PASSWD/" /etc/webmin/ldap-server/config
The content of the ldaptklsetup script is the following:
 
#!/bin/bash -e
# ldapsetinitialdn: Ask for domain name to create LDAP dn initial entries
# and configure the Turnkeylinux OpenLDAP appliance
# Created by Adrian Moya 2010
echo
echo "Turnkeylinux LDAP Appliance"
echo "Please input the domain for your LDAP directory"
echo "Example: example.com (for dc=example, dc=com)"
ANSWER="n"
while [ $ANSWER != "y" ]; do
  dn=""
  echo
  read -p "Domain: " DOMAIN
  read -p "Organization name: " ORGNAME
  stty -echo 
  read -p "Password for admin: " PASSWD; echo 
  stty echo  
  FIRST="true"
  for i in $(echo $DOMAIN | tr "." "\n")
  do
    dn=$dn"dc=$i,"    
    if [ "$FIRST" = "true" ]; then
      dc=$i
      FIRST="false"
    fi
  done    
  dn=`echo $dn|sed s/.$//`
  REPLICATION=""
  while [[ $REPLICATION != "y" && $REPLICATION != "n" ]]; do
    read -p "Do you want to configure replication (y/n): " REPLICATION
  done
  if [ $REPLICATION = "y" ]; then
    HOSTNAME=""
    while [[ $HOSTNAME = "" ]]; do
      read -p "Hostname for this server: " HOSTNAME
    done
    ROLE=""
    while [[ $ROLE != "p" && $ROLE != "c" ]]; do
      read -p "Will this server act as a provider or consumer? (p/c): " ROLE
    done
    ROLETEXT="Provider"
    if [ $ROLE = "c" ]; then
      read -p "Provider's server Hostname: " PROVIDERHOSTNAME
      read -p "Provider's server IP: " PROVIDERIP
      ROLETEXT="Consumer"
    fi
  fi  
  echo 
  echo "Information summary:"
  echo 
  echo "Domain set to: $DOMAIN ($dn)"
  echo "Organization name: $ORGNAME"
  echo "Replication: $REPLICATION"
  if [ $REPLICATION = "y" ]; then
    echo "Role: $ROLETEXT"
    echo "Hostname: $HOSTNAME"
    if [ $ROLE = "c" ]; then
      echo "Provider's Hostname: $PROVIDERHOSTNAME"      
      echo "Provider's IP: $PROVIDERIP"
    fi
  fi
  echo
  read -p "Is this information correct: (y/n)" ANSWER
done

# Modify and Load previously overlayed backend and frontend examples.
# Also config scriptutils

echo "Loading info for $ORGNAME"
# Backend
sed -i "s/dc=example,dc=com/$dn/" /src/backend.example.com.ldif
sed -i "s/olcRootPW: turnkey/olcRootPW: $PASSWD/" /src/backend.example.com.ldif

# Frontend
sed -i "s/dc=example,dc=com/$dn/" /src/frontend.example.com.ldif
sed -i "s/Example Organization/$ORGNAME/" /src/frontend.example.com.ldif
sed -i "s/dc: Example/dc: $dc/" /src/frontend.example.com.ldif
sed -i "s/userPassword: turnkey/userPassword: $PASSWD/" /src/frontend.example.com.ldif

# Replication
sed -i "s/dc=example,dc=com/$dn/" /src/provider_sync.ldif
sed -i "s/dc=example,dc=com/$dn/" /src/consumer_sync.ldif
sed -i "s|ldap://ldap01.example.com|ldap://$PROVIDERHOSTNAME|" /src/consumer_sync.ldif
sed -i "s/credentials=turnkey/credentials=$PASSWD/" /src/consumer_sync.ldif

# Add backend and frontend
ldapadd -Y EXTERNAL -H ldapi:/// -f /src/backend.example.com.ldif
ldapadd -x -D cn=admin,$dn -w $PASSWD -f /src/frontend.example.com.ldif

# If replication is enabled, make configurations
if [ $REPLICATION = "y" ]; then  
  echo "$HOSTNAME" > /etc/hostname
  sed -i "s|127.0.1.1 \(.*\)|127.0.1.1 $HOSTNAME|" /etc/hosts
  if [ $ROLE = "p" ]; then 
    certtool --generate-privkey > /etc/ssl/private/${HOSTNAME}_slapd_key.pem
    echo "organization = Turnkeylinux Appliances" > /etc/ssl/${HOSTNAME}.info
    echo "cn = $HOSTNAME" >> /etc/ssl/${HOSTNAME}.info
    echo "tls_www_server" >> /etc/ssl/${HOSTNAME}.info
    echo "encryption_key" >> /etc/ssl/${HOSTNAME}.info
    echo "signing_key" >> /etc/ssl/${HOSTNAME}.info
    certtool --generate-privkey > /etc/ssl/private/${HOSTNAME}_slapd_key.pem
    certtool --generate-certificate --load-privkey /etc/ssl/private/${HOSTNAME}_slapd_key.pem --load-ca-certificate /etc/ssl/certs/cacert.pem --load-ca-privkey /etc/ssl/private/cakey.pem --template /etc/ssl/${HOSTNAME}.info --outfile /etc/ssl/certs/${HOSTNAME}_slapd_cert.pem    
    sed -i "s/}//" /etc/apparmor.d/usr.sbin.slapd
    echo "  # accesslog database location" >> /etc/apparmor.d/usr.sbin.slapd
    echo "  /var/lib/ldap/accesslog/ r," >> /etc/apparmor.d/usr.sbin.slapd
    echo "  /var/lib/ldap/accesslog/** rwk," >> /etc/apparmor.d/usr.sbin.slapd
    echo "}" >> /etc/apparmor.d/usr.sbin.slapd
    sudo -u openldap mkdir /var/lib/ldap/accesslog
    sudo -u openldap cp /var/lib/ldap/DB_CONFIG /var/lib/ldap/accesslog/    
    service apparmor reload
    ldapadd -Y EXTERNAL -H ldapi:/// -f /src/provider_sync.ldif
  else
    echo "$PROVIDERIP $PROVIDERHOSTNAME" >> /etc/hosts
    echo 
    echo "Please answer yes and provide root password for $PROVIDERHOSTNAME"
    echo 
    ssh-copy-id -i /etc/ssh/ssh_host_rsa_key.pub $PROVIDERHOSTNAME
    ssh root@$PROVIDERHOSTNAME "mkdir -p /etc/ssl/${HOSTNAME}"
    ssh root@$PROVIDERHOSTNAME "certtool --generate-privkey > /etc/ssl/${HOSTNAME}/${HOSTNAME}_slapd_key.pem"
    ssh root@$PROVIDERHOSTNAME "echo organization = ${ORGNAME} > /etc/ssl/${HOSTNAME}.info"
    ssh root@$PROVIDERHOSTNAME "echo cn = ${HOSTNAME} >> /etc/ssl/${HOSTNAME}.info"
    ssh root@$PROVIDERHOSTNAME "echo tls_www_client >> /etc/ssl/${HOSTNAME}.info"
    ssh root@$PROVIDERHOSTNAME "echo encryption_key >> /etc/ssl/${HOSTNAME}.info"            
    ssh root@$PROVIDERHOSTNAME "echo signing_key >> /etc/ssl/${HOSTNAME}.info"            
    ssh root@$PROVIDERHOSTNAME "certtool --generate-certificate --load-privkey /etc/ssl/${HOSTNAME}/${HOSTNAME}_slapd_key.pem --load-ca-certificate /etc/ssl/certs/cacert.pem --load-ca-privkey /etc/ssl/private/cakey.pem --template /etc/ssl/${HOSTNAME}.info --outfile /etc/ssl/${HOSTNAME}/${HOSTNAME}_slapd_cert.pem"
    ssh root@$PROVIDERHOSTNAME "cp /etc/ssl/certs/cacert.pem /etc/ssl/${HOSTNAME}/"   
    scp root@$PROVIDERHOSTNAME:/etc/ssl/${HOSTNAME}/\{cacert.pem,${HOSTNAME}_slapd_cert.pem\} /etc/ssl/certs
    scp root@$PROVIDERHOSTNAME:/etc/ssl/${HOSTNAME}/${HOSTNAME}_slapd_key.pem /etc/ssl/private
    ldapadd -c -Y EXTERNAL -H ldapi:/// -f /src/consumer_sync.ldif
    echo "TLS_REQCERT allow" >> /etc/ldap/ldap.conf
    echo "TLS_CERT /etc/ssl/certs/${HOSTNAME}_slapd_cert.pem" >> /etc/ldap/ldap.conf
    echo "TLS_KEY /etc/ssl/private/${HOSTNAME}_slapd_key.pem" >> /etc/ldap/ldap.conf
    echo "TLS_CACERT /etc/ssl/certs/cacert.pem" >> /etc/ldap/ldap.conf
  fi
  sed -i "s/ldap_slapd_cert.pem/${HOSTNAME}_slapd_cert.pem/" /src/tls-ssl-replication.ldif
  sed -i "s/ldap_slapd_key.pem/${HOSTNAME}_slapd_key.pem/" /src/tls-ssl-replication.ldif      
  ldapmodify -Y EXTERNAL -H ldapi:/// -f /src/tls-ssl-replication.ldif
  service slapd restart
fi

echo "Configuring ldapscripts"
# ldapscripts
sed -i "s/dc=example,dc=com/$dn/" /etc/ldapscripts/ldapscripts.conf
echo -n $PASSWD > /etc/ldapscripts/ldapscripts.passwd

	echo "Configuring Webmin Module"
# Set pass in webmin module
sed -i -r "s/pass=.*/pass=$PASSWD/" /etc/webmin/ldap-server/config

echo "Configuring phpldapadmin" # phpldapadmin sed -i "s/dc=example,dc=com/$dn/" /usr/share/phpldapadmin/config/config.php # Restart Apache service apache2 restart echo "Done!"

This script changed as I added the support for replication as suggested by Basil. 
 

Other updates:

Added an overlayed script to regenerate certificates on firstboot.
Added more ldif templates on /src (don't know if this is the right place, haven't read the HFS yet!)
Moved changed script name and moved it into /usr/sbin (just to be in the same place as ldapscripts)
 

Known issues:

- phpldapadmin seems a bit unstable. But it's the best choice I saw on the internet. Via ubuntu's repository, version 1.1.0.7 seems to be more stable, but the official homepage states that it has a security vulnerability. Anyway, try it out, maybe it's me that don't know how to fully use it. 
- ldaptklsetup it's a bit strict in it's job. So if you input some wrong information, you could end up with a broken appliance. You have two choices: either reinstall and run it again, or apply your ldap knowledge and repair things manually. The operations that the script performs need that the user is carefull when working with it. But if you input your settings right, you'll see the magic! 
 

Examples on replication settings:

On the provider:
(tklpatch)root@ldap ~# ldaptklsetup 
Turnkeylinux LDAP Appliance
Please input the domain for your LDAP directory
Example: example.com (for dc=example, dc=com)

Domain: turnkeylinux.com
Organization name: Turnkeylinux appliances
Password for admin: 
Do you want to configure replication (y/n): y
Hostname for this server: ldapmaster
Will this server act as a provider or consumer? (p/c): p

Information summary:

Domain set to: turnkeylinux.com (dc=turnkeylinux,dc=com)
Organization name: Turnkeylinux appliances
Replication: y
Role: Provider
Hostname: ldapmaster

Is this information correct: (y/n)y
 
On the consumer:
(tklpatch)root@ldap ~# ldaptklsetup 
Turnkeylinux LDAP Appliance
Please input the domain for your LDAP directory
Example: example.com (for dc=example, dc=com)

Domain: turnkeylinux.com
Organization name: Turnkeylinux Appliances
Password for admin: 
Do you want to configure replication (y/n): y
Hostname for this server: ldap01
Will this server act as a provider or consumer? (p/c): c
Provider's server Hostname: ldap00
Provider's server IP: 192.168.3.7

Information summary:

Domain set to: turnkeylinux.com (dc=turnkeylinux,dc=com)
Organization name: Turnkeylinux Appliances
Replication: y
Role: Consumer
Hostname: ldap01
Provider's Hostname: ldap00
                                                                                
Is this information correct: (y/n)y 
 
As always, feedback and good criticism are welcome.

Open for ideas to enhance this TKLPatch

 

Initially, my idea was that ldapsetinitialdn runned on the first boot. That way, the user would have installed the TKL and get it configured on startup. I placed the script in /usr/lib/firstboot.d but when it got executed, there were no keyboard input in VirtualBox, which is my hypervisor of choice. Since the appliance got stuck waiting for user input, I had to remove the script from there. Maybe this is a bug in VirtualBox or maybe this is the way it should work, the fact is that I feel there is a big base of VBox users out there which are going to be dissapointed. So I just moved it to /usr/bin (maybe I should have moved it to /usr/local/bin but that can be done on a later version). 
 
Now, the user can login to the appliance the first time and run ldapsetinitialdn to get the DIT initial config and ldapscripts and phpldapadmin configured. Suggestions for a better user experience are welcome, as well as suggestions and constructive critic. 
 
LDAP is a complex subject which I haven't studied yet, but I've learned a bit working on this TKLPatch. 
Basil Kurian's picture

My 2 cents

Earler i tried to implement it on turnkey

http://www.turnkeylinux.org/forum/general/20100804/user-authentication-s...

There are some technical problems which i face are  

As far as i know , no one is going  to deploy an authentication server on cloud. Also no one will use a  turnkey applaince on a dedicated hardware  only for user authentication.

 

Also user authentication systems normally require replication (for ensuring reliablity and loadsharing ), that is a another slave LDAP appliaince is also required.... which makes the task much more harder

I just read the documentation of your patch . It would be nice if you can share the homefolder using NFS


I would!

no one is going  to deploy an authentication server on cloud

I would! smiley And I think there is a demand for this type of appliance. Remember there are public and private clouds. You can easily deploy this one on your private cloud (behind the corporate firewall) or if you wish (or need) to deploy it public, be sure to take care of details regarding security. If you look in the forum there are some old posts asking for an LDAP server, even TKLs guys where planning on making one. Now, there is one for the community! 

Also no one will use a  turnkey applaince on a dedicated hardware  only for user authentication.

We agree on this one. I won't use dedicated hardware for almost anything that it isn't a baremetal hypervisor this time!!! 

Also user authentication systems normally require replication

This one is a matter of taste. If you run a small business with 20 or less workstations, maybe you won't need replication. Now, if you really need high availability or your user base is bigger, that would be important. Based on this appliance, you can config your replication mechanism, but based on your suggestion, I'm working to enhance the initial setup script to add some questions about replication. I'll see if I can finish it today. 

It would be nice if you can share the homefolder using NFS

I didn't wanted to mix this appliance with users home folders, as maybe not everyone (me for example) is going to use that kind of setup. I know that we could mix this one with a pdc and make a more complex appliance, we could discuss this one on the forum on another thread. 

Thanks for your comments!

Basil Kurian's picture

I didn't knew about Private

I didn't knew about Private clouds . So some of my points are not valid.

In my humble openion , in a system with some 20 nodes , NIS would be a good choice than LDAP.

It would be nice if you can add TLS Security to the LDAP server. Because without TLS all data including password will be  transmitted as plain text. Some one may be able to sniff the 389 port using tools like TCPDump

I 'm writing all this because  you said that the project is open to suggestions and criticisms .


Basil Kurian's picture

i mean Home folder of users

i mean

Home folder of users on server should be on /rhome

eg : /rhome/basil

 

Server # nano /etc/exports

/rhome *(rw)

 

Client # nano /etc/fstab

 

<Server_IP>:/rhome     /rhome         nfs          user,auto,defaults       0   0


Liraz Siri's picture

Wowsers!

Adrian, we pretty much feel the same way about LDAP. Having maintained a DNS server or two in my sordid past I'm much more comfortable with that.

If the stars align maybe an LDAP expert from the community steps in and share his wisdom with us.

I can't comment on any LDAP specific bits but the complexity and attention to detail here is again very impressive. As you can imagine, not being an LDAP person myself I found the documentation provided to be immensely helpful in understanding what was going on. Kudos!

Liraz Siri's picture

Feedback on the update

If you don't mind I added a bit of syntax highlighting to that beautiful configuration script you created by putting a <code> tag after the <pre>.

  • I love that you've gone to the trouble of enabling SSL certificates and didn't forget to regenerate them on first boot.
  • Nice to see slapd has an AppArmor profile for it and that you've installed AppArmor to take advantage of it.
  • I would rename the configuration script something really simple like /usr/local/bin/ldap-setup
  • The configuration script looks extremely useful. I know some people are afraid of the command line but the alternative would be much more complex to implement.
  • Did you look at the webmin openldap module? It's a bit dated but it might still be useful...

Some changes

I've uploaded a newer version that includes the official ldap-server webmin module (I think Liraz missed that one, as he suggested a very outdated module). It allows you to manage openldap form within webmin. It's not totally seamless with the current configuration, as it doesn't take the certificates generated by default. I think it's not getting the configuration from ldap backend. 

I updated the script (and changed the name as suggested) to set the password for this module. So after running the script, you will be able to manage openldap from webmin. The module is not for beginners in my opinion, you will still need ldap knowledge to be able to do something with it. I think it's still easier to use ldapscript on console or phpldapadmin. 

Waiting for more feedback on how to make this one more useful. 

You need to rename de file

Be sure to rename the patch file from openldap.tar_1.gz to openldap.tar.gz. The file gets renamed when I uploadit to this forum, but the name must be openldap.tar.gz.

Also, the patch was tested to be applied on turnkey-core. I'm not sure it will work in TKL PDC. 

Last but not least: the patch is some months old, and the main Devs are working on the official TKL OpenLDAP appliance, so it won't be updated anymore. Use it at your own risk. 

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account, used to display your avatar.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <p> <span> <div> <h1> <h2> <h3> <h4> <h5> <h6> <img> <map> <area> <hr> <br> <br /> <ul> <ol> <li> <dl> <dt> <dd> <table> <tr> <td> <em> <b> <u> <i> <strong> <font> <del> <ins> <sub> <sup> <quote> <blockquote> <pre> <address> <code> <cite> <strike> <caption>

More information about formatting options

Leave this field empty. It's part of a security mechanism.
(Dear spammers: moderators are notified of all new posts. Spam is deleted immediately)