Cannot get "redirect scheme" to work in backend section

Hi, I have a haproxy cluster with two frontends for http and https and many backends which are selected using a domain2backend map.

Some of the backends must be accessed only through HTTPS.

I tried using redirect scheme https code 301 if !{ ssl_fc } in those backends but haproxy seems to be ignoring it.

Configuration excerpt:

global
   maxconn 1024
   debug
   log /sidecar/log local0 debug
   stats socket /var/run/haproxy.sock mode 600 level admin
   stats timeout 2m

defaults
    balance roundrobin
    maxconn 32
    log global
    monitor-uri /haproxy_test

frontend http-in
    bind *:80
    mode http
    option httplog
    option forwardfor
    use_backend %[req.hdr(host),lower,map_dom(/usr/local/etc/haproxy/domain2backend.map)]

frontend https-in
    bind *:443 ssl crt /usr/local/etc/haproxy/ssl
    mode http
    option httplog
    option forwardfor
    http-request add-header X-Proto https if { ssl_fc }
    use_backend %[req.hdr(host),lower,map_dom(/usr/local/etc/haproxy/domain2backend.map)]

backend redmine_www
    redirect scheme https code 301 if !{ ssl_fc }
    server 10.19.12.253:5200 10.19.12.253:5200 check
    server 10.19.11.197:5200 10.19.11.197:5200 check
    server 10.19.13.150:5200 10.19.13.150:5200 check

I am using haproxy version 1.7.3

/ # haproxy -vv
HA-Proxy version 1.7.3 2017/02/28
Copyright 2000-2017 Willy Tarreau <willy@haproxy.org>

Build options :
  TARGET  = linux2628
  CPU     = generic
  CC      = gcc
  CFLAGS  = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement
  OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1

Default settings :
  maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.8
Running on zlib version : 1.2.8
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with OpenSSL version : OpenSSL 1.0.2k  26 Jan 2017
Running on OpenSSL version : OpenSSL 1.0.2k  26 Jan 2017
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 8.39 2016-06-14
Running on PCRE version : 8.39 2016-06-14
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with Lua version : Lua 5.3.3
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND

Available polling systems :
      epoll : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

Available filters :
	[COMP] compression
	[TRACE] trace
	[SPOE] spoe

I have been looking for a solution and trying different options without any success.

I would appreciate any help.

Thanks.

P.S. Also in StackOverflow: http://stackoverflow.com/questions/42699540/haproxy-redirect-scheme-in-backend-not-working

The redirect would probably work, but I don’t think the variable ssl_fc is available in a backend.

Can you verify if it works without the “if !{ ssl_fc }”?

Try accessing the X-Proto header, like
redirect scheme https code 301 if !{ hdr(X-Proto) -m str https }

Hi Lukas, thanks for your time,

I have just tried without the condition and it does not work.

backend redmine_www
    redirect scheme https code 301
    server localhost:3000 127.0.0.1:3000 check

The documentation says that redirect scheme can be used in the backend section. I am out of ideas.

Anything else I can try?

Mmmh, I’m not sure what why this wouldn’t work. Can you try to force “mode http” in the backend?

1 Like

Thanks!!! That solved the issue!

Using mode http in the backend the “redirect” works as supposed. In fact, the variable ssl_fc is available in the backend as I can use if !{ ssl_fc}.

Thanks again for your time!

Ok, great. I suggest putting “mode http” in the default section, that will fix all front and backends.

I have one backend where I need to use mode tcp. I guess that’s the reason why I was not using mode http in the default section. I will review the docs to refresh how the mode keyword is used, defaults,…

Thanks again!.

You can just define “mode tcp” where you need it, it will overwrite the “mode http” default.

1 Like