Traefik rewrite URI while keeping query string - traefik

In Traefik 1.7 I would like to rewrite:
https://example.com/?uuid=1234
to
https://example.com/foo/bar/?uuid=1234
I'm using something like this in a docker-compose file
labels:
- traefik.frontend.redirect.regex=^https?://example.com/$$
- traefik.frontend.redirect.replacement=https://example.com/foo/bar/
Which only works without the query string. How do I get it to work with a query string?

Related

Traefik URL rewrite from subdomain A to subdomain B

I would like to get all requests from subdomain subdomainA.domain.io to subdomainB.domain.io with URL replace. I specifically do not want to have a redirect as I want to keep the original URL. Is that possible with replace?
I have tried replacePathRegex, but even the most straight up case doesn't seem to work (I have a second reverse proxy, used for identity, that doesn't recognize the new URL).
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-replaceregex
spec:
replacePathRegex:
regex: https://subdomainA.domain.io/graphql
replacement: https://subdomainB.domain.io/graphql
Is this possible in traefik (k8s) and if yes what needs to be done?

Can I use "redirect.regex" and "redirect.replacement"? to redirect from mysite.com to my-site.com?

I'm trying to redirect all traffic from mysite.com to my-site.com. I'd like to do this with Traefik, if possible.
- traefik.frontend.redirect.regex=^https?://(?:www.)?.mysite.([a-z.]+)
- traefik.frontend.redirect.replacement=https://www.my-site.$$1
- traefik.frontend.rule=HostRegexp:www.my-site.{tld:[a-z.]+}
The documentation for redirect.regex and redirect.replacement is a little unclear to me :
Redirects to another URL to this frontend.
Before a match (redirect.regex) is made, do I still need to match the request with rule first - in order to qualify that request to be tested against redirect.regex?
Is what I am trying to achieve doable with regex and replacement?

Traefik path based routing in kubernetes ingress not working as expected

