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.

1 Like

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

1 Like

Thank you for your help and time

1 Like