Goal

I wanted a centralised address book that is:

  • LAN-only (no internet exposure)
  • Encrypted end-to-end using TLS
  • Compatible with common mail clients (Thunderbird, etc.)
  • Simple: address book only (not authentication)

Architecture

  • Host: Proxmox VE
  • Guest: Ubuntu 25.04 LXC container
  • Directory: OpenLDAP (slapd)
  • Admin UI: phpLDAPadmin
  • Transport security: Private internal CA + LDAPS on port 636
  • Network scope: VLAN-segmented, allowlisted internal subnets only

The LDAP server hostname:

  • hl-mail.int.hillnet.co.nz

Schema choices for “address book” use

This directory is deliberately designed for contacts, not logins.

Primary object classes:

  • inetOrgPerson
  • organizationalPerson
  • person
  • top

Key attributes:

  • mail (unique identifier for contact usability)
  • cn
  • sn
  • givenName
  • telephoneNumber
  • mobile
  • street
  • l
  • postalCode
  • o

Only entries with a valid mail attribute are imported. That single rule keeps the directory clean and ensures every object is actually usable as a contact.

Importing contacts (CSV → LDIF)

Contacts exported from Google Contacts (CSV) were converted to LDIF and cleaned during transformation:

  • Removed unsupported attributes
  • Dropped schema-incompatible fields
  • Excluded entries without an email address
  • Aligned object classes to the schema above

Then imported with:

1
ldapadd -x -D "cn=admin,dc=int,dc=hillnet,dc=co,dc=nz" -W -f contacts.ldif

phpLDAPadmin is handy for quick verification and edits after import.

TLS with an internal CA (LDAPS)

Because this is an internal-only service, I used a private root CA and issued a server certificate for:

  • hl-mail.int.hillnet.co.nz

High-level steps:

  1. Create internal root CA
  2. Generate server key + CSR
  3. Sign server certificate with the internal CA
  4. Install server key/cert under /etc/ldap/ssl/
  5. Configure slapd to use the certificate
  6. Enable ldaps:/// in /etc/default/slapd
  7. Restart slapd and confirm it’s listening on 389 and 636

Verify LDAPS from a client:

1
openssl s_client -connect hl-mail.int.hillnet.co.nz:636

Trust the internal CA on clients (example for Debian/Ubuntu):

1
2
sudo cp hillnet-root-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

If trust is correct, you should see a successful verification (e.g. “verify return code: 0 (ok)”).

Why LDAPS (636) instead of StartTLS?

OpenLDAP supports StartTLS, but native LDAPS can be simpler for client configuration and avoids some extended-operation negotiation quirks. For a small internal environment, LDAPS is straightforward and robust.

Network segmentation & security posture

  • LDAP restricted to selected internal VLANs (allowlist)
  • No external exposure
  • Encryption required via TLS (LDAPS)
  • Private CA trusted only on internal systems
  • No auth integration: address book only

Client configuration notes

Clients typically connect using:

  • ldaps://hl-mail.int.hillnet.co.nz:636

Base DN:

  • ou=People,dc=int,dc=hillnet,dc=co,dc=nz

Final state

The end result is a clean, centralised, TLS-secured internal address book that:

  • stays isolated to the LAN
  • uses a private certificate authority
  • follows standard schema practices for mail-client lookups
  • requires minimal ongoing maintenance

It does exactly what it needs to do — and nothing more.