<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OpenLDAP Archives - Linuxcent</title>
	<atom:link href="https://linuxcent.com/tag/openldap/feed/" rel="self" type="application/rss+xml" />
	<link>https://linuxcent.com/tag/openldap/</link>
	<description>Infrastructure security, from the kernel up.</description>
	<lastBuildDate>Sat, 09 May 2026 18:38:46 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://linuxcent.com/wp-content/uploads/2026/04/favicon-512x512-1-150x150.png</url>
	<title>OpenLDAP Archives - Linuxcent</title>
	<link>https://linuxcent.com/tag/openldap/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">211632295</site>	<item>
		<title>LDAP High Availability: Load Balancing and Production Architecture</title>
		<link>https://linuxcent.com/ldap-high-availability/</link>
					<comments>https://linuxcent.com/ldap-high-availability/#respond</comments>
		
		<dc:creator><![CDATA[Vamshi Krishna Santhapuri]]></dc:creator>
		<pubDate>Wed, 06 May 2026 05:00:00 +0000</pubDate>
				<category><![CDATA[Identity & Authentication]]></category>
		<category><![CDATA[Directory Services]]></category>
		<category><![CDATA[HAProxy]]></category>
		<category><![CDATA[High Availability]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OpenLDAP]]></category>
		<category><![CDATA[Security]]></category>
		<guid isPermaLink="false">https://linuxcent.com/?p=1790</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 6</span> <span class="rt-label rt-postfix">minutes</span></span>LDAP high availability architecture: HAProxy load balancing, read/write split, connection pooling, cn=monitor metrics, and what to watch for at 10M+ entries.</p>
