Traefik

Iš Žinynas.
Jump to navigation Jump to search

Docker

Docker tinklas skirtas traefik

docker network create \
  --driver=bridge \
  --subnet=172.16.224.0/24 \
  traefik

Docker compose

services:
  traefik:
    container_name: traefik
    restart: unless-stopped
    image: traefik:v3.2
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /srv/dockers/traefik/etc:/config
      - /srv/dockers/traefik/rules:/rules
      - /srv/dockers/traefik/logs:/logs
      - /srv/dockers/traefik/acme:/acme
    networks:
      traefik:
          aliases:
            - traefik.${DOMAINNAME}
    command:
      - "--configFile=/config/traefik.yaml"
    ports:
      - name: web
        host_ip: 0.0.0.0    # All interfaces, not a specific one
        target: 80          # Container Port
        published: "80"     # STRING
        protocol: tcp       # tcp or udp
        app_protocol: http  # OPTIONAL. Layer 7 Protocol used.  "Richer behavior"
        mode: host          # or Ingress for load balancing
      - name: websecure
        host_ip: 0.0.0.0
        target: 443
        published: "443"
        protocol: tcp
        app_protocol: https
        mode: host
    environment:
      - TZ
      - DOMAINNAME
      - CLOUDFLARE_EMAIL="mano@email.lt"
      - CLOUDFLARE_API_KEY="xxx"
    mem_limit: 640M
    cpus: 1.0
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.traefik-rtr.rule=Host(`traefik.${DOMAINNAME}`) || Host(`traefik.traefik`)"
      - "traefik.http.routers.traefik-rtr.entrypoints=websecure"  # Defined in traefik.yaml
      - "traefik.http.routers.traefik-rtr.middlewares=middlewares-authentik@file"
      ## Services - API
      - "traefik.http.routers.traefik-rtr.service=api@internal"
networks:
  traefik:
    external: true

Konfigūracija

traefik.yaml

Failas randasi: /srv/dockers/traefik/etc/traefik.yaml

# Traefik 3.x (YAML)
# Updated 2024-June-04

################################################################
# Global configuration - https://doc.traefik.io/traefik/reference/static-configuration/file/
################################################################
global:
  checkNewVersion: false
  sendAnonymousUsage: false

################################################################
# Entrypoints - https://doc.traefik.io/traefik/routing/entrypoints/
################################################################
entryPoints:
  web:
    address: ":80"
    # Global HTTP to HTTPS redirection
    http:
      redirections:
        entrypoint:
          to: websecure
          scheme: https

  websecure:
    address: ":443"
    http:
      tls:
        #options: tls-opts@file
        certResolver: le
        domains:
          - main: "domenas.lt"
            sans:
              - "*.domenas.lt"
    forwardedHeaders:
      trustedIPs:
        # Local IPs
        - "127.0.0.1/32"
        - "10.0.0.0/8"
        - "192.168.0.0/16"
        - "172.16.224.0/24"
        - "172.16.0.0/12"

# Logs - https://doc.traefik.io/traefik/observability/logs/
################################################################
log:
  level: INFO # Options: DEBUG, PANIC, FATAL, ERROR (Default), WARN, and INFO
  filePath: /logs/traefik-container.log # Default is to STDOUT
  # format: json # Uses text format (common) by default
  noColor: false # Recommended to be true when using common
  maxSize: 100 # In megabytes
  compress: true # gzip compression when rotating

################################################################
# Access logs - https://doc.traefik.io/traefik/observability/access-logs/
################################################################
accessLog:
  addInternals: true  # things like ping@internal
  filePath: /logs/traefik-access.log # In the Common Log Format (CLF) by default
  bufferingSize: 100 # Number of log lines
  fields:
    names:
      StartUTC: drop  # Write logs in Container Local Time instead of UTC
  filters:
    statusCodes:
      - "204-299"
      - "400-499"
      - "500-599"

################################################################
# API and Dashboard
################################################################
api:
  dashboard: true
  # Rely on api@internal and Traefik with Middleware to control access
  # insecure: true

################################################################
# Providers - https://doc.traefik.io/traefik/providers/docker/
################################################################
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik  # network to use for connections to all containers
    # defaultRule: TODO
    watch: true

  # Enable auto loading of newly created rules by watching a directory
  file:
  # Apps, LoadBalancers, TLS Options, Middlewares, Middleware Chains
    directory: /rules
    watch: true

################################################################
# Let's Encrypt (ACME)
################################################################
certificatesResolvers:
  le:
    acme:
      email: "mano@email.lt"
      storage: "/acme/acme.json"
      dnsChallenge:
        provider: cloudflare
        delayBeforeCheck: 30
        # Custom DNS server resolution
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"

Rules (taisyklės)

Taisyklių rinkinys, jog vėliau galima būtų suintegruoti su Authentik globalia ar per application tipo autorizacija tinkle.

chain-no-auth.yaml

Dedame į /srv/dockers/traefik/rules/chain-no-auth.yaml

http:
  middlewares:
    chain-no-auth:
      chain:
        middlewares:
          - middlewares-rate-limit
          - middlewares-secure-headers
          - middlewares-compress

forwardAuth-authentik.yaml

Dedame į /srv/dockers/traefik/rules/forwardAuth-authentik.yaml

http:
  middlewares:
    ################################################################
    # Forward Authentication - OAUTH / 2FA
    ################################################################
    #
    # https://github.com/goauthentik/authentik/issues/2366
    forwardAuth-authentik:
      forwardAuth:
        address: "https://authentik.domenas.lt/outpost.goauthentik.io/auth/traefik"
        trustForwardHeader: true
        authResponseHeaders:
          - X-authentik-username
          - X-authentik-groups
          - 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


middlewares-authentik.yaml

Dedame į /srv/dockers/traefik/rules/middlewares-authentik.yaml

http:
  middlewares:
# https://github.com/goauthentik/authentik/issues/2366
    middlewares-authentik:
      forwardAuth:
        address: "https://authentik.domenas.lt/outpost.goauthentik.io/auth/traefik"
        trustForwardHeader: true
        authResponseHeaders:
          - X-authentik-username
          - X-authentik-groups
          - 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

middlewares-buffering.yaml

Dedame į /srv/dockers/traefik/rules/middlewares-buffering.yaml

http:
  middlewares:
    # Prevent too large of a body
    # https://stackoverflow.com/questions/49717670/how-to-config-upload-body-size-restriction-in-traefik
    middlewares-buffering:
      buffering:
        maxRequestBodyBytes: 10485760
        memRequestBodyBytes: 2097152
        maxResponseBodyBytes: 10485760
        memResponseBodyBytes: 2097152
        retryExpression: "IsNetworkError() && Attempts() <= 2"


middlewares-https-redirectscheme.yaml

Dedame į /srv/dockers/traefik/rules/middlewares-https-redirectscheme.yaml

http:
  middlewares:
    # Middleware for Redirection
    # This can be used instead of global redirection
    middlewares-https-redirectscheme:
      redirectScheme:
        scheme: https
        permanent: true


middlewares-rate-limit.yaml

Dedame į /srv/dockers/traefik/rules/middlewares-rate-limit.yaml

http:
  middlewares:
    # DDoS Prevention
    middlewares-rate-limit:
      rateLimit:
        average: 100
        burst: 50


middlewares-secure-headers.yaml

Dedame į /srv/dockers/traefik/rules/middlewares-secure-headers.yaml

http:
  middlewares:
    ################################################################
    # Good Basic Security Practices
    ################################################################
    middlewares-secure-headers:
      headers:
        accessControlAllowMethods:
          - GET
          - OPTIONS
          - PUT
        accessControlMaxAge: 100
        hostsProxyHeaders:
          - "X-Forwarded-Host"
        stsSeconds: 63072000
        stsIncludeSubdomains: true
        stsPreload: true
        forceSTSHeader: true
        customFrameOptionsValue: "allow-from https:{{env "DOMAINNAME"}}" #CSP takes care of this but may be needed for organizr.
        # customFrameOptionsValue: SAMEORIGIN # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
        contentTypeNosniff: true
        browserXssFilter: true
        # sslForceHost: true # add sslHost to all of the services
        # sslHost: "{{env "DOMAINNAME"}}"
        referrerPolicy: "same-origin"
        permissionsPolicy: "camera=(), microphone=(), geolocation=(), payment=(), usb=()"
        customResponseHeaders:
          X-Robots-Tag: "none,noarchive,nosnippet,notranslate,noimageindex,"
          server: ""
          # https://community.traefik.io/t/how-to-make-websockets-work-with-traefik-2-0-setting-up-rancher/1732
          # X-Forwarded-Proto: "https"


tls-opts.yaml

Dedame į /srv/dockers/traefik/rules/tls-opts.yaml

tls:
  options:
    tls-opts:
      sniStrict: true
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
        - TLS_AES_128_GCM_SHA256
        - TLS_AES_256_GCM_SHA384
        - TLS_CHACHA20_POLY1305_SHA256
        - TLS_FALLBACK_SCSV # Client is doing version fallback. See RFC 7507
      curvePreferences:
        - secp521r1 # CurveP521
        - secp384r1 # CurveP384
    mintls13:
      minVersion: VersionTLS13