Originally I researched a bit to get ideas and started writing a tool to add email user accounts in LDAP. That eventualy manfested into another separate script which creates email distribution groups. While one could just as easily use phpLDAPadmin, Apache Directory Studio and others by giving a .ldif file - I wanted something with less overhead, so I began to write a script that was specific to only adding LDAP email users and distribution groups interactively. In a nutshell these scripts use an LDIF template to help create the email user account or email distribution group on the fly. There is no need to ever manually edit a .ldif file since all you do is give some preliminary info and be done with it.

Email Users

Invoking the script as root or sudo will run through the following.

# ./add_ldap_mail_user.sh
First Name: Jane
Last Name: Doe
User Name [uid]: jane.doe


Enter the domain to use for the mail account: domain4.email
creating mail account on domain4.email
adding new entry "uid=jane.doe,ou=Mail,dc=example,dc=com"

modifying entry "cn=vmail,ou=Groups,c=example,dc=com"

Successfully added Mail account

We can see our new email user gets added to an LDAP group. Note that this is a standard groupOfNames group and not an email distribution group.

Email Welcome Message

When an LDAP email user is added, a welcome email message is sent to the newly created user's Inbox. A default html and plain text email template are available to use. It is also easy to have your own customizable email templates.

Email Distribution Groups

Invoking the script will run through the following to create an email distribution group.

# ./add_ldap_mail_group.sh
Email Group Name: engineers


Enter the domain to use for the mail group: domain4.email
creating mail group on domain4.email
adding new entry "cn=engineers,ou=Groups,ou=Mail,dc=example,dc=com"

Successfully added Email Distribution Group

Group members can be added using the mailGroupMember attribute provided by postfix-book.schema, respectively.


Comments, improvements, PRs and everything else should be directed on GitHub.

PRs welcome.


I stumbled across openssh-ldap-publickey while looking to setup SSH keys in LDAP and found the setup to be a breeze. The project provides a wrapper for OpenSSH to store public keys inside the OpenLDAP entry. Here I will document the steps I went through to get SSH key auth working with OpenLDAP.


  1. First install some dependencies. Here are the Arch Linux package names and designated repos.

Update 09/22/17: For those on Arch Linux, I created an Arch PKGBUILD that can be used to install openssh-ldap-publickey and dependencies.

community/perl-net-ldap-server 0.43-3 [installed]
  Perl extension for LDAP server side protocol handling

aur/pear-net-ldap2 2.2.0-3 [installed] (1) (0.41)
  Object oriented interface for searching and manipulating LDAP-entries

aur/pear-net-ldap3 1.0.4-2 [installed] (1) (0.41)
  Object oriented interface for searching and manipulating LDAP-entries
  1. Load openssh-lpk-openldap.schema into OpenLDAP.

Inside sshd_config we have a couple of options

  1. Use authorized_keys and LDAP: AuthorizedKeysFile .ssh/authorized_keys
  2. Use only LDAP: AuthorizedKeysFile /dev/null

  3. Include these two lines
    AuthorizedKeysCommand /usr/local/bin/openssh-ldap-publickey
    AuthorizedKeysCommandUser nobody


A typical LDAP People record can now have a new objectClass ldapPublicKey and attribute sshPublicKey in which case a user's public key can be attached to the sshPublicKey attribute.


I have used Splunk for years and still use Splunk Enterprise at work and for my own use as part of the Free license group. With Splunk Free you have to keep your daily quota below 500 MB. Splunk Free is technically Splunk Enterprise, but with certain features disabled. In my own environment Splunk and Apache are external facing, so that means if someone knows the URL they can simply login without any kind of authentication since Splunk Free disables this. The following is a block of code that can be used with Apache 2.4.

Apache Config

Adjust /etc/httpd/conf/extra/splunk.conf to match your own environment as needed.

# LDAP auth
  Require all denied
  AuthName "This Splunk Restricted Area Requires LDAP Authentication"
  AuthType Basic
  AuthBasicProvider ldap
  AuthLDAPURL "ldap://,dc=domain,dc=net"
  Require ldap-group cn=splunk-staff,ou=Groups,dc=domain,dc=net
  AuthLDAPMaxSubGroupDepth 1

After reloading httpd we can see that visiting our Splunk page over SSL presents our login.


I wanted a quick way to monitor a remote Nagios host from a secondary Linux server in the event the primary Nagios instance became unavailabile for any number of reasons like httpd going down.

Check if host is alive

#!/usr/bin/env bash

# Monitor if remote service (ie httpd) is down
# and alert staff/admins. Useful in the event a Nagios
# instance is hosted on same http host

