Skip to content

nasomers/ldap-proxy-service

Repository files navigation

LDAP Authentication Proxy

A transparent socket-based LDAP proxy that intelligently routes authentication requests to the correct Domain Controller based on the user's UPN (User Principal Name) domain.

The Problem It Solves

Scenario: You're migrating from Domain A to Domain B. Users are split across two domains, but your legacy application only accepts ONE LDAP endpoint. Users who moved to Domain B can't authenticate anymore because their UPNs don't exist in Domain A.

Solution: A proxy that presents a single endpoint but intelligently routes authentication requests to the correct domain controller based on the user's UPN (user@domain.com).

Architecture

Legacy App → LDAP Proxy (single endpoint) → Routes to correct DC
                  ↓
     john@domainA.com → DC-A (10.1.1.5)
     jane@domainB.com → DC-B (10.2.2.5)

The proxy:

  1. Listens on a single port (389 or 3389)
  2. Accepts authentication requests
  3. Extracts the domain from the username (user@domain.com)
  4. Routes to the appropriate Domain Controller
  5. Returns the authentication result

Features

Core Proxy

  • Transparent routing - Legacy apps don't need changes
  • Multi-domain support - Route to different DCs based on UPN domain
  • Configuration-driven - Add domains via JSON, no code changes
  • Concurrent connections - Threading for multiple simultaneous authentications
  • SSL/TLS support - Use LDAPS (port 636) for secure connections
  • Comprehensive logging - Track all authentication attempts (passwords never logged)
  • Production-ready - Includes systemd service, deployment guide

Web Dashboard (NEW!)

  • Real-time monitoring - Live activity feed with WebSocket updates
  • Statistics & charts - Visual insights with Chart.js (trends, success rates, domain breakdown)
  • Configuration editor - Manage domains and settings via web interface
  • Alert management - Create custom alerts for failed auth patterns
  • Easy deployment - Modern web UI built with Flask and Bootstrap

Requirements

  • Python 3.8 or higher
  • Network connectivity to Domain Controllers
  • Domain Controllers with LDAP enabled (port 389 or 636)

Quick Start

1. Install Dependencies

pip install ldap3

2. Configure

Edit ldap_proxy_config.json:

{
  "listen_host": "0.0.0.0",
  "listen_port": 3389,
  "default_domain": "domainA.com",
  "domain_routes": {
    "domainA.com": {
      "dc_host": "10.1.1.5",
      "dc_port": 389,
      "use_ssl": false
    },
    "domainB.com": {
      "dc_host": "10.2.2.5",
      "dc_port": 389,
      "use_ssl": false
    }
  }
}

3. Run the Proxy

python3 ldap_proxy.py

4. Test It

# In another terminal
python3 test_client.py -u john@domainA.com -p password123

Web Dashboard

The LDAP proxy includes a modern web dashboard for monitoring and configuration!

Quick Start (Web UI)

# Install web dependencies
pip install flask flask-socketio python-socketio

# Start the web dashboard (in addition to the proxy)
cd web_ui
python3 app.py

# Open in browser
# http://localhost:5000

Web Dashboard Features

  • Dashboard: Real-time authentication feed, statistics, domain breakdown
  • Statistics: Interactive charts, trends, top users, domain stats
  • Configuration: Visual editor for domain routes and settings
  • Alerts: Create alerts for failed auth patterns, view trigger history

See WEB_UI_GUIDE.md for complete documentation!

Configuration

Configuration File: ldap_proxy_config.json

{
  "listen_host": "0.0.0.0",
  "listen_port": 3389,
  "connection_timeout": 30,
  "default_domain": "domainA.com",
  "domain_routes": {
    "domainA.com": {
      "dc_host": "dc1.domainA.com",
      "dc_port": 389,
      "use_ssl": false
    },
    "domainB.com": {
      "dc_host": "dc1.domainB.com",
      "dc_port": 636,
      "use_ssl": true
    }
  }
}

Configuration Options

Option Description Default
listen_host Interface to bind to (0.0.0.0 = all) 0.0.0.0
listen_port Port to listen on 3389
connection_timeout Timeout for DC connections (seconds) 30
default_domain Domain to use when username has no @domain -
domain_routes Map of domains to DC configurations {}

Domain Route Options

Option Description Default
dc_host Domain Controller hostname or IP Required
dc_port LDAP port (389 or 636 for SSL) 389
use_ssl Use LDAPS (SSL/TLS) false

Port Selection

  • Port 3389: Non-privileged port, good for testing (no root required)
  • Port 389: Standard LDAP port (requires root or port forwarding)

For production on port 389, use iptables forwarding or setcap (see DEPLOYMENT_GUIDE.md).

Testing

Using the Test Client

Interactive mode:

python3 test_client.py

Single test:

python3 test_client.py -u john@domainA.com -p password123

Different host/port:

python3 test_client.py -H 192.168.1.100 -P 389 -u john@domainA.com -p pass

Test Both Domains

Verify routing works for multiple domains:

python3 test_client.py -u user1@domainA.com -p password1
python3 test_client.py -u user2@domainB.com -p password2

How It Works

Request Flow

  1. Client connects to proxy (port 3389)
  2. Client sends username and password
  3. Proxy extracts domain from username (e.g., john@domainA.comdomainA.com)
  4. Proxy looks up DC configuration for that domain
  5. Proxy connects to the correct DC (e.g., 10.1.1.5:389)
  6. Proxy attempts LDAP BIND with user credentials
  7. DC responds with success or failure
  8. Proxy returns result to client

