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:
-
Set up an LDAP Account for Pro Custodibus access
-
Gather LDAP Connection Details
-
Set up a WireGuard Connection to Pro Custodibus (SaaS Edition only)
You may also want to do the following before you turn on the integration (but you may also do this afterwards, as well):
-
Set up LDAP User Groups for synchronization
-
Adjust your LDAP Schema for WireGuard devices
-
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:
-
The LDAP server’s IP address
-
The LDAP server’s port
-
If you have one or more LDAP replica servers, a replica’s IP address
-
Whether or not you use TLS to connect
-
If you use TLS, the TLS hostname used in the server’s TLS certificate
-
If you use TLS and have LDAP replication servers, the replica’s TLS hostname (used in the replica’s TLS certificate)
-
If you use TLS, the TLS CA certificate chain that signed the server’s TLS certificate
-
The base DN used to connect to and query the LDAP server
-
The memberOf attribute name used by LDAP member entities to identify the groups of which they are a member
WireGuard Connection to Pro Custodibus
Next, if you’re using the Software as a Service Edition, 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. If you’re using the Enterprise Edition, skip to the LDAP On-Premises Set Up section.
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 On-Premises Set Up
If you’re using the Pro Custodibus Enterprise Edition, you don’t need to set up a WireGuard connection to your LDAP server — you can set up a connection to it directly from your on-premises Pro Custodibus API server.
To set up a connection to your LDAP server with the Enterprise Edition, follow these steps:
-
Click the Admin link in the Pro Custodibus app header.
-
Click the LDAP link in the Administration panel.
-
Click the Set Up LDAP link in any panel.
-
Fill out the following fields:
-
TLS (to use a TLS connection)
-
Login Password (if a password is required)
-
Click the Set Up button.
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:
-
Private Key Attribute: WireGuard private key (44-character base64-encoded text)
-
Public Key Attribute: WireGuard public key (44-character base64-encoded text)
-
Port Attribute: WireGuard listen port (32-bit unsigned integer)
-
Endpoint Attribute: WireGuard endpoint (text value like
vpn.example.org:51820
) -
Routes Attribute: WireGuard allowed IPs (multi-valued text like
10.0.0.0/24
orfd10::/56
) -
Peers Attribute: WireGuard peer DNs or public keys (multi-valued text)
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):
-
Display Name Attribute: Displayed name for host/peer; the
cn
attribute is normally good for this. -
Owner Attribute: Multi-valued user/host DN; the
owner
orManaged-By
attributes, depending on the entity classes used, are usually good for this. -
Address Attribute: WireGuard interface IP address
ipHostNumber
attribute can be good for this (when using theipHost
class).
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