<p>The post <a href="https://linuxcent.com/ldap-high-availability/">LDAP High Availability: Load Balancing and Production Architecture</a> appeared first on <a href="https://linuxcent.com">Linuxcent</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 6</span> <span class="rt-label rt-postfix">minutes</span></span><style>
pre{position:relative;background:#1e1e1e;color:#d4d4d4;
    padding:16px 16px 16px 20px;border-radius:6px;overflow-x:auto;
    font-family:'JetBrains Mono','Fira Code','Cascadia Code',Consolas,'Courier New',monospace;
    font-size:.88em;line-height:1.6;border-left:4px solid #555}
code{background:#f4f4f4;padding:2px 5px;border-radius:3px;font-size:.9em}
pre code{background:transparent;padding:0;color:inherit}
pre[data-lang="bash"],pre[data-lang="sh"],
pre[data-lang="shell"],pre[data-lang="zsh"]{border-left-color:#4ec9b0}
pre[data-lang="yaml"],pre[data-lang="json"],
pre[data-lang="toml"],pre[data-lang="xml"]{border-left-color:#569cd6}
pre[data-lang="python"],pre[data-lang="go"],pre[data-lang="rust"],
pre[data-lang="java"],pre[data-lang="c"],pre[data-lang="cpp"]{border-left-color:#c586c0}
pre[data-lang="text"],pre[data-lang="output"],
pre[data-lang="console"]{border-left-color:#888}
.lc-copy-btn{position:absolute;top:8px;right:8px;background:#2d2d2d;color:#ccc;
    border:1px solid #444;border-radius:4px;padding:3px 9px;font-size:.75em;
    font-family:system-ui,sans-serif;cursor:pointer;opacity:0;
    transition:opacity .15s,background .15s;line-height:1.6}
pre:hover .lc-copy-btn{opacity:1}
.lc-copy-btn:hover{background:#3a3a3a;color:#fff}
.lc-copy-btn.copied{color:#4ec9b0;border-color:#4ec9b0}
.lc-lang-badge{position:absolute;top:8px;left:20px;font-family:system-ui,sans-serif;
    font-size:.7em;color:#666;text-transform:uppercase;letter-spacing:.04em;
    line-height:1;pointer-events:none;opacity:0;transition:opacity .15s}
pre:hover .lc-lang-badge{opacity:1}
table{border-collapse:collapse;width:100%;margin:16px 0}
th,td{border:1px solid #ddd;padding:10px 14px;text-align:left}
th{background:#f0f0f0;font-weight:600}
tr:nth-child(even){background:#fafafa}
</style>
<p><script>
(function(){
  if(window.__lcCodeEnhanced)return;
  window.__lcCodeEnhanced=true;
  function enhance(){
    document.querySelectorAll('pre').forEach(function(pre){
      var code=pre.querySelector('code');
      var lang='';
      if(code){var m=(code.className||'').match(/language-(\S+)/);if(m)lang=m[1].toLowerCase();}
      if(lang)pre.setAttribute('data-lang',lang);
      if(lang){var badge=document.createElement('span');badge.className='lc-lang-badge';badge.textContent=lang;pre.insertBefore(badge,pre.firstChild);}
      var btn=document.createElement('button');
      btn.className='lc-copy-btn';btn.textContent='Copy';btn.setAttribute('aria-label','Copy code to clipboard');
      pre.appendChild(btn);
      btn.addEventListener('click',function(){
        var text=code?code.innerText:pre.innerText;
        if(navigator.clipboard&&window.isSecureContext){
          navigator.clipboard.writeText(text).then(function(){ok(btn);}).catch(function(){fb(text,btn);});
        }else{fb(text,btn);}
      });
    });
  }
  function ok(btn){btn.textContent='Copied!';btn.classList.add('copied');setTimeout(function(){btn.textContent='Copy';btn.classList.remove('copied');},2000);}
  function fb(text,btn){
    try{var ta=document.createElement('textarea');ta.value=text;ta.style.cssText='position:fixed;left:-9999px;top:-9999px;opacity:0';document.body.appendChild(ta);ta.select();document.execCommand('copy');document.body.removeChild(ta);ok(btn);}
    catch(e){btn.textContent='✗ Failed';setTimeout(function(){btn.textContent='Copy';},2000);}
  }
  if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',enhance);}else{enhance();}
})();
</script></p>
<p><em>The Identity Stack, Episode 7</em><br />
<a href="/openldap-setup-replication/">EP06: OpenLDAP</a> → <strong>EP07</strong> → <a href="/freeipa-linux-identity-management/">EP08: FreeIPA</a> → &#8230;</p>
<hr />
<h2 id="tldr">TL;DR</h2>
<ul>
<li>LDAP HA means multiple directory servers behind a load balancer — clients connect to a VIP, not to individual servers</li>
<li>Read/write split: all writes go to the provider, reads are distributed across consumers — the load balancer enforces this by routing on port or backend check</li>
<li>SSSD handles multi-server failover natively (<code class="" data-line="">ldap_uri</code> accepts a comma-separated list) — for apps without built-in failover, HAProxy with health checks does the work</li>
<li>Connection pooling is critical at scale — <code class="" data-line="">nss_ldap</code> and <code class="" data-line="">pam_ldap</code> opened a new connection per login; SSSD maintains a pool; apps that use libldap directly must implement their own</li>
<li><code class="" data-line="">cn=monitor</code> is the built-in monitoring endpoint — exposes connection counts, operation rates, and backend stats readable via <code class="" data-line="">ldapsearch</code></li>
<li>389-DS (Red Hat Directory Server) is the production choice for &gt;1M entries — purpose-built for large directories with a dedicated replication engine</li>
</ul>
<hr />
<h2 id="the-big-picture-production-ldap-topology">The Big Picture: Production LDAP Topology</h2>
<pre><code class="" data-line="">         Clients (SSSD, apps, VPN concentrators)
                      │
              ┌───────▼───────┐
              │   HAProxy VIP  │   ← single endpoint, port 389/636
              │  10.0.0.10     │
              └───────┬───────┘
                      │
          ┌───────────┼───────────┐
          ▼           ▼           ▼
   ldap1.corp.com  ldap2.corp.com  ldap3.corp.com
   (Provider)      (Consumer)      (Consumer)
   Reads + Writes  Reads only      Reads only
          │           ▲               ▲
          └───────────┴───────────────┘
               SyncRepl replication
</code></pre>
<p>EP06 built a two-node replicated directory. This episode covers what happens when the directory becomes infrastructure — when it needs to survive a node failure, handle thousands of connections, and be monitored like any other critical service.</p>
<hr />
<h2 id="haproxy-for-ldap">HAProxy for LDAP</h2>
<p>HAProxy is the standard choice for LDAP load balancing. Unlike HTTP, LDAP is a stateful protocol — once a client binds, subsequent operations on that connection share the authenticated session. The load balancer must use connection persistence, not per-request routing.</p>
<pre><code class="" data-line=""># /etc/haproxy/haproxy.cfg

global
    log /dev/log local0
    maxconn 50000

defaults
    mode tcp                  # LDAP is TCP, not HTTP
    timeout connect 5s
    timeout client  30s
    timeout server  30s
    option tcplog

# ── LDAP read/write split ─────────────────────────────────────────────

# Writes → provider only
frontend ldap-write
    bind *:389
    default_backend ldap-provider

backend ldap-provider
    balance first                   # always use first available (provider)
    option tcp-check
    tcp-check connect
    server ldap1 ldap1.corp.com:389 check inter 5s rise 2 fall 3
    server ldap2 ldap2.corp.com:389 check inter 5s rise 2 fall 3 backup

# Reads → all nodes round-robin
frontend ldap-read
    bind *:3389                     # internal read port
    default_backend ldap-consumers

backend ldap-consumers
    balance roundrobin
    option tcp-check
    tcp-check connect
    server ldap1 ldap1.corp.com:389 check inter 5s
    server ldap2 ldap2.corp.com:389 check inter 5s
    server ldap3 ldap3.corp.com:389 check inter 5s

# LDAPS (TLS)
frontend ldaps
    bind *:636
    default_backend ldap-consumers-tls

backend ldap-consumers-tls
    balance roundrobin
    server ldap1 ldap1.corp.com:636 check inter 5s ssl verify required ca-file /etc/ssl/certs/ca.pem
    server ldap2 ldap2.corp.com:636 check inter 5s ssl verify required ca-file /etc/ssl/certs/ca.pem
</code></pre>
<p>The health check (<code class="" data-line="">tcp-check connect</code>) just verifies TCP connectivity. For a more precise check — verifying that <code class="" data-line="">slapd</code> is actually responding to LDAP requests — use a custom script that runs <code class="" data-line="">ldapsearch</code> and checks the result code.</p>
<hr />
<h2 id="sssd-multi-server-failover">SSSD Multi-Server Failover</h2>
<p>SSSD has native failover — no load balancer required for SSSD-based clients:</p>
<pre><code class="" data-line=""># /etc/sssd/sssd.conf
[domain/corp.com]
ldap_uri = ldap://ldap1.corp.com, ldap://ldap2.corp.com, ldap://ldap3.corp.com
# SSSD tries them in order; switches to next on failure
# Switches back to primary after ldap_recovery_interval (default: 30s)

# For AD, discovery via DNS SRV records is even better:
ad_server = _srv_
# SSSD queries _ldap._tcp.corp.com SRV records and gets all DCs automatically
</code></pre>
<p>SSSD monitors the connection health. If the current server becomes unreachable, it switches to the next in the list within seconds. Existing cached data keeps serving during the switchover. Clients using SSSD don&#8217;t need a load balancer for basic HA.</p>
<hr />
<h2 id="connection-pooling">Connection Pooling</h2>
<p>Every LDAP bind creates an authenticated session on the server. A server with connection limits (<code class="" data-line="">olcConnMaxPending</code>, <code class="" data-line="">olcConnMaxPendingAuth</code> in OLC) will reject new connections when those limits are hit.</p>
<p>The problem: applications that use <code class="" data-line="">libldap</code> directly tend to open a new connection per operation. At 500 requests/second, that&#8217;s 500 new TCP connections, 500 binds, 500 TLS handshakes per second — a directory that can handle 5000 concurrent connections starts refusing new ones.</p>
<p>The solutions:</p>
<p><strong>SSSD</strong> — handles this automatically. SSSD maintains one or a small number of persistent connections per domain and multiplexes all PAM/NSS queries through them.</p>
<p><strong>Application-level pooling</strong> — frameworks like <code class="" data-line="">python-ldap</code> with connection pooling, <code class="" data-line="">ldap3</code> with connection strategies, or dedicated middleware like <code class="" data-line="">389-DS</code>&#8216;s Directory Proxy Server.</p>
<p><strong><code class="" data-line="">ldap_maxconnections</code></strong> in OpenLDAP — sets a hard limit. When hit, new connections block until existing ones close. Set this to something reasonable (<code class="" data-line="">olcConnMaxPending: 100</code> in OLC) so you get a controlled failure mode instead of unbounded queuing.</p>
<hr />
<h2 id="monitoring-with-cnmonitor">Monitoring with cn=monitor</h2>
<p>OpenLDAP exposes live operational statistics via the <code class="" data-line="">cn=monitor</code> database — a virtual LDAP subtree that reflects the server&#8217;s current state. Enable it:</p>
<pre><code class="" data-line=""># enable-monitor.ldif
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib/ldap
olcModuleLoad: back_monitor

dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
olcDatabase: monitor
olcAccess: to *
  by dn=&quot;cn=admin,dc=corp,dc=com&quot; read
  by * none
</code></pre>
<p>Query it:</p>
<pre><code class="" data-line=""># Overall statistics
ldapsearch -x -H ldap://localhost \
  -D &quot;cn=admin,dc=corp,dc=com&quot; -w password \
  -b &quot;cn=monitor&quot; -s sub &quot;(objectClass=*)&quot; \
  monitorOpInitiated monitorOpCompleted

# Connection counts
ldapsearch -x -H ldap://localhost \
  -D &quot;cn=admin,dc=corp,dc=com&quot; -w password \
  -b &quot;cn=Connections,cn=monitor&quot; -s one \
  monitorConnectionNumber

# Operations by type
ldapsearch -x -H ldap://localhost \
  -D &quot;cn=admin,dc=corp,dc=com&quot; -w password \
  -b &quot;cn=Operations,cn=monitor&quot; -s one \
  monitorOpInitiated monitorOpCompleted
</code></pre>
<p>Useful metrics to export to Prometheus (via <code class="" data-line="">prometheus-openldap-exporter</code> or similar):<br />
&#8211; <code class="" data-line="">monitorOpCompleted</code> per operation type (bind, search, modify)<br />
&#8211; <code class="" data-line="">monitorConnectionNumber</code> — current connection count<br />
&#8211; Backend-specific: <code class="" data-line="">olmMDBEntries</code>, <code class="" data-line="">olmMDBPagesMax</code>, <code class="" data-line="">olmMDBPagesUsed</code></p>
<hr />
<h2 id="389-ds-ldap-at-scale">389-DS: LDAP at Scale</h2>
<p>OpenLDAP is excellent for directories up to a few million entries. When you need:<br />
&#8211; 10M+ entries<br />
&#8211; High write throughput (more than a few hundred writes/second)<br />
&#8211; Fine-grained replication filtering<br />
&#8211; A dedicated web-based admin UI</p>
<p>…389-DS (Red Hat Directory Server, community edition) is the production answer. It&#8217;s what FreeIPA uses under the hood.</p>
<p>Key architectural differences from OpenLDAP:</p>
<p><strong>Multi-supplier replication</strong> — 389-DS&#8217;s replication engine uses a dedicated changelog (stored in LMDB) and Change Sequence Numbers (CSNs) for conflict resolution. Multi-supplier (multi-master) replication is first-class, not a bolted-on feature.</p>
<p><strong>Changelog</strong> — every change is written to a persistent changelog before being applied. This enables precise replication: a consumer can reconnect after a network partition and get exactly the changes it missed, rather than doing a full resync.</p>
<p><strong>Plugin architecture</strong> — 389-DS functionality (replication, managed entries, DNA for automatic UID allocation, memberOf, password policy) is all implemented as plugins that can be enabled/disabled per directory instance.</p>
<pre><code class="" data-line=""># Install 389-DS
dnf install -y 389-ds-base

# Create a new instance
dscreate interactive
# — or use a template:
dscreate from-file /path/to/instance.inf

# Manage with dsctl
dsctl slapd-corp status
dsctl slapd-corp start
dsctl slapd-corp stop

# Admin with dsconf
dsconf slapd-corp backend suffix list
dsconf slapd-corp replication status -suffix &quot;dc=corp,dc=com&quot;
</code></pre>
<p>The <code class="" data-line="">dsconf replication status</code> command gives a live view of replication lag across all suppliers and consumers — something OpenLDAP requires you to compute manually from contextCSN comparisons.</p>
<hr />
<h2 id="global-catalog-cross-domain-search-in-ad">Global Catalog: Cross-Domain Search in AD</h2>
<p>When your directory spans multiple AD domains in a forest, the Global Catalog solves a specific problem: a user in <code class="" data-line="">emea.corp.com</code> needs to be found by an app that only knows <code class="" data-line="">corp.com</code>.</p>
<pre><code class="" data-line="">Forest: corp.com
  ├── corp.com       → DC port 389    full directory: 500K entries
  ├── emea.corp.com  → DC port 389    full directory: 200K entries
  └── Global Catalog → GC port 3268  partial replica: 700K entries
                                       (not all attributes — just the most queried ones)
</code></pre>
<p>The GC replicates a subset of attributes from every domain in the forest. By default: <code class="" data-line="">cn</code>, <code class="" data-line="">mail</code>, <code class="" data-line="">sAMAccountName</code>, <code class="" data-line="">userPrincipalName</code>, <code class="" data-line="">memberOf</code>, and about 150 others. Attributes marked with <code class="" data-line="">isMemberOfPartialAttributeSet</code> in the schema are replicated to the GC.</p>
<p>If an application is configured to use port 3268 instead of 389, it&#8217;s using the GC — and it won&#8217;t see attributes not included in the partial attribute set. This surprises teams that add a custom attribute to AD and then wonder why their application can&#8217;t see it on 3268 but can on 389.</p>
<hr />
<h2 id="production-gotchas"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Production Gotchas</h2>
<p><strong>HAProxy TCP health checks don&#8217;t verify LDAP is responsive.</strong> A server can accept TCP connections but have <code class="" data-line="">slapd</code> in a degraded state (database corruption, out-of-memory). Build a proper LDAP health check: a script that binds and searches a known entry and checks the result.</p>
<p><strong>replication lag under write load.</strong> SyncRepl consumers can fall behind under sustained write load. Monitor the contextCSN difference between provider and consumers. If consumers are more than a few seconds behind, investigate the provider&#8217;s write throughput and the consumer&#8217;s processing speed.</p>
<p><strong>Directory size and the MDB mapsize.</strong> LMDB requires a pre-configured maximum database size (<code class="" data-line="">olcDbMaxSize</code>). If the database grows beyond this, <code class="" data-line="">slapd</code> starts failing writes. Set it to 2–4x your expected data size and monitor <code class="" data-line="">olmMDBPagesUsed / olmMDBPagesMax</code>.</p>
<hr />
<h2 id="key-takeaways">Key Takeaways</h2>
<ul>
<li>HAProxy in TCP mode provides LDAP load balancing — use <code class="" data-line="">balance first</code> for write routing (provider only), <code class="" data-line="">balance roundrobin</code> for reads</li>
<li>SSSD has native failover via <code class="" data-line="">ldap_uri</code> — for SSSD clients, a load balancer adds HA but isn&#8217;t strictly required</li>
<li><code class="" data-line="">cn=monitor</code> is the built-in OpenLDAP monitoring endpoint — export its counters to Prometheus for operational visibility</li>
<li>389-DS is the right choice for &gt;1M entries, high write throughput, or multi-supplier replication as a first-class feature</li>
<li>Global Catalog (port 3268/3269) is a partial replica of all AD domains — useful for forest-wide searches, but missing non-replicated attributes</li>
</ul>
<hr />
<h2 id="whats-next">What&#8217;s Next</h2>
<p>EP07 covers the infrastructure layer. EP08 zooms out to FreeIPA — what you get when LDAP, Kerberos, DNS, PKI, and HBAC are integrated into a single Linux-native identity stack, and why most Linux shops running their own directory should be running FreeIPA instead of bare OpenLDAP.</p>
<p><em>Next: <a href="/freeipa-linux-identity-management/">FreeIPA: LDAP + Kerberos + PKI in a Single Linux Identity Stack</a></em></p>
<p>Get EP08 in your inbox when it publishes → <a href="https://linuxcent.com/subscribe">linuxcent.com/subscribe</a></p>
<p><a class="a2a_button_mastodon" href="https://www.addtoany.com/add_to/mastodon?linkurl=https%3A%2F%2Flinuxcent.com%2Fldap-high-availability%2F&amp;linkname=LDAP%20High%20Availability%3A%20Load%20Balancing%20and%20Production%20Architecture" title="Mastodon" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_email" href="https://www.addtoany.com/add_to/email?linkurl=https%3A%2F%2Flinuxcent.com%2Fldap-high-availability%2F&amp;linkname=LDAP%20High%20Availability%3A%20Load%20Balancing%20and%20Production%20Architecture" title="Email" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_whatsapp" href="https://www.addtoany.com/add_to/whatsapp?linkurl=https%3A%2F%2Flinuxcent.com%2Fldap-high-availability%2F&amp;linkname=LDAP%20High%20Availability%3A%20Load%20Balancing%20and%20Production%20Architecture" title="WhatsApp" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_reddit" href="https://www.addtoany.com/add_to/reddit?linkurl=https%3A%2F%2Flinuxcent.com%2Fldap-high-availability%2F&amp;linkname=LDAP%20High%20Availability%3A%20Load%20Balancing%20and%20Production%20Architecture" title="Reddit" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Flinuxcent.com%2Fldap-high-availability%2F&amp;linkname=LDAP%20High%20Availability%3A%20Load%20Balancing%20and%20Production%20Architecture" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_linkedin" href="https://www.addtoany.com/add_to/linkedin?linkurl=https%3A%2F%2Flinuxcent.com%2Fldap-high-availability%2F&amp;linkname=LDAP%20High%20Availability%3A%20Load%20Balancing%20and%20Production%20Architecture" title="LinkedIn" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_copy_link" href="https://www.addtoany.com/add_to/copy_link?linkurl=https%3A%2F%2Flinuxcent.com%2Fldap-high-availability%2F&amp;linkname=LDAP%20High%20Availability%3A%20Load%20Balancing%20and%20Production%20Architecture" title="Copy Link" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Flinuxcent.com%2Fldap-high-availability%2F&#038;title=LDAP%20High%20Availability%3A%20Load%20Balancing%20and%20Production%20Architecture" data-a2a-url="https://linuxcent.com/ldap-high-availability/" data-a2a-title="LDAP High Availability: Load Balancing and Production Architecture"></a></p><p>The post <a href="https://linuxcent.com/ldap-high-availability/">LDAP High Availability: Load Balancing and Production Architecture</a> appeared first on <a href="https://linuxcent.com">Linuxcent</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxcent.com/ldap-high-availability/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1790</post-id>	</item>
		<item>
		<title>OpenLDAP Setup and Replication: Running Your Own Directory</title>
		<link>https://linuxcent.com/openldap-setup-replication/</link>
					<comments>https://linuxcent.com/openldap-setup-replication/#respond</comments>
		
		<dc:creator><![CDATA[Vamshi Krishna Santhapuri]]></dc:creator>
		<pubDate>Tue, 05 May 2026 05:00:00 +0000</pubDate>
				<category><![CDATA[Identity & Authentication]]></category>
		<category><![CDATA[Directory Services]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OpenLDAP]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SyncRepl]]></category>
		<guid isPermaLink="false">https://linuxcent.com/?p=1787</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 5</span> <span class="rt-label rt-postfix">minutes</span></span>Set up OpenLDAP with SyncRepl replication, OLC (cn=config), and MDB backend. Hands-on guide for a production-ready two-node replicated directory.</p>
<p>The post <a href="https://linuxcent.com/openldap-setup-replication/">OpenLDAP Setup and Replication: Running Your Own Directory</a> appeared first on <a href="https://linuxcent.com">Linuxcent</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 5</span> <span class="rt-label rt-postfix">minutes</span></span><style>
pre{position:relative;background:#1e1e1e;color:#d4d4d4;
    padding:16px 16px 16px 20px;border-radius:6px;overflow-x:auto;
    font-family:'JetBrains Mono','Fira Code','Cascadia Code',Consolas,'Courier New',monospace;
    font-size:.88em;line-height:1.6;border-left:4px solid #555}
code{background:#f4f4f4;padding:2px 5px;border-radius:3px;font-size:.9em}
pre code{background:transparent;padding:0;color:inherit}
pre[data-lang="bash"],pre[data-lang="sh"],
pre[data-lang="shell"],pre[data-lang="zsh"]{border-left-color:#4ec9b0}
pre[data-lang="yaml"],pre[data-lang="json"],
pre[data-lang="toml"],pre[data-lang="xml"]{border-left-color:#569cd6}
pre[data-lang="python"],pre[data-lang="go"],pre[data-lang="rust"],
pre[data-lang="java"],pre[data-lang="c"],pre[data-lang="cpp"]{border-left-color:#c586c0}
pre[data-lang="text"],pre[data-lang="output"],
pre[data-lang="console"]{border-left-color:#888}
.lc-copy-btn{position:absolute;top:8px;right:8px;background:#2d2d2d;color:#ccc;
    border:1px solid #444;border-radius:4px;padding:3px 9px;font-size:.75em;
    font-family:system-ui,sans-serif;cursor:pointer;opacity:0;
    transition:opacity .15s,background .15s;line-height:1.6}
pre:hover .lc-copy-btn{opacity:1}
.lc-copy-btn:hover{background:#3a3a3a;color:#fff}
.lc-copy-btn.copied{color:#4ec9b0;border-color:#4ec9b0}
.lc-lang-badge{position:absolute;top:8px;left:20px;font-family:system-ui,sans-serif;
    font-size:.7em;color:#666;text-transform:uppercase;letter-spacing:.04em;
    line-height:1;pointer-events:none;opacity:0;transition:opacity .15s}
pre:hover .lc-lang-badge{opacity:1}
table{border-collapse:collapse;width:100%;margin:16px 0}
th,td{border:1px solid #ddd;padding:10px 14px;text-align:left}
th{background:#f0f0f0;font-weight:600}
tr:nth-child(even){background:#fafafa}
</style>
<p><script>
(function(){
  if(window.__lcCodeEnhanced)return;
  window.__lcCodeEnhanced=true;
  function enhance(){
    document.querySelectorAll('pre').forEach(function(pre){
      var code=pre.querySelector('code');
      var lang='';
      if(code){var m=(code.className||'').match(/language-(\S+)/);if(m)lang=m[1].toLowerCase();}
      if(lang)pre.setAttribute('data-lang',lang);
      if(lang){var badge=document.createElement('span');badge.className='lc-lang-badge';badge.textContent=lang;pre.insertBefore(badge,pre.firstChild);}
      var btn=document.createElement('button');
      btn.className='lc-copy-btn';btn.textContent='Copy';btn.setAttribute('aria-label','Copy code to clipboard');
      pre.appendChild(btn);
      btn.addEventListener('click',function(){
        var text=code?code.innerText:pre.innerText;
        if(navigator.clipboard&&window.isSecureContext){
          navigator.clipboard.writeText(text).then(function(){ok(btn);}).catch(function(){fb(text,btn);});
        }else{fb(text,btn);}
      });
    });
  }
  function ok(btn){btn.textContent='Copied!';btn.classList.add('copied');setTimeout(function(){btn.textContent='Copy';btn.classList.remove('copied');},2000);}
  function fb(text,btn){
    try{var ta=document.createElement('textarea');ta.value=text;ta.style.cssText='position:fixed;left:-9999px;top:-9999px;opacity:0';document.body.appendChild(ta);ta.select();document.execCommand('copy');document.body.removeChild(ta);ok(btn);}
    catch(e){btn.textContent='✗ Failed';setTimeout(function(){btn.textContent='Copy';},2000);}
  }
  if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',enhance);}else{enhance();}
})();
</script></p>
<p><em>The Identity Stack, Episode 6</em><br />
<a href="/what-is-ldap/">EP01</a> → &#8230; → <a href="/how-kerberos-works-tickets-kdc/">EP05: Kerberos</a> → <strong>EP06</strong> → <a href="/ldap-high-availability-scale/">EP07: LDAP HA</a> → &#8230;</p>
<hr />
<h2 id="tldr">TL;DR</h2>
<ul>
<li>OpenLDAP&#8217;s server process is <code class="" data-line="">slapd</code> — the backend that stores data is MDB (LMDB), a memory-mapped B-tree that replaced the old Berkeley DB backend</li>
<li>Configuration lives in the directory itself: <code class="" data-line="">cn=config</code> (OLC — Online Configuration) lets you modify <code class="" data-line="">slapd</code> at runtime without restarting</li>
<li>SyncRepl is the replication protocol: a consumer subscribes to a provider and stays in sync via either polling (<code class="" data-line="">refreshOnly</code>) or a persistent connection (<code class="" data-line="">refreshAndPersist</code>)</li>
<li>Multi-Provider (formerly Multi-Master) lets multiple nodes accept writes — conflict resolution uses CSN (Change Sequence Number), last-writer-wins</li>
<li>The essential tools: <code class="" data-line="">slapd</code>, <code class="" data-line="">ldapadd</code>, <code class="" data-line="">ldapmodify</code>, <code class="" data-line="">ldapsearch</code>, <code class="" data-line="">slapcat</code>, <code class="" data-line="">slaptest</code></li>
<li>Always build indexes on the attributes you search most — <code class="" data-line="">uid</code>, <code class="" data-line="">cn</code>, <code class="" data-line="">memberOf</code> — or every search is a full scan</li>
</ul>
<hr />
<h2 id="the-big-picture-slapd-architecture">The Big Picture: slapd Architecture</h2>
<pre><code class="" data-line="">ldapsearch / ldapadd / SSSD / any LDAP client
              │ TCP 389 / 636
              ▼
         ┌─────────────────────────────────┐
         │  slapd (OpenLDAP server)         │
         │                                 │
         │  Frontend (protocol layer)       │
         │    • parse BER requests          │
         │    • ACL enforcement             │
         │    • schema validation           │
         │                                 │
         │  Backend (storage layer)         │
         │    • MDB (LMDB) — default       │
         │    • memory-mapped file I/O      │
         │    • ACID transactions           │
         └────────────┬────────────────────┘
                      │
              /var/lib/ldap/
              data.mdb   (the directory data)
              lock.mdb   (LMDB lock file)
</code></pre>
<p>EP05 showed Kerberos in isolation. OpenLDAP is where you run the identity store that Kerberos references — and where SSSD looks up user and group attributes. This episode builds a working two-node replicated directory from scratch.</p>
<hr />
<h2 id="installation">Installation</h2>
<pre><code class="" data-line=""># Ubuntu / Debian
apt-get install -y slapd ldap-utils

# RHEL / Rocky / AlmaLinux
dnf install -y openldap-servers openldap-clients

# After install — Ubuntu runs a configuration wizard
# Skip it: dpkg-reconfigure slapd
# Or answer it and then switch to OLC management
</code></pre>
<p>On RHEL-family systems, <code class="" data-line="">slapd</code> is not configured after install — you work entirely through OLC from the start.</p>
<hr />
<h2 id="olc-the-directory-configures-itself">OLC: The Directory Configures Itself</h2>
<p>The old way was <code class="" data-line="">slapd.conf</code> — a static file that required a full restart on every change. OLC (Online Configuration) replaced it: <code class="" data-line="">slapd</code>&#8216;s own configuration is stored as LDAP entries under <code class="" data-line="">cn=config</code>. You modify configuration the same way you modify data — with <code class="" data-line="">ldapmodify</code>. Changes take effect immediately.</p>
<pre><code class="" data-line="">cn=config                        ← root config entry
├── cn=schema,cn=config          ← schema definitions
│     ├── cn={0}core             ← core schema
│     ├── cn={1}cosine           ← RFC 1274 attributes
│     └── cn={2}inetorgperson    ← inetOrgPerson object class
├── olcDatabase={-1}frontend     ← default settings for all databases
├── olcDatabase={0}config        ← the config database itself
└── olcDatabase={1}mdb           ← your actual directory data
      ├── olcAccess              ← ACLs
      ├── olcSuffix              ← base DN (e.g., dc=corp,dc=com)
      └── olcDbIndex             ← search indexes
</code></pre>
<p>Everything under <code class="" data-line="">cn=config</code> has attributes prefixed with <code class="" data-line="">olc</code> (OpenLDAP Configuration). You query and modify it just like any other LDAP subtree — with one restriction: only the <code class="" data-line="">cn=config</code> admin (usually <code class="" data-line="">gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth</code> — the local root via SASL EXTERNAL) can write to it.</p>
<hr />
<h2 id="bootstrapping-a-directory">Bootstrapping a Directory</h2>
<p>The quickest way to get a working directory is a set of LDIF files applied in order.</p>
<h3 id="1-load-schemas">1. Load schemas</h3>
<pre><code class="" data-line=""># Apply the schemas OpenLDAP ships with
ldapadd -Y EXTERNAL -H ldapi:/// \
  -f /etc/ldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// \
  -f /etc/ldap/schema/inetorgperson.ldif
ldapadd -Y EXTERNAL -H ldapi:/// \
  -f /etc/ldap/schema/nis.ldif       # adds posixAccount, posixGroup
</code></pre>
<h3 id="2-configure-the-mdb-database">2. Configure the MDB database</h3>
<pre><code class="" data-line=""># mdb-config.ldif
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=corp,dc=com
-
replace: olcRootDN
olcRootDN: cn=admin,dc=corp,dc=com
-
replace: olcRootPW
olcRootPW: {SSHA}hashed_password_here
</code></pre>
<p>Generate the hash: <code class="" data-line="">slappasswd -s yourpassword</code></p>
<pre><code class="" data-line="">ldapmodify -Y EXTERNAL -H ldapi:/// -f mdb-config.ldif
</code></pre>
<h3 id="3-add-indexes">3. Add indexes</h3>
<pre><code class="" data-line=""># indexes.ldif
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: uid eq,pres
olcDbIndex: cn eq,sub
olcDbIndex: sn eq,sub
olcDbIndex: mail eq
olcDbIndex: memberOf eq
olcDbIndex: entryCSN eq
olcDbIndex: entryUUID eq
</code></pre>
<p>The last two (<code class="" data-line="">entryCSN</code>, <code class="" data-line="">entryUUID</code>) are required for SyncRepl replication to work efficiently.</p>
<h3 id="4-load-initial-data">4. Load initial data</h3>
<pre><code class="" data-line=""># base.ldif
dn: dc=corp,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: Corp
dc: corp

dn: ou=people,dc=corp,dc=com
objectClass: organizationalUnit
ou: people

dn: ou=groups,dc=corp,dc=com
objectClass: organizationalUnit
ou: groups

dn: uid=vamshi,ou=people,dc=corp,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: Vamshi Krishna
sn: Krishna
uid: vamshi
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/vamshi
loginShell: /bin/bash
mail: vamshi@corp.com
userPassword: {SSHA}hashed_password_here
</code></pre>
<pre><code class="" data-line="">ldapadd -x -H ldap://localhost \
  -D &quot;cn=admin,dc=corp,dc=com&quot; \
  -w adminpassword \
  -f base.ldif
</code></pre>
<hr />
<h2 id="acls-who-can-read-what">ACLs: Who Can Read What</h2>
<p>OpenLDAP ACLs are evaluated top-to-bottom; first match wins.</p>
<pre><code class="" data-line=""># acls.ldif — set via OLC
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
# Users can change their own passwords
olcAccess: to attrs=userPassword
  by self write
  by anonymous auth
  by * none
# Users can read their own entry
olcAccess: to dn.base=&quot;ou=people,dc=corp,dc=com&quot;
  by self read
  by users read
  by * none
# Service accounts can read everything (for SSSD)
olcAccess: to *
  by dn=&quot;cn=svc-ldap,ou=services,dc=corp,dc=com&quot; read
  by self read
  by * none
</code></pre>
<p>A service account (<code class="" data-line="">cn=svc-ldap</code>) that SSSD uses to search the directory needs read access to <code class="" data-line="">ou=people</code> and <code class="" data-line="">ou=groups</code>. Never give SSSD admin (write) access.</p>
<hr />
<h2 id="syncrepl-replication">SyncRepl Replication</h2>
<p>SyncRepl is a pull-based replication protocol built on the LDAP Sync operation (RFC 4533). A consumer connects to a provider and requests changes. The provider sends them. The consumer stays in sync.</p>
<h3 id="on-the-provider-enable-the-syncprov-overlay">On the Provider: Enable the syncprov overlay</h3>
<pre><code class="" data-line=""># syncprov.ldif
dn: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpCheckpoint: 100 10     # checkpoint every 100 ops or 10 minutes
olcSpSessionLog: 100        # keep last 100 changes for delta-sync
</code></pre>
<pre><code class="" data-line="">ldapadd -Y EXTERNAL -H ldapi:/// -f syncprov.ldif
</code></pre>
<h3 id="on-the-consumer-configure-syncrepl">On the Consumer: Configure syncrepl</h3>
<pre><code class="" data-line=""># consumer-config.ldif
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcSyncrepl
olcSyncrepl: rid=001
  provider=ldap://ldap1.corp.com:389
  bindmethod=simple
  binddn=&quot;cn=repl-svc,dc=corp,dc=com&quot;
  credentials=replication-password
  searchbase=&quot;dc=corp,dc=com&quot;
  scope=sub
  schemachecking=on
  type=refreshAndPersist    # persistent connection (vs refreshOnly = polling)
  retry=&quot;5 5 60 +&quot;          # retry: 5 times every 5s, then every 60s forever
  interval=00:00:05:00      # (for refreshOnly) sync every 5 minutes
-
add: olcUpdateRef
olcUpdateRef: ldap://ldap1.corp.com   # redirect writes to provider
</code></pre>
<p><code class="" data-line="">refreshAndPersist</code> keeps a persistent connection open. Changes replicate within milliseconds. <code class="" data-line="">refreshOnly</code> polls on an interval — simpler, but adds latency.</p>
<h3 id="verify-replication">Verify Replication</h3>
<pre><code class="" data-line=""># On provider: check the contextCSN (the sync state token)
ldapsearch -x -H ldap://ldap1.corp.com \
  -D &quot;cn=admin,dc=corp,dc=com&quot; -w password \
  -b &quot;dc=corp,dc=com&quot; -s base contextCSN
# contextCSN: 20260427010000.000000Z#000000#000#000000

# On consumer: should match after sync
ldapsearch -x -H ldap://ldap2.corp.com \
  -D &quot;cn=admin,dc=corp,dc=com&quot; -w password \
  -b &quot;dc=corp,dc=com&quot; -s base contextCSN
# Same CSN = in sync
</code></pre>
<hr />
<h2 id="multi-provider-accepting-writes-on-both-nodes">Multi-Provider: Accepting Writes on Both Nodes</h2>
<p>Standard SyncRepl has one provider and one or more consumers — only the provider accepts writes. Multi-Provider (formerly Multi-Master) lets every node accept writes.</p>
<pre><code class="" data-line=""># On each node — add mirrormode to the database config
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcMirrorMode
olcMirrorMode: TRUE
</code></pre>
<p>With mirrormode enabled and each node configured as both provider and consumer of the other, writes on either node replicate to the other. Conflict resolution is CSN-based (Change Sequence Number) — a monotonically increasing timestamp. Last write wins at the attribute level.</p>
<p>Multi-Provider does not prevent split-brain conflicts — if two clients write the same attribute on two different nodes during a network partition, the higher CSN wins when the partition heals. For most directory use cases (user passwords, group memberships), this is acceptable. For others, it requires careful thought.</p>
<hr />
<h2 id="production-gotchas"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Production Gotchas</h2>
<p><strong>MDB data file grows monotonically.</strong> LMDB never shrinks the data file automatically. Deleted entries leave free space inside the file that gets reused, but the file on disk doesn&#8217;t shrink. Use <code class="" data-line="">slapcat</code> to export and <code class="" data-line="">slapadd</code> to reimport if you need to reclaim disk space.</p>
<p><strong><code class="" data-line="">slapcat</code> is the only safe backup.</strong> <code class="" data-line="">slapcat</code> reads the MDB database directly and exports LDIF — it does not go through <code class="" data-line="">slapd</code>. Run it while <code class="" data-line="">slapd</code> is running (LMDB is MVCC-safe for readers), but never copy the raw MDB files while <code class="" data-line="">slapd</code> is running.</p>
<p><strong>Schema changes on a replicated directory require coordination.</strong> Load the new schema on the provider first. SyncRepl will propagate it to consumers — but if a consumer gets a new entry using the new schema before the schema itself is replicated, the import will fail. Load schemas manually on all nodes before adding entries that use them.</p>
<hr />
<h2 id="key-takeaways">Key Takeaways</h2>
<ul>
<li>OpenLDAP uses LMDB (MDB backend) — a memory-mapped, ACID-compliant storage engine with no external dependency</li>
<li>OLC (<code class="" data-line="">cn=config</code>) is the right way to configure <code class="" data-line="">slapd</code> — changes apply without restarts</li>
<li>SyncRepl pulls changes from a provider to a consumer — <code class="" data-line="">refreshAndPersist</code> for near-real-time, <code class="" data-line="">refreshOnly</code> for poll-based</li>
<li>Always index <code class="" data-line="">uid</code>, <code class="" data-line="">cn</code>, <code class="" data-line="">entryCSN</code>, and <code class="" data-line="">entryUUID</code> — unindexed searches are full scans</li>
<li>Multi-Provider allows writes on all nodes with CSN-based last-write-wins conflict resolution</li>
</ul>
<hr />
<h2 id="whats-next">What&#8217;s Next</h2>
<p>A single OpenLDAP server works. Two nodes with SyncRepl work better. EP07 goes further: how you put multiple LDAP servers behind a load balancer, how connection pooling works, what to monitor, and how 389-DS handles directories with tens of millions of entries.</p>
<p><em>Next: <a href="/ldap-high-availability-scale/">LDAP High Availability: Load Balancing and Production Architecture</a></em></p>
<p>Get EP07 in your inbox when it publishes → <a href="https://linuxcent.com/subscribe">linuxcent.com/subscribe</a></p>
<p><a class="a2a_button_mastodon" href="https://www.addtoany.com/add_to/mastodon?linkurl=https%3A%2F%2Flinuxcent.com%2Fopenldap-setup-replication%2F&amp;linkname=OpenLDAP%20Setup%20and%20Replication%3A%20Running%20Your%20Own%20Directory" title="Mastodon" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_email" href="https://www.addtoany.com/add_to/email?linkurl=https%3A%2F%2Flinuxcent.com%2Fopenldap-setup-replication%2F&amp;linkname=OpenLDAP%20Setup%20and%20Replication%3A%20Running%20Your%20Own%20Directory" title="Email" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_whatsapp" href="https://www.addtoany.com/add_to/whatsapp?linkurl=https%3A%2F%2Flinuxcent.com%2Fopenldap-setup-replication%2F&amp;linkname=OpenLDAP%20Setup%20and%20Replication%3A%20Running%20Your%20Own%20Directory" title="WhatsApp" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_reddit" href="https://www.addtoany.com/add_to/reddit?linkurl=https%3A%2F%2Flinuxcent.com%2Fopenldap-setup-replication%2F&amp;linkname=OpenLDAP%20Setup%20and%20Replication%3A%20Running%20Your%20Own%20Directory" title="Reddit" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Flinuxcent.com%2Fopenldap-setup-replication%2F&amp;linkname=OpenLDAP%20Setup%20and%20Replication%3A%20Running%20Your%20Own%20Directory" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_linkedin" href="https://www.addtoany.com/add_to/linkedin?linkurl=https%3A%2F%2Flinuxcent.com%2Fopenldap-setup-replication%2F&amp;linkname=OpenLDAP%20Setup%20and%20Replication%3A%20Running%20Your%20Own%20Directory" title="LinkedIn" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_copy_link" href="https://www.addtoany.com/add_to/copy_link?linkurl=https%3A%2F%2Flinuxcent.com%2Fopenldap-setup-replication%2F&amp;linkname=OpenLDAP%20Setup%20and%20Replication%3A%20Running%20Your%20Own%20Directory" title="Copy Link" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Flinuxcent.com%2Fopenldap-setup-replication%2F&#038;title=OpenLDAP%20Setup%20and%20Replication%3A%20Running%20Your%20Own%20Directory" data-a2a-url="https://linuxcent.com/openldap-setup-replication/" data-a2a-title="OpenLDAP Setup and Replication: Running Your Own Directory"></a></p><p>The post <a href="https://linuxcent.com/openldap-setup-replication/">OpenLDAP Setup and Replication: Running Your Own Directory</a> appeared first on <a href="https://linuxcent.com">Linuxcent</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxcent.com/openldap-setup-replication/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1787</post-id>	</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: linuxcent.com @ 2026-07-03 05:05:31 by W3 Total Cache
-->