maxlerebourg / crowdsec-bouncer-traefik-plugin

Traefik plugin for Crowdsec - WAF and IP protection

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Config] K8S - Unknown plugin type

jLemmings opened this issue Β· comments

Describe the bug πŸ›
The plugin is loaded according to the traefik debug logs:

{"level":"debug","msg":"loading of plugin: crowdsec-bouncer-traefik-plugin: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin@v1.1.11","time":"2023-04-14T14:45:31+02:00"}

All routers then report that the plugin "bouncer" is unknown:

{"entryPointName":"websecure","level":"error","msg":"plugin: unknown plugin type: bouncer","routerName":"paperless-paperless-ingress-bd6074e47e859bbe5ad9@kubernetescrd","time":"2023-04-14T14:45:32+02:00"}

Expected behavior πŸ‘€
The plugin type should be known as the plugin is loaded.

Context πŸ”Ž
See "To Reproduce"

Version (please complete the following information):

  • OS: Ubuntu + RKE2 (Kubernetes)
  • Traefik version: 2.9.9
  • Plugin version: 1.1.11
  • Redis : No

To Reproduce


kind: Deployment
apiVersion: apps/v1
metadata:
  name: traefik-deployment
  namespace: traefik
  labels:
    app: traefik
spec:
  replicas: 3
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-account
      terminationGracePeriodSeconds: 60
      containers:
        - name: traefik
          image: traefik:v2.9.10
          env:
            - name: TZ
              value: Europe/Zurich
          volumeMounts:
          - name: varlog
            mountPath: /var/log
          args:
            - --global.sendanonymoususage=false
            - --global.checknewversion=false
            - --entryPoints.web.proxyProtocol.trustedIPs=192.168.1.0/24
            - --entryPoints.web.proxyProtocol.insecure=true
            # https
            - --entryPoints.websecure.proxyProtocol.trustedIPs=192.168.1.0/24
            - --entryPoints.websecure.proxyProtocol.insecure=true
            - --api.dashboard=true
            - --api.insecure=false
            - --entrypoints.web.address=:80/tcp
            - --entrypoints.websecure.address=:443/tcp
            - --entrypoints.websecure.http.middlewares=traefik-default-secure-traefik@kubernetescrd
            - --entrypoints.traefik.address=:9000/tcp
            - --providers.kubernetescrd
            - --providers.kubernetescrd.ingressclass=traefik-external
            - --providers.kubernetescrd.allowCrossNamespace=true
            - --providers.kubernetesingress
            - --entrypoints.web.http.redirections.entryPoint.to=:443
            - --entrypoints.web.http.redirections.entryPoint.scheme=https
            - --entrypoints.websecure.http.tls=true
            - --serversTransport.insecureSkipVerify=true
            - --log.format=json
            - --log.level=DEBUG
            - --accesslog=true
            - --accesslog.filepath=/var/log/access.log
            - --accesslog.fields.names.StartUTC=drop
            - --accesslog.format=json
            - --experimental.plugins.crowdsec-bouncer-traefik-plugin.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
            - --experimental.plugins.crowdsec-bouncer-traefik-plugin.version=v1.1.11
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
            - name: websecure
              containerPort: 443
              protocol: TCP
            - name: traefik
              containerPort: 9000
              protocol: TCP
        - name: traefik-access-log
          image: busybox:1.28
          args: [/bin/sh, -c, 'tail -n+1 -F /var/log/access.log']
          volumeMounts:
          - name: varlog
            mountPath: /var/log
      volumes:
      - name: varlog
        emptyDir: {}
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: default-secure-traefik
  namespace: traefik
spec:
  chain:
    middlewares:
    - name: default-header
    - name: errorpage-nginx-middleware
      namespace: errorpage
    - name: bouncer
      namespace: crowdsec
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: bouncer
  namespace: crowdsec
spec:
  plugin:
    bouncer:
      enabled: "true"
      logLevel: DEBUG
      crowdsecMode: live
      crowdsecLapiScheme: http
      crowdsecLapiHost: crowdsec-service.crowdsec.svc.cluster.local:8080
      CrowdsecLapiKey: MY-SECRET-API

Deployed Crowdsec with the Helm chart and following values:

container_runtime: containerd
tls:
  enabled: true
  bouncer:
    secret: "traefik-certificate"
agent:
  tolerations:
    - key: node-role.kubernetes.io/control-plane
      operator: Equal
      effect: NoSchedule
  # Specify each pod whose logs you want to process
  acquisition:
    # The namespace where the pod is located
    - namespace: traefik
      # The pod name
      podName: traefik-*
      # as in crowdsec configuration, we need to specify the program name to find a matching parser
      program: traefik
  env:
    - name: PARSERS
      value: "crowdsecurity/cri-logs"
    - name: COLLECTIONS
      value: "crowdsecurity/traefik"
  persistentVolume:
    config:
      enabled: false
