2026-08-21 12:12:50 +02:00
# ldap-rp
2026-08-20 21:05:09 +02:00
Proxy LDAP requests to different LDAP servers based on base DN. Based on code from [kanidm/ldap-proxy ](https://github.com/kanidm/ldap-proxy/ ) under the [MPL license ](LICENSE.md ).
## Features
- [x] No TLS setup ; use only in trusted networks
- [x] LDAP bind requests
- [x] LDAP search requests
2026-08-28 12:03:23 +02:00
- [x] extract requested backend from mail attribute filter
- [x] bind to requested backend with mapping `user` and `password` fields
- [ ] **not (yet?) planned: ** extract requested backend from more filters
- [x] rewrite the search dn with backend `to` dn (eg. `ou=people,dc=a,dc=localhost` -> `ou=people,dc=example,dc=com` )
- [x] rewrite returned entries with backend dn (eg. `uid=a,ou=people,dc=example,dc=com` -> `uid=a,ou=people,dc=a,dc=localhost` )
- [ ] rewrite search dn and result entries for authenticated searches on a backend
2026-08-21 11:50:53 +02:00
- [x] Configurable listening port
2026-08-21 12:12:50 +02:00
- [ ] Default fallback to `/etc/ldap-rp/config.toml`
2026-08-21 11:50:53 +02:00
- [x] Unix Domain Socket support (incoming requests)
- [ ] Unix Domain Socket garbage collection (incoming requests)
2026-08-21 15:14:52 +02:00
- [x] Unix Domain Socket support (outgoing requests)
2026-08-21 11:50:53 +02:00
- [ ] **not planned: ** TLS termination (incoming requests)
- [ ] **not planned: ** TLS backend connections (outgoing requests)
- [ ] **not planned: ** TLS SNI passthrough
2026-08-20 21:05:09 +02:00
2026-08-21 11:50:53 +02:00
## Running
2026-08-20 21:05:09 +02:00
Create a configuration file `config.toml` with the following:
```toml
2026-08-21 11:50:53 +02:00
# Where to listen to incoming connections ([::1]:389 by default, requires privileges)
# - ip/port: `127.0.0.1:3389` (ipv4 only on localhost) `[::1]:3389` (ipv4/ipv6 on localhost),
# `0.0.0.0:3389` (ipv4 only on all interfaces, `[::]:3389` (ipv4/ipv6 on any interface)
# - socket: `./ldap.sock` for a socket in the current working directory
# `/var/run/ldap.sock` for a socket with an absolute path
listen = "[::]:3389"
2026-08-20 21:05:09 +02:00
[[mapping]]
from = "a.localhost"
to = "example.com"
2026-08-21 15:14:52 +02:00
# The LDAP address of the backend server:
# - start with `./` or `/` for a socket URI
# - start with anything else for a TCP connection
# backend = "/run/lldap/example.com.sock"
2026-08-20 21:05:09 +02:00
backend = "127.0.0.1:4389"
2026-08-28 12:03:23 +02:00
# Credentials for performing search query to the backend
# set `lldap_strict_readonly` perms on the account in lldap.
2026-09-19 11:47:11 +02:00
user = "cn=stalwart,ou=people,dc=example,dc=com"
2026-08-28 12:03:23 +02:00
password = "adminadmin"
2026-08-20 21:05:09 +02:00
[[mapping]]
from = "b.localhost"
to = "example.com"
backend = "127.0.0.1:5389"
2026-09-19 11:47:11 +02:00
user = "cn=stalwart,ou=people,dc=example,dc=com"
2026-08-28 12:03:23 +02:00
password = "adminadmin"
2026-08-20 21:05:09 +02:00
```
2026-08-21 12:12:50 +02:00
~~By default, `ldap-rp` will look for a config file in `/etc/ldap-rp/config.toml` but you can change that
with the `--config` CLI flag.~~
2026-08-20 21:05:09 +02:00
2026-08-21 11:50:53 +02:00
You can now run:
```
2026-08-21 12:12:50 +02:00
ldap-rp --config config.toml
2026-08-20 21:05:09 +02:00
```
2026-08-21 11:50:53 +02:00
# Testing your setup
Once you have a LDAP server running, you can test your settings with the `ldapwhoami` command from the openldap package:
```bash
# Test when listening on port 3389
ldapwhoami -H ldap://localhost:3389 -D "cn=b,ou=people,dc=a,dc=localhost" -W
2026-08-21 12:12:50 +02:00
# Test when listening on socket /run/ldap-rp/ldap-rp.sock, where `/` is escaped
2026-08-21 11:50:53 +02:00
# with `%2F` and the protocol is changed to `ldapi`
2026-08-21 12:12:50 +02:00
ldapwhoami -H ldapi://%2Frun%2Fldap-rp%2Fldap-rp.sock -D "cn=b,ou=people,dc=a,dc=localhost" -W
2026-08-20 21:05:09 +02:00
```
2026-08-28 12:03:23 +02:00
You can also perform a search by email without binding with specific credentials, the base dn provided will have its hostname set to the backend mapping's `from` value:
```
ldapsearch -x -b "ou=people" -H "ldap://localhost:3389" -s sub "(mail=a@a .localhost)" uid mail
```
This is strictly equivalent to using `-b "ou=people,dc=a,dc=localhost"` because the search dn is always overwritten.