Netflix Zuul stop redirecting / enable reverse-proxy - reverse-proxy

I have following Zuul configuration. Also I have disabled Eureka since I have service discovery in place.
server:
port: 7777
ribbon:
eureka:
enabled: false
zuul:
prefix: /api
routes:
yourService:
path: /newpath/**
serviceId: yourService
yourService:
ribbon:
listOfServers: localhost:8080/rest
Now when I hit localhost:7777/api/newpath Zuul does a 302 redirection rather than reverse-proxying transparently. Please advise how to stop this redirection and get Zuul to reverse-proxy transparently.

Try it with trailing slash as it's in the rule:
http://localhost:7777/api/newpath/

Related

traefik redirect http to https with PathPrefix

I have nginx running in a container behind Traefik, and I'm trying to redirect any http to https using Traefik middleware.
If I browse to https://domain-name/website-name I can see my container, but if I browse to http://domain-name/website-name, I get a 404 error.
Below is my config file for website-name:
http:
routers:
entrypoints:
- web
- web-secure
tls: true
rule: "PathPrefix(`/website-name`)"
middlewares:
- "http-redirect"
service: "website-name"
middlewares:
http-redirect:
regex: "http://domain-name/(.*)"
replacement: "https://domain-name/$1"
services:
website-name:
loadBalancer:
servers:
- url: http://website-name:80
Why won't http redirect to https with this setup? It only recognizes https.
For example if I change the http-redirect code to:
http-redirect:
redirectRegex:
regex: "https://domain-name/(.*)"
replacement: "https://$1?test"
This works and redirects https://domain-name/website-name to https://domain-name/website-name?test, but for some reason http won't work.
http://domain-name/website-name gives me a 404 error. And, it is not a 404 error produced by nginx. So it is not even routing to the container.

Traefik as a reverse proxy for S3 Static website

Is there a way to set up Traefik as a reverse proxy for S3 Static website hosting?
I tried by using the file provider as follows:
# http routing section
http:
routers:
# Define a connection between requests and services
to-site:
rule: "PathPrefix(`/site`)"
middlewares:
- site-stripprefix
service: site
middlewares:
site-stripprefix:
stripPrefix:
prefixes:
- "/site"
services:
# Define how to reach an existing service on our infrastructure
site:
loadBalancer:
servers:
- url: http://mysite.s3-website-us-east-1.amazonaws.com
It redirects me to https://aws.amazon.com/s3/.
I can't find a setup example of traefik-v2 , only for Nginx.
After setting up the proxy with Nginx I figure this out.
I think Traefik is much more elegant.
For anyone how will need it:
# http routing section
http:
routers:
# Define a connection between requests and services
to-site:
rule: "PathPrefix(`/site`)"
middlewares:
- site-stripprefix
- site-add-headers
service: site
middlewares:
site-stripprefix:
stripPrefix:
prefixes:
- "/site"
site-add-headers:
headers:
customRequestHeaders:
Host: "mysite"
services:
# Define how to reach an existing service on our infrastructure
site:
loadBalancer:
passHostHeader: false
servers:
- url: http://mysite.s3-website-us-east-1.amazonaws.com

Traefik 2 middleware is working on https, but not http entry points

I'm trying to setup a route do a basic 301 redirect with the added benefit of supporting both HTTP and HTTPS requests. Expected results would be that requests to http://subdom.domain.org or https://subdom.domain.org would receive a 301 and be forwarded to https://othersub.domain.org/route. Actual results is that https://subdom.domain.org 301's as expected, but http://subdom.domain.org 404's. With the config, you can see I've tried doing both an elevate to HTTPS with the hopes that the rule might be caught there, but with the way the middleware is configured, I would expect it would work in either scenario.
Here's my current config:
http:
routers:
subdom.domain.org:
entryPoints:
- web
- web-secure
middlewares:
- https-redirect # I've tried with this on and off
- sudbdom-redirect
service: dummy
rule: Host(`subdom.domain.org`)
tls:
certResolver: letsEncryptResolver
middlewares:
https-redirect:
redirectScheme:
scheme: https
subdom-redirect:
redirectRegex:
regex: ".*"
replacement: "https://othersub.domain.org/route"
permanent: true
services:
dummy:
loadBalancer:
servers:
- url: localhost
I was originally having trouble matching specific regex patterns for the redirect, but in realizing I didn't really need to scope the pattern at all given that I'm applying it per route, a wildcard match seems to work quite well there. Any thoughts or suggestions are appreciated. Thanks!
You should try to make 2 different router one for web entry point where you can perform redirection and 2rd one for redirectRegex where you can redirect your application to different url.
Following TLS section from official documentation:
When a TLS section is specified, it instructs Traefik that the current router is dedicated to HTTPS requests only (and that the router should ignore HTTP (non TLS) requests).
Solutions:
1. Define separate routers (for http and https), but it noisy for multiple services.
If you need to define the same route for both HTTP and HTTPS requests, you will need to define two different routers: one with the tls section, one without.
Example from documentation
2. Disable TLS for router
traefik.http.routers.YOUR-SERVICE.tls=false
Example:
services:
mailhog:
image: mailhog/mailhog
networks:
- traefik-public
deploy:
placement:
constraints:
- node.role != manager
labels:
- "traefik.enable=true"
- "traefik.http.routers.mailhog.rule=Host(`mailhog.somehost.ru`)"
- "traefik.http.routers.mailhog.service=mailhog"
- "traefik.http.routers.mailhog.entrypoints=web,websecure"
# Should be false
- "traefik.http.routers.mailhog.tls=false"
- "traefik.http.middlewares.redirectos.redirectscheme.scheme=https"
- "traefik.http.routers.mailhog.middlewares=redirectos"
- "traefik.http.services.mailhog.loadbalancer.server.port=8025"
- "traefik.tags=traefik-public"
- "traefik.docker.network=traefik-public"

Can traefik rewrite the location header of redirect responses (302)

I am using traefik 2.0.2 as reverse proxy in front of some services. One backend services is returning a redirect response (302), where the location header contains the absolute redirected url. The url of the backend is not reachable from the outside, how can I rewrite the location to go through the reverse proxy again?
E.g. a client requests http://my-domain/foo and receives a 302 response with location header containing http://backend:8080/foo/bar/, which of course will not work.
I am looking for something similar to ProxyPassReverse of apache mod_proxy. I have read through the available middlewares of traefik, but nothing seems to fit my requirement.
My simplified configuration:
# traefik.yml
entryPoints:
web:
address: ":80"
providers:
file:
filename: "dynamic-conf.yml"
# dynamic-conf.yml
http:
routers:
router1:
entryPoints:
- web
service: service1
rule: "PathPrefix(`/foo`)"
services:
service1
loadBalancer:
servers:
- url: http://backend:8080
I did not find an option to rewrite the location header of a service response using traefik.
A feature request to replaceResponseHeaders exists.
My (temporary) solution is to perform the redirection in traefik using the RedirectRegex middleware, such that the backend service does not need to response with a redirect.
The updated configuration would look like this:
# dynamic-conf.yml
http:
routers:
router1:
entryPoints:
- web
service: service1
rule: "PathPrefix(`/foo`)"
middlewares:
- my-redirect
middlewares:
my-redirect: # Workaround for service1 redirection
redirectRegex:
regex: "^https?://[^/]+/foo/?$"
replacement: "/foo/webapp/"
services:
service1
loadBalancer:
servers:
- url: http://backend:8080
I had the same issue as you, could not resolve it with your solution, but now, with the traefik plugins, we can:
Static config:
pilot:
token: "xxxx"
experimental:
plugins:
rewriteHeaders:
modulename: "github.com/XciD/traefik-plugin-rewrite-headers"
version: "v0.0.2"
Dynamic config:
http:
routes:
my-router:
rule: "Host(`localhost`)"
service: "my-service"
middlewares :
- "rewriteHeaders"
services:
my-service:
loadBalancer:
servers:
- url: "http://127.0.0.1"
middlewares:
rewriteHeaders:
plugin:
rewriteHeaders:
header: "Location"
regex: "^http://(.+)$"
replacement: "https://$1"
Disclaimer: I'm the author of the plugin

Setting up https on a server with Phoenix/Elixir and nginx

I know how to setup https for, say, clojure web app with nginx. How to do that for Phoenix?
In the prod.exs I have this:
config :my_app, MyApp.Endpoint,
url: [host: "my_website.com", port: 443],
http: [port: 4000],
# https: [port: 443,
# keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"),
# certfile: System.get_env("SOME_APP_SSL_CERT_PATH")],
cache_static_manifest: "priv/static/manifest.json"
I have this:
ssl_certificate: /etc/letsencrypt/live/my_app.com/fullchain.pem;
ssl_certificate_key: /etc/letsencrypt/live/my_app.com/privkey.pem;
I want to use nginx with Phoenix as well.
1) Should I remove "http: [port: 4000]," compeletely from "prod.exs"?
2) Should I instead uncomment "https: [port: 443,...." ? Or should I have them both? I don't want to website to be accessible at http or I'd let nginx take care of it by redirecting a user from http to https.
3) Or should I remove https and http and let nginx handle that?
4) How about the key "url" and its "port"?
If you are using Nginx to terminate the SSL part of the connection, then you leave the app server configured for HTTP and any port you like (4000 is fine as long as you configure Nginx to forward to it). If your server is configured correctly, it will not answer HTTP port 4000 requests, thus the SSL cannot be bypassed.
The SSL configuration you are referring to at the app server level configures the app server to terminate the SSL connection (no Nginx necessary). Phoenix apps are all "full featured" web servers thanks to cowboy. Thus, they can handle the SSL termination as well as serving the application's dynamic and static assets.
The URL configuration is so your application knows its domain and can generate full urls as well as paths.
If you're set on using nginx in front of your Phoenix app then use nginx to terminate the ssl connection (your option 3). You still need to configure http in Phoenix though since nginx will proxy to your app using http. Therefore:
config :my_app, MyApp.Endpoint,
url: [host: "my_website.com", port: 4000],
http: [port: 4000]
Which assumes you will configure nginx to proxy to your app on port 4000. You will also want to adjust the host config key to be the base url of your site since any URL's you generate will use this base name (as Jason mentioned).