
Zimbra Federation Layer
Zimbra Federation Layer - Implementation Guide
Overview
This federation system enables transparent cross-instance sharing between completely separated Zimbra instances without creating proxy accounts or using shared LDAP.
What You Get
- ✅ UserA@Zimbra1 shares folder with UserB@Zimbra2
- ✅ UserB sees it automatically in their mailbox (no link clicking)
- ✅ UserB accesses it transparently (automatic SOAP proxying)
- ✅ Works exactly like local sharing
- ✅ No proxy accounts needed
- ✅ No shared LDAP required
Architecture
┌──────────────────────────────────────────────────────┐
│ TRANSPARENT SHARING FLOW │
└──────────────────────────────────────────────────────┘
Step 1: UserA@Zimbra1 grants share to UserB@Zimbra2
│
▼
Step 2: FederatedProvisioning detects UserB is remote
│
▼
Step 3: FederatedShareNotifier sends notification to Zimbra2
│
▼
Step 4: Zimbra2 receives CreateFederatedMountpoint request
│
▼
Step 5: Auto-creates mountpoint in UserB's mailbox
│
▼
Step 6: UserB sees shared folder (TRANSPARENT!)
│
▼
Step 7: UserB accesses → SOAP proxy → Zimbra1 (TRANSPARENT!)
Components Implemented
1. FederatedProvisioning.java
Location: zm-mailbox/store/src/java/com/zimbra/cs/account/ldap/FederatedProvisioning.java
Purpose: Multi-instance account lookup
Features:
- Searches across multiple Zimbra LDAPs
- Caches federated instance configuration
- Returns account location information
2. FederatedShareNotifier.java
Location: zm-mailbox/store/src/java/com/zimbra/cs/service/mail/FederatedShareNotifier.java
Purpose: Share notification bridge
Features:
- Detects remote shares automatically
- Sends SOAP notifications to remote instances
- Handles grant and revoke operations
3. CreateFederatedMountpoint.java
Location: zm-mailbox/store/src/java/com/zimbra/cs/service/mail/CreateFederatedMountpoint.java
Purpose: Auto mountpoint creation
Features:
- Receives federated share notifications
- Creates mountpoints automatically
- Prevents duplicates
Configuration
LocalConfig Settings
On BOTH Zimbra instances, configure:
# Enable federation
zmlocalconfig -e zimbra_federation_enabled=true
# Configure federated instances (comma-separated LDAP URLs)
# On Zimbra1:
zmlocalconfig -e zimbra_federation_instances="ldap://zimbra2.internal.com:389"
# On Zimbra2:
zmlocalconfig -e zimbra_federation_instances="ldap://zimbra1.internal.com:389"
# LDAP credentials for remote instance lookup
zmlocalconfig -e zimbra_federation_bind_dn="uid=zimbra,cn=admins,cn=zimbra"
zmlocalconfig -e zimbra_federation_bind_password="<zimbra-ldap-password>"
zmlocalconfig -e zimbra_federation_base_dn="dc=example,dc=com"
Get LDAP Password
# On each Zimbra instance:
zmlocalconfig zimbra_ldap_password
Example Configuration
Zimbra1 (zimbra1.internal.com):
zmlocalconfig -e zimbra_federation_enabled=true
zmlocalconfig -e zimbra_federation_instances="ldap://zimbra2.internal.com:389"
zmlocalconfig -e zimbra_federation_bind_dn="uid=zimbra,cn=admins,cn=zimbra"
zmlocalconfig -e zimbra_federation_bind_password="SecurePassword123"
zmlocalconfig -e zimbra_federation_base_dn="dc=example,dc=com"
Zimbra2 (zimbra2.internal.com):
zmlocalconfig -e zimbra_federation_enabled=true
zmlocalconfig -e zimbra_federation_instances="ldap://zimbra1.internal.com:389"
zmlocalconfig -e zimbra_federation_bind_dn="uid=zimbra,cn=admins,cn=zimbra"
zmlocalconfig -e zimbra_federation_bind_password="SecurePassword456"
zmlocalconfig -e zimbra_federation_base_dn="dc=example,dc=com"
Integration Steps
Step 1: Hook FederatedShareNotifier into FolderAction
Modify /zm-mailbox/store/src/java/com/zimbra/cs/service/mail/FolderAction.java:
Find the grant operation handler (around line 500-600) and add:
// After successful ACL.Grant operation
if (grantee != null && grantee instanceof Account) {
try {
// Notify federated instances
FederatedShareNotifier.notifyFederatedShare(
mbox.getAccount(),
folder,
grantee.getName(),
rights
);
} catch (Exception e) {
ZimbraLog.share.warn("Failed to notify federated share", e);
// Don't fail the share operation
}
}
Step 2: Hook FederatedShareNotifier into Revoke
In the same file, find revoke operation and add:
// After successful revoke
try {
FederatedShareNotifier.notifyFederatedRevoke(
mbox.getAccount(),
folder,
granteeEmail
);
} catch (Exception e) {
ZimbraLog.share.warn("Failed to notify federated revoke", e);
}
Step 3: Register CreateFederatedMountpoint SOAP Handler
Add to /zm-mailbox/store/src/java/com/zimbra/soap/SoapServlet.java:
// In the handler registration section
register(new CreateFederatedMountpoint(), SoapProtocol.SoapJS);
Step 4: Build and Deploy
# In zm-mailbox directory
cd /home/node0/IdeaProjects/Zimbra10FOSS/zm-mailbox
ant clean jar
# Deploy JARs to both Zimbra instances
# Copy build/dist/*.jar to /opt/zimbra/lib/jars/
# Restart mailbox
zmmailboxdctl restart
Network Requirements
Firewall Rules
On both servers, allow:
# LDAP access (for account lookup)
iptables -A INPUT -p tcp --dport 389 -j ACCEPT
# HTTPS (for SOAP notifications)
iptables -A INPUT -p tcp --dport 7071 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 8443 -j ACCEPT
DNS Resolution
Ensure both servers can resolve each other:
# Test from Zimbra1:
ping zimbra2.internal.com
telnet zimbra2.internal.com 389
# Test from Zimbra2:
ping zimbra1.internal.com
telnet zimbra1.internal.com 389
Testing
Test 1: Verify Federation Configuration
# Check configuration
zmlocalconfig | grep zimbra_federation
# Should show:
# zimbra_federation_enabled = true
# zimbra_federation_instances = ldap://remote:389
# zimbra_federation_bind_dn = uid=zimbra,cn=admins,cn=zimbra
# etc.
Test 2: Test LDAP Connectivity
# From Zimbra1, query Zimbra2's LDAP:
ldapsearch -x -H ldap://zimbra2.internal.com:389 \
-D "uid=zimbra,cn=admins,cn=zimbra" \
-w <password> \
-b "dc=example,dc=com" \
mail=userB@example.com
Test 3: Create Federated Share
# On Zimbra1, UserA shares calendar with UserB@Zimbra2
zmmailbox -z -m userA@example.com mfg /Calendar rw userB@example.com
# Check logs on Zimbra1:
tail -f /opt/zimbra/log/mailbox.log | grep -i federation
# Should see:
# "Searching federated instances for account: userB@example.com"
# "Found account userB@example.com on instance: ldap://zimbra2..."
# "Notifying federated instance about share..."
# "Federated share notification successful"
Test 4: Verify Auto Mountpoint Creation
# On Zimbra2, check UserB's folders:
zmmailbox -z -m userB@example.com gaf
# Should show mountpoint to UserA's calendar:
# Id Type Perms Name
# --- ---- ----- ----
# 257 mount rw Shared Calendar (owner: userA@example.com)
Test 5: Access Shared Data
# UserB searches shared calendar
zmmailbox -z -m userB@example.com search -t appointment "in:'/Shared Calendar'"
# Should transparently fetch data from Zimbra1
Troubleshooting
Issue: "Federation disabled"
Check:
zmlocalconfig zimbra_federation_enabled
# Must be: true (lowercase)
Fix:
zmlocalconfig -e zimbra_federation_enabled=true
zmmailboxdctl restart
Issue: "Account not found in federated instance"
Check LDAP connectivity:
telnet zimbra2.internal.com 389
Check LDAP credentials:
ldapsearch -x -H ldap://zimbra2.internal.com:389 \
-D "uid=zimbra,cn=admins,cn=zimbra" \
-w <password> \
-b "dc=example,dc=com" \
mail=userB@example.com
Check base DN:
zmlocalconfig zimbra_federation_base_dn
# Must match remote LDAP structure
Issue: "Failed to notify federated instance"
Check firewall:
telnet zimbra2.internal.com 7071
telnet zimbra2.internal.com 443
Check logs on receiving server:
tail -f /opt/zimbra/log/mailbox.log | grep CreateFederatedMountpoint
Issue: Mountpoint not created
Check CreateFederatedMountpoint handler registration:
# Verify SOAP handler is registered
# Check SoapServlet.java includes CreateFederatedMountpoint
Manual mountpoint creation test:
# Create mountpoint manually to verify it works
zmmailbox -z -m userB@example.com cm /TestMount owner ownerZimbraId remoteId remoteUuid
Limitations
Current Implementation
- One-way notification - Share initiates from local to remote
- No automatic sync - Changes to share permissions require re-notification
- HTTPS required - Remote instance must be accessible via HTTPS
- Single domain - Both users must be in same domain (can be extended)
Future Enhancements
- Bidirectional federation - Either instance can initiate
- Share permission sync - Automatic updates on permission changes
- Multi-domain support - Cross-domain sharing
- Encryption - TLS/SSL for LDAP connections
- Load balancing - Multiple instances per organization
- Caching - Cache remote account lookups
Security Considerations
LDAP Security
# Use LDAPS (LDAP over SSL) instead of plain LDAP:
zmlocalconfig -e zimbra_federation_instances="ldaps://zimbra2.internal.com:636"
SOAP Security
- All SOAP requests use HTTPS
- Requires admin/service authentication
- Validate sender identity
Firewall
- Restrict LDAP access to known Zimbra IPs
- Use VPN for cross-datacenter federation
- Monitor federation logs for suspicious activity
Monitoring
Log Monitoring
# Watch federation activity:
tail -f /opt/zimbra/log/mailbox.log | grep -i "federation\|federated"
# Key log messages:
# "Federation enabled with N instances"
# "Searching federated instances for account..."
# "Found account X on instance..."
# "Notifying federated instance about share..."
# "Received federated mountpoint request..."
# "Successfully created federated mountpoint..."
Metrics
Track:
- Federated account lookups per minute
- Federated share notifications sent/received
- Mountpoints created via federation
- Failed federation operations
Performance
LDAP Query Optimization
- Federation adds one LDAP query per remote instance
- Queries are sequential (first match wins)
- Average overhead: ~50-100ms per remote query
Caching (TODO)
Implement caching layer:
// Cache federated account lookups for 5 minutes
// Reduce repeated LDAP queries
Connection Pooling (TODO)
Reuse LDAP connections:
// Maintain connection pool to remote instances
// Avoid connection overhead on every lookup
Summary
This federation layer provides true transparent sharing between separated Zimbra instances:
Without Federation:
- Manual account creation required
- Share links needed
- Separate logins
- Not transparent
With Federation:
- ✅ Automatic account discovery
- ✅ Automatic mountpoint creation
- ✅ Transparent access
- ✅ Works like local sharing
Next Steps:
- Build modified zm-mailbox
- Deploy to both instances
- Configure federation settings
- Test federated sharing
- Monitor logs
- Iterate and improve
Support
For issues or questions:
- Check logs:
/opt/zimbra/log/mailbox.log - Verify configuration:
zmlocalconfig | grep federation - Test connectivity: LDAP (389) and HTTPS (7071, 443)
- Review this guide's troubleshooting section
Good luck with your federated Zimbra deployment!