I am trying to use the path based routing mechanism provided by Traefik ingress controller in Kubernetes but I have some issues with the url rewriting.
My [UPDATED] configuration is as follow
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/auth-type: "basic"
traefik.ingress.kubernetes.io/auth-tls-insecure: "true"
traefik.ingress.kubernetes.io/frontend-entry-points: "http,https"
traefik.ingress.kubernetes.io/app-root: "/"
traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"
traefik.ingress.kubernetes.io/rewrite-target: "/"
name: webapp-ingress
namespace: my-company
spec:
rules:
- host: local-ubuntu
- http:
paths:
- path: /
backend:
serviceName: webapp
servicePort: 80
- path: /db
backend:
serviceName: db-manager
servicePort: 8081
The traffic is routed to the right services but the url is still prefixed with /db when I look at the log for the db-manager (kubernetes) service.
What I would have expected with the PathPrefixStrip is that the traffic will be routed without the /db prefix to the container running the db-manager micro-service which is listening on / (http://db-manager:8081) on the backend side.
Am I missing something ? Is it supported by traefik or only nginx ?
Thank you by advance for your feedback.
[EDIT]
To be more specific I observe the following with the current annotations discussed below
traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"
traefik.ingress.kubernetes.io/rewrite-target: "/"
URL: http://local-ubuntu/db [OK] -> 200
Then other resources are loading but are pointing on the wrong base url
Example:
Resource URL is : http://local-ubuntu/public/css/bootstrap.min.css
But this should be : http://local-ubuntu/db/public/css/bootstrap.min.css
(which works when I've tried manually)
I am not sure what I am missing here in the current configuration.
Regarding the static contents not being served, the documentation states the following:
Use a *Strip matcher if your backend listens on the root path (/) but should be routeable on a specific prefix. For instance, PathPrefixStrip: /products would match /products but also /products/shoes and /products/shirts.
Since the path is stripped prior to forwarding, your backend is expected to listen on /.
If your backend is serving assets (e.g., images or Javascript files), chances are it must return properly constructed relative URLs.
Continuing on the example, the backend should return /products/shoes/image.png (and not /images.png which Traefik would likely not be able to associate with the same backend).
The X-Forwarded-Prefix header (available since Traefik 1.3) can be queried to build such URLs dynamically.
Thank you very much for your help in this matter.
First of all I had to fix an issue regarding the formatting of the annotations in the yaml file.
All the instructions with traefik as a prefix need to be double quoted
Example :
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip [Not
correct]
traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"
[correct]
In the first case none of the annotations were reflected in the ingress.
But I still cannot route properly the traffic.
With the current configuration only the resource served on / is returned.
None of the js, css or other resources are loaded.
So I wonder if I need to use the traefik.frontend.redirect.regex instruction.
Try with one of the following:
traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"
traefik.ingress.kubernetes.io/rewrite-target: "/
They both achieve similar results, but they are different, and they have slightly different behavior.
I would read more on our documentation for the differences: (https://docs.traefik.io/v1.7/configuration/backends/kubernetes/#general-annotations)
As for your second issue:
Resource URL is : local-ubuntu/public/css/bootstrap.min.css
But this should be : local-ubuntu/db/public/css/bootstrap.min.css (which works when I've tried
You stripped that path from the request...your DB service never sees the DB prefix...How is it supposed to know to add them back in?
You need to set a root URL in your web application to handle the stripped path.
Once you do that, you may not even need to strip the path at all, and just leave it as is. If you cannot set a base URL for your application, you may not be able to use directories for routing, and may have to use subdomains instead.
use only traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
Bellow what I used to send only subpath to my k8s pods
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: global-ingress
namespace: app
annotations:
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip

VueJS router history mode with Traefik

I need to do rewrite a URL of my application like this: https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations
I'm using Traefik as a reverse proxy and Docker Compose.
Here is my raw configuration in Docker:
application:
build: ./domain.app
volumes:
- ./domain.app/dist:/app
networks:
- net
labels:
- "traefik.frontend.rule=Host:domain.me"
- "traefik.port=8081"
- "traefik.backend=domain.me"
- "traefik.frontend.entryPoints=http,https"
With that configuration:
https://domain.me is working
https://domain.me/anything returns 404
How can I fix this rewrite rule?
For vue.js router history mode you want to catch all Routes that do not point to a resource on the server and forward them to your index.html. For Example:
https://example.com --> /index.html
https://example.com/route/to/subsite --> /index.html
But you still want to be able to access resources that are on the server. E.g.:
https://example.com/path/to/kitten.jpg --> /path/to/kitten.jpg not /index.html
In order to do that you have to find a Backend Server supporting Catch-All Fallback. You can use the ones noted in the vue.js Guide (Apache, Nginx, Node, IIS)
Why can't I use traefik for this?
As stated above you still want to be able to serve static resources. But traefik is just a router. It does only has access to the information of the request, not to the information of the server. But in order to decide if to serve the index.html or the static resource you must have access to the resources.
You could route all the traffic to the index.html using Traefik's PathPrefixStripRegex:but this would result in serving index.html for every request, even if you would have wanted kitten.jpg.

How to combine PathPrefixStrip with Redirect:Regex?

My configuration looks like this:
frontend
traefik.frontend.rule=Host:my.domain;PathPrefixStrip:/mypath/
traefik param
--entrypoints="Name:http Address::80 Redirect.EntryPoint:https Redirect.Regex:http://my.domain/(.*)$ Redirect.Replacement:https://my.domain/$1 Redirect.Permanent:true"
My goal is to redirect HTTP requests on a given path to its HTTPS endpoint. However, the path prefix removal seems to be happening before the "main" redirect.regex/replacement logic, which is breaking some requests. For example:
http://my.domain/mypath/v1/foo
Will become:
https://my.domain/v1/foo
While I expected it to be:
https://my.domain/mypath/v1/foo
Anyway to workaround this issue?
Please note that regex and replacement do not have to be set in the redirect structure if an entrypoint is defined for the redirection (they will not be used in this case).
https://docs.traefik.io/v1.5/configuration/entrypoints/#redirect-http-to-https
Note also that Redirect.Permanent:true come in 1.6
Try something like that:
--entrypoints="Name:http Address::80 Redirect.Regex:http://my.domain/(.*)$ Redirect.Replacement:https://my.domain/mypath/$1 Redirect.Permanent:true"