Initial Traefik compose stack commit
This commit is contained in:
+47
@@ -0,0 +1,47 @@
|
|||||||
|
### macOS
|
||||||
|
# Finder metadata
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Custom folder icons
|
||||||
|
Icon␍
|
||||||
|
|
||||||
|
# Volume root files
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
# Backup files
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Temporary files from deleted open files
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# NFS temporary files
|
||||||
|
.nfs*
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
# Traefik reverse proxy stack
|
||||||
|
|
||||||
|
Docker Compose stack for [Traefik](https://traefik.io/) with Let’s Encrypt (Cloudflare DNS challenge), a secured dashboard, and a reusable middleware library for security headers, CSP tiers, Authentik SSO, redirects, and IP allowlists.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Docker Engine with Compose v2
|
||||||
|
- A Cloudflare account with API access for the domains you terminate here
|
||||||
|
- DNS for those domains pointed at the host that runs this stack
|
||||||
|
- A shared Docker network that your backend services also join (default: `docknet`)
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <this-repo> traefik && cd traefik
|
||||||
|
cp example.env .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit `.env` (see [Environment variables](#environment-variables)), then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --env-file .env up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Traefik will join (or create) the Docker network named by `NETWORK_NAME`, watch containers on that host for Traefik labels, and issue certificates via Cloudflare DNS. ACME data is stored in the Docker named volume `traefik-acme` (created automatically; no manual file setup).
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── compose.yml # Traefik service, ports, dashboard labels, ACME volume
|
||||||
|
├── example.env # Env template (copy to .env)
|
||||||
|
└── traefik/
|
||||||
|
├── traefik.yaml # Static config: entrypoints, providers, TLS SANs
|
||||||
|
└── conf.d/
|
||||||
|
├── middlewares.yaml # Shared middleware library
|
||||||
|
├── routers.yaml # Optional file-based routers
|
||||||
|
└── services.yaml # Optional file-based services
|
||||||
|
```
|
||||||
|
|
||||||
|
Static config lives in `traefik/traefik.yaml`. Dynamic config (middlewares, optional routers/services) is loaded from `traefik/conf.d/` and hot-reloads when files change. Certificate state lives in the `traefik-acme` volume, not in the repo.
|
||||||
|
|
||||||
|
## Environment variables
|
||||||
|
|
||||||
|
Copy `example.env` to `.env` and fill in real values:
|
||||||
|
|
||||||
|
| Variable | Purpose |
|
||||||
|
| --- | --- |
|
||||||
|
| `CLOUDFLARE_EMAIL` | Cloudflare account email (ACME + API) |
|
||||||
|
| `CLOUDFLARE_API_KEY` | Cloudflare Global API Key (or scoped token with DNS edit) |
|
||||||
|
| `CONSOLE_HOST` | Hostname for the Traefik dashboard (e.g. `traefik.example.com`) |
|
||||||
|
| `NETWORK_NAME` | Docker network name shared with backends (default `docknet`) |
|
||||||
|
| `TRAEFIK_CONSOLE_AUTH` | Basic-auth users for the dashboard (`htpasswd` format) |
|
||||||
|
| `TRAEFIK_YAML` | Host path to static config (default `./traefik/traefik.yaml`) |
|
||||||
|
| `TRAEFIK_CONFD` | Host path to dynamic config dir (default `./traefik/conf.d`) |
|
||||||
|
|
||||||
|
Generate dashboard credentials:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install apache2-utils / httpd-tools if needed, then:
|
||||||
|
htpasswd -nbB admin 'your-strong-password'
|
||||||
|
```
|
||||||
|
|
||||||
|
Paste the output into `TRAEFIK_CONSOLE_AUTH`. If the value contains `$`, escape them for Compose (use `$$`) or quote carefully in `.env`.
|
||||||
|
|
||||||
|
## Ports
|
||||||
|
|
||||||
|
| Host | Container | Role |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `8342` | `80` | HTTP → redirects to HTTPS |
|
||||||
|
| `8767` | `443` | HTTPS |
|
||||||
|
| `8080` | `8080` | Traefik API / dashboard (also exposed via `CONSOLE_HOST` with TLS + basic auth) |
|
||||||
|
|
||||||
|
Point your public reverse path or firewall at `8767` (and `8342` if you want HTTP→HTTPS at the edge). Adjust the left-hand ports in `compose.yml` if you prefer `80`/`443` on the host.
|
||||||
|
|
||||||
|
## TLS and certificates
|
||||||
|
|
||||||
|
- Challenge: **DNS-01** via Cloudflare (`certificatesResolvers.letsencrypt`)
|
||||||
|
- Storage: Docker named volume `traefik-acme` mounted at `/letsencrypt` (Traefik creates `acme.json` on first run)
|
||||||
|
- Default certificate SANs for the TLS store are defined under `tls.stores.default` in `traefik/traefik.yaml` — edit that list for your domains
|
||||||
|
|
||||||
|
The volume survives `docker compose down` / `up`. Prefer `docker compose down` over `docker compose down -v` unless you intentionally want to wipe certs (which will re-hit Let’s Encrypt rate limits).
|
||||||
|
|
||||||
|
Ensure Cloudflare credentials can create/delete `_acme-challenge` TXT records for every zone you serve.
|
||||||
|
|
||||||
|
## Dashboard
|
||||||
|
|
||||||
|
The dashboard is enabled and routed with Docker labels on the Traefik container:
|
||||||
|
|
||||||
|
- URL: `https://<CONSOLE_HOST>/`
|
||||||
|
- Entrypoint: `websecure`
|
||||||
|
- Auth: middleware `traefik-auth` (basic auth from `TRAEFIK_CONSOLE_AUTH`)
|
||||||
|
- Certificate: Let’s Encrypt via `letsencrypt` resolver
|
||||||
|
|
||||||
|
## Using middlewares on your services
|
||||||
|
|
||||||
|
Connect apps to the same Docker network (`NETWORK_NAME`), enable Traefik, and attach middlewares by name with the `@file` provider:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
myapp:
|
||||||
|
image: myapp:latest
|
||||||
|
networks:
|
||||||
|
- docknet
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.myapp.rule=Host(`app.example.com`)
|
||||||
|
- traefik.http.routers.myapp.entrypoints=websecure
|
||||||
|
- traefik.http.routers.myapp.tls.certresolver=letsencrypt
|
||||||
|
- traefik.http.routers.myapp.middlewares=security-supermax@file,gzip@file
|
||||||
|
- traefik.http.services.myapp.loadbalancer.server.port=8080
|
||||||
|
|
||||||
|
networks:
|
||||||
|
docknet:
|
||||||
|
external: true
|
||||||
|
name: docknet
|
||||||
|
```
|
||||||
|
|
||||||
|
Chain multiple middlewares with commas. File-provider names resolve as `<name>@file`.
|
||||||
|
|
||||||
|
## Middleware catalog
|
||||||
|
|
||||||
|
Defined in `traefik/conf.d/middlewares.yaml`.
|
||||||
|
|
||||||
|
### Security chains (pick one)
|
||||||
|
|
||||||
|
| Middleware | Intent |
|
||||||
|
| --- | --- |
|
||||||
|
| `default` | CSP strict + frame deny + gzip + HSTS + baseline security headers |
|
||||||
|
| `secure-all` | Permissive CSP + same-origin frames + HSTS + security headers |
|
||||||
|
| `security-mallcop` | Open referrer + open CSP + HSTS + security headers |
|
||||||
|
| `security-lax` | Lax referrer + lax CSP + HSTS + security headers |
|
||||||
|
| `security-medium` | Permissive referrer/CSP + same-origin frames + HSTS + security headers |
|
||||||
|
| `security-prison` | Medium referrer + balanced CSP + same-origin frames + HSTS + security headers |
|
||||||
|
| `security-supermax` | No-referrer + strict CSP + frame deny + HSTS + security headers |
|
||||||
|
| `security-supermax-with-analytics` | Supermax plus GA/Clarity/Umami-friendly CSP and COOP |
|
||||||
|
|
||||||
|
### CSP building blocks
|
||||||
|
|
||||||
|
| Middleware | Notes |
|
||||||
|
| --- | --- |
|
||||||
|
| `csp-open-header` | Very permissive (legacy / hard-to-lock apps) |
|
||||||
|
| `csp-lax-header` | Self + common inline/eval allowances |
|
||||||
|
| `csp-permissive-header` | Self-focused with inline/eval for scripts/styles |
|
||||||
|
| `csp-balanced-header` | Self + common CDNs (jsDelivr, cdnjs, unpkg, Google Fonts) |
|
||||||
|
| `csp-strict-header` | Self-only |
|
||||||
|
| `csp-strict-header-with-ga` | Strict plus analytics/Clarity/GTM endpoints |
|
||||||
|
|
||||||
|
### Other headers & utilities
|
||||||
|
|
||||||
|
| Middleware | Role |
|
||||||
|
| --- | --- |
|
||||||
|
| `security-headers` | `X-Content-Type-Options: nosniff`, disables legacy `X-XSS-Protection` |
|
||||||
|
| `hsts-header` | HSTS 2y, includeSubDomains, preload |
|
||||||
|
| `frame-deny-header` | `X-Frame-Options: DENY` |
|
||||||
|
| `frame-sameorigin-header` | `X-Frame-Options: SAMEORIGIN` |
|
||||||
|
| `cross-origin-opener-strict-policy` | `Cross-Origin-Opener-Policy: same-origin` |
|
||||||
|
| `gzip` | Response compression |
|
||||||
|
| `referrer-*-header` | Referrer-Policy tiers (`open` → `supermax`) |
|
||||||
|
| `strip-server-path` | Strips `/db`, `/server`, `/traefik` prefixes |
|
||||||
|
|
||||||
|
### Auth & access
|
||||||
|
|
||||||
|
| Middleware | Role |
|
||||||
|
| --- | --- |
|
||||||
|
| `authentik-outpost` | ForwardAuth to Authentik outpost (`outpost.mifi.holdings`) |
|
||||||
|
| `authentik-no-cache` | Disable caching on Authentik responses |
|
||||||
|
| `authentik-static-immutable` | Long-cache immutable static assets |
|
||||||
|
| `internal-ips` | IP allowlist (edit `sourceRange` for your networks) |
|
||||||
|
|
||||||
|
### Redirects
|
||||||
|
|
||||||
|
| Middleware | Role |
|
||||||
|
| --- | --- |
|
||||||
|
| `redirect-www-to-non-www` | `www.` → apex |
|
||||||
|
| `redirect-non-www-to-www` | apex → `www.` |
|
||||||
|
| `redirect-postfixadmin` | Mail settings path redirect (site-specific) |
|
||||||
|
|
||||||
|
Update Authentik outpost URL, IP allowlists, and domain-specific redirects in `middlewares.yaml` before deploying outside this environment.
|
||||||
|
|
||||||
|
## File-based routers and services
|
||||||
|
|
||||||
|
`traefik/conf.d/routers.yaml` and `services.yaml` are stubs for optional non-Docker backends. Uncomment or add entries when you need host/path rules that are not expressed as container labels.
|
||||||
|
|
||||||
|
## Operations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start / recreate after config or .env changes
|
||||||
|
docker compose --env-file .env up -d
|
||||||
|
|
||||||
|
# Follow logs
|
||||||
|
docker compose logs -f traefik
|
||||||
|
|
||||||
|
# Stop (keeps the ACME volume)
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# Inspect ACME volume location (optional)
|
||||||
|
docker volume inspect traefik_traefik-acme
|
||||||
|
```
|
||||||
|
|
||||||
|
Dynamic files under `conf.d/` reload without a full restart. Changes to `traefik.yaml`, Compose labels, ports, or env vars generally need `docker compose up -d` (or a container recreate).
|
||||||
|
|
||||||
|
## Customization checklist
|
||||||
|
|
||||||
|
1. Set `.env` from `example.env` and generate `TRAEFIK_CONSOLE_AUTH`
|
||||||
|
2. Edit TLS SANs in `traefik/traefik.yaml` for your domains
|
||||||
|
3. Adjust `internal-ips` and Authentik URLs in `middlewares.yaml`
|
||||||
|
4. Ensure backends use `traefik.enable=true` and join `NETWORK_NAME`
|
||||||
|
5. Publish host ports (`8342`/`8767`) as needed for your network edge
|
||||||
|
|
||||||
|
## Security notes
|
||||||
|
|
||||||
|
- Do not commit `.env` or real API keys
|
||||||
|
- Prefer a scoped Cloudflare API token limited to DNS edit on required zones when possible
|
||||||
|
- Keep the dashboard behind strong basic auth (and consider further restricting with `internal-ips` or Authentik)
|
||||||
|
- Review CSP chains per app; start stricter and loosen only where breakage requires it
|
||||||
|
- Do not use `docker compose down -v` in production unless you mean to discard certificates
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
services:
|
||||||
|
traefik:
|
||||||
|
image: traefik:latest
|
||||||
|
container_name: traefik
|
||||||
|
restart: unless-stopped
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
volumes:
|
||||||
|
- ${TRAEFIK_YAML:-./traefik/traefik.yaml}:/etc/traefik/traefik.yaml
|
||||||
|
- ${TRAEFIK_CONFD:-./traefik/conf.d}:/etc/traefik/conf.d
|
||||||
|
- traefik-acme:/letsencrypt
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
networks:
|
||||||
|
- docknet
|
||||||
|
labels:
|
||||||
|
- 'traefik.enable=true'
|
||||||
|
- 'traefik.http.routers.api.rule=Host(`${CONSOLE_HOST}`)'
|
||||||
|
- 'traefik.http.routers.api.entrypoints=websecure'
|
||||||
|
- 'traefik.http.routers.api.service=api@internal'
|
||||||
|
- 'traefik.http.routers.api.tls=true'
|
||||||
|
- 'traefik.http.routers.api.tls.certresolver=letsencrypt'
|
||||||
|
- 'traefik.http.routers.api.middlewares=traefik-auth'
|
||||||
|
- 'traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_CONSOLE_AUTH}'
|
||||||
|
ports:
|
||||||
|
- 8342:80
|
||||||
|
- 8767:443
|
||||||
|
- 8080:8080
|
||||||
|
environment:
|
||||||
|
- CLOUDFLARE_EMAIL=${CLOUDFLARE_EMAIL}
|
||||||
|
- CLOUDFLARE_API_KEY=${CLOUDFLARE_API_KEY}
|
||||||
|
command:
|
||||||
|
- --api
|
||||||
|
# Enable the Trafik dashboard
|
||||||
|
- --api.dashboard=true
|
||||||
|
# Tell Traefik to discover containers using the Docker API
|
||||||
|
- --providers.docker=true
|
||||||
|
- --providers.docker.exposedByDefault=false
|
||||||
|
# Set up LetsEncrypt
|
||||||
|
- --certificatesresolvers.letsencrypt.acme.dnschallenge=true
|
||||||
|
- --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare
|
||||||
|
- --certificatesresolvers.letsencrypt.acme.email=${CLOUDFLARE_EMAIL}
|
||||||
|
# Set up an insecure listener that redirects all traffic to TLS
|
||||||
|
- --entrypoints.web.address=:80
|
||||||
|
- --entrypoints.web.http.redirections.entrypoint.to=websecure
|
||||||
|
- --entrypoints.web.http.redirections.entrypoint.scheme=https
|
||||||
|
- --entrypoints.websecure.address=:443
|
||||||
|
# Set up the TLS configuration for our websecure listener
|
||||||
|
- --entrypoints.websecure.http.tls=true
|
||||||
|
- --entrypoints.websecure.http.tls.certResolver=letsencrypt
|
||||||
|
- --log=true
|
||||||
|
- --log.level=INFO
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "1m"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
docknet:
|
||||||
|
name: ${NETWORK_NAME:-docknet}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
traefik-acme:
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
CLOUDFLARE_EMAIL=[EMAIL]
|
||||||
|
CLOUDFLARE_API_KEY=[API_KEY]
|
||||||
|
CONSOLE_HOST=traefik.mifi.dev
|
||||||
|
NETWORK_NAME=docknet
|
||||||
|
TRAEFIK_CONSOLE_AUTH=[username]:[password]
|
||||||
|
TRAEFIK_YAML=./traefik/traefik.yaml
|
||||||
|
TRAEFIK_CONFD=./traefik/conf.d
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
default:
|
||||||
|
chain:
|
||||||
|
middlewares:
|
||||||
|
- csp-strict-header
|
||||||
|
- frame-deny-header
|
||||||
|
- gzip
|
||||||
|
- hsts-header
|
||||||
|
- security-headers
|
||||||
|
# middlewares
|
||||||
|
authentik-no-cache:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Cache-Control: "no-store, no-cache, must-revalidate, max-age=0"
|
||||||
|
Pragma: "no-cache"
|
||||||
|
Expires: "0"
|
||||||
|
authentik-outpost:
|
||||||
|
forwardAuth:
|
||||||
|
address: "https://outpost.mifi.holdings/outpost.goauthentik.io/auth/traefik"
|
||||||
|
trustForwardHeader: true
|
||||||
|
authResponseHeaders:
|
||||||
|
- X-authentik-username
|
||||||
|
- X-authentik-groups
|
||||||
|
- X-authentik-entitlements
|
||||||
|
- X-authentik-email
|
||||||
|
- X-authentik-name
|
||||||
|
- X-authentik-uid
|
||||||
|
- X-authentik-jwt
|
||||||
|
- X-authentik-meta-jwks
|
||||||
|
- X-authentik-meta-outpost
|
||||||
|
- X-authentik-meta-provider
|
||||||
|
- X-authentik-meta-app
|
||||||
|
- X-authentik-meta-version
|
||||||
|
authentik-static-immutable:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Cache-Control: "public, max-age=31536000, immutable"
|
||||||
|
cross-origin-opener-strict-policy:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Cross-Origin-Opener-Policy: "same-origin"
|
||||||
|
csp-open-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Content-Security-Policy: "default-src * data: blob: 'unsafe-inline' 'unsafe-eval'; script-src * data: blob: 'unsafe-inline' 'unsafe-eval'; style-src * data: blob: 'unsafe-inline'; img-src * data: blob:; font-src * data: blob:; frame-src *; frame-ancestors *; base-uri *; form-action *; frame-src *; connect-src 'self'; worker-src 'self' blob:;"
|
||||||
|
csp-lax-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Content-Security-Policy: "default-src 'self'; img-src 'self' data: https:; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; font-src 'self' data: https:; frame-ancestors 'self'; frame-src 'self' https:; base-uri 'self'; form-action 'self' https:; connect-src 'self'; worker-src 'self' blob:;"
|
||||||
|
csp-permissive-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Content-Security-Policy: "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; connect-src 'self'; worker-src 'self';"
|
||||||
|
csp-balanced-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Content-Security-Policy: "default-src 'self'; script-src 'self' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com https://unpkg.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com data:; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; connect-src 'self'; worker-src 'self';"
|
||||||
|
csp-strict-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Content-Security-Policy: "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; connect-src 'self'; worker-src 'self';"
|
||||||
|
csp-strict-header-with-ga:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Content-Security-Policy: "default-src 'self'; script-src 'self' https://analytics.mifi.holdings https://scripts.clarity.ms https://www.clarity.ms https://www.googletagmanager.com; style-src 'self' 'unsafe-inline'; img-src 'self' https://analytics.mifi.holdings https://*.clarity.ms https://c.bing.com https://www.google-analytics.com https://www.googletagmanager.com https://stats.g.doubleclick.net; font-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; connect-src 'self' https://analytics.mifi.holdings https://*.clarity.ms https://c.bing.com https://www.google.com https://www.google-analytics.com https://region1.google-analytics.com https://stats.g.doubleclick.net; worker-src 'self'; require-trusted-types-for 'script'; trusted-types default forceInner goog#html mifi-ventures-policy svelte-trusted-html 'allow-duplicates';"
|
||||||
|
frame-deny-header:
|
||||||
|
headers:
|
||||||
|
frameDeny: true # X-Frame-Options: DENY
|
||||||
|
frame-sameorigin-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
X-Frame-Options: "SAMEORIGIN"
|
||||||
|
gzip:
|
||||||
|
compress: {}
|
||||||
|
hsts-header:
|
||||||
|
headers:
|
||||||
|
# Enable HSTS (Strict Transport Security)
|
||||||
|
stsSeconds: 63072000 # 2 years
|
||||||
|
stsIncludeSubdomains: true
|
||||||
|
stsPreload: true # for preload list
|
||||||
|
internal-ips:
|
||||||
|
ipWhiteList:
|
||||||
|
sourceRange:
|
||||||
|
- 127.0.0.1/32
|
||||||
|
- 192.168.50.1/32
|
||||||
|
- 50.116.61.55
|
||||||
|
- 173.255.238.101
|
||||||
|
- 72.93.250.18
|
||||||
|
redirect-postfixadmin:
|
||||||
|
redirectRegex:
|
||||||
|
regex: "^https://mail\\.mifi\\.holdings/settings/?(.*)"
|
||||||
|
replacement: "https://postmaster.mifi.holdings/$1"
|
||||||
|
permanent: true
|
||||||
|
redirect-www-to-non-www:
|
||||||
|
redirectRegex:
|
||||||
|
regex: "^https://www\\.(.*)"
|
||||||
|
replacement: "https://${1}"
|
||||||
|
permanent: true
|
||||||
|
redirect-non-www-to-www:
|
||||||
|
redirectregex:
|
||||||
|
permanent: true
|
||||||
|
regex: "^https?://(?:www\\.)?(.+)"
|
||||||
|
replacement: "https://www.${1}"
|
||||||
|
referrer-open-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Referrer-Policy: "unsafe-url"
|
||||||
|
referrer-lax-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Referrer-Policy: "origin-when-cross-origin"
|
||||||
|
referrer-permissive-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Referrer-Policy: "strict-origin-when-cross-origin"
|
||||||
|
referrer-medium-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Referrer-Policy: "same-origin"
|
||||||
|
referrer-supermax-header:
|
||||||
|
headers:
|
||||||
|
customResponseHeaders:
|
||||||
|
Referrer-Policy: "no-referrer"
|
||||||
|
security-headers:
|
||||||
|
headers:
|
||||||
|
contentTypeNosniff: true # X-Content-Type-Options: nosniff
|
||||||
|
customResponseHeaders:
|
||||||
|
X-XSS-Protection: "0" # Disable legacy browser XSS filter (modern best practice)
|
||||||
|
secure-all:
|
||||||
|
chain:
|
||||||
|
middlewares:
|
||||||
|
- csp-permissive-header
|
||||||
|
- frame-sameorigin-header
|
||||||
|
- hsts-header
|
||||||
|
- security-headers
|
||||||
|
security-mallcop:
|
||||||
|
chain:
|
||||||
|
middlewares:
|
||||||
|
- referrer-open-header
|
||||||
|
- csp-open-header
|
||||||
|
- hsts-header
|
||||||
|
- security-headers
|
||||||
|
security-lax:
|
||||||
|
chain:
|
||||||
|
middlewares:
|
||||||
|
- referrer-lax-header
|
||||||
|
- csp-lax-header
|
||||||
|
- hsts-header
|
||||||
|
- security-headers
|
||||||
|
security-medium:
|
||||||
|
chain:
|
||||||
|
middlewares:
|
||||||
|
- referrer-permissive-header
|
||||||
|
- csp-permissive-header
|
||||||
|
- frame-sameorigin-header
|
||||||
|
- hsts-header
|
||||||
|
- security-headers
|
||||||
|
security-prison:
|
||||||
|
chain:
|
||||||
|
middlewares:
|
||||||
|
- referrer-medium-header
|
||||||
|
- csp-balanced-header
|
||||||
|
- frame-sameorigin-header
|
||||||
|
- hsts-header
|
||||||
|
- security-headers
|
||||||
|
security-supermax:
|
||||||
|
chain:
|
||||||
|
middlewares:
|
||||||
|
- referrer-supermax-header
|
||||||
|
- csp-strict-header
|
||||||
|
- frame-deny-header
|
||||||
|
- hsts-header
|
||||||
|
- security-headers
|
||||||
|
security-supermax-with-analytics:
|
||||||
|
chain:
|
||||||
|
middlewares:
|
||||||
|
- referrer-supermax-header
|
||||||
|
- cross-origin-opener-strict-policy
|
||||||
|
- csp-strict-header-with-ga
|
||||||
|
- frame-deny-header
|
||||||
|
- hsts-header
|
||||||
|
- security-headers
|
||||||
|
strip-server-path:
|
||||||
|
stripPrefix:
|
||||||
|
prefixes:
|
||||||
|
- "/db"
|
||||||
|
- "/server"
|
||||||
|
- "/traefik"
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
http:
|
||||||
|
routers:
|
||||||
|
# redirect-postfixadmin:
|
||||||
|
# entryPoints:
|
||||||
|
# - websecure
|
||||||
|
# rule: "Host(`mail.mifi.holdings`) && PathPrefix(`/settings`)"
|
||||||
|
# middlewares:
|
||||||
|
# - redirect-postfixadmin@file
|
||||||
|
# service: webmin-service
|
||||||
|
# tls:
|
||||||
|
# certResolver: letsencrypt
|
||||||
|
# webmin:
|
||||||
|
# entryPoints:
|
||||||
|
# - websecure
|
||||||
|
# middlewares: strip-server-path@file
|
||||||
|
# rule: "Host(`mail.mifi.holdings`) && PathPrefix(`/server`)"
|
||||||
|
# service: webmin-service
|
||||||
|
# tls:
|
||||||
|
# certResolver: letsencrypt
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
http:
|
||||||
|
services:
|
||||||
|
# webmin-service:
|
||||||
|
# loadBalancer:
|
||||||
|
# passHostHeader: true
|
||||||
|
# servers:
|
||||||
|
# - url: "http://173.255.238.101:10000/"
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
api:
|
||||||
|
dashboard: true
|
||||||
|
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: ":80"
|
||||||
|
http:
|
||||||
|
redirections:
|
||||||
|
entryPoint:
|
||||||
|
to: websecure
|
||||||
|
scheme: https
|
||||||
|
websecure:
|
||||||
|
address: ":443"
|
||||||
|
traefik:
|
||||||
|
address: ":8080"
|
||||||
|
|
||||||
|
ping: {}
|
||||||
|
|
||||||
|
providers:
|
||||||
|
docker:
|
||||||
|
endpoint: unix:///var/run/docker.sock
|
||||||
|
watch: true
|
||||||
|
exposedByDefault: false
|
||||||
|
file:
|
||||||
|
directory: /etc/traefik/conf.d
|
||||||
|
|
||||||
|
log:
|
||||||
|
level: info
|
||||||
|
|
||||||
|
accesslog:
|
||||||
|
filepath: /dev/stdout
|
||||||
|
format: json
|
||||||
|
fields:
|
||||||
|
defaultmode: keep
|
||||||
|
headers:
|
||||||
|
defaultmode: keep
|
||||||
|
|
||||||
|
certificatesResolvers:
|
||||||
|
letsencrypt:
|
||||||
|
acme:
|
||||||
|
email: badmf@mifi.dev
|
||||||
|
storage: /letsencrypt/acme.json
|
||||||
|
dnsChallenge:
|
||||||
|
provider: cloudflare
|
||||||
|
resolvers:
|
||||||
|
- 1.1.1.1:53
|
||||||
|
- 1.0.0.1:53
|
||||||
|
|
||||||
|
tls:
|
||||||
|
stores:
|
||||||
|
default:
|
||||||
|
defaultGeneratedCert:
|
||||||
|
resolver: letsencrypt
|
||||||
|
domain:
|
||||||
|
main: mifi.holdings
|
||||||
|
sans:
|
||||||
|
- mifi.com.br
|
||||||
|
- mifi.dev
|
||||||
|
- mifi.ventures
|
||||||
|
- fitz.guru
|
||||||
|
- michael-gerard.com
|
||||||
|
- asgardianpunk.com
|
||||||
|
- camilla-rena.com
|
||||||
|
- dining-it.com
|
||||||
|
- goodfeatherfarms.com
|
||||||
|
- mylocalpro.biz
|
||||||
|
- officelift.net
|
||||||
|
- starnora.com
|
||||||
|
- starnoraelizabethfitzpatrick.com
|
||||||
|
- thenewenglandpalletguy.com
|
||||||
|
- umlautpress.com
|
||||||
|
|
||||||
|
serversTransport:
|
||||||
|
insecureSkipVerify: false
|
||||||
Reference in New Issue
Block a user