New Traefik set-up guide

Hello. I am redoing my treafik setup and I am looking for a newer guide for treafik, middleware-manager, and crowdsec. I am moving away from Pangolin because I am not using a vps. I have and older traefik set up, but it is having problems getting certificates from the dns challenge? Any help will be appreciated.

maybe you are getting timeout. did you backup your acme.json?

Share your traefik.yml

You don’t need a vps to use pangolin

This is what I was using before I used Pangolin. I have made a new acme.json and tried the one from Pangolin. I am wanting a traefik stack without Pangolin, gerbil, etc. I can’t access traefik dashboard. I get

Serving default certificate for request: “cloudflare-ech.com

remote error: tls: bad certificate

Traefik global configuration

global:
checkNewVersion: true
sendAnonymousUsage: false

Enable traefik ui dashboard

api:
dashboard: true
insecure: true

crowdsec bouncer

experimental:
plugins:
bouncer:
moduleName: GitHub - maxlerebourg/crowdsec-bouncer-traefik-plugin: Traefik plugin for Crowdsec - WAF and IP protection
version: v1.4.2

#metrics:

influxDB2:

address: http://influxdb2:8086

token: pass

org: influx-org

bucket: influx-bucket

# addEntryPointsLabels: true

addRoutersLabels: true

addServicesLabels: true

pushInterval: 60s

Configuring Multiple Filters

log:
level: DEBUG # Set log level to DEBUG for more detailed logs

filePath: “/var/log/traefik/traefik.log” # Path to the Traefik log file

format: json # Log format (json or common)

accessLog:
filePath: “/var/log/traefik/traefik.log” # Path to the access log file
format: json # Access log format (json or common)
filters:
statusCodes:
- “200-299” # Log successful HTTP requests
- “400-599” # Log failed HTTP requests
bufferingSize: 0 # No buffering
fields:
headers:
defaultMode: drop # Drop all headers by default
names:
User-Agent: keep # Keep User-Agent header

The setting below is to allow insecure backend connections.

serverTransport:
insecureSkipVerify: true

Traefik entrypoints (network ports) configuration

entryPoints:

Not used in apps, but redirect everything from HTTP to HTTPS

http:
address: :80
forwardedHeaders:
trustedIPs: &trustedIps
# start of Clouflare public IP list for HTTP requests, remove this if you don’t use it; IP-Bereiche
- 103.21.244.0/22
- 103.22.200.0/22
- 103.31.4.0/22
- 104.16.0.0/13
- 104.24.0.0/14
- 108.162.192.0/18
- 131.0.72.0/22
- 141.101.64.0/18
- 162.158.0.0/15
- 172.64.0.0/13
- 173.245.48.0/20
- 188.114.96.0/20
- 190.93.240.0/20
- 197.234.240.0/22
- 198.41.128.0/17
- 2400:cb00::/32
- 2606:4700::/32
- 2803:f800::/32
- 2405:b500::/32
- 2405:8100::/32
- 2a06:98c0::/29
- 2c0f:f248::/32
# end of Cloudlare public IP list
http:
redirections:
entryPoint:
to: https
scheme: https

HTTPS endpoint, with domain wildcard

https:
address: :443
forwardedHeaders:
# reuse list of Cloudflare Trusted IP’s above for HTTPS requests
trustedIPs: trustedIps
# enable HTTP3 QUIC via UDP/443
#http3:
# advertisedPort: ‘443’
http:
tls:
# Generate a wildcard domain certificate
certResolver: myresolver
domains:
- main: example.com # change this to your proxy domain
sans:
- '
. example.com’ # change this to your proxy domain
middlewares:
- security-headers@file # reference to a dynamic middleware for setting http security headers per default
- rate-limit@file # reference to a dynamic middleware for enabling rate limiting per default
- crowdsec@file # reference to a dynamic middleware for enabling crowdsec bouncer

providers:
providersThrottleDuration: 2s

File provider for connecting things that are outside of docker / defining middleware

file:
filename: /etc/traefik/fileConfig.yml
watch: true

Docker provider for connecting all apps that are inside of the docker network

