how to use X-Forwarded-Prefix in file backend - http-headers

I'm try to configure traefik with file backend to contact a grafana server in a LXC container.
This is my configuration file:
[file]
# rules
[backends]
[backends.backend2.servers.server1]
url = "http://192.168.255.250:3000"
[frontends]
[frontends.frontend2]
entryPoints = ["http"]
backend = "backend2"
passHostHeader = true
[frontends.frontend2.routes]
[frontends.frontend2.routes.route0]
rule = "PathPrefixStrip: /grafana"
Grafana backend listen on /
So, I can contact http://example.com/grafana but I have a redirection to http://example.com/login which does not work. But http://example.com/grafana/login responding (without css, certainly because grafana seems to use relative url).
According to the documentation :
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.
It seems that I have to use the X-Forwarded-Prefix header but I do not know how to use it (I did not see anything in the documentation). Maybe you can help me solve this problem ?
Regards
jmc

In fact, the problem does not come from traefik. I just forgot to specify the path in /etc/grafana.ini (root_url field). I thought it was not necessary since the incoming query does not contain the path /grafana (because we use PathPrefixStrip). But in fact, grafana needs it to indicate effective url to client.
Regards.
jmc

Related

Apache 2.4 rewriting directory URLs without trailing slash to https://default_site/dir/ instead of preserving domain

