# hydraldaplam All-in-One Docker Image ## Overview This repository contains all necessary configuration and templates to build a single Docker image that bundles and configures: - **OpenLDAP** (slapd) as the LDAP directory. - **Ory Hydra** (an OAuth 2.0 / OIDC server). - **LDAP Account Manager (LAM)** under Apache2 + PHP as the web-based LDAP UI. The container is orchestrated using **Supervisor** to launch and manage all three services. All credentials and configuration values are provided at runtime via environment variables, ensuring no sensitive data is baked into the image. --- ## Repository Structure ``` hydraldaplam/ ├─ Dockerfile ├─ entrypoint.sh ├─ supervisord.conf └─ templates/ ├─ bootstrap.ldif.tpl ├─ hydra-config.yaml.tpl └─ lam.conf.php.tpl ``` - **Dockerfile**: Builds the Docker image, installs dependencies, and copies template files. - **entrypoint.sh**: Entry-point script that performs runtime configuration substitution (`envsubst`), bootstraps LDAP, and starts Supervisor. - **supervisord.conf**: Supervisor configuration to run `slapd`, `hydra`, and Apache2 in the foreground. - **templates/**: - **bootstrap.ldif.tpl**: LDIF template for initializing the LDAP data (domain, organization, and a sample user). - **hydra-config.yaml.tpl**: Hydra configuration template pointing to in-memory SQLite and defining login/consent URLs. - **lam.conf.php.tpl**: LAM configuration template specifying LDAP bind settings. --- ## Prerequisites - [Docker](https://docs.docker.com/get-docker/) (version 20.10+ recommended) - (Optional) A local or remote Gitea instance for committing the `README.md`. --- ## Building the Image 1. Clone (or place) this directory locally: ```bash git clone https://git.ewnix.net/phlux/hydraldaplam.git cd hydraldaplam ``` 2. Build the Docker image: ```bash docker build -t hydraldaplam:latest . ``` This will produce an image named `hydraldaplam:latest` containing: - OpenLDAP (slapd) - Ory Hydra binary - Apache2 + PHP + LAM (LDAP Account Manager) - Supervisor and supporting scripts --- ## Running the Container To run the container, you must supply all required environment variables. Example: ```bash docker run -d --name hydra_ldap_lam -e LDAP_DOMAIN="example.com" -e LDAP_ORGANISATION="Example Corp" -e LDAP_ADMIN_PASSWORD="adminpassword" -e LDAP_USER_PASSWORD="password123" -e LAM_BIND_DN="cn=admin,dc=example,dc=com" -e LAM_BIND_PASSWORD="adminpassword" -e HYDRA_SECRETS_SYSTEM="a-very-long-32+-character-secret" -e HYDRA_ISSUER_URL="http://127.0.0.1:4444" -p 389:389 -p 636:636 -p 4444:4444 -p 4445:4445 -p 80:80 hydraldaplam:latest ``` - `-p 389:389`: Exposes LDAP (OpenLDAP) on host port 389. - `-p 636:636`: Exposes LDAPS (OpenLDAP over TLS) on host port 636 (if TLS is configured). - `-p 4444:4444`: Exposes Hydra Public (OAuth2) endpoints. - `-p 4445:4445`: Exposes Hydra Admin endpoints (client registration, introspection, etc.). - `-p 80:80`: Exposes Apache + LAM (web UI). --- ### Environment Variables | Variable | Description | |--------------------------|------------------------------------------------------------------------------------------------------------------------| | `LDAP_DOMAIN` | LDAP base domain (e.g., `example.com`). Used to initialize LDAP DIT (`dc=example,dc=com`). | | `LDAP_ORGANISATION` | Organization name (e.g., `"Example Corp"`). Populates LDAP `o` attribute. | | `LDAP_ADMIN_PASSWORD` | Password for the LDAP admin user (`cn=admin,dc=${LDAP_DOMAIN}`). | | `LDAP_USER_PASSWORD` | Password for the sample LDAP user (`uid=jdoe`). | | `LAM_BIND_DN` | LDAP Bind DN for LAM (e.g., `cn=admin,dc=${LDAP_DOMAIN}`). | | `LAM_BIND_PASSWORD` | Password for the above `LAM_BIND_DN`. | | `HYDRA_SECRETS_SYSTEM` | A 32+ character random secret for Hydra’s HMAC and session encryption. | | `HYDRA_ISSUER_URL` | The issuer URL for Hydra (e.g., `http://127.0.0.1:4444`). Hydra’s config will use this to set `urls.self.base`. | > **Note**: For production, consider replacing `LDAP_USER_PASSWORD` with an SSHA hash in `bootstrap.ldif.tpl`, and configuring a proper database (e.g., Postgres) for Hydra instead of in-memory SQLite. --- ## Service URLs and Testing 1. **LDAP (OpenLDAP)** - Host: `ldap://localhost:389` - Admin Bind DN: `cn=admin,dc=${LDAP_DOMAIN}` - Example query: ```bash ldapsearch -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -w adminpassword -b "dc=example,dc=com" "(uid=jdoe)" ``` - Should return the entry for `cn=John Doe, uid=jdoe`. 2. **LDAP Account Manager (LAM)** - URL: `http://localhost/lam` - Login with: - Bind DN: `cn=admin,dc=${LDAP_DOMAIN}` - Password: `${LAM_BIND_PASSWORD}` - Browse the DIT at `dc=${LDAP_DOMAIN} → ou=users → cn=John Doe`. 3. **Hydra Admin API** - Base URL: `http://localhost:4445` - Register a client (example): ```bash docker exec -it hydra_ldap_lam hydra clients create --endpoint http://127.0.0.1:4445 --id my-client --secret my-secret --grant-types authorization_code,refresh_token --response-types code,id_token --scope openid,offline --callbacks http://localhost/callback ``` 4. **Hydra OAuth2 Public Endpoints** - Authorization endpoint: ``` http://localhost:4444/oauth2/auth?response_type=code&client_id=my-client &scope=openid&redirect_uri=http://localhost/callback&state=xyz ``` - Token endpoint (example): ```bash curl -X POST http://localhost:4444/oauth2/token -u my-client:my-secret -d grant_type=authorization_code -d code= -d redirect_uri=http://localhost/callback ``` - Successful response returns `access_token`, `id_token`, etc. --- ## Customization & Next Steps - **Switch to a Persistent Database for Hydra** Modify `templates/hydra-config.yaml.tpl` to use a `${HYDRA_DSN}` (e.g., `postgres://hydrabox:secret@postgres:5432/hydra?sslmode=disable`) and pass `-e HYDRA_DSN="your-database-url"` at runtime. Add a separate Postgres container or external DB. - **Enable TLS for OpenLDAP** - Generate or supply certificates and adjust `/etc/ldap/slapd.d/` configuration to enable LDAPS (`ldaps://`). - Update `templates/bootstrap.ldif.tpl` or dynamically configure TLS. - **Secure Apache (LAM)** - Obtain a TLS certificate (e.g., via Let’s Encrypt) and configure Apache’s SSL vhost. - Adjust `entrypoint.sh` and the Dockerfile to copy in certificates or mount them at runtime. - **Multiple LDAP Users / Additional LDIFs** - Add more `.tpl` LDIF files under `templates/` (e.g., `custom-groups.ldif.tpl`) and apply them in `entrypoint.sh`. --- ## Development 1. **Modify Templates** - Update `templates/bootstrap.ldif.tpl` to add more objects (groups, additional users). - Update `templates/lam.conf.php.tpl` for advanced LAM settings (database, theming, etc.). - Update `templates/hydra-config.yaml.tpl` for production-ready features (HTTPS, introspection limits, etc.). 2. **Rebuild the Docker Image** ```bash docker build -t hydraldaplam:latest . ``` 3. **Run with New Environment Variables** ```bash docker run -d -e LDAP_DOMAIN="yourdomain.com" -e LDAP_ORGANISATION="Your Org" -e LDAP_ADMIN_PASSWORD="YourAdminPassword" -e LDAP_USER_PASSWORD="YourUserPassword" -e LAM_BIND_DN="cn=admin,dc=yourdomain,dc=com" -e LAM_BIND_PASSWORD="YourAdminPassword" -e HYDRA_SECRETS_SYSTEM="your-long-32+-char-secret" -e HYDRA_ISSUER_URL="https://your-hydra-host" -p 389:389 -p 636:636 -p 4444:4444 -p 4445:4445 -p 80:80 hydraldaplam:latest ``` --- ## License This project is provided “as-is” under the MIT License. See [LICENSE](LICENSE) for details.