[SOLVED] IngressRoute ratelimit not working

I want to specify ratelimit to specific api endpoints which includes login, verification, reset, version but anything else shouldn't have any ratelimit.

So I created following IngressRoute

IngressRoute
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: api-external-0                            #Everything Else
  namespace: dev-ethernet
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - kind: Rule
      match: Host(`api.dev.example.com`)
      services:
        - name: nginx
          port: 80
          strategy: RoundRobin
      middlewares:
        - name: https-redirect
          namespace: dev-ethernet
  tls:
    secretName: dev-cert

---

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: api-external-1
  namespace: dev-ethernet
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - kind: Rule
      match: Host(`api.dev.example.com`) && PathPrefix(`/api/v1/user/`)
      services:
        - name: nginx
          port: 80
          strategy: RoundRobin
      middlewares:
        - name: redirect-ratelimit
          namespace: dev-ethernet
  tls:
    secretName: dev-cert

---

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: api-external-2
  namespace: dev-ethernet
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - kind: Rule
      match: Host(`api.dev.example.com`) && PathPrefix(`/api/v1/login/`)
      services:
        - name: nginx
          port: 80
          strategy: RoundRobin
      middlewares:
        - name: redirect-ratelimit
          namespace: dev-ethernet
  tls:
    secretName: dev-cert

---

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: api-external-3
  namespace: dev-ethernet
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - kind: Rule
      match: Host(`api.dev.example.com`) && PathPrefix(`/api/v1/agreement/`)
      services:
        - name: nginx
          port: 80
          strategy: RoundRobin
      middlewares:
        - name: redirect-ratelimit
          namespace: dev-ethernet
  tls:
    secretName: dev-cert

---

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: api-external-4
  namespace: dev-ethernet
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - kind: Rule
      match: Host(`api.dev.example.com`) && PathPrefix(`/api/v1/user/reset-password/request`)
      services:
        - name: nginx
          port: 80
          strategy: RoundRobin
      middlewares:
        - name: redirect-ratelimit
          namespace: dev-ethernet
  tls:
    secretName: dev-cert

---

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: api-external-5
  namespace: dev-ethernet
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - kind: Rule
      match: Host(`api.dev.example.com`) && PathPrefix(`/api/v1/user/([a-z0-9]+-[a-z0-9]+-[a-z0-9]+-[a-z0-9]+-[a-z0-9]+)/verify/\?code=([0-9]+)`)
      services:
        - name: nginx
          port: 80
          strategy: RoundRobin
      middlewares:
        - name: redirect-ratelimit
          namespace: dev-ethernet
  tls:
    secretName: dev-cert

---

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: api-external-6
  namespace: dev-ethernet
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - kind: Rule
      match: Host(`api.dev.example.com`) && PathPrefix(`/api/v1/build_version`)
      services:
        - name: nginx
          port: 80
          strategy: RoundRobin
      middlewares:
        - name: redirect-ratelimit
          namespace: dev-ethernet
  tls:
    secretName: dev-cert

I have Middleware

Middleware
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: redirect-ratelimit
  namespace: dev-ethernet
spec:
  chain:
    middlewares:
    - name: https-redirect
    - name: ratelimit-api

---

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: https-redirect
  namespace: dev-ethernet
spec:
  redirectScheme:
    scheme: https
    permanent: true

---

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: ratelimit-api
  namespace: dev-ethernet
spec:
  rateLimit:
      period: 1m
      average: 8
      burst: 5

With this setup for endpoint api.dev.example.com/api/v1/build_version I get Too Many Requests on 5th request hit from same IP, which is as expected.
But for endpoint api.dev.example.com/api/v1/login I don't see rate-limit is working at all.

What I am missing here ?

Hello @rp346

Would you please try to use Path instead of PathPrefix? I suspect that the request doesn't match the matching rule.

Referring to our documentation my assumption can make sense.

Use Path if your service listens on the exact path only. For instance, Path: /products would match /products but not /products/shoes .

Use a *Prefix* matcher if your service listens on a particular base path but also serves requests on sub-paths. For instance, PathPrefix: /products would match /products but also /products/shoes and /products/shirts . Since the path is forwarded as-is, your service is expected to listen on /products .

https://doc.traefik.io/traefik/routing/routers/#rule

Thank you,

Hi,

I updated with following following in IngressRoute

Host(`api.dev.example.com`)
Host(`api.dev.example.com`) && PathPrefix(`/api/v1/user/`)
Host(`api.dev.example.com`) && Path(`/api/v1/login/`)
Host(`api.dev.example.com`) && Path(`/api/v1/agreement/`)
Host(`api.dev.example.com`) && Path(`/api/v1/user/reset-password/request`)
Host(`api.dev.example.com`) && Path(`/api/v1/user/([a-z0-9]+-[a-z0-9]+-[a-z0-9]+-[a-z0-9]+-[a-z0-9]+)/verify/\?code=([0-9]+)`)
Host(`api.dev.example.com`) && Path(`/api/v1/build_version`)

But there is no difference. I still don't see rate-limit on /api/v1/login/

I was able to get it working with following

Host(`api.dev.example.com`) && PathPrefix(`/api/v1/user/`)
Host(`api.dev.example.com`) && Path(`/api/v1/login`, `/api/v1/agreement`, `/api/v1/user/reset-password/request`, `/api/v1/user/([a-z0-9]+-[a-z0-9]+-[a-z0-9]+-[a-z0-9]+-[a-z0-9]+)/verify/\?code=([0-9]+)`, `/api/v1/build_version`)

@jakubhajek thanks for pointing out Path .

1 Like

Congrats! Glad to hear that you solved the issue! :wave:

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.