OATH-LDAP

Download

oath-ldap-tool
Command-line tool implementing various use-cases via sub-commands
oath-ldap-srv
Server services (bind listeners and OATH enrollment web app)

For a turn-key solution you might want to consider using Æ-DIR as identity and access management which has OATH-LDAP integrated and automatically configured.

Installation

Prerequisites

Command-line tool

For first tests simply create a separate Python virtualenv (herein it is directory /opt/oathldap):

$ python3 -m venv /opt/oathldap

Now install oathldap package:

$ /opt/oathldap/bin/pip3 install oath-ldap-tool
[..lots of output..]

The CLI tool shows available sub-commands:

$ /opt/oathldap/bin/oath-ldap-tool --help
usage: oath-ldap-tool [-h] {decpin,genkey,ykinfo,ykadd,ykinit} ...

OATH-LDAP tool

positional arguments:
  {decpin,genkey,ykinfo,ykadd,ykinit}
                        sub-command help
    decpin              sub-command decpin
    genkey              sub-command genkey
    ykinfo              sub-command ykinfo
    ykadd               sub-command ykadd
    ykinit              sub-command ykinit

optional arguments:
  -h, --help            show this help message and exit
michael@nb2:~> /opt/oathldap/bin/oath-ldap-tool --help
usage: oath-ldap-tool [-h] {decpin,genkey,ykinfo,ykadd,ykinit} ...

OATH-LDAP tool

positional arguments:
  {decpin,genkey,ykinfo,ykadd,ykinit}
                        sub-command help
    decpin              sub-command decpin
    genkey              sub-command genkey
    ykinfo              sub-command ykinfo
    ykadd               sub-command ykadd
    ykinit              sub-command ykinit

optional arguments:
  -h, --help            show this help message and exit

You should encrypt the shared secrets (seeds) in attribute oathSecret. For this you generate a key pair used for seed encryption during enrollment on a secured system and transfer the private key to the OATH-LDAP providers over a secure channel.

$ mkdir -p /etc/oath-ldap/primary-keys
$ chmod 0600 /etc/oath-ldap/primary-keys
$ /opt/oathldap/bin/oath-ldap-tool genkey --key-path /etc/oath-ldap/primary-keys
Generate RSA-2048 key pair...
wrote /opt/oathldap/etc/oath-ldap/primary-keys/oathldap_primary_key_202006091718.priv
wrote /opt/oathldap/etc/oath-ldap/primary-keys/oathldap_primary_key_202006091718.pub

The filenames (here oathldap_primary_key_202006091718) are generated based on timestamps and are also used as JWK key identifier (see RFC 7517 and RFC 7516).

slapd listeners

For OpenLDAP configuration instructions see slapd-sock(5).

oathldap_srv.hotp_validator

Used as overlay it intercepts BIND requests and checks a combined password against password hash in attribute userPassword and the HOTP value against counters and shared secret stored in user entry.

Start listener demon:

/usr/bin/python3 -m oathldap_srv.hotp_validator /etc/oath-ldap/hotp_validator.cfg

Example configuration

[hotp_validator]

# Pathname of Unix domain socket where slapd-sock sends requests to
socket_path = /run/hotp_validator/socket

# LDAPI URI for connecting to local slapd
ldapi_uri = ldapi://

# logging level (key-word known in logging module)
log_level = INFO

# logging configuration file
logging_conf = /etc/py-logging.conf

# logging qualifier name
logger_name = syslog

# time in seconds for which to cache bind requests
# (set to negative number to disable caching)
cache_ttl = -1.0

# Globbing pattern for searching JSON web key files (private keys)
# used for decrypting the shared secrets
primary_key_files = /etc/oath-ldap/primary-keys/*.priv

# UIDs which are granted access
allowed_uids = 0 slapd

oathldap_srv.bind_proxy

Used as overlay it intercepts BIND requests and passes the simple bind request to a remote LDAP server if a configurable LDAP filter is matched.

Start listener demon:

/usr/bin/python3 -m oathldap_srv.bind_proxy /etc/oath-ldap/bind_proxy.cfg

Example configuration

[bind_proxy]

# Pathname of Unix domain socket where slapd-sock sends requests to
socket_path = /run/bind_proxy/socket

# LDAPI URI for connecting to local slapd
ldapi_uri = ldapi://

# logging level (key-word known in logging module)
log_level = INFO

# logging configuration file
logging_conf = /etc/py-logging.conf

# logging qualifier name
logger_name = syslog

# UIDs which are granted access
allowed_uids = 0 ae-dir-slapd

# time in seconds for which to cache bind requests
# (set to negative number to disable caching)
cache_ttl = -1.0

# CA certificate file to use for connecting to OATH-LDAP providers
cacert_file = /opt/ae-dir/etc/tls/my-ae-dir-testca-2017-06.pem

# Space- or line separated list of LDAP URIs of OATH-LDAP providers
providers =
  ldaps://openldap-provider1.vnet1.local
  ldaps://openldap-provider2.vnet1.local
  ldaps://openldap-provider3.vnet1.local

# Space- or line separated list network addresses of clients for which bind
# requests might be proxied to an OATH-LDAP provider
#proxy_peer_nets = 0.0.0.0/0
proxy_peer_nets = 10.0.0.0/8

# peer addresses always excluded from proxying to OTP validator
noproxy_peer_addrs = /run/slapd/ldapi 127.0.0.1