Files
docker-infrastructure/traefik/README.md
T
2026-06-05 14:46:40 +03:00

87 lines
4.2 KiB
Markdown

# traefik — ОСК reverse proxy / SNI router
Replaces **nginx-proxy-manager** on serverweb. One `:443` entrypoint that does
**both**:
- **TLS pass-through (Layer 4)** for the Windows services that use Windows-Integrated
auth — TLS terminates at the backend, native Kerberos/NTLM/Negotiate is preserved
(NPM/openresty cannot do this):
- `workfolders.osk.team` → serverfile `192.168.0.11:443` (Work Folders)
- `mail.osk.team`, `autodiscover.osk.team` → servermail `192.168.0.6:443` (Exchange 2019)
- `kdcproxy.osk.team` → serverwsus `192.168.0.7:443` (KDC proxy)
- **TLS termination + Let's Encrypt** for the web dashboards:
- `start.osk.team` (flame), `portainer.osk.team`, `traefik.osk.team` (dashboard)
## Files
| File | Purpose |
|------|---------|
| `docker-compose.yaml` | Traefik v3 service, binds 80/443, mounts config + acme |
| `traefik.yml` | static config (entrypoints, providers, ACME) |
| `dynamic/passthrough.yml` | the TCP SNI-passthrough routers → Windows hosts |
| `dynamic/web.yml` | HTTP routers (dashboards) + dashboard basic-auth |
Config files (`traefik.yml`, `dynamic/`) are the source of truth in git, but must be
**placed on the host** at `/mnt/containers/traefik/container-data/` and mounted by
**absolute path**. Portainer GitOps runs compose with paths relative to its own
container (`/data/compose/<id>/…`), which the Docker daemon can't resolve — so relative
`./` bind mounts silently become empty dirs (`is a directory` crash loop). Keep the host
copies in sync with this repo; Traefik's `watch: true` still hot-reloads `dynamic/` when
the host files change. `acme.json` is **not** in git (private keys) and persists on the host.
## One-time host prep (serverweb)
```bash
mkdir -p /mnt/containers/traefik/container-data/acme
touch /mnt/containers/traefik/container-data/acme/acme.json
chmod 600 /mnt/containers/traefik/container-data/acme/acme.json
mkdir -p /mnt/containers/traefik/container-data/dynamic
```
Then copy the config from this repo onto the host (re-copy whenever they change):
```bash
scp traefik.yml root@serverweb:/mnt/containers/traefik/container-data/traefik.yml
scp dynamic/*.yml root@serverweb:/mnt/containers/traefik/container-data/dynamic/
```
## Before deploying — edit
1. `traefik.yml`: set the real ACME `email`.
2. `dynamic/web.yml`: set a real `dash-auth` hash (`htpasswd -nbB admin 'pass'`),
and confirm the portainer backend (add portainer to `reverseproxy-nw`, or point
at `https://192.168.0.8:9443`).
## Deploy (Portainer GitOps)
- Decommission NPM first (it owns 80/443): stop/remove the `nginx-proxy-manager`
stack. **Do not** delete its data yet (rollback insurance).
- Add a new Portainer **Git** stack, compose path `traefik/docker-compose.yaml`,
same repo. Deploy.
- Test while the edge still points 443 → serverfile: from inside the LAN, hit each
SNI name against serverweb and confirm routing/cert.
- **Flip the edge** last:
- `TCP/80 → serverweb 192.168.0.8` (ACME http-01 + OWA http→https)
- `TCP/443 → serverweb 192.168.0.8` (was → serverfile)
- `UDP/443 → serverfile 192.168.0.11` (SMB over QUIC — unchanged, bypasses Traefik)
## Recommended consolidation
Once Traefik fronts 443, **retire the `kdcproxy` `:8443` hack**: route
`kdcproxy.osk.team` through Traefik on 443 (passthrough above) and revert the
client GPO `KdcProxy\ProxyServers\CORP.LOCAL` back to `<https kdcproxy.osk.team />`
(no port). Then the edge `TCP/8443` forward can be removed.
## Caveats
- **SNI required.** Passthrough routes only by SNI; any client not sending SNI
can't be routed (all modern Outlook/ActiveSync/Work Folders do send it).
- **Passthrough backends keep their own certs.** Traefik's LE only covers the
dashboards it terminates — **serverfile's Work Folders LE cert still renews on
serverfile** (the Sept-3 expiry is unchanged), and Exchange/KDC-proxy keep theirs.
- **Exchange cert** on servermail must cover `mail.osk.team` + `autodiscover.osk.team`
(and any other published names).
- **QUIC** stays a direct edge forward to serverfile; Traefik does not touch UDP/443.
- The dashboards' LE certs need public `:80` reachability for http-01. If they are
internal-only, use a DNS-01 challenge or a default cert instead.