LDAP Set Up

In order to set up integration between your LDAP servers and Pro Custodibus, some preparatory steps are needed. At minimum, you must do the following to prepare:

You may also want to do the following before you turn on the integration (but you may also do this afterwards, as well):

  1. Set up LDAP User Groups for synchronization

  2. Adjust your LDAP Schema for WireGuard devices

  3. Add some LDAP Host Entities

LDAP Account for Pro Custodibus

First, create an account in your LDAP store that Pro Custodibus can use to connect to and query your LDAP server. This account will need access to the LDAP User Groups that you choose to synchronize to Pro Custodibus. In particular, it may need to access the following attributes of each user (if you choose to synchronize them):

This account will also need to access the LDAP Host Entities that you choose to synchronize with Pro Custodibus. In particular, it may need to access the following attributes of each host (if you choose to synchronize them):

LDAP Connection Details

Next, gather the connection details for LDAP server. In particular, determine these settings:

WireGuard Connection to Pro Custodibus

Next, prepare a WireGuard connection that allows inbound access to your LDAP servers from Pro Custodibus. If you have an LDAP replica server, you may want to prepare a separate WireGuard connection for it, too.

You can either set up WireGuard directly on your LDAP servers (in a point-to-point configuration with Pro Custodibus), or set up WireGuard on a host that has direct network access to your LDAP servers (in a point-to-site configuration with Pro Custodibus, where your WireGuard host is the “site” side of the connection).

For each connection, choose the WireGuard address that you want to use for your side of the connection, the WireGuard address that you want us to use on our side of the connection, and generate a WireGuard key pair for your side of the connection. Then email support to let us know that you want to set up an LDAP integration, and include the following information (for both your primary and replica LDAP servers, if you want to use a separate WireGuard connection for your replica LDAP server):

  • Your WireGuard public key

  • Our WireGuard IP address

  • Your LDAP server’s IP address and port

  • The other LDAP Connection Details you have gathered so far

We’ll set up a WireGuard endpoint (or two, if you want a separate connection for your replica LDAP server) for you to connect to, and provide you with the following information for you to finish setting up the WireGuard connection:

  • Our WireGuard public key

  • Our WireGuard endpoint address

For example, if you set up WireGuard on a separate host with a point-to-site with site gateway configuration, where your WireGuard host is on a LAN that can route between your LDAP server and our WireGuard endpoint, you might set up your WireGuard connection with the following configuration:

# local settings for your LDAP gateway
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.123.45.2

PreUp = sysctl -w net.ipv4.conf.all.forwarding=1

# remote settings for Pro Custodibus
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
Endpoint = abcd1234.ldap.custodib.us:51820
AllowedIPs = 10.123.45.1
PersistentKeepalive = 25

In the above example, you’ve generated a public key pair, and sent us the public key corresponding to your private key, as well as the WireGuard address you’ve chosen for our side of the connection (10.123.45.1). We’ve also generated a public key pair for our side of the connection, and sent you the public key (/TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=), as well as the endpoint to which you can connect (abcd1234.ldap.custodib.us:51820).

With the above example, you’ve also configured your network to be able to route connections between our WireGuard IP address (10.123.45.1), and your LDAP server (say 192.168.67.89 for example); and you’ve configured any firewalls between your WireGuard host and your LDAP server to let our WireGuard IP address initiate connections to your LDAP server’s LDAP port (say TCP port 389).

Alternatively, you might want to set up your WireGuard host with a point-to-site with masquerading configuration. This may enable you to avoid having to make any routing or firewall changes to your network. With this configuration, your WireGuard config file might look like the following:

# local settings for your LDAP gateway
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.123.45.2

PreUp = sysctl -w net.ipv4.conf.all.forwarding=1
PreUp = iptables -t nat -A POSTROUTING -s 10.123.45.1 -d 192.168.67.89 -p tcp --dport 389 -j MASQUERADE
PostDown = iptables -t nat -A POSTROUTING -s 10.123.45.1 -d 192.168.67.89 -p tcp --dport 389 -j MASQUERADE

# remote settings for Pro Custodibus
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
Endpoint = abcd1234.ldap.custodib.us:51820
AllowedIPs = 10.123.45.1
PersistentKeepalive = 25

In the above example, you’ve added an iptables rule to allow your WireGuard host to masquerade connections coming from our side of the WireGuard tunnel (10.123.45.1) to your LDAP server (listening on TCP port 389 at 192.168.67.89). This will make connections from our side of the WireGuard tunnel appear to your LDAP server as if they were coming from your own WireGuard host (say 192.168.67.123 for example).

LDAP User Groups

