Hello everyone,
after setting up my self-hosted setup for a couple of weeks now I would like to know if my config is good currently.
My structure is the following:
/apps/traefik
/apps/crowdsec
/apps/{other_apps}
Here is my current docker-compose.yml
for traefik:
version: "3.9"
networks:
proxy:
name: proxy
driver: bridge
default:
driver: bridge
services:
traefik:
image: traefik:latest
container_name: traefik
restart: always
healthcheck:
test: grep -qr "traefik" /proc/*/status || exit 1
interval: 1m
timeout: 30s
retries: 3
env_file: .env
ports:
- 80:80
- 443:443
command:
# Adding cloudflare IPs
- "--entrypoints.https.forwardedHeaders.trustedIPs=$CLOUDFLARE_IPS" # they are inside .env file
# Adding Prometheus Metrics
- "--metrics.prometheus=true"
- "--metrics.prometheus.manualrouting=true"
- '--entryPoints.metrics.address=:8080'
environment:
- TZ=Europe/Berlin
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config/traefik.yml:/traefik.yml:ro
- ./config/config.yml:/config.yml:ro
- ./config/acme.json:/acme.json
- ./logs:/var/log/traefik
labels:
# Front API
autoupdate: monitor
traefik.enable: true
traefik.http.routers.api.entrypoints: https
traefik.http.routers.api.rule: Host("traefik.domain.com")
traefik.http.routers.api.service: api@internal
traefik.http.routers.api.middlewares: auth
traefik.http.middlewares.auth.basicauth.users: admin:$$apr1$$GSzqoMxl$$fSpUtNiz0jIV6QHkpJO5k/
networks:
- proxy
This is my current config/traefik.yml
:
api:
dashboard: true
log:
level: "INFO"
filePath: "/var/log/traefik/traefik.log"
accessLog:
filePath: "/var/log/traefik/access.log"
entryPoints:
http:
address: ":80"
http:
middlewares:
- crowdsec-bouncer@file
http: # <--- Unsure about this, vscode showing me an error (map key must be unique)
redirections:
entryPoint:
to: https
scheme: https
https:
address: ":443"
http:
middlewares:
- crowdsec-bouncer@file
http: # <--- Same here "Map key must be unique"
tls:
certResolver: http
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
directory: custom/
watch: true
certificatesResolvers:
http:
acme:
email: test@mail.com
storage: acme.json
# Staging - Comment for prod
#caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
httpChallenge:
entryPoint: http
serverstransport:
insecureskipverify: true
metrics:
prometheus:
buckets:
- 0.1
- 0.3
- 1.2
- 5.0
And this is my config/config.yml
:
tls:
options:
default:
minVersion: VersionTLS12
sniStrict: true
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
curvePreferences:
- CurveP521
- CurveP384
http:
middlewares:
https-redirect:
redirectScheme:
scheme: https
compression:
compress:
excludedContentTypes:
- text/event-stream
default-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
# HSTS - uncomment for HSTS
#forceSTSHeader: true
#stsIncludeSubdomains: true
#stsPreload: true
middlewares-rate-limit:
rateLimit:
average: 100
burst: 50
secured:
chain:
middlewares:
- default-headers
crowdsec-bouncer:
forwardauth:
address: http://bouncer-traefik:8080/api/v1/forwardAuth
trustForwardHeader: true
security:
headers:
accessControlAllowMethods:
- GET
- OPTIONS
- PUT
accessControlMaxAge: 100
addVaryHeader: true
browserXssFilter: true
contentTypeNosniff: true
#forceSTSHeader: true
frameDeny: true
sslRedirect: true
sslForceHost: true
#stsPreload: true
customFrameOptionsValue: SAMEORIGIN
referrerPolicy: "same-origin"
featurePolicy: "camera 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none'; vibrate 'self';"
#stsSeconds: 315360000
hostsProxyHeaders:
- "X-Forwarded-Host"
#tls:
# options:
# default:
# minVersion: VersionTLS13
# sniStrict: true
This setup works so far, now my crowdsec (/apps/crowdsec/docker-compose.yml
):
version: '3.8'
networks:
proxy:
name: proxy
driver: bridge
default:
driver: bridge
services:
crowdsec:
image: crowdsecurity/crowdsec:latest
container_name: crowdsec
environment:
GID: "${GID-1000}"
COLLECTIONS: "crowdsecurity/linux crowdsecurity/traefik crowdsecurity/http-cve"
# depends_on: #uncomment if running traefik in the same compose file
# - 'traefik'
volumes:
- ./data:/var/lib/crowdsec/data:rw
- ./config/acquis.yaml:/etc/crowdsec/acquis.yaml
- /var/log/auth.log:/var/log/auth.log:ro
- /var/log/traefik:/var/log/traefik:ro
#- /apps/traefik/logs:/var/log/traefik:ro
- /var/log:/var/log/host:ro
# Make sure this path is correct to grab traefik logs
- /apps/traefik/logs/access.log:/var/log/crowdsec/access.log
networks:
- proxy
expose:
- 8080
restart: unless-stopped
bouncer-traefik:
image: docker.io/fbonalair/traefik-crowdsec-bouncer:latest
container_name: bouncer-traefik
environment:
CROWDSEC_BOUNCER_API_KEY: daf37972db4acc31faab4e10a6b73d32
CROWDSEC_AGENT_HOST: crowdsec:8080
GIN_MODE: release
networks:
- proxy # same network as traefik + crowdsec
depends_on:
- crowdsec
restart: unless-stopped
crowdsec-dashboard:
#we're using a custom Dockerfile so that metabase pops with pre-configured dashboards
build: ./dashboard
restart: always
#ports:
# - 3000:3000
environment:
MB_DB_FILE: /data/metabase.db
MGID: "${GID-1000}"
depends_on:
- 'crowdsec'
volumes:
- ./data:/metabase-data/
labels:
- autoupdate=monitor
- traefik.enable=true
- traefik.http.routers.metabase.entrypoints=https
- traefik.http.routers.metabase.rule=Host("metabase.example.com")
- traefik.http.routers.metabase.service=metabase
- traefik.http.services.metabase.loadbalancer.server.port=3000
- traefik.docker.network=proxy
# Uncomment the next line to enable HSTS header.
#- "traefik.frontend.headers.STSSeconds=15768000"
networks:
proxy:
#volumes:
# crowdsec-db:
# crowdsec-config:
# traefik_traefik-logs: # this will be the name of the volume from trarfic logs
# external: true # remove if traefik is running on same stack
And last but not least my acquis.yml
:
filenames:
- /var/log/traefik/traefik.log
labels:
type: traefik
---
filenames:
- /var/log/auth.log
labels:
type: syslog
The setup works and from the metabase dashboard I can see that crowdsec also works, but I still would like to know if there is anything I can improve or making it cleaner overall.
Thank you very much!