3

Background

I recently migrated my websites to an all Docker environment using haproxy as the front end load balancer. I have SSL certificates for all domains issued by Let's Encrypt and everything works great. When I enable CloudFlare, everything breaks in an infinite redirect loop.

I've read a few posts saying that using full or strict SSL on CloudFlare will fix the issue, but then CSS, JS, and images fail to load.

Leaving CloudFlare disabled and only using the DNS they provide is the only option I've found where everything works. This is not ideal, because the whole reason I wanted to use Cloudflare was, because of Cloudflare.

I currently have 2 sites hosted on my server: my basic biography page and a site I'm working on for a local church fundraiser.

I'm not sure what I did to the fundraising site, but it's not working at all anymore even after I disabled everything Cloudflare. It's stuck in an infinite loop right now. The good news is that I basically just started on that and can restart if necessary. What's stupid is that in the time it's taken me to write this post, the fundraising site has fixed itself. Maybe due to various caches??

Format

  • bkvaluemeal.net my basic biography page, is some custom PHP that I wrote and hosted in a NGINX container

  • theresianbazaar.tk the church fundraiser is a plain and simple Word Press container

They are all linked together with a haproxy container

Configuration

haproxy.cfg

global
    daemon
    maxconn 100
    pidfile /var/run/haproxy.pid
        stats socket /var/run/haproxy.stat mode 600
    tune.ssl.default-dh-param 4096

defaults
    mode http
    maxconn 50
    timeout client 60s
    timeout server 60s
    timeout queue  60s
    timeout connect 4s
    timeout http-request 5s
    option httpclose
    option abortonclose
    option http-server-close
    balance roundrobin
    option forwardfor
    retries 2

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

    redirect scheme https code 301 if !{ ssl_fc }

    acl host_haproxy hdr_beg(host) -i haproxy.
    acl host_bkvaluemeal hdr(host) -i www.bkvaluemeal.net
    acl host_bkvaluemeal hdr(host) -i bkvaluemeal.net
    acl host_theresianbazaar hdr(host) -i www.theresianbazaar.tk
    acl host_theresianbazaar hdr(host) -i theresianbazaar.tk
    acl letsencrypt path_beg -i /.well-known/acme-challenge/

    use_backend haproxy if host_haproxy
    use_backend bkvaluemeal if host_bkvaluemeal
    use_backend bkvaluemeal if host_bkvaluemeal letsencrypt
    use_backend bkvaluemeal if host_haproxy host_bkvaluemeal letsencrypt
    use_backend theresianbazaar if host_theresianbazaar
    use_backend theresianbazaar if host_theresianbazaar letsencrypt

    default_backend haproxy

frontend https
    bind *:443 ssl crt /ssl
    reqadd X-Forwarded-Proto:\ https

    acl host_haproxy hdr_beg(host) -i haproxy.
    acl host_bkvaluemeal hdr(host) -i www.bkvaluemeal.net
    acl host_bkvaluemeal hdr(host) -i bkvaluemeal.net
    acl host_theresianbazaar hdr(host) -i www.theresianbazaar.tk
    acl host_theresianbazaar hdr(host) -i theresianbazaar.tk
    acl letsencrypt path_beg -i /.well-known/acme-challenge/

    use_backend haproxy if host_haproxy
    use_backend bkvaluemeal if host_bkvaluemeal
    use_backend bkvaluemeal if host_bkvaluemeal letsencrypt
    use_backend bkvaluemeal if host_haproxy host_bkvaluemeal letsencrypt
    use_backend theresianbazaar if host_theresianbazaar
    use_backend theresianbazaar if host_theresianbazaar letsencrypt

    default_backend haproxy

backend bkvaluemeal
    server bkvaluemeal bkvaluemeal:80 check

backend theresianbazaar
    server theresianbazaar theresianbazaar:80 check

backend haproxy
    stats enable
    stats hide-version
    stats uri /

bkvaluemeal.net NGINX default.conf

server {
    server_name bkvaluemeal.net www.bkvaluemeal.net;

    root /www;
    index index.php;

    location / {
        try_files $uri $uri/ = 404;
    }

    location ~ /(includes|lib|res|.htpasswd) {
        deny all;
        return 404;
    }

    location ^~ /admin/ {
        try_files $uri $uri/ = 404;
        auth_basic 'Restricted Content';
        auth_basic_user_file /www/.htpasswd;
    }

    location ~ \.php$ {
        try_files $uri = 404;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/bkvaluemeal/$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $document_root/bkvaluemeal;
    }
}

I hope that I'm not revealing critical information about my setup to the point where I can get hacked...

Goal

Currently, CloudFlare is disabled for both sites and they are only acting as a DNS. I would like to be able to use CloudFlare in its entirety for both sites without experiencing an infinite redirect loop.

Updates

  • As suggested by @Jules, I have removed the redirect in haproxy and enabled CloudFlare's Full (Strict) SSL on both sites. My personal site works just fine, but the promotional site is stuck in an infinite loop now. The statistics page for haproxy has shown zero requests since I made the changes, but recently has crept up to two.

  • I decided to try the Word Press login page. While it did fail to connect, my Docker Compose stack logged 21 requests. The first was a 301 and the other 20 were 302. All future requests to that URL result in another 21 302 responses.

  • I used curl to map out the craziness that's going on here. I've posted it to pastebin for brevity. https http

  • CloudFlare is disabled for the promotional site as of now. The site is being served directly from my server.

4
  • A redirect loop when using CloudFlare is often triggered by using the Flexible SSL (free) CF option (because the site is served over HTTP between CF and your server, so any "normal" checks for SSL in your site fail). However, in comments below, you state you enabled the strict option and it still failed? Can you please confirm which option you are using?
    – MrWhite
    Mar 19, 2017 at 19:26
  • @w3dk I have confirmed that I am using Full (Strict) SSL from CF with everything else disabled on that crypto page. Is that the intended configuration? Mar 19, 2017 at 19:35
  • Not sure if this will help but I had numerous problems when my host decided to enable Let's Encrypt on my sites that were already going through Cloudflare with 'flexible' article from Clouflare, I had to ask them to disable it on our sites as it was causing numerous problems - I'm on a shared host with no root access
    – zod
    Mar 22, 2017 at 21:44
  • @zod I'm actually hosting this on a VPS, not shared hosting. So, I have complete control over the setup. I don't think the issue is with LE, because my personal site that I custom wrote and run with NGINX is just fine, but rather something with WP, CF or WP+CF specifically. What I noticed was that CF was redirecting secure requests to http and then my server was upgrading them creating a cyclical loop, but an identical setup exists for my personal site and everything is just fine. It's not making much sense, but for the time being until I can figure it out, hosting it without CF is fine. Mar 23, 2017 at 1:23

1 Answer 1

1

Wordpress is the typical culprit in these redirect loops. Make sure it is configured as a https site, otherwise wp will redirect to http and cloudflare redirects to https infinitely.

5
  • You mean to edit both URLs in the settings to use https vs http, right? I did already have that set. Mar 19, 2017 at 18:51
  • Then I would remove the redirects from your server code. If that makes the redirect loop go away then output information about the page request, to see how CF was connecting.
    – Jules
    Mar 19, 2017 at 18:55
  • I commented that line and turned on CF using strict SSL and the problem started again. There is a certificate issued and it says it's from CF. I did the same on my personal site and everything works just fine. Mar 19, 2017 at 19:08
  • Try full instead of strict.
    – Jules
    Mar 19, 2017 at 21:46
  • Have you tried clearing CF cache - clear everything
    – zod
    Mar 27, 2017 at 22:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.