If you want to synchronize LDAP users to Pro Custodibus (to allow some users to log into Pro Custodibus and manage their WireGuard devices, or to use Multi-Factor Authentication with WireGuard) set up some or all of the following user groups:

  • Admins Group: users who will have full admin access to everything in Pro Custodibus

  • Auditors Group: users who will have read-only access to everything in Pro Custodibus

  • Users Group: users who will have limited access in Pro Custodibus to the individual hosts of which they are owners

LDAP Schema for WireGuard

Before you set up LDAP Host Entities, you will probably need to adjust your LDAP schema to include some WireGuard-specific attributes that you don’t already have. In particular, the following host/interface attributes have no standard schema definition:

The following attributes have standard schema definitions that should be usable for WireGuard hosts and interfaces in many situations (although you may still want to add a custom attribute definition for one or more of them):

We recommend adding the following LDIF (LDAP Data Interchange Format) schema to your LDAP store. It includes an x-wg-peer class with attribute definitions you can use for WireGuard-specific attributes that don’t have a standard definition:

dn: cn=x-wg,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: x-wg
olcAttributeTypes: ( 1.3.6.1.4.1.1783.86.389.1.1
  NAME 'x-wg-privateKey'
  DESC 'WireGuard private key, base64 encoded.'
  EQUALITY caseExactMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{44}
  SINGLE-VALUE
  )
olcAttributeTypes: ( 1.3.6.1.4.1.1783.86.389.1.2
  NAME 'x-wg-publicKey'
  DESC 'WireGuard public key, base64 encoded.'
  EQUALITY caseExactMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{44}
  SINGLE-VALUE
  )
olcAttributeTypes: ( 1.3.6.1.4.1.1783.86.389.1.3
  NAME 'x-wg-address'
  DESC 'WireGuard IP address and optional network mask (eg 192.0.2.2 or 192.0.2.2/24 or 2001:db8::2 or 2001:db8::2/56).'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{49}
  )
olcAttributeTypes: ( 1.3.6.1.4.1.1783.86.389.1.4
  NAME 'x-wg-port'
  DESC 'WireGuard listen port number.'
  EQUALITY integerMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  SINGLE-VALUE
  )
olcAttributeTypes: ( 1.3.6.1.4.1.1783.86.389.1.5
  NAME 'x-wg-endpoint'
  DESC 'Hostname other WireGuard peers can use to access this peer\27 listen port (eg 198.51.100.2 or vpn or vpn.example.com).'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44
  SINGLE-VALUE
  )
olcAttributeTypes: ( 1.3.6.1.4.1.1783.86.389.1.6
  NAME 'x-wg-route'
  DESC 'Network address other WireGuard peers can route via this peer (eg 192.0.2.2 or 192.0.2.0/24 or 2001:db8::2 or 2001:db8::/56).'
  EQUALITY caseIgnoreMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{49}
  )
olcAttributeTypes: ( 1.3.6.1.4.1.1783.86.389.1.7
  NAME 'x-wg-peerOf'
  DESC 'DN of a WireGuard peer of this peer.'
  EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  )
olcObjectClasses: ( 1.3.6.1.4.1.1783.86.389.2.1
  NAME 'x-wg-peer' SUP top AUXILIARY
  DESC 'WireGuard peer. Auxiliary to structural classes like device or computer.'
  MAY (
    x-wg-privateKey $
    x-wg-publicKey $
    x-wg-address $
    x-wg-port $
    x-wg-endpoint $
    x-wg-route $
    x-wg-peerOf
    )
  )

LDAP Host Entities

Once you make the necessary changes to your LDAP Schema for WireGuard, you can start setting up WireGuard host (and interface) entities in your LDAP store. You should have a host entity for every WireGuard host you want to manage through your LDAP integration.

For hosts that have more than one WireGuard interface, you should create a separate interface entity for each additional interface. The Owner Attribute of host entities should point to the users who manage the host; whereas the owner of interface entities should identify the host to which the interface belongs.

For example, you might define a simple WireGuard network like the following:

dn: cn=vpn,ou=hosts,dc=example,dc=org
objectClass: x-wg-peer
objectClass: ipHost
objectClass: device
objectClass: top
cn: vpn
owner: uid=cathy,ou=people,dc=example,dc=org
owner: uid=dave,ou=people,dc=example,dc=org
x-wg-publicKey: jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=
x-wg-port: 51820
x-wg-route: 10.0.0.0/24
x-wg-route: 192.168.1.0/24
x-wg-endpoint: vpn.example.org
ipHostNumber: 10.0.0.1