Logging

All authentication attempts are logged:

2025-11-19 10:05:23 - INFO - New connection from ('192.168.1.100', 54321)
2025-11-19 10:05:23 - INFO - Attempting authentication for 'john@domainA.com' via DC: 10.1.1.5:389
2025-11-19 10:05:23 - INFO - ✓ Authentication SUCCESSFUL for 'john@domainA.com' via 10.1.1.5
2025-11-19 10:05:23 - INFO - Connection closed from ('192.168.1.100', 54321)

Important: Passwords are NEVER logged.

Production Deployment

See DEPLOYMENT_GUIDE.md for complete deployment instructions including:

  • Installing as a systemd service
  • Port forwarding for port 389
  • Security hardening
  • Monitoring and logging
  • Troubleshooting

Quick Deployment

# Copy files to production location
sudo cp ldap_proxy.py /opt/ldap-proxy/
sudo cp ldap_proxy_config.json /opt/ldap-proxy/

# Install dependencies
sudo pip3 install ldap3

# Create systemd service
sudo nano /etc/systemd/system/ldap-proxy.service

# Enable and start
sudo systemctl enable ldap-proxy
sudo systemctl start ldap-proxy

# Check status
sudo systemctl status ldap-proxy

Project Structure

ldap-proxy-project/
├── ldap_proxy.py                # Main proxy server
├── ldap_proxy_config.json       # Configuration (your settings)
├── ldap_proxy_config.example.json  # Example configuration
├── test_client.py               # Test client tool
├── DEPLOYMENT_GUIDE.md          # Production deployment guide
├── README.md                    # This file
└── requirements.txt             # Python dependencies

Adding More Domains

Simply edit the configuration file - no code changes needed:

{
  "domain_routes": {
    "domainA.com": {"dc_host": "10.1.1.5", "dc_port": 389},
    "domainB.com": {"dc_host": "10.2.2.5", "dc_port": 389},
    "domainC.com": {"dc_host": "10.3.3.5", "dc_port": 636, "use_ssl": true}
  }
}

Restart the proxy:

sudo systemctl restart ldap-proxy

Troubleshooting

Proxy won't start

# Check configuration syntax
python3 -c "import json; json.load(open('ldap_proxy_config.json'))"

# Check port is not in use
sudo netstat -tlnp | grep 3389

# Check logs
sudo journalctl -u ldap-proxy -n 50

Authentication fails

# Test DC connectivity from proxy server
ldapsearch -x -H ldap://dc1.domainA.com:389 -b "" -s base

# Check proxy logs for routing
sudo journalctl -u ldap-proxy | grep "Attempting authentication"

# Verify username is in UPN format (user@domain.com)

Can't connect to proxy

# Check firewall
sudo ufw status
sudo firewall-cmd --list-all

# Test connection
telnet localhost 3389
nc -zv localhost 3389

Security Considerations

Network Security

  • Use LDAPS (SSL/TLS) with Domain Controllers in production
  • Firewall: Only allow traffic from application servers
  • Use private network/VPN between proxy and DCs

Application Security

  • Run as non-privileged user
  • Restrict config file permissions (chmod 600)
  • Regular security updates
  • Monitor authentication logs

Monitoring

  • Alert on service failures
  • Monitor failed authentication attempts
  • Regular log review
  • Track authentication patterns

Performance

The proxy uses threading to handle multiple concurrent authentications:

  • Each connection gets its own thread
  • Multiple users can authenticate simultaneously
  • Lightweight - minimal resource usage
  • Tested with hundreds of concurrent connections

Limitations

Current version handles:

  • ✓ LDAP BIND (authentication)
  • ✓ Multiple domains
  • ✓ SSL/TLS support
  • ✓ Concurrent connections

Not implemented (yet):

  • ✗ Full LDAP protocol (searches, adds, modifies)
  • ✗ Connection pooling
  • ✗ Health checks / automatic failover
  • ✗ Load balancing across multiple DCs

For full LDAP proxy functionality, additional protocol operations would need to be implemented.

Use Cases

This proxy is perfect for:

  • Domain migrations - Users split across multiple domains
  • Legacy applications - Can only handle one LDAP endpoint
  • Multi-tenant environments - Different customers on different domains
  • Testing environments - Route test users to different DCs
  • Gradual migrations - Transparent routing as users migrate

License

MIT

Contributing

Contributions welcome! Areas for improvement:

  • Connection pooling
  • Health checks and failover
  • Full LDAP protocol support
  • Metrics/monitoring endpoints
  • Load balancing

Support

  1. Check logs: sudo journalctl -u ldap-proxy
  2. Test DC connectivity: ldapsearch -x -H ldap://dc:389
  3. Verify configuration: python3 -c "import json; json.load(open('config.json'))"
  4. See DEPLOYMENT_GUIDE.md for detailed troubleshooting

Related Files


The Bottom Line:

This proxy solves a real enterprise problem with simple, elegant code. It's transparent to users, configuration-driven, and production-ready. Perfect for domain migrations and legacy application support.

About

Smart LDAP proxy for AD domain migrations. Routes user authentication to the correct domain controller based on UPN domain suffix, solving the problem of legacy applications that only support one LDAP endpoint. Handles users split between old and new domains during staged migrations without requiring costly enterprise identity management platforms.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors