Search code examples
docker-composerulestraefik

Regex how to match a substring that does not contain a fixed string. Regex in Traefik


I've several containers running in the same page (some.website.com) with traefik and docker-compose, I'm trying to make a rule to forward each request with referrer from a certain subdomain to the same subdomain only if the redirection doesn't have the subdomain on it.

i.e: some.website.com/dolibarr/ I try to login but it sends me to: some.website.com/answer.php?whatever

I've already fixed this with traefik rules, so it sends me to: some.website.com/dolibarr/answer.php?whatever but there are several other sub pages that send me to some.website.com/ so I'd have to make one rule for every one of them.

The traefik rules I already have

labels:
      - "traefik.enable=true"
      - "traefik.backend=dolibarr"
      - "traefik.dolibarr.frontend.rule=Host:${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD};PathPrefixStrip:/${DOLIBARR_PATH}"
      - "traefik.dolibarr_url_fix.frontend.rule=Host:${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD};PathPrefix: /admin, /user, /expensereport, /index.php;HeadersRegexp: referer, ^https://${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}/${DOLIBARR_PATH}/"
      - "traefik.dolibarr_url_fix.frontend.redirect.permanent=true"
      - "traefik.dolibarr_url_fix.frontend.redirect.regex=https://${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}/dolibarr/(.*)"
      - "traefik.dolibarr_url_fix.frontend.redirect.replacement=https://${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}/${DOLIBARR_PATH}/$$1"


the regex should be something like ^((?!dolibarr).)*$ but I cant get it to work with traefik rules

Im trying to do a rule like I explained at the beggining, so it would send me to some.website.com/dolibarr/ only if the referer comes from some.website.com/dolibarr/(.*) and the redirection isn't something with some.website.com/dolibarr/ [to avoid getting some.website.com/dolibarr/dolibarr/]


Solution

  • What you are trying to do is a negative lookahead.

    Traefik is written in Go, therefore uses Go's regex which has no support for negative lookahead as explained here. You'll have to rewrite your regex in a way you don't use it.

    UPDATE: One way to achieve what you are looking for is using priority to avoid infinite loops. Also be carefull with naem collisions, better to use a trailing slash:

    labels:
          - "traefik.enable=true"
          - "traefik.backend=dolibarr"
          - "traefik.dolibarr.frontend.rule=Host:${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}; PathPrefixStrip:/${DOLIBARR_PATH}/"
          - "traefik.dolibarr.frontend.priority=100"
          - "traefik.dolibarr_url_fix.frontend.rule=Host:${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}; HeadersRegexp: referer, ^https://${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}/${DOLIBARR_PATH}/"
          - "traefik.dolibarr_url_fix.frontend.priority=50"
          - "traefik.dolibarr_url_fix.frontend.redirect.permanent=true"
          - "traefik.dolibarr_url_fix.frontend.redirect.regex=https://${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}/(.*)"
          - "traefik.dolibarr_url_fix.frontend.redirect.replacement=https://${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}/${DOLIBARR_PATH}/$$1"
          - "traefik.dolibarr_trail_slash_fix.frontend.rule=Host:${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}; Path:/${DOLIBARR_PATH}"
          - "traefik.dolibarr_trail_slash_fix.frontend.priority=10"
          - "traefik.dolibarr_trail_slash_fix.frontend.redirect.permanent=true"
          - "traefik.dolibarr_trail_slash_fix.frontend.redirect.regex=https://${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}/${DOLIBARR_PATH}"
          - "traefik.dolibarr_trail_slash_fix.frontend.redirect.replacement=https://${SUBDOMAIN}.${DOMAIN_NAME}.${DOMAIN_TLD}/${DOLIBARR_PATH}/"