dn: cn=alice-laptop,ou=hosts,dc=example,dc=org
objectClass: x-wg-peer
objectClass: ipHost
objectClass: device
objectClass: top
cn: alice-laptop
owner: uid=alice,ou=people,dc=example,dc=org
x-wg-privateKey: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
x-wg-peerOf: cn=vpn,ou=hosts,dc=example,dc=org
ipHostNumber: 10.0.0.11

dn: cn=bob-laptop,ou=hosts,dc=example,dc=org
objectClass: x-wg-peer
objectClass: ipHost
objectClass: device
objectClass: top
cn: bob-laptop
owner: uid=bob,ou=people,dc=example,dc=org
x-wg-privateKey: ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
x-wg-peerOf: cn=vpn,ou=hosts,dc=example,dc=org
ipHostNumber: 10.0.0.12

dn: cn=vpn-hosts,ou=groups,dc=example,dc=org
objectClass: groupOfUniqueNames
objectClass: top
cn: vpn-hosts
uniqueMember: cn=vpn,ou=hosts,dc=example,dc=org
uniqueMember: cn=alice-laptop,ou=hosts,dc=example,dc=org
uniqueMember: cn=bob-laptop,ou=hosts,dc=example,dc=org

This example allows two remote hosts, alice-laptop and` bob-laptop, to connect to a central vpn WireGuard hub. The central hub can route tunneled connections both to the other hosts in the network, as well as the hub’s own LAN. All three hosts are members of the vpn-hosts group.

If Alice’s laptop hosted several different WireGuard interfaces, it might be defined with one host entity and several additional interface entities:

dn: cn=alice-laptop,ou=hosts,dc=example,dc=org
objectClass: x-wg-peer
objectClass: ipHost
objectClass: device
objectClass: top
cn: alice-laptop
owner: uid=alice,ou=people,dc=example,dc=org
x-wg-privateKey: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
x-wg-peerOf: cn=vpn,ou=hosts,dc=example,dc=org
ipHostNumber: 10.0.0.11

dn: cn=alice-laptop.voip.corp,cn=alice-laptop,ou=hosts,dc=example,dc=org
objectClass: x-wg-peer
objectClass: ipHost
objectClass: device
objectClass: top
cn: alice-laptop.voip.corp
owner: cn=alice-laptop,ou=hosts,dc=example,dc=org
x-wg-privateKey: 2G22222222222222222222222222222222222222220=
x-wg-peerOf: cn=sip-de.voip.corp,ou=hosts,dc=example,dc=org
x-wg-peerOf: cn=sip-es.voip.corp,ou=hosts,dc=example,dc=org
x-wg-peerOf: cn=sip-us.voip.corp,ou=hosts,dc=example,dc=org
ipHostNumber: 10.0.2.211

dn: cn=alice-laptop.mail.corp,cn=alice-laptop,ou=hosts,dc=example,dc=org
objectClass: x-wg-peer
objectClass: ipHost
objectClass: device
objectClass: top
cn: alice-laptop.mail.corp
owner: cn=alice-laptop,ou=hosts,dc=example,dc=org
x-wg-privateKey: 2H33333333333333333333333333333333333333330=
x-wg-peerOf: cn=imap.mail.corp,ou=hosts,dc=example,dc=org
x-wg-peerOf: cn=smtp.mail.corp,ou=hosts,dc=example,dc=org
ipHostNumber: 10.0.3.31

dn: cn=vpn-hosts,ou=groups,dc=example,dc=org
objectClass: groupOfUniqueNames
objectClass: top
cn: vpn-hosts
uniqueMember: cn=vpn,ou=hosts,dc=example,dc=org
uniqueMember: cn=alice-laptop,ou=hosts,dc=example,dc=org
uniqueMember: cn=bob-laptop,ou=hosts,dc=example,dc=org

dn: cn=voip.corp,ou=groups,dc=example,dc=org
objectClass: groupOfUniqueNames
objectClass: top
cn: voip.corp
uniqueMember: cn=sip-de.voip.corp,ou=hosts,dc=example,dc=org
uniqueMember: cn=sip-es.voip.corp,ou=hosts,dc=example,dc=org
uniqueMember: cn=sip-us.voip.corp,ou=hosts,dc=example,dc=org
uniqueMember: cn=alice-laptop.voip.corp,cn=alice-laptop,ou=hosts,dc=example,dc=org
uniqueMember: cn=bob-laptop.voip.corp,cn=bob-laptop,ou=hosts,dc=example,dc=org

dn: cn=mail.corp,ou=groups,dc=example,dc=org
objectClass: groupOfUniqueNames
objectClass: top
cn: mail.corp
uniqueMember: cn=imap.mail.corp,ou=hosts,dc=example,dc=org
uniqueMember: cn=smtp.mail.corp,ou=hosts,dc=example,dc=org
uniqueMember: cn=alice-laptop.mail.corp,cn=alice-laptop,ou=hosts,dc=example,dc=org
uniqueMember: cn=bob-laptop.mail.corp,cn=bob-laptop,ou=hosts,dc=example,dc=org

In the above example, the alice-laptop host entity is the owner of two interface entities, alice-laptop.voip.corp and alice-laptop.mail.corp. Each interface entity also belongs to a dedicated group (voip.corp and mail.corp) that contains all the interfaces in its WireGuard network.

As an alternative to the above, the host entity representing Alice’s laptop could be defined without any WireGuard-specific attributes attached to it, and instead have a separate interface entity defined for each of the three WireGuard interfaces hosted by her laptop:

dn: cn=alice-laptop,ou=hosts,dc=example,dc=org
objectClass: device
objectClass: top
cn: alice-laptop
owner: uid=alice,ou=people,dc=example,dc=org

dn: cn=alice-laptop.vpn.corp,cn=alice-laptop,ou=hosts,dc=example,dc=org
objectClass: x-wg-peer
objectClass: ipHost
objectClass: device
objectClass: top
cn: alice-laptop.vpn.corp
owner: cn=alice-laptop,ou=hosts,dc=example,dc=org
x-wg-privateKey: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
x-wg-peerOf: cn=vpn,ou=hosts,dc=example,dc=org
ipHostNumber: 10.0.0.11

dn: cn=alice-laptop.voip.corp,cn=alice-laptop,ou=hosts,dc=example,dc=org
objectClass: x-wg-peer
objectClass: ipHost
objectClass: device
objectClass: top
cn: alice-laptop.voip.corp
owner: cn=alice-laptop,ou=hosts,dc=example,dc=org
x-wg-privateKey: 2G22222222222222222222222222222222222222220=
x-wg-peerOf: cn=sip-de.voip.corp,ou=hosts,dc=example,dc=org
x-wg-peerOf: cn=sip-es.voip.corp,ou=hosts,dc=example,dc=org
x-wg-peerOf: cn=sip-us.voip.corp,ou=hosts,dc=example,dc=org
ipHostNumber: 10.0.2.211

dn: cn=alice-laptop.mail.corp,cn=alice-laptop,ou=hosts,dc=example,dc=org
objectClass: x-wg-peer
objectClass: ipHost
objectClass: device
objectClass: top
cn: alice-laptop.mail.corp
owner: cn=alice-laptop,ou=hosts,dc=example,dc=org
x-wg-privateKey: 2H33333333333333333333333333333333333333330=
x-wg-peerOf: cn=imap.mail.corp,ou=hosts,dc=example,dc=org
x-wg-peerOf: cn=smtp.mail.corp,ou=hosts,dc=example,dc=org
ipHostNumber: 10.0.3.31

dn: cn=vpn-hosts,ou=groups,dc=example,dc=org
objectClass: groupOfUniqueNames
objectClass: top
cn: vpn-hosts
uniqueMember: cn=vpn,ou=hosts,dc=example,dc=org
uniqueMember: cn=alice-laptop.vpn.corp,cn=alice-laptop,ou=hosts,dc=example,dc=org
uniqueMember: cn=bob-laptop.vpn.corp,cn=bob-laptop,ou=hosts,dc=example,dc=org

dn: cn=voip.corp,ou=groups,dc=example,dc=org
objectClass: groupOfUniqueNames
objectClass: top
cn: voip.corp
uniqueMember: cn=sip-de.voip.corp,ou=hosts,dc=example,dc=org
uniqueMember: cn=sip-es.voip.corp,ou=hosts,dc=example,dc=org
uniqueMember: cn=sip-us.voip.corp,ou=hosts,dc=example,dc=org
uniqueMember: cn=alice-laptop.voip.corp,cn=alice-laptop,ou=hosts,dc=example,dc=org
uniqueMember: cn=bob-laptop.voip.corp,cn=bob-laptop,ou=hosts,dc=example,dc=org

dn: cn=mail.corp,ou=groups,dc=example,dc=org
objectClass: groupOfUniqueNames
objectClass: top
cn: mail.corp
uniqueMember: cn=imap.mail.corp,ou=hosts,dc=example,dc=org
uniqueMember: cn=smtp.mail.corp,ou=hosts,dc=example,dc=org
uniqueMember: cn=alice-laptop.mail.corp,cn=alice-laptop,ou=hosts,dc=example,dc=org
uniqueMember: cn=bob-laptop.mail.corp,cn=bob-laptop,ou=hosts,dc=example,dc=org

Next Steps

Edit the configuration settings, and check the polling status.