This is a relatively recent behavioral change and appears to be related only to requests which include a "Upgrade-Insecure-Requests: 1" request header.
Apache has started rewriting such requests for sites which are HTTP-only to an HTTPS URL using the default site name instead of just adding the / at the end of the requested URL.
Example: URL submitted in browser: http://www.example.com/blah
Intended redirect: 301 to http://www.example.com/blah/
Instead redirects: 301 to https://default.site.configured/blah/
This happens whether it's a named virtual on the same address as the default server or a virtual using a separate address with separate Listen directives.
I understand all the arguments in favor of the idea that everything should always be encrypted and I don't want to get into a debate about that. This site doesn't consider the tradeoffs desirable at this time.
The default site does have SSL and is configured to redirect HTTP->HTTPS, but the www.foo.com site is not configured that way and does not wish to implement SSL at this time.
Is there any way to get Apache 2.4 to disregard that "Upgrade" header and simply rewrite the URL as desired rather than altering the domain name?
After banging on this some more, I finally found the source of my woes.
This happens when you have IP based virtual hosts and did not configure a name for them using the "ServerName" directive.
tl;dr: If you are having this problem, try adding a "ServerName www.example.com" directive within the VirtualHost definition for the site and that should resolve it.
Details:
It does not happen until you encounter a URL that requires a rewrite other than adding a trailing /. (i.e. if you get a request that doesn't contain the "Upgrade-Insecure-Requests: 1" header, it only gets the trailing / added, but if you get one with that header, it also tries to rewrite the protocol to https which triggers the full URL rewrite).
In my case, the default host name had an SSL configuration, so it didn't fall back to HTTP after the rewrite or reject the rewrite as invalid.
YMMV, I did not continue to do an exhaustive test of all permutations once I found the solution.

WebSphere reverse proxy plugin - skipping domains

Hoping someone can give me some advice if possible.
We have a Linux box in our DMZ with the WebSphere plugin. This points to a Windows box running WebSphere Application Server.
httpd config only contains the default virtualhost with no ServerAlias specified. There is a redirect set up in the virtualhost in httpd.conf to forward any requests to service.domain.com to service.domain.com/wascontext1. Plugin-cfg.xml is set up with two uri groups, wascontext1 and wascontext2, but only 1 is actively used.
I want to use the Linux box as a reverse proxy for another application totally separate to WAS. It would have a different domain (i.e. dimsim.domain.com) but point to the same IP.
I was going to add another virtualhost for this but am unsure exactly how the WebSphere plugin will behave with it. From what I understand if I set this up and went to dimsim.domain.com/wascontext1 it would serve the WebSphere content as httpd forwards all requests to the plugin.
Is there a way to tell httpd to not send requests to the WebSphere plugin based on domain name or virtualhost? Or would doing a rewrite on any requests to dimsim.domain.com/wascontext be considered ok?
thanks
jc
EDIT: Thanks for the responses! I'll test changing the virtualhost name in plugin-cfg.xml on our second unused context and let you know how it goes.
A solution that doesn't require plugin-cfg.xml changes: If you use an Apache-based HTTP server, you can conditionally set the per-request variable "skipwas" to short-circuit the WAS Plugin processing.
e.g.
SetEnvIf Host ^dimsim\.domain\.com$ skipwas=1
If you look at the plugin-cfg.xml file, in the first part of the file you will find virtualhostgroup section similar to this:
<VirtualHostGroup Name="default_host">
<VirtualHost Name="*:9080"/>
<VirtualHost Name="*:9443"/>
<VirtualHost Name="*:443"/>
<VirtualHost Name="*:80"/>
</VirtualHostGroup>
just change the Name from * to the required domain name e.g. service.domain.com and then plugin will forward only requests for the service.domain.com hostname.
So something like:
<VirtualHost Name="service.domain.com:80"/>
should work for you.
When a request comes into the web server, it is passed to the WebSphere plugin and then plugin examines the request based on its configuration to determine if it should forward to WebSphere or pass back to the web server for further processing.
The "route" clauses in the plugin-cfg.xml are key to determining what will be forwarded and what will not. A request must match all the values in the route to be forwarded. A route contains virtual hosts, uris and clusters. The request must match one a virtual host from the VirtualHostGroup in the route, a URI from the UriGroup in the route and there must be an available server in the ServerCluster value of the route for the request to be sent to WebSphere.
Note-If you manipulate your plugin-cfg.xml for your setup, be aware that plugin is very sensitive about the format of this configuration and incorrect or invalid entries could cause a crash of the webserver. Be sure to backup the file and test before using in production. Also, if you modify your WebSphere configuration, it could overwrite this file and wipe out your changes.
Sorry for the late response.
covener's answer of setting the following does what I need.
SetEnvIf Host ^dimsim\.domain\.com$ skipwas=1

Redirect Multiple Paths to external URLs

i have a problem redirecting multiple paths with traefik to multiple Destinations.
Because of software legacy reasons i have to redirect some paths behind my application to external urls.
My app is running in rancher and i'm using rancher labels to configure traefik with it:
traefik.enable: 'true'
traefik.app.backend: app
traefik.app.frontend.redirect.entryPoint: https
traefik.app.frontend.rule: 'Host: app.url'
traefik.app.protocol: http
traefik.app.port: '8080'
traefik.support.backend: support
traefik.support.protocol: https
traefik.support.frontend.redirect.regex: ^https?://app.url/support/(.*)
traefik.support.frontend.redirect.replacement: https://other.support.url
traefik.support.port: '8080'
However https://app.url/support does not redirect to https://other.support.url and i got an 404 Error.
If i had only on URL to redirct i'd add an redirect at entrypoint level of https entrypoint.
But like i suggest entrypoint doesn't support multiple redirects.
[entryPoints.https]
address = ":443"
[entryPoints.https.redirect]
regex = "^https://app.url/support"
replacement = "https://other.support.url"
How can i achieve this using latest traefik 1.6.4 and Rancher 1.6.x.
Or is it even possible ?
I don't wan't to use another proxy like nginx only for redirection that adds a lot of complications and i find the configuration with labels very comfortabel and transparent.
Any ideas anyone?
You can move the rules into frontends. Since frontends seem to need a backend defined, just define it even though it will never be called.
[backends]
[backends.fake]
[backends.fake.servers.s1]
url="http://1.2.3.4"
[frontends]
[frontends.r1]
backend = "fake"
[frontends.r1.redirect]
regex = "^http://foo.bar/(.*)"
replacement = "http://mydomain1/$1"
permanent = false
[frontends.r2]
backend = "fake"
[frontends.r2.redirect]
regex = "^http://bar.blech/(.*)"
replacement = "http://mydomain2/$1"
permanent = false

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"

Use https instead of http in urls in templates for static files

Currently we are using the default wirecloud template. But sinde we enabled SSL and redirect every request to the ssl port I would love to change the urls of static ressources to start with https to avoid mixed content warnings.
Is there a simple way to change the urls to always start wit hhttps instead of http?
That's done automatically, except if WireCloud is behind a proxy (so requests comes using HTTP instead of HTTPS). In those cases you can force WireCloud to use https links by adding this line into the settings.py file:
FORCE_PROTO = "https"
See this link for more info.