$(nc -z -w5 $SERVER $PORT)


#check remote host/port status
if [ "$result" != 0 ]; then

    mail -s "$SERVICE service on $HOST is not responding" -r "$MAILFROM" "$MAILTO"  <<END_OF_EMAIL
$SERVICE is not listening on $HOST port $PORT. Please check.


exit 0

I would highly recommend Uptime Robot for an external monitoring service.


With OpenVPN it is quite common to use Easy-RSA to create a Public Key Infrastructure (PKI) so that client certificates may be distributed. For my use case I much prefer to use LDAP authentication with OpenVPN. I use OpenLDAP but any LDAP server should be fine. I am also using an Arch PKGBUILD file to build the actual plugin that makes OpenVPN work with LDAP auth.

LDAP Prerequisite

Before anything can work we need to have an OpenVPN LDAP schema loaded into our environment. While this LDAP schema offers many attributes, for my use case I only care about having authorized VPN users connect. Once openvpn-ldap.schema is loaded, an LDAP record can contain a new VPN objectClass and attributes.

objectClass: openVPNUser
openvpnEnabled: TRUE
openvpnClientx509CN: mydomain.net

The nice thing about this is we can easily modify a People record to enable or disable VPN user access.

LDAP OpenVPN Config

There are only a few fairly simple things to do once our environment is ready for OpenVPN.

  1. Build and install the openvpn-auth-ldap plugin. On Arch Linux you can easily build and install the plugin from AUR.
  2. Add the following to your OpenVPN server configuration:
    plugin /usr/lib/openvpn/plugins/openvpn-auth-ldap.so /etc/openvpn/auth/auth-ldap.conf

    Adjust the paths for openvpn-auth-ldap.so and auth-ldap.conf as needed.

  3. It is a good idea to keep a default copy of auth-ldap.conf. An example configuration can be found on GitHub. Since I like to be organized I keep my LDAP config inside /etc/openvpn/auth.
  4. Restart OpenVPN after modifying auth-ldap.conf accordingly. With systemd one can execute systemctl restart openvpn-server@server, respectively.


Upon restarting, openvpn.log should show a plugin initialization entry similar to

PLUGIN_INIT: POST /usr/lib/openvpn/plugins/openvpn-auth-ldap.so '[/usr/lib/openvpn/plugins/openvpn-auth-ldap.so] [/etc/openvpn/auth/auth-ldap.conf]' intercepted=PLUGIN_AUTH_USER_PASS_VERIFY|PLUGIN_CLIENT_CONNECT|PLUGIN_CLIENT_DISCONNECT

At this point we can now have our VPN client authenticate with a username and password using our LDAP auth backend. We can see successful LDAP connections in openvpn.log when a new client connects. TLS: Initial packet from [AF_INET], sid=42bec808 6635b5f5 peer info: IV_VER=2.4.3 peer info: IV_PLAT=mac peer info: IV_PROTO=2 peer info: IV_NCP=2 peer info: IV_LZ4=1 peer info: IV_LZ4v2=1 peer info: IV_LZO=1 peer info: IV_COMP_STUB=1 peer info: IV_COMP_STUBv2=1 peer info: IV_TCPNL=1 PLUGIN_CALL: POST /usr/lib/openvpn/plugins/openvpn-auth-ldap.so/PLUGIN_AUTH_USER_PASS_VERIFY status=0 TLS: Username/Password authentication succeeded for username 'tony' Control Channel: TLSv1.2, cipher TLSv1.2 DHE-RSA-AES256-GCM-SHA384 [] Peer Connection Initiated with [AF_INET] MULTI_sva: pool returned IPv4=, IPv6=(Not enabled) PLUGIN_CALL: POST /usr/lib/openvpn/plugins/openvpn-auth-ldap.so/PLUGIN_CLIENT_CONNECT status=0 OPTIONS IMPORT: reading client specific options from: /tmp/openvpn_cc_0e9bde0ccb231123af86cd70e8a6f37c.tmp MULTI: Learn: -> MULTI: primary virtual IP for PUSH: Received control message: 'PUSH_REQUEST' SENT CONTROL [UNDEF]: 'PUSH_REPLY,route,route,redirect-gateway def1 bypass-dhcp,dhcp-option DNS,dhcp-option DNS,route,topology net30,ping 10,ping-restart 120,ifconfig,peer-id 1,cipher AES-256-GCM' (status=1) Data Channel: using negotiated cipher 'AES-256-GCM' Data Channel Encrypt: Cipher 'AES-256-GCM' initialized with 256 bit key Data Channel Decrypt: Cipher 'AES-256-GCM' initialized with 256 bit key