Registry testing - part 9

This commit is contained in:
Maurus Decimus
2026-03-19 19:29:17 +01:00
parent 7ae6654735
commit a67921f18c
57 changed files with 2886 additions and 1312 deletions

View File

@@ -0,0 +1,167 @@
# Stalwart Test Infrastructure
Ephemeral Docker Compose stack for testing Stalwart against external services.
All data is lost on `docker compose down` every restart is a clean slate.
## Quick Start
```bash
cd stalwart-test
docker compose up -d
```
Wait ~30 seconds for all services to initialize (Keycloak takes the longest).
## Connection Reference
| Service | Host | Port(s) | Credentials / Notes |
|----------------|-------------------|-----------------|--------------------------------------------|
| PostgreSQL | localhost | 5432 | `stalwart` / `stalwart`, db: `stalwart` |
| MySQL | localhost | 3306 | `stalwart` / `stalwart`, db: `stalwart` |
| FoundationDB | localhost | 4500 | Cluster file from container |
| Redis | localhost | 6379 | No auth |
| OpenSearch | localhost | 9200 | No auth, security plugin disabled |
| Meilisearch | localhost | 7700 | Master key: `stalwart-master-key` |
| MinIO (S3) | localhost | 9000 / 9001 | `minioadmin` / `minioadmin`, bucket: `stalwart` |
| Keycloak (OIDC)| localhost | 9080 | Admin: `admin` / `admin` |
| OpenLDAP | localhost | 389 / 636 (TLS) | Admin DN: `cn=admin,dc=stalwart,dc=test`, pw: `admin` |
| Pebble (ACME) | localhost | 14000 / 15000 | Self-signed TLS, auto-valid challenges |
| PowerDNS | localhost | 5300 / 8081 | API key: `stalwart-api-key` |
| NATS | localhost | 4222 / 8222 | No auth |
## OIDC (Keycloak) Details
- **OIDC Discovery**: `http://localhost:9080/realms/stalwart/.well-known/openid-configuration`
- **Token Endpoint**: `http://localhost:9080/realms/stalwart/protocol/openid-connect/token`
- **Client ID**: `stalwart`
- **Client Secret**: `stalwart-secret`
- **Realm**: `stalwart`
### Test Users
| Username | Password | Groups |
|---------------------------|--------------------------|----------------------------------------|
| john.doe@example.org | this is an OIDC password | sales@example.org |
| jane.smith@example.org | this is an OIDC password | sales@example.org, corporate@example.org |
| bill.foobar@example.org | this is an OIDC password | corporate@example.org |
### Example: Get a Token
```bash
curl -X POST http://localhost:9080/realms/stalwart/protocol/openid-connect/token \
-d "grant_type=password" \
-d "client_id=stalwart" \
-d "client_secret=stalwart-secret" \
-d "username=john.doe@example.org" \
-d "password=this is an OIDC password"
```
## LDAP Details
- **Base DN**: `dc=stalwart,dc=test`
- **Admin DN**: `cn=admin,dc=stalwart,dc=test`
- **Admin Password**: `admin`
- **Read-only DN**: `cn=readonly,dc=stalwart,dc=test`
- **Read-only Password**: `readonly`
- **User DN pattern**: `uid={username},ou=users,dc=stalwart,dc=test`
### Test Users
| DN | Mail | Password |
|------------------------------------------------|--------------------------|--------------------------|
| uid=john.doe,ou=users,dc=stalwart,dc=test | john.doe@example.org | this is an LDAP password |
| uid=jane.smith,ou=users,dc=stalwart,dc=test | jane.smith@example.org | this is an LDAP password |
| uid=bill.foobar,ou=users,dc=stalwart,dc=test | bill.foobar@example.org | this is an LDAP password |
### Groups
| DN | Mail | Members |
|---------------------------------------------|-------------------------|------------------|
| cn=sales,ou=groups,dc=stalwart,dc=test | sales@example.org | john.doe, jane.smith |
| cn=corporate,ou=groups,dc=stalwart,dc=test | corporate@example.org | bill.foobar, jane.smith |
### Example: Search by Email
```bash
ldapsearch -x -H ldap://localhost:389 \
-D "cn=admin,dc=stalwart,dc=test" -w admin \
-b "dc=stalwart,dc=test" "(mail=john.doe@example.org)"
```
## S3 (MinIO) Details
- **Endpoint**: `http://localhost:9000`
- **Access Key**: `minioadmin`
- **Secret Key**: `minioadmin`
- **Bucket**: `stalwart`
- **Console**: `http://localhost:9001`
- **Region**: `us-east-1` (MinIO default)
## DNS (PowerDNS) Details
- **DNS port**: 5300 (TCP+UDP)
- **API**: `http://localhost:8081` (API key: `stalwart-api-key`)
- **Zone**: `stalwart.test`
- **TSIG key name**: `stalwart-update-key`
- **TSIG algorithm**: `hmac-sha256`
- **TSIG secret (base64)**: `c3RhbHdhcnQtdGVzdC10c2lnLXNlY3JldC1rZXkxMjM0NTY3ODkw`
> **Note on SIG(0):** PowerDNS does not support SIG(0) authentication for RFC2136
> updates. Only BIND has (limited) SIG(0) support. If you need to test SIG(0),
> a separate BIND instance would be required.
### Example: Query TLSA Record
```bash
dig @localhost -p 5300 _25._tcp.mail.stalwart.test TLSA
```
### Example: RFC2136 Dynamic Update
```bash
nsupdate -y hmac-sha256:stalwart-update-key:c3RhbHdhcnQtdGVzdC10c2lnLXNlY3JldC1rZXkxMjM0NTY3ODkw <<EOF
server 127.0.0.1 5300
zone stalwart.test
update add test.stalwart.test 300 A 192.168.1.100
send
EOF
```
## ACME (Pebble) Details
- **Directory URL**: `https://localhost:14000/dir`
- **Management URL**: `https://localhost:15000`
- **TLS**: Self-signed (use `PEBBLE_VA_ALWAYS_VALID=1` — all challenges auto-pass)
- Stalwart must be configured to trust the Pebble CA or skip TLS verification.
## Self-Signed TLS Certificate
A shared self-signed certificate is generated at startup and mounted into services
that need it. The cert is valid for:
- `localhost`, `keycloak`, `openldap`, `pebble`, `*.stalwart.test`, `127.0.0.1`
To extract the cert for use with Stalwart:
```bash
docker compose cp cert-init:/certs/cert.pem ./test-cert.pem
docker compose cp cert-init:/certs/key.pem ./test-key.pem
```
## Troubleshooting
```bash
# Check all services are running
docker compose ps
# View logs for a specific service
docker compose logs -f keycloak
# Restart everything fresh
docker compose down && docker compose up -d
# Check FoundationDB status
docker compose exec foundationdb fdbcli --exec "status"
# Verify TSIG key is loaded
docker compose exec powerdns pdnsutil list-tsig-keys
```