docker:
watch: true
network: proxy # add Your Docker Network Name Here
endpoint: “tcp://socket-proxy:2375” # use socket-proxy for secure access to docker api
defaultRule: “Host({{ index .Labels \"com.docker.compose.service\"}}.example.com)” # change ‘example.com’ to your proxy domain
exposedByDefault: false

Use letsencrypt to generate ssl certificates

certificatesResolvers:
myresolver:
acme:
email: example.com # the email address used for ssl certificate registration
storage: ./acme.json
#httpChallenge: # acme http challenge; requires port 80 and proper dns entries
# entryPoint: http # specify the entry point for the HTTP challenge (adjust if needed)
dnsChallenge: # acme dns challenge; requires api token of dns provider
provider: cloudflare
propagation:
delayBeforeChecks: 240 # Delay before checking DNS propagation
# Used to make sure the dns challenge is propagated to the right dns servers
resolvers:
- “1.1.1.1:53”
- “1.0.0.1:53”

Step-by-Step

1. ACME / Certificate Handling

  • Ensure acme.json exists and has correct permissions:
    touch acme.json
    chmod 600 acme.json
    
  • In traefik.yml, confirm:
    certificatesResolvers:
      myresolver:
        acme:
          email: your@email
          storage: /etc/traefik/acme.json
          dnsChallenge:
            provider: cloudflare
            resolvers:
              - "1.1.1.1:53"
              - "1.0.0.1:53"
    
  • Make sure the Cloudflare API token has Zone.DNS:Edit permissions.

2. Dashboard Access

  • The error cloudflare-ech.com suggests Traefik is serving its default cert instead of your domain cert.
  • Double-check:
    • Your DNS records (A/CNAME) point to the server.
    • The Host() rule in your router matches the domain you’re using.
    • Example:
      http:
        routers:
          traefik:
            rule: Host(`traefik.example.com`)
            service: api@internal
            entryPoints:
              - https
            tls:
              certResolver: myresolver
      

3. CrowdSec Bouncer Integration

  • The plugin config looks fine, but ensure you also define the middleware in fileConfig.yml:
    http:
      middlewares:
        crowdsec:
          plugin:
            bouncer:
              enabled: true
              api_url: http://crowdsec:8080
              api_key: ${CROWDSEC_BOUNCER_KEY}
    
  • Then attach it to routers:
    middlewares:
      - crowdsec@file
    

4. Middleware-Manager

  • If you want a middleware-manager (like traefik-middleware-manager), it can simplify attaching defaults:
    • Security headers
    • Rate limiting
    • CrowdSec bouncer

Troubleshooting

  • acme.json exists, correct permissions.
  • Cloudflare API token scoped properly.
  • DNS records resolve to server IP.
  • Router Host() matches domain.
  • Dashboard router defined with TLS + certResolver.
  • CrowdSec bouncer middleware attached.

docker-compose.yml

services:
  traefik:
    image: traefik:v3.1
    container_name: traefik
    restart: unless-stopped
    command:
      - --configFile=/etc/traefik/traefik.yml
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"   # dashboard/API
    volumes:
      - ./config/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
      - ./config/traefik/rules:/rules
      - ./acme.json:/etc/traefik/acme.json
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - proxy

  middleware-manager:
    image: hhftechnology/middleware-manager:traefik-int
    container_name: middleware-manager
    restart: unless-stopped
    volumes:
      - ./data:/data
      - ./config/traefik/rules:/conf
      - ./config/middleware-manager:/app/config
      - ./config/traefik:/etc/traefik
      - ./config/middleware-manager/templates.yaml:/app/config/templates.yaml
      - ./config/middleware-manager/templates_services.yaml:/app/config/templates_services.yaml
    environment:
      - TRAEFIK_API_URL=http://traefik:8080
      - TRAEFIK_CONF_DIR=/conf
      - DB_PATH=/data/middleware.db
      - PORT=3456
      - PLUGINS_JSON_URL=https://raw.githubusercontent.com/hhftechnology/middleware-manager/traefik-int/plugin/plugins.json
      - TRAEFIK_STATIC_CONFIG_PATH=/etc/traefik/traefik.yml
      - ACTIVE_DATA_SOURCE=traefik
    ports:
      - "3456:3456"
    networks:
      - proxy

  crowdsec:
    image: crowdsecurity/crowdsec:latest
    container_name: crowdsec
    restart: unless-stopped
    volumes:
      - ./config/crowdsec:/etc/crowdsec
      - ./data/crowdsec:/var/lib/crowdsec/data
      - /var/log:/var/log:ro
    networks:
      - proxy

  crowdsec-bouncer:
    image: fbonalair/traefik-crowdsec-bouncer:latest
    container_name: crowdsec-bouncer
    restart: unless-stopped
    environment:
      - CROWDSEC_BOUNCER_API_KEY=${CROWDSEC_BOUNCER_KEY}
      - CROWDSEC_AGENT_HOST=crowdsec:8080
    networks:
      - proxy

networks:
  proxy:
    external: true

traefik.yml

global:
  checkNewVersion: true
  sendAnonymousUsage: false

api:
  dashboard: true
  insecure: false

log:
  level: INFO
accessLog: {}

entryPoints:
  http:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: https
          scheme: https
  https:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: proxy
  file:
    directory: /rules
    watch: true

certificatesResolvers:
  myresolver:
    acme:
      email: you@example.com
      storage: /etc/traefik/acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"

fileConfig.yml (dynamic middlewares)

http:
  middlewares:
    security-headers:
      headers:
        frameDeny: true
        sslRedirect: true
        contentTypeNosniff: true
        browserXssFilter: true

    rate-limit:
      rateLimit:
        average: 100
        burst: 50

    crowdsec:
      plugin:
        bouncer:
          enabled: true
          api_url: http://crowdsec:8080
          api_key: ${CROWDSEC_BOUNCER_KEY}

Setup Checklist

  • touch acme.json && chmod 600 acme.json
  • Create proxy network:
    docker network create proxy
    
  • Set CROWDSEC_BOUNCER_KEY in .env (generate with cscli bouncers add traefik-bouncer).
  • Update you@example.com and example.com to your domain.
  • Ensure Cloudflare API token has Zone.DNS:Edit.

Ping me on cord HHF Technology for detailed step by step

Thank you for your help and time