Haproxy Redirect


#1

Hi guys, Im trying to achieve the following:

I want to serve my index.html from the CDN and set a rule to match /api to my backend services loadbalanced by haproxy.

Right now im using

backend static
    http-request set-header X-Forwarded-For https://<CDN-URL>/static/site/index.html

The problem is that im getting redirected to the CDN-URL. Is there any way to get the content of the file without the URL redirection? Thanks in advance


#2

Hi mattdc -

I’m not sure I understand exactly what you’re trying to do. The first thing to note, however, is that the X-Fowarded-For header is typically used to send the IP address along of the original client (since in a proxyed world, those addresses would be hidden). Additionally, HAProxy is not really a web server in the traditional sense, so there’s no way to ‘get the content of the file’ directly from HAProxy, as I understand your request.

In any case, I think what you want is something more like this - this config is not a complete config:

frontend http-in
  option forwardfor
  use_backend api if { path_beg /api }
  use_backend cdn if { path_end /index.html }
  default_backend cdn

backend api
  server s1 <ip of api server>

backend cdn
  server s1 <ip of cdn>

#3

Hi ahayworth!

Thakns for the reply!!!

Maybe I didn’t explain myself clearly with the “get the contents from the file”. What I’m trying to do is a redirect to CDN & rewrite the URI in order to get the file from the CDN with the initial url

I believe this is the correct way to perform a redirect

frontend http-in
    acl host_client hdr(host) -i <mydomain.com>
    use_backend client if host_client

backend client
    redirect location https://<CDN-URL>/static/site/index.html

But I keep getting redirected to https://<.CDN-URL>/static/site/index.html, instead of having <.mydomain.com>

Since the CDN works with a host header routing, using the IP in this case (server s1 <ip of cdn>) doesnt work for me


#4

Okay - thanks for the explanation. It makes more sense now. Maybe something like:

frontend http-in
  acl host_client hdr(host) -i mydomain.com
  http-request redirect code 301 location https://cdn/static/site/index.html if host_client
  
  default_backend api

backend api
  ...foo

And if you need to more dynamically set the URL for the CDN, you could do that too:

http-request redirect code 301 location https://cdn/static/%[hdr(host)]/index.html if host_client

…or something like that. I would say it’s better to explicitly redirect away from HAProxy in the frontend, rather than trying to coerce a backend into doing what you want.

Hopefully that makes sense!

  • Andrew

#5

Doing:

frontend http-in
    acl host_client hdr(host) -i mydomain.com
    http-request redirect code 301 location https://cdn/static/site/index.html if host_client

Im still getting redirected to https://cdn/static/site/index.html with the CDN URL :disappointed:


#6

I think there’s a lot of context that I don’t have on your config. Can you post the whole config? Can you be more specific about which routes should go where?

:frowning:

  • Andrew

#7

Yes, sorry. This is the entire file (I’m not using the /api yet since I want to make the redirect work correctly first)

global
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    user        root
    group       root
    daemon
    maxconn     10000

    tune.ssl.default-dh-param 2048

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats level admin

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s

frontend www-http
    bind *:80
    reqadd X-Forwarded-Proto:\ http
    default_backend api

frontend www-https
    bind *:443 ssl crt /home/certs/cert.pem

    acl host_client hdr(host) -i <mydomain.com>
    http-request redirect code 301 location https://cdn/static/site/index.html if host_client

    default_backend api

backend api
    redirect scheme https code 301 if !{ ssl_fc }
    cookie SERVERID insert indirect nocache
    server web1 <server ip> check cookie web1

My hope is after I type <.mydomain.com> I get the file from the CDN but with the URL still pointing <.mydomain.com>


#8

Maybe this is closer to what you want:

frontend www-http
    bind *:80
    redirect scheme https code 301 if !{ ssl_fc }
    default_backend api

frontend www-https
    bind *:443 ssl crt /home/certs/cert.pem
    acl host_client hdr(host) -i <mydomain.com>
    http-request set-path /static/foo/bar<put client specific things here> if host_client
    use_backend cdn if host_client
    default_backend api

backend api
    cookie SERVERID insert indirect nocache
    server web1 <server ip> check cookie web1

backend cdn
  server s1 https://cdn/

The idea here is that if it is a specific domain ‘mydomain.com’, we will fetch all requests from the CDN. We will also modify the path to reflect the CDN url. Then we send it to a CDN specific backend.

Otherwise, we consider it an api request and let it go.


#9

Apparently you cant use hostnames on the

  server s1 https://cdn/

The error is [ALERT] 080/181322 (5585) : parsing [/etc/haproxy/haproxy.cfg:60] : 'server s1' : invalid address: 'https' in 'https://cnd'

PS: It could be an api call, but its specifically what Im trying to avoid :smiling_imp:

EDIT: setting server s1 cdn/ gives me a 502 (without the HTTPS)


#10

Of course; how could I forget? Try:
server s1 hostname:443 ssl


#11

Im still hitting a 502 with that config :weary: