Traefik

Iš Žinynas.
22:27, 2 gruodžio 2024 versija, sukurta \dev\null (Aptarimas | indėlis)
(skirt) ← Ankstesnė versija | Dabartinė versija (skirt) | Vėlesnė versija → (skirt)
Jump to navigation Jump to search

Traefik yra atvirojo kodo atvirkštinis tarpinis serveris (reverse proxy) ir apkrovos balansavimo sprendimas, sukurtas specialiai modernioms debesijos aplikacijoms. Jis yra skirtas valdyti tinklo srautą konteinerizuotose ir dinamiškai keičiamose sistemose, tokiose kaip Docker, Kubernetes, ir kitos platformos.

Pagrindinės savybės:

  1. Automatinė konfigūracija: Traefik automatiškai aptinka paslaugas jūsų infrastruktūroje ir pritaiko tinklo taisykles, remdamasis jų aprašymais (pvz., Docker Compose arba Kubernetes manifestais).
  2. SSL/TLS palaikymas: Jis integruojasi su Let's Encrypt sertifikatų išdavimu, todėl automatiškai gali generuoti ir atnaujinti SSL sertifikatus.
  3. Dinamiškumas: Geba aptikti pasikeitimus infrastruktūroje be poreikio rankiniu būdu atnaujinti konfigūraciją.
  4. Palaikymo protokolai: Palaiko HTTP, HTTPS, TCP, UDP protokolus.
  5. Integracijos: Lengvai integruojamas su populiariais įrankiais, tokiais kaip Docker, Kubernetes, Rancher, Nomad ir kt.
  6. Stebėjimas ir analizė: Turi įmontuotą vartotojo sąsają (dashboard) stebėti srautą bei patikrinimams atlikti.

Traefik ypač naudingas kuriant mikroservisų architektūras ir naudojant konteinerių orkestravimo sistemas. Tai efektyvus sprendimas, kuris sumažina tinklo konfigūravimo sudėtingumą ir leidžia greičiau diegti aplikacijas debesų aplinkoje.

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