lapi:
  dashboard:
    enabled: true
  persistentVolume:
    config:
      enabled: false

Apply above manifest to a cluster and let all pods be created (ignore the other two middlewares). All pods will start but Traefik will report that the plugin is unknown and no router using it will work. If you remove the bouncer middleware everything works great again.

Some logs:

{"level":"debug","msg":"Propagating new UP status","time":"2023-04-14T14:45:31+02:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"tracing","middlewareType":"TracingForwarder","msg":"Added outgoing tracing middleware sonarr-sonarr-ingress-486104bc5adb2e24936e","routerName":"sonarr-sonarr-ingress-486104bc5adb2e24936e@kubernetescrd","time":"2023-04-14T14:45:31+02:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"traefik-default-whitelist@kubernetescrd","middlewareType":"IPWhiteLister","msg":"Creating middleware","routerName":"sonarr-sonarr-ingress-486104bc5adb2e24936e@kubernetescrd","time":"2023-04-14T14:45:31+02:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"traefik-default-whitelist@kubernetescrd","middlewareType":"IPWhiteLister","msg":"Setting up IPWhiteLister with sourceRange: [192.168.1.0/24]","routerName":"sonarr-sonarr-ingress-486104bc5adb2e24936e@kubernetescrd","time":"2023-04-14T14:45:31+02:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"traefik-default-whitelist@kubernetescrd","msg":"Adding tracing to middleware","routerName":"sonarr-sonarr-ingress-486104bc5adb2e24936e@kubernetescrd","time":"2023-04-14T14:45:31+02:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"traefik-default-secure-traefik@kubernetescrd","middlewareType":"Chain","msg":"Creating middleware","routerName":"sonarr-sonarr-ingress-486104bc5adb2e24936e@kubernetescrd","time":"2023-04-14T14:45:31+02:00"}
{"entryPointName":"websecure","level":"error","msg":"plugin: unknown plugin type: bouncer","routerName":"sonarr-sonarr-ingress-486104bc5adb2e24936e@kubernetescrd","time":"2023-04-14T14:45:31+02:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"pipelining","middlewareType":"Pipelining","msg":"Creating middleware","routerName":"errorpage-errorpage-nginx-ingress-ecdfac5635deacb1b36d@kubernetescrd","serviceName":"errorpage-errorpage-nginx-ingress-ecdfac5635deacb1b36d","time":"2023-04-14T14:45:31+02:00"}
{"entryPointName":"websecure","level":"debug","msg":"Creating load-balancer","routerName":"errorpage-errorpage-nginx-ingress-ecdfac5635deacb1b36d@kubernetescrd","serviceName":"errorpage-errorpage-nginx-ingress-ecdfac5635deacb1b36d","time":"2023-04-14T14:45:31+02:00"}
{"entryPointName":"websecure","level":"debug","msg":"Creating server 0 http://10.42.4.60:80","routerName":"errorpage-errorpage-nginx-ingress-ecdfac5635deacb1b36d@kubernetescrd","serverName":0,"serviceName":"errorpage-errorpage-nginx-ingress-ecdfac5635deacb1b36d","time":"2023-04-14T14:45:31+02:00"}
{"level":"debug","msg":"child http://10.42.4.60:80 now UP","time":"2023-04-14T14:45:31+02:00"}
{"level":"debug","msg":"Propagating new UP status","time":"2023-04-14T14:45:31+02:00"}
{"entryPointName":"websecure","level":"debug","msg":"Creating server 1 http://10.42.1.41:80","routerName":"errorpage-errorpage-nginx-ingress-ecdfac5635deacb1b36d@kubernetescrd","serverName":1,"serviceName":"errorpage-errorpage-nginx-ingress-ecdfac5635deacb1b36d","time":"2023-04-14T14:45:31+02:00"}
{"level":"debug","msg":"child http://10.42.1.41:80 now UP","time":"2023-04-14T14:45:31+02:00"}
{"level":"debug","msg":"Still UP, no need to propagate","time":"2023-04-14T14:45:31+02:00"}

What did I miss while setting up the plugin?

Hey, thanks for the detailed informations,
I will take a look during the weekend and get back to you

I have found the issue and it is totally my fault. Traefik sets the plugin name based on those two lines:

            - --experimental.plugins.crowdsec-bouncer-traefik-plugin.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
            - --experimental.plugins.crowdsec-bouncer-traefik-plugin.version=v1.1.11

The above example sets the plugin to "crowdsec-bouncer-traefik-plugin" and in the Middleware I tried to access the plugin "bouncer". Knowing the way Traefik loads plugins the issue is obvious.

Sorry for opening this issue.

Hey @jLemmings Thanks for the feedback, glad to know it works now.

I'm pretty sure this will help someone else searching finding the same config mistake.

If you like the plugin, please consider starring at it so you can get updates when new releases are out.

Best,
Mathieu