Working after iterations
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -86,9 +86,13 @@ logs/
|
|||||||
*.bak
|
*.bak
|
||||||
*.tmp
|
*.tmp
|
||||||
|
|
||||||
# Environment files with secrets
|
# Environment files
|
||||||
|
# Note: .env is tracked and contains non-secret configuration (ports, etc.)
|
||||||
|
# Add secrets only to .env.local which is ignored
|
||||||
.env.local
|
.env.local
|
||||||
.env.*.local
|
.env.*.local
|
||||||
|
.env.production
|
||||||
|
.env.development
|
||||||
|
|
||||||
# MacOS
|
# MacOS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
94
CHANGELOG.md
Normal file
94
CHANGELOG.md
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.1.0] - 2025-01-XX
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial release of LDAP Docker development tool
|
||||||
|
- OpenLDAP 1.5.0 container with SSL/TLS support
|
||||||
|
- phpLDAPadmin web interface for easy administration
|
||||||
|
- Pre-configured test users and groups for testing.local domain
|
||||||
|
- SSL certificate generation script using Python cryptography
|
||||||
|
- Comprehensive CLI tool for managing LDAP server (`ldap-docker` command)
|
||||||
|
- Makefile with convenient shortcuts for common operations
|
||||||
|
- Interactive quickstart script (`quickstart.sh`) for guided setup
|
||||||
|
- Example Python authentication script demonstrating LDAP integration
|
||||||
|
- Support for custom dev-ca certificates
|
||||||
|
- Persistent Docker volumes for data and configuration
|
||||||
|
- Test suite for certificate generation
|
||||||
|
- Comprehensive documentation:
|
||||||
|
- README.md - Full project documentation
|
||||||
|
- GETTING_STARTED.md - Beginner-friendly guide
|
||||||
|
- QUICKREF.md - Quick command reference
|
||||||
|
- certs/README.md - Certificate management guide
|
||||||
|
- examples/README.md - Integration patterns and examples
|
||||||
|
|
||||||
|
### Test Data
|
||||||
|
- 4 pre-configured test users (admin, jdoe, jsmith, testuser)
|
||||||
|
- 3 test groups (admins, developers, users)
|
||||||
|
- All test users use password: `password123`
|
||||||
|
- Admin credentials: `cn=admin,dc=testing,dc=local` / `admin_password`
|
||||||
|
|
||||||
|
### Infrastructure
|
||||||
|
- Docker Compose configuration for easy deployment
|
||||||
|
- UV package manager integration for Python dependencies
|
||||||
|
- Cross-platform support (MacOS, Linux, Windows)
|
||||||
|
- Rancher Desktop and Docker Desktop compatibility
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Updated `pyproject.toml` to use `dependency-groups.dev` instead of deprecated `tool.uv.dev-dependencies`
|
||||||
|
- Added `tool.hatch.build.targets.wheel.packages` configuration to fix build errors
|
||||||
|
- Removed obsolete `version` field from `docker-compose.yml` (Docker Compose v2+ compatibility)
|
||||||
|
- Fixed LDAP user password hashes to use proper SSHA format generated by `slappasswd`
|
||||||
|
- Fixed attribute type conversion in example scripts for uidNumber and gidNumber
|
||||||
|
|
||||||
|
### Technical Details
|
||||||
|
- Base DN: `dc=testing,dc=local`
|
||||||
|
- LDAP Port: 389 (standard)
|
||||||
|
- LDAPS Port: 636 (SSL/TLS)
|
||||||
|
- Web Admin Port: 8080
|
||||||
|
- Python 3.9+ required
|
||||||
|
- Docker/Rancher Desktop required
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Planned Features
|
||||||
|
- Additional integration examples (Node.js, Go, Ruby, etc.)
|
||||||
|
- Health check endpoints
|
||||||
|
- Automated backup scripts
|
||||||
|
- Docker image with pre-built configuration
|
||||||
|
- Kubernetes/Helm deployment examples
|
||||||
|
- LDAP replication setup guide
|
||||||
|
- Performance tuning guide
|
||||||
|
- Security hardening options
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Release Notes
|
||||||
|
|
||||||
|
### Version 0.1.0
|
||||||
|
This is the initial release providing a complete LDAP development environment suitable for:
|
||||||
|
- Testing LDAP authentication in applications
|
||||||
|
- Development and integration testing
|
||||||
|
- Learning LDAP concepts
|
||||||
|
- Prototyping LDAP-based systems
|
||||||
|
|
||||||
|
**Important Security Notes:**
|
||||||
|
- This tool is for **DEVELOPMENT USE ONLY**
|
||||||
|
- Default passwords are well-known and insecure
|
||||||
|
- Self-signed certificates are not suitable for production
|
||||||
|
- Never use this with real user data or in production environments
|
||||||
|
|
||||||
|
### Upgrade Instructions
|
||||||
|
Not applicable for initial release.
|
||||||
|
|
||||||
|
### Breaking Changes
|
||||||
|
Not applicable for initial release.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
For support, issues, or feature requests, please refer to the project documentation or open an issue on the project repository.
|
||||||
22
Makefile
22
Makefile
@@ -1,5 +1,11 @@
|
|||||||
.PHONY: help install init start stop restart down logs status certs-generate certs-check test-connection test-auth test-users clean clean-all
|
.PHONY: help install init start stop restart down logs status certs-generate certs-check test-connection test-auth test-users clean clean-all
|
||||||
|
|
||||||
|
# Load environment variables from .env file if it exists
|
||||||
|
ifneq (,$(wildcard ./.env))
|
||||||
|
include .env
|
||||||
|
export
|
||||||
|
endif
|
||||||
|
|
||||||
# Default target
|
# Default target
|
||||||
.DEFAULT_GOAL := help
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
@@ -55,9 +61,9 @@ start: ## Start the LDAP server
|
|||||||
@echo "✅ LDAP server started"
|
@echo "✅ LDAP server started"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Services available at:"
|
@echo "Services available at:"
|
||||||
@echo " - LDAP: ldap://localhost:389"
|
@echo " - LDAP: ldap://localhost:$${LDAP_PORT:-389}"
|
||||||
@echo " - LDAPS: ldaps://localhost:636"
|
@echo " - LDAPS: ldaps://localhost:$${LDAPS_PORT:-636}"
|
||||||
@echo " - Admin: http://localhost:8080"
|
@echo " - Admin: http://localhost:$${PHPLDAPADMIN_PORT:-8080}"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Admin credentials:"
|
@echo "Admin credentials:"
|
||||||
@echo " DN: cn=admin,dc=testing,dc=local"
|
@echo " DN: cn=admin,dc=testing,dc=local"
|
||||||
@@ -105,19 +111,19 @@ status: ## Show container status
|
|||||||
|
|
||||||
test-connection: ## Test connection to LDAP server
|
test-connection: ## Test connection to LDAP server
|
||||||
@echo "Testing LDAP connection..."
|
@echo "Testing LDAP connection..."
|
||||||
uv run python -c "from ldap3 import Server, Connection, ALL; s = Server('ldap://localhost:389', get_info=ALL); c = Connection(s, auto_bind=True); print('✅ Connection successful'); c.unbind()"
|
@export LDAP_PORT=$${LDAP_PORT:-389}; uv run python -c "import os; from ldap3 import Server, Connection, ALL; s = Server(f\"ldap://localhost:{os.environ.get('LDAP_PORT', '389')}\", get_info=ALL); c = Connection(s, auto_bind=True); print('✅ Connection successful'); c.unbind()"
|
||||||
|
|
||||||
test-auth: ## Test authentication with admin user
|
test-auth: ## Test authentication with admin user
|
||||||
@echo "Testing LDAP authentication..."
|
@echo "Testing LDAP authentication..."
|
||||||
uv run python -c "from ldap3 import Server, Connection; s = Server('ldap://localhost:389'); c = Connection(s, 'cn=admin,dc=testing,dc=local', 'admin_password', auto_bind=True); print('✅ Authentication successful'); c.unbind()"
|
@export LDAP_PORT=$${LDAP_PORT:-389}; uv run python -c "import os; from ldap3 import Server, Connection; s = Server(f\"ldap://localhost:{os.environ.get('LDAP_PORT', '389')}\"); c = Connection(s, 'cn=admin,dc=testing,dc=local', 'admin_password', auto_bind=True); print('✅ Authentication successful'); c.unbind()"
|
||||||
|
|
||||||
test-users: ## List all users in LDAP
|
test-users: ## List all users in LDAP
|
||||||
@echo "Listing LDAP users..."
|
@echo "Listing LDAP users..."
|
||||||
@uv run python -c "from ldap3 import Server, Connection; s = Server('ldap://localhost:389'); c = Connection(s, 'cn=admin,dc=testing,dc=local', 'admin_password', auto_bind=True); c.search('dc=testing,dc=local', '(objectClass=inetOrgPerson)', attributes=['uid', 'cn', 'mail']); [print(f' - {e.cn}: {e.uid} ({e.mail})') for e in c.entries]; c.unbind()"
|
@export LDAP_PORT=$${LDAP_PORT:-389}; uv run python -c "import os; from ldap3 import Server, Connection; s = Server(f\"ldap://localhost:{os.environ.get('LDAP_PORT', '389')}\"); c = Connection(s, 'cn=admin,dc=testing,dc=local', 'admin_password', auto_bind=True); c.search('dc=testing,dc=local', '(objectClass=inetOrgPerson)', attributes=['uid', 'cn', 'mail']); [print(f' - {e.cn}: {e.uid} ({e.mail})') for e in c.entries]; c.unbind()"
|
||||||
|
|
||||||
test-ssl: ## Test SSL/TLS connection
|
test-ssl: ## Test SSL/TLS connection
|
||||||
@echo "Testing LDAPS connection..."
|
@echo "Testing LDAPS connection..."
|
||||||
openssl s_client -connect localhost:636 -CAfile certs/ca.crt </dev/null
|
openssl s_client -connect localhost:$${LDAPS_PORT:-636} -CAfile certs/ca.crt </dev/null
|
||||||
|
|
||||||
test-all: test-connection test-auth test-users ## Run all tests
|
test-all: test-connection test-auth test-users ## Run all tests
|
||||||
|
|
||||||
@@ -126,7 +132,7 @@ shell: ## Open a shell in the LDAP container
|
|||||||
|
|
||||||
ldapsearch: ## Run ldapsearch command (example query)
|
ldapsearch: ## Run ldapsearch command (example query)
|
||||||
@echo "Running ldapsearch..."
|
@echo "Running ldapsearch..."
|
||||||
ldapsearch -H ldap://localhost:389 -x -b "dc=testing,dc=local" -D "cn=admin,dc=testing,dc=local" -w admin_password
|
ldapsearch -H ldap://localhost:$${LDAP_PORT:-389} -x -b "dc=testing,dc=local" -D "cn=admin,dc=testing,dc=local" -w admin_password
|
||||||
|
|
||||||
clean: ## Clean Python build artifacts
|
clean: ## Clean Python build artifacts
|
||||||
@echo "Cleaning build artifacts..."
|
@echo "Cleaning build artifacts..."
|
||||||
|
|||||||
436
PORT_CONFIGURATION.md
Normal file
436
PORT_CONFIGURATION.md
Normal file
@@ -0,0 +1,436 @@
|
|||||||
|
# Port Configuration Guide
|
||||||
|
|
||||||
|
This guide explains how to configure custom ports for your LDAP Docker environment to avoid conflicts with other services.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
**To change ports, simply edit the `.env` file:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Edit .env file
|
||||||
|
LDAP_PORT=20389
|
||||||
|
LDAPS_PORT=20636
|
||||||
|
PHPLDAPADMIN_PORT=8080
|
||||||
|
```
|
||||||
|
|
||||||
|
Then restart:
|
||||||
|
```bash
|
||||||
|
make down && make start
|
||||||
|
```
|
||||||
|
|
||||||
|
That's it! All scripts and tools will automatically use your custom ports.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Why Custom Ports?
|
||||||
|
|
||||||
|
You might want to use custom ports if:
|
||||||
|
- You have another LDAP server running on standard ports (389/636)
|
||||||
|
- Port 389 requires root/admin privileges
|
||||||
|
- You're running multiple LDAP environments simultaneously
|
||||||
|
- Your organization has specific port requirements
|
||||||
|
|
||||||
|
## Files Involved
|
||||||
|
|
||||||
|
The port configuration system uses these files:
|
||||||
|
|
||||||
|
### 1. `.env` - Your Configuration (Edit This!)
|
||||||
|
```bash
|
||||||
|
LDAP_PORT=20389 # Your custom LDAP port
|
||||||
|
LDAPS_PORT=20636 # Your custom LDAPS port
|
||||||
|
PHPLDAPADMIN_PORT=8080 # Web admin interface port
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. `docker-compose.yml` - Uses Environment Variables
|
||||||
|
```yaml
|
||||||
|
ports:
|
||||||
|
- "${LDAP_PORT:-389}:389" # Host:Container mapping
|
||||||
|
- "${LDAPS_PORT:-636}:636"
|
||||||
|
```
|
||||||
|
|
||||||
|
The `${LDAP_PORT:-389}` syntax means:
|
||||||
|
- Use `$LDAP_PORT` if set in `.env`
|
||||||
|
- Otherwise use default `389`
|
||||||
|
|
||||||
|
### 3. Scripts - Auto-detect Ports
|
||||||
|
All Python scripts and Makefile commands read from `.env` automatically:
|
||||||
|
- `scripts/cli.py`
|
||||||
|
- `scripts/ldapsearch_helper.sh`
|
||||||
|
- `examples/simple_auth.py`
|
||||||
|
- `Makefile`
|
||||||
|
|
||||||
|
## How to Change Ports
|
||||||
|
|
||||||
|
### Method 1: Edit .env File (Recommended)
|
||||||
|
|
||||||
|
1. **Edit `.env`:**
|
||||||
|
```bash
|
||||||
|
vim .env # or your favorite editor
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Change the port values:**
|
||||||
|
```bash
|
||||||
|
LDAP_PORT=20389
|
||||||
|
LDAPS_PORT=20636
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Restart the containers:**
|
||||||
|
```bash
|
||||||
|
make down && make start
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Verify:**
|
||||||
|
```bash
|
||||||
|
docker-compose ps
|
||||||
|
# Should show 0.0.0.0:20389->389/tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 2: Environment Variables (Temporary)
|
||||||
|
|
||||||
|
For one-time use without modifying `.env`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
LDAP_PORT=30389 LDAPS_PORT=30636 docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 3: Create .env.local (Advanced)
|
||||||
|
|
||||||
|
For personal overrides without modifying the main `.env`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create .env.local (git-ignored)
|
||||||
|
echo "LDAP_PORT=12389" > .env.local
|
||||||
|
echo "LDAPS_PORT=12636" >> .env.local
|
||||||
|
|
||||||
|
# Docker Compose will merge both files
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing with Custom Ports
|
||||||
|
|
||||||
|
### Automatic - Use Our Tools
|
||||||
|
|
||||||
|
All our tools automatically detect your ports from `.env`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# These all work automatically with your custom ports
|
||||||
|
make test-users
|
||||||
|
make test-connection
|
||||||
|
uv run python examples/simple_auth.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Generate ldapsearch Commands
|
||||||
|
|
||||||
|
Use our helper script to generate commands with your ports:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/ldapsearch_helper.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Output includes commands like:
|
||||||
|
```bash
|
||||||
|
# List all users
|
||||||
|
ldapsearch -H ldap://localhost:20389 \
|
||||||
|
-D "cn=admin,dc=testing,dc=local" \
|
||||||
|
-w admin_password \
|
||||||
|
-b "ou=people,dc=testing,dc=local" \
|
||||||
|
"(objectClass=inetOrgPerson)" \
|
||||||
|
uid cn mail
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual ldapsearch Commands
|
||||||
|
|
||||||
|
Replace `389` with your `LDAP_PORT` and `636` with your `LDAPS_PORT`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Standard LDAP (unencrypted)
|
||||||
|
ldapsearch -H ldap://localhost:20389 \
|
||||||
|
-D "cn=admin,dc=testing,dc=local" \
|
||||||
|
-w admin_password \
|
||||||
|
-b "dc=testing,dc=local"
|
||||||
|
|
||||||
|
# LDAPS (SSL/TLS)
|
||||||
|
ldapsearch -H ldaps://localhost:20636 \
|
||||||
|
-D "cn=admin,dc=testing,dc=local" \
|
||||||
|
-w admin_password \
|
||||||
|
-b "dc=testing,dc=local"
|
||||||
|
|
||||||
|
# Search for specific user
|
||||||
|
ldapsearch -H ldap://localhost:20389 \
|
||||||
|
-D "cn=admin,dc=testing,dc=local" \
|
||||||
|
-w admin_password \
|
||||||
|
-b "dc=testing,dc=local" \
|
||||||
|
"(uid=jdoe)"
|
||||||
|
|
||||||
|
# Test user authentication
|
||||||
|
ldapsearch -H ldap://localhost:20389 \
|
||||||
|
-D "uid=jdoe,ou=people,dc=testing,dc=local" \
|
||||||
|
-w password123 \
|
||||||
|
-b "dc=testing,dc=local" \
|
||||||
|
"(uid=jdoe)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
import os
|
||||||
|
from ldap3 import Server, Connection
|
||||||
|
|
||||||
|
# Automatically uses LDAP_PORT from environment
|
||||||
|
port = os.environ.get('LDAP_PORT', '389')
|
||||||
|
server = Server(f'ldap://localhost:{port}')
|
||||||
|
conn = Connection(server,
|
||||||
|
user='cn=admin,dc=testing,dc=local',
|
||||||
|
password='admin_password',
|
||||||
|
auto_bind=True)
|
||||||
|
|
||||||
|
conn.search('dc=testing,dc=local', '(objectClass=*)')
|
||||||
|
print(f"Connected on port {port}")
|
||||||
|
conn.unbind()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Port Configurations
|
||||||
|
|
||||||
|
### Development (Unprivileged Ports)
|
||||||
|
```bash
|
||||||
|
LDAP_PORT=20389
|
||||||
|
LDAPS_PORT=20636
|
||||||
|
PHPLDAPADMIN_PORT=8080
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing (High Ports)
|
||||||
|
```bash
|
||||||
|
LDAP_PORT=30389
|
||||||
|
LDAPS_PORT=30636
|
||||||
|
PHPLDAPADMIN_PORT=8090
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple Environments
|
||||||
|
```bash
|
||||||
|
# Environment 1 (.env)
|
||||||
|
LDAP_PORT=20389
|
||||||
|
LDAPS_PORT=20636
|
||||||
|
|
||||||
|
# Environment 2 (separate directory or .env.local)
|
||||||
|
LDAP_PORT=21389
|
||||||
|
LDAPS_PORT=21636
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Port Already in Use
|
||||||
|
|
||||||
|
**Error:** `Bind for 0.0.0.0:20389 failed: port is already allocated`
|
||||||
|
|
||||||
|
**Check what's using the port:**
|
||||||
|
```bash
|
||||||
|
lsof -i :20389
|
||||||
|
# or
|
||||||
|
netstat -an | grep 20389
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. Stop the conflicting service
|
||||||
|
2. Choose a different port in `.env`
|
||||||
|
3. Use `make down` to stop this LDAP server first
|
||||||
|
|
||||||
|
### Scripts Not Using Custom Ports
|
||||||
|
|
||||||
|
**Problem:** Scripts still connect to port 389
|
||||||
|
|
||||||
|
**Solution:** Ensure `.env` is loaded:
|
||||||
|
|
||||||
|
1. **Check .env exists:**
|
||||||
|
```bash
|
||||||
|
ls -la .env
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Verify ports are set:**
|
||||||
|
```bash
|
||||||
|
grep LDAP_PORT .env
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Reload environment:**
|
||||||
|
```bash
|
||||||
|
source .env # For bash scripts
|
||||||
|
make down && make start # Restart containers
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Compose Not Reading .env
|
||||||
|
|
||||||
|
**Problem:** Containers still on default ports
|
||||||
|
|
||||||
|
**Check:**
|
||||||
|
```bash
|
||||||
|
# View what Docker Compose sees
|
||||||
|
docker-compose config | grep -A2 ports
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Ensure .env is in project root
|
||||||
|
pwd # Should be ldap_docker/
|
||||||
|
ls .env # Should exist
|
||||||
|
|
||||||
|
# Force reload
|
||||||
|
docker-compose down
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Can't Connect After Port Change
|
||||||
|
|
||||||
|
**Verify containers are running on correct ports:**
|
||||||
|
```bash
|
||||||
|
docker-compose ps
|
||||||
|
# Should show: 0.0.0.0:20389->389/tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
**Test connectivity:**
|
||||||
|
```bash
|
||||||
|
# Test if port is listening
|
||||||
|
nc -zv localhost 20389
|
||||||
|
|
||||||
|
# Test LDAP response
|
||||||
|
ldapsearch -H ldap://localhost:20389 -x -b "" -s base
|
||||||
|
```
|
||||||
|
|
||||||
|
**Check logs:**
|
||||||
|
```bash
|
||||||
|
make logs
|
||||||
|
# Look for: "slapd starting"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Port Reference Table
|
||||||
|
|
||||||
|
| Service | Default Port | Docker Internal Port | Configurable Via |
|
||||||
|
|---------|--------------|---------------------|------------------|
|
||||||
|
| LDAP | 389 | 389 | `LDAP_PORT` in .env |
|
||||||
|
| LDAPS | 636 | 636 | `LDAPS_PORT` in .env |
|
||||||
|
| phpLDAPadmin | 8080 | 80 | `PHPLDAPADMIN_PORT` in .env |
|
||||||
|
|
||||||
|
**Note:** The "Docker Internal Port" (right side of mapping) never changes. Only the host port (left side) is configurable.
|
||||||
|
|
||||||
|
## Advanced: Port Mapping Explained
|
||||||
|
|
||||||
|
Docker port mapping format: `HOST:CONTAINER`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
ports:
|
||||||
|
- "20389:389"
|
||||||
|
```
|
||||||
|
|
||||||
|
This means:
|
||||||
|
- **20389** = Port on your Mac (accessible via `localhost:20389`)
|
||||||
|
- **389** = Port inside the Docker container (LDAP's standard port)
|
||||||
|
|
||||||
|
The container always listens on 389 internally. We just map it to 20389 externally.
|
||||||
|
|
||||||
|
## Testing Multiple Configurations
|
||||||
|
|
||||||
|
Run multiple LDAP servers simultaneously:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Terminal 1: First instance
|
||||||
|
cd ldap_docker_1
|
||||||
|
echo "LDAP_PORT=20389" > .env
|
||||||
|
echo "LDAPS_PORT=20636" >> .env
|
||||||
|
make start
|
||||||
|
|
||||||
|
# Terminal 2: Second instance
|
||||||
|
cd ldap_docker_2
|
||||||
|
echo "LDAP_PORT=21389" > .env
|
||||||
|
echo "LDAPS_PORT=21636" >> .env
|
||||||
|
make start
|
||||||
|
|
||||||
|
# Now you have two LDAP servers running!
|
||||||
|
ldapsearch -H ldap://localhost:20389 ... # Server 1
|
||||||
|
ldapsearch -H ldap://localhost:21389 ... # Server 2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Use .env for configuration** - Don't hardcode ports in scripts
|
||||||
|
2. **Document your ports** - Add comments in .env explaining your choices
|
||||||
|
3. **Use unprivileged ports** - Ports above 1024 don't require root
|
||||||
|
4. **Avoid common ports** - Skip 8080, 3000, 5000 (often used by other tools)
|
||||||
|
5. **Be consistent** - If LDAP is 20389, make LDAPS 20636 (same prefix)
|
||||||
|
|
||||||
|
## Integration Examples
|
||||||
|
|
||||||
|
### Configure Your Application
|
||||||
|
|
||||||
|
After changing ports, update your application's LDAP configuration:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Django settings.py
|
||||||
|
AUTH_LDAP_SERVER_URI = "ldap://localhost:20389"
|
||||||
|
|
||||||
|
# Flask
|
||||||
|
LDAP_HOST = "localhost"
|
||||||
|
LDAP_PORT = 20389
|
||||||
|
|
||||||
|
# Environment variable
|
||||||
|
export LDAP_URL="ldap://localhost:20389"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using with Docker Networks
|
||||||
|
|
||||||
|
If your application is also in Docker:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Your app's docker-compose.yml
|
||||||
|
services:
|
||||||
|
your-app:
|
||||||
|
environment:
|
||||||
|
LDAP_URL: "ldap://ldap-server:389" # Use container name and internal port
|
||||||
|
networks:
|
||||||
|
- ldap_docker_ldap-network # Connect to LDAP network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ldap_docker_ldap-network:
|
||||||
|
external: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View current configuration
|
||||||
|
cat .env | grep PORT
|
||||||
|
|
||||||
|
# Generate ldapsearch commands
|
||||||
|
./scripts/ldapsearch_helper.sh
|
||||||
|
|
||||||
|
# Test connection on custom port
|
||||||
|
make test-connection
|
||||||
|
|
||||||
|
# Check what ports containers are using
|
||||||
|
docker-compose ps
|
||||||
|
|
||||||
|
# Change ports (example)
|
||||||
|
echo "LDAP_PORT=12389" > .env
|
||||||
|
echo "LDAPS_PORT=12636" >> .env
|
||||||
|
make down && make start
|
||||||
|
|
||||||
|
# Verify new ports work
|
||||||
|
make test-users
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
**To use custom ports:**
|
||||||
|
1. Edit `LDAP_PORT` and `LDAPS_PORT` in `.env`
|
||||||
|
2. Run `make down && make start`
|
||||||
|
3. All tools automatically use your new ports!
|
||||||
|
|
||||||
|
**Need ldapsearch commands?**
|
||||||
|
- Run `./scripts/ldapsearch_helper.sh`
|
||||||
|
- Or manually replace 389 → your LDAP_PORT, 636 → your LDAPS_PORT
|
||||||
|
|
||||||
|
That's it! The port configuration system is designed to be simple and automatic.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**See Also:**
|
||||||
|
- [README.md](README.md) - Full documentation
|
||||||
|
- [GETTING_STARTED.md](GETTING_STARTED.md) - Setup guide
|
||||||
|
- [QUICKREF.md](QUICKREF.md) - Command reference
|
||||||
@@ -1,35 +1,33 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
openldap:
|
openldap:
|
||||||
image: osixia/openldap:1.5.0
|
image: osixia/openldap:1.5.0
|
||||||
container_name: ldap-server
|
container_name: ${LDAP_CONTAINER_NAME:-ldap-server}
|
||||||
hostname: ldap.testing.local
|
hostname: ${LDAP_HOSTNAME:-ldap.testing.local}
|
||||||
environment:
|
environment:
|
||||||
# Base domain configuration
|
# Base domain configuration
|
||||||
LDAP_ORGANISATION: "Testing Organization"
|
LDAP_ORGANISATION: ${LDAP_ORGANISATION:-Testing Organization}
|
||||||
LDAP_DOMAIN: "testing.local"
|
LDAP_DOMAIN: ${LDAP_DOMAIN:-testing.local}
|
||||||
LDAP_BASE_DN: "dc=testing,dc=local"
|
LDAP_BASE_DN: ${LDAP_BASE_DN:-dc=testing,dc=local}
|
||||||
|
|
||||||
# Admin credentials (change these for production)
|
# Admin credentials (change these for production)
|
||||||
LDAP_ADMIN_PASSWORD: "admin_password"
|
LDAP_ADMIN_PASSWORD: ${LDAP_ADMIN_PASSWORD:-admin_password}
|
||||||
LDAP_CONFIG_PASSWORD: "config_password"
|
LDAP_CONFIG_PASSWORD: ${LDAP_CONFIG_PASSWORD:-config_password}
|
||||||
|
|
||||||
# SSL/TLS Configuration
|
# SSL/TLS Configuration
|
||||||
LDAP_TLS: "true"
|
LDAP_TLS: ${LDAP_TLS:-true}
|
||||||
LDAP_TLS_CRT_FILENAME: "server.crt"
|
LDAP_TLS_CRT_FILENAME: ${LDAP_TLS_CRT_FILENAME:-server.crt}
|
||||||
LDAP_TLS_KEY_FILENAME: "server.key"
|
LDAP_TLS_KEY_FILENAME: ${LDAP_TLS_KEY_FILENAME:-server.key}
|
||||||
LDAP_TLS_CA_CRT_FILENAME: "ca.crt"
|
LDAP_TLS_CA_CRT_FILENAME: ${LDAP_TLS_CA_CRT_FILENAME:-ca.crt}
|
||||||
LDAP_TLS_VERIFY_CLIENT: "try"
|
LDAP_TLS_VERIFY_CLIENT: ${LDAP_TLS_VERIFY_CLIENT:-try}
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
LDAP_LOG_LEVEL: "256"
|
LDAP_LOG_LEVEL: ${LDAP_LOG_LEVEL:-256}
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
# Standard LDAP port
|
# Standard LDAP port
|
||||||
- "389:389"
|
- "${LDAP_PORT:-389}:389"
|
||||||
# LDAPS (SSL) port
|
# LDAPS (SSL) port
|
||||||
- "636:636"
|
- "${LDAPS_PORT:-636}:636"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
# Custom certificates - place your dev-ca certs here
|
# Custom certificates - place your dev-ca certs here
|
||||||
@@ -52,12 +50,12 @@ services:
|
|||||||
# Optional: phpLDAPadmin for web-based management
|
# Optional: phpLDAPadmin for web-based management
|
||||||
phpldapadmin:
|
phpldapadmin:
|
||||||
image: osixia/phpldapadmin:0.9.0
|
image: osixia/phpldapadmin:0.9.0
|
||||||
container_name: ldap-admin
|
container_name: ${PHPLDAPADMIN_CONTAINER_NAME:-ldap-admin}
|
||||||
environment:
|
environment:
|
||||||
PHPLDAPADMIN_LDAP_HOSTS: "openldap"
|
PHPLDAPADMIN_LDAP_HOSTS: "openldap"
|
||||||
PHPLDAPADMIN_HTTPS: "false"
|
PHPLDAPADMIN_HTTPS: "false"
|
||||||
ports:
|
ports:
|
||||||
- "8080:80"
|
- "${PHPLDAPADMIN_PORT:-8080}:80"
|
||||||
depends_on:
|
depends_on:
|
||||||
- openldap
|
- openldap
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ Usage:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
from typing import Dict, List, Optional
|
from typing import Dict, List, Optional
|
||||||
|
|
||||||
@@ -24,7 +25,8 @@ except ImportError:
|
|||||||
|
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
LDAP_SERVER = "ldap://localhost:389"
|
LDAP_PORT = os.environ.get("LDAP_PORT", "389")
|
||||||
|
LDAP_SERVER = f"ldap://localhost:{LDAP_PORT}"
|
||||||
LDAP_BASE_DN = "dc=testing,dc=local"
|
LDAP_BASE_DN = "dc=testing,dc=local"
|
||||||
LDAP_PEOPLE_OU = "ou=people,dc=testing,dc=local"
|
LDAP_PEOPLE_OU = "ou=people,dc=testing,dc=local"
|
||||||
LDAP_GROUPS_OU = "ou=groups,dc=testing,dc=local"
|
LDAP_GROUPS_OU = "ou=groups,dc=testing,dc=local"
|
||||||
@@ -104,8 +106,8 @@ class LDAPAuthenticator:
|
|||||||
"first_name": str(entry.givenName) if entry.givenName else "",
|
"first_name": str(entry.givenName) if entry.givenName else "",
|
||||||
"last_name": str(entry.sn),
|
"last_name": str(entry.sn),
|
||||||
"email": str(entry.mail),
|
"email": str(entry.mail),
|
||||||
"uid_number": int(entry.uidNumber) if entry.uidNumber else None,
|
"uid_number": int(str(entry.uidNumber)) if entry.uidNumber else None,
|
||||||
"gid_number": int(entry.gidNumber) if entry.gidNumber else None,
|
"gid_number": int(str(entry.gidNumber)) if entry.gidNumber else None,
|
||||||
"dn": entry.entry_dn,
|
"dn": entry.entry_dn,
|
||||||
}
|
}
|
||||||
conn.unbind()
|
conn.unbind()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ cn: John Doe
|
|||||||
sn: Doe
|
sn: Doe
|
||||||
givenName: John
|
givenName: John
|
||||||
mail: jdoe@testing.local
|
mail: jdoe@testing.local
|
||||||
userPassword: {SSHA}5en6G6MezRroT3XKqkdPOmY/BFQ= # password: password123
|
userPassword: {SSHA}Vj/QLoVDZbjklfhV/e6JdTo8MUNRy9dN
|
||||||
uidNumber: 10001
|
uidNumber: 10001
|
||||||
gidNumber: 10001
|
gidNumber: 10001
|
||||||
homeDirectory: /home/jdoe
|
homeDirectory: /home/jdoe
|
||||||
@@ -42,7 +42,7 @@ cn: Jane Smith
|
|||||||
sn: Smith
|
sn: Smith
|
||||||
givenName: Jane
|
givenName: Jane
|
||||||
mail: jsmith@testing.local
|
mail: jsmith@testing.local
|
||||||
userPassword: {SSHA}5en6G6MezRroT3XKqkdPOmY/BFQ= # password: password123
|
userPassword: {SSHA}Vj/QLoVDZbjklfhV/e6JdTo8MUNRy9dN
|
||||||
uidNumber: 10002
|
uidNumber: 10002
|
||||||
gidNumber: 10002
|
gidNumber: 10002
|
||||||
homeDirectory: /home/jsmith
|
homeDirectory: /home/jsmith
|
||||||
@@ -59,7 +59,7 @@ cn: Admin User
|
|||||||
sn: User
|
sn: User
|
||||||
givenName: Admin
|
givenName: Admin
|
||||||
mail: admin@testing.local
|
mail: admin@testing.local
|
||||||
userPassword: {SSHA}5en6G6MezRroT3XKqkdPOmY/BFQ= # password: password123
|
userPassword: {SSHA}Vj/QLoVDZbjklfhV/e6JdTo8MUNRy9dN
|
||||||
uidNumber: 10000
|
uidNumber: 10000
|
||||||
gidNumber: 10000
|
gidNumber: 10000
|
||||||
homeDirectory: /home/admin
|
homeDirectory: /home/admin
|
||||||
@@ -76,7 +76,7 @@ cn: Test User
|
|||||||
sn: User
|
sn: User
|
||||||
givenName: Test
|
givenName: Test
|
||||||
mail: testuser@testing.local
|
mail: testuser@testing.local
|
||||||
userPassword: {SSHA}5en6G6MezRroT3XKqkdPOmY/BFQ= # password: password123
|
userPassword: {SSHA}Vj/QLoVDZbjklfhV/e6JdTo8MUNRy9dN
|
||||||
uidNumber: 10003
|
uidNumber: 10003
|
||||||
gidNumber: 10003
|
gidNumber: 10003
|
||||||
homeDirectory: /home/testuser
|
homeDirectory: /home/testuser
|
||||||
|
|||||||
@@ -33,8 +33,11 @@ ldap-docker = "scripts.cli:main"
|
|||||||
requires = ["hatchling"]
|
requires = ["hatchling"]
|
||||||
build-backend = "hatchling.build"
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.hatch.build.targets.wheel]
|
||||||
dev-dependencies = [
|
packages = ["scripts", "tests"]
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
dev = [
|
||||||
"pytest>=7.4.0",
|
"pytest>=7.4.0",
|
||||||
"pytest-cov>=4.1.0",
|
"pytest-cov>=4.1.0",
|
||||||
"black>=23.0.0",
|
"black>=23.0.0",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ This tool provides convenient commands for starting, stopping, and testing
|
|||||||
the LDAP server, as well as managing test users and certificates.
|
the LDAP server, as well as managing test users and certificates.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
@@ -27,8 +28,8 @@ PROJECT_ROOT = Path(__file__).parent.parent
|
|||||||
CERTS_DIR = PROJECT_ROOT / "certs"
|
CERTS_DIR = PROJECT_ROOT / "certs"
|
||||||
LDIF_DIR = PROJECT_ROOT / "ldif"
|
LDIF_DIR = PROJECT_ROOT / "ldif"
|
||||||
DEFAULT_HOST = "localhost"
|
DEFAULT_HOST = "localhost"
|
||||||
DEFAULT_PORT = 389
|
DEFAULT_PORT = int(os.environ.get("LDAP_PORT", "389"))
|
||||||
DEFAULT_LDAPS_PORT = 636
|
DEFAULT_LDAPS_PORT = int(os.environ.get("LDAPS_PORT", "636"))
|
||||||
DEFAULT_BASE_DN = "dc=testing,dc=local"
|
DEFAULT_BASE_DN = "dc=testing,dc=local"
|
||||||
DEFAULT_ADMIN_DN = "cn=admin,dc=testing,dc=local"
|
DEFAULT_ADMIN_DN = "cn=admin,dc=testing,dc=local"
|
||||||
DEFAULT_ADMIN_PASSWORD = "admin_password"
|
DEFAULT_ADMIN_PASSWORD = "admin_password"
|
||||||
|
|||||||
195
scripts/ldapsearch_helper.sh
Executable file
195
scripts/ldapsearch_helper.sh
Executable file
@@ -0,0 +1,195 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# LDAP Search Helper
|
||||||
|
# Generates ldapsearch commands configured for your environment
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
|
# Load environment variables from .env if it exists
|
||||||
|
if [ -f "$PROJECT_ROOT/.env" ]; then
|
||||||
|
source "$PROJECT_ROOT/.env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set defaults if not in environment
|
||||||
|
LDAP_PORT=${LDAP_PORT:-389}
|
||||||
|
LDAPS_PORT=${LDAPS_PORT:-636}
|
||||||
|
LDAP_BASE_DN=${LDAP_BASE_DN:-dc=testing,dc=local}
|
||||||
|
LDAP_ADMIN_PASSWORD=${LDAP_ADMIN_PASSWORD:-admin_password}
|
||||||
|
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo -e "${BLUE}LDAP Search Command Generator${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "Configuration:"
|
||||||
|
echo " LDAP Port: $LDAP_PORT"
|
||||||
|
echo " LDAPS Port: $LDAPS_PORT"
|
||||||
|
echo " Base DN: $LDAP_BASE_DN"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Function to print a command example
|
||||||
|
print_cmd() {
|
||||||
|
local description="$1"
|
||||||
|
local command="$2"
|
||||||
|
|
||||||
|
echo -e "${GREEN}# $description${NC}"
|
||||||
|
echo -e "${YELLOW}$command${NC}"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo -e "${BLUE}Basic Connection Tests${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_cmd "Test server is responding (anonymous bind)" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -x -b \"\" -s base"
|
||||||
|
|
||||||
|
print_cmd "Test with admin credentials" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"$LDAP_BASE_DN\""
|
||||||
|
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo -e "${BLUE}Search Users${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_cmd "List all users" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"ou=people,$LDAP_BASE_DN\" \"(objectClass=inetOrgPerson)\" uid cn mail"
|
||||||
|
|
||||||
|
print_cmd "Search for specific user (jdoe)" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"$LDAP_BASE_DN\" \"(uid=jdoe)\""
|
||||||
|
|
||||||
|
print_cmd "Test user authentication (as jdoe)" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"uid=jdoe,ou=people,$LDAP_BASE_DN\" -w password123 -b \"$LDAP_BASE_DN\" \"(uid=jdoe)\""
|
||||||
|
|
||||||
|
print_cmd "Get all user attributes for jdoe" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"ou=people,$LDAP_BASE_DN\" \"(uid=jdoe)\" '*' '+'"
|
||||||
|
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo -e "${BLUE}Search Groups${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_cmd "List all groups" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"ou=groups,$LDAP_BASE_DN\" \"(objectClass=groupOfNames)\" cn member"
|
||||||
|
|
||||||
|
print_cmd "Find groups for user jdoe" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"ou=groups,$LDAP_BASE_DN\" \"(member=uid=jdoe,ou=people,$LDAP_BASE_DN)\" cn"
|
||||||
|
|
||||||
|
print_cmd "Get members of developers group" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"ou=groups,$LDAP_BASE_DN\" \"(cn=developers)\" member"
|
||||||
|
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo -e "${BLUE}LDAPS (SSL/TLS) Commands${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_cmd "Test LDAPS connection" \
|
||||||
|
"ldapsearch -H ldaps://localhost:$LDAPS_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"$LDAP_BASE_DN\""
|
||||||
|
|
||||||
|
print_cmd "LDAPS with CA certificate verification" \
|
||||||
|
"LDAPTLS_CACERT=$PROJECT_ROOT/certs/ca.crt ldapsearch -H ldaps://localhost:$LDAPS_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"$LDAP_BASE_DN\""
|
||||||
|
|
||||||
|
print_cmd "Check SSL certificate" \
|
||||||
|
"openssl s_client -connect localhost:$LDAPS_PORT -CAfile $PROJECT_ROOT/certs/ca.crt -showcerts"
|
||||||
|
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo -e "${BLUE}Secure Commands (Password Prompt)${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_cmd "Admin search with password prompt (more secure)" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -W -b \"$LDAP_BASE_DN\""
|
||||||
|
|
||||||
|
print_cmd "User authentication with password prompt" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"uid=jdoe,ou=people,$LDAP_BASE_DN\" -W -b \"$LDAP_BASE_DN\" \"(uid=jdoe)\""
|
||||||
|
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo -e "${BLUE}Advanced Queries${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_cmd "Search with wildcard (all users starting with 'j')" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"ou=people,$LDAP_BASE_DN\" \"(uid=j*)\" uid cn"
|
||||||
|
|
||||||
|
print_cmd "Search by email domain" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"ou=people,$LDAP_BASE_DN\" \"(mail=*@testing.local)\" uid mail"
|
||||||
|
|
||||||
|
print_cmd "Count total users" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"ou=people,$LDAP_BASE_DN\" \"(objectClass=inetOrgPerson)\" dn | grep -c '^dn:'"
|
||||||
|
|
||||||
|
print_cmd "Export entire directory to LDIF file" \
|
||||||
|
"ldapsearch -H ldap://localhost:$LDAP_PORT -D \"cn=admin,$LDAP_BASE_DN\" -w $LDAP_ADMIN_PASSWORD -b \"$LDAP_BASE_DN\" -LLL > ldap_backup.ldif"
|
||||||
|
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo -e "${BLUE}Quick Reference${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "Common flags:"
|
||||||
|
echo " -H : LDAP URI (ldap:// or ldaps://)"
|
||||||
|
echo " -D : Bind DN (user to authenticate as)"
|
||||||
|
echo " -w : Password (visible in process list)"
|
||||||
|
echo " -W : Prompt for password (more secure)"
|
||||||
|
echo " -x : Use simple authentication"
|
||||||
|
echo " -b : Base DN to search from"
|
||||||
|
echo " -s : Scope (base, one, sub)"
|
||||||
|
echo " -LLL: LDIF output without comments"
|
||||||
|
echo ""
|
||||||
|
echo "Test credentials:"
|
||||||
|
echo " Admin: cn=admin,$LDAP_BASE_DN / $LDAP_ADMIN_PASSWORD"
|
||||||
|
echo " Test user: uid=jdoe,ou=people,$LDAP_BASE_DN / password123"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}Tip:${NC} Copy any command above and run it in your terminal!"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Option to run a command interactively
|
||||||
|
if [ "$1" = "--interactive" ] || [ "$1" = "-i" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "Select a command to run:"
|
||||||
|
echo " 1) List all users"
|
||||||
|
echo " 2) Search for user jdoe"
|
||||||
|
echo " 3) Test user authentication"
|
||||||
|
echo " 4) List all groups"
|
||||||
|
echo " 5) Test LDAPS connection"
|
||||||
|
echo " 6) Custom command"
|
||||||
|
echo ""
|
||||||
|
read -p "Choice (1-6): " choice
|
||||||
|
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
ldapsearch -H ldap://localhost:$LDAP_PORT -D "cn=admin,$LDAP_BASE_DN" -w $LDAP_ADMIN_PASSWORD -b "ou=people,$LDAP_BASE_DN" "(objectClass=inetOrgPerson)" uid cn mail
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
ldapsearch -H ldap://localhost:$LDAP_PORT -D "cn=admin,$LDAP_BASE_DN" -w $LDAP_ADMIN_PASSWORD -b "$LDAP_BASE_DN" "(uid=jdoe)"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
read -p "Enter password for jdoe: " -s user_pass
|
||||||
|
echo ""
|
||||||
|
ldapsearch -H ldap://localhost:$LDAP_PORT -D "uid=jdoe,ou=people,$LDAP_BASE_DN" -w "$user_pass" -b "$LDAP_BASE_DN" "(uid=jdoe)"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
ldapsearch -H ldap://localhost:$LDAP_PORT -D "cn=admin,$LDAP_BASE_DN" -w $LDAP_ADMIN_PASSWORD -b "ou=groups,$LDAP_BASE_DN" "(objectClass=groupOfNames)" cn member
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
LDAPTLS_CACERT=$PROJECT_ROOT/certs/ca.crt ldapsearch -H ldaps://localhost:$LDAPS_PORT -D "cn=admin,$LDAP_BASE_DN" -w $LDAP_ADMIN_PASSWORD -b "$LDAP_BASE_DN"
|
||||||
|
;;
|
||||||
|
6)
|
||||||
|
read -p "Enter custom filter: " filter
|
||||||
|
ldapsearch -H ldap://localhost:$LDAP_PORT -D "cn=admin,$LDAP_BASE_DN" -w $LDAP_ADMIN_PASSWORD -b "$LDAP_BASE_DN" "$filter"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid choice"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user