haproxy redirect scheme https if !$request_uri - redirect

If it's possible to disable https on some url, i try this, but it's not working.
I need a piece of my site without https and redirect
frontend http
bind *:80
mode http
acl folder path_beg -i ^/somefolder/subfolder/.* ^/somefolder/subfolder2/.*
redirect scheme https if !folder
option http-server-close
reqadd X-Forwarded-Proto:\ http
option forwardfor header X-Real-IP
default_backend nodes
frontend https
bind *:443
mode http
option http-server-close
reqadd X-Forwarded-Proto:\ https
option forwardfor header X-Real-IP
default_backend nodes
backend nodes
balance leastconn
server server1 10.10.10.7:80 cookie A check
server server2 10.10.10.8:80 cookie A check

Access list
acl folder path_dir -i /somefolder/subfolder/ /somefolder/subfolder2/
In backend you need rule
redirect scheme https if !folder !{ ssl_fc }
After that - all site has redirect to htts, but if uri contains /somefolder/subfolder/ or /somefolder/subfolder2/ it's be able to connect by http.
In nginx you need add some rules if you wanna redirect https to http
if ( $http_x_forwarded_proto = "https" ) {
rewrite ^/somefolder/subfolder2/ http://domain//somefolder/subfolder2/ permanent;
}

Related

Specific routing for subdomains and wildcard domain on HAProxy

How could I achieve the correcting routing for specific subdomains and then route any domains that doesnt match any of the previous ACLSs?
frontend web_dashs
mode http
bind *:443 ssl crt /etc/ssl/domain/
http-request add-header X-Forwarded-Proto https
redirect scheme https if !{ ssl_fc }
acl domain_a hdr_sub(host) -i a.domain.com
acl domain_b hdr_sub(host) -i b.domain.com
acl wilds hdr(host) -i
# Default Route to normal backends
use_backend backend_a if domain_a
use_backend backend_b if domain_b
use_backend backend_c if wilds
Basically, what i'm trying to do is basically:
a. ----> backend A
b. ----> backend B
*.-----> backend C
Thanks in advance.
ACL is not needed for matching the rest, just use default_backend:
frontend web_dashs
mode http
bind *:443 ssl crt /etc/ssl/domain/
http-request add-header X-Forwarded-Proto https
redirect scheme https if !{ ssl_fc }
acl domain_a hdr_sub(host) -i a.domain.com
acl domain_b hdr_sub(host) -i b.domain.com
use_backend backend_a if domain_a
use_backend backend_b if domain_b
default_backend backend_c

haproxy and 'fixing" host names in http requests

I'm starting to use haproxy to balance across nginx servers (in order to load balance the rails instances behind those nginxen). I want to 301 redirect all names that aren't the www name to the www name (and all http -> https). So I write this, which doesn't quite work. What actually happens is that http -> https, but all the names on https return 200 rather than 301 for all but www.staging.example.com. In addition, I was hoping to 301, say http://staging.example.com/ directly to https://www.staging.example.com/, but instead it just 301's to https://staging.example.com/
frontend www-http
bind 1.2.3.4:80
acl redirect_canonical req_ssl_sni -i staging.example.com
acl redirect_canonical req_ssl_sni -i myname.example.com
http-request redirect code 301 location https://www.staging.example.com%[capture.req.uri] if\
redirect_canonical
http-request redirect code 301 scheme https if !{ ssl_fc }
reqadd X-Forwarded-Proto:\ http
default_backend railswebapp-backend
frontend www-https
bind 1.2.3.4:443 ssl crt /etc/haproxy/ssl/
# Test URI to see if its a letsencrypt request.
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl
acl redirect_canonical req_ssl_sni -i staging.example.com
acl redirect_canonical req_ssl_sni -i myname.example.com
http-request redirect code 301 location https://www.staging.example.com%[capture.req.uri] if\
redirect_canonical
reqadd X-Forwarded-Proto:\ https
default_backend railswebapp-backend
Any pointers on what I'm doing wrong?
Update
The corrected block is this:
frontend www-http
bind 1.2.3.4:80
acl redirect_canonical hdr(host) -i staging.example.com
acl redirect_canonical hdr(host) -i myname.example.com
http-request redirect code 301 location https://www.staging.example.com%[capture.req.uri] if\
redirect_canonical
http-request redirect code 301 scheme https if !{ ssl_fc }
reqadd X-Forwarded-Proto:\ http
default_backend railswebapp-backend
frontend www-https
bind 1.2.3.4:443 ssl crt /etc/haproxy/ssl/
# Test URI to see if its a letsencrypt request.
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl
acl redirect_canonical ssl_fc_sni -i staging.example.com
acl redirect_canonical ssl_fc_sni -i myname.example.com
http-request redirect code 301 location https://www.staging.example.com%[capture.req.uri] if\
redirect_canonical
reqadd X-Forwarded-Proto:\ https
default_backend railswebapp-backend

HAProxy not redirecting http to https (ssl)

I'm using HAProxy for load balancing and only want my site to support https. Thus, I'd like to redirect all requests on port 80 to port 443.
How would I do this?
Edit: We'd like to redirect to the same url on https, preserving query params. Thus, http://foo.com/bar would redirect to https://foo.com/bar
frontend httpfront
mode http
bind *:80
redirect scheme https code 301 if !{ ssl_fc }
You need configure frontend for 443 port.
frontend (port 80) -> frontend (port 443) -> backend
Check my example:
frontend httpfront
mode http
bind *:80
redirect scheme https code 301 if !{ ssl_fc }
frontend httpsfront
mode tcp
bind *:443
default_backend app
backend app
mode tcp
balance roundrobin
server server01 10.10.10.11:443 check
server server02 10.10.10.12:443 check

HAProxy redirect based on path?

I need to redirect certain paths to https - frontend secured
The reason for this is that i want certain parts of my web application to only be allowed to run over https.
I've figured out how to redirect all traffic by changing my HAproxy conf like this:
frontend unsecured *:80
#timeout client 86400000
#redirect prefix http://domain.com code 301
mode http
timeout client 120s
But how can i configure it to only redirect certain sub-folder on my domain?
What i would like is to redirect only the following URLs:
http://domain.com/info
http://domain.com/echo
http://domain.com/broadcast
http://domain.com/close
http://domain.com/probe
http://domain.com/cd* (wildcard)
Is this possible?
You should use acl to match you criteria.
frontend unsecured *:80
acl is-unsecure-path01 path_beg /info
acl is-unsecure-path02 path_beg /echo
acl is-unsecure-path03 path_beg /broadcast
acl is-unsecure-path04 path_beg /close
acl is-unsecure-path05 path_beg /probe
acl is-unsecure-path06 path_beg /cd
use_backend application-backend if is-unsecure-path01
use_backend application-backend if is-unsecure-path02
use_backend application-backend if is-unsecure-path03
use_backend application-backend if is-unsecure-path04
use_backend application-backend if is-unsecure-path05
use_backend application-backend if is-unsecure-path06
backend application-backend
redirect scheme https if !{ ssl_fc }
This one should do the trick
frontend http
bind *:80
acl is-secure path_reg ^\/(info|echo|close|cd.*)
redirect scheme https code 301 if is-secure !{ ssl_fc }
use_backend the-app unless is-secure
frontend https
bind *:443 ssl crt /usr/local/etc/haproxy/ssl
use_backend the-app
backend the-app
server account-1 account:80 check
NOTE: Change the SSL cert path on your app.

haproxy acl not working in https/tcp mode

I am experiencing some problems, it seems I can't get acl's to work in tcp mode, everything works in http mode.
Here is my config.
frontend http *:80
acl http_test_acl path_beg -i /test
use_backend http_test if http_test_acl
default_backend http_default
backend http_test
balance roundrobin
server httptest 10.10.10.10:80 check
backend http_default
balance roundrobin
server httpdefault 10.10.10.10:80 check
############# HTTPS #################
frontend https *:443
mode tcp
acl https_test_acl path_beg -i /test
use_backend https_test if https_test_acl
default_backend https_default
backend https_test
mode tcp
balance roundrobin
server httpstest 10.10.10.10:443 check
backend https_default
mode tcp
balance roundrobin
server httpsdefault 10.10.10.10:443 check
Don't pay attention to ip 10.10.10.10 as I have hidden my orginal one. Could you please let me know why https is not working, http frontend/backend acl rules are working just fine.
cheers
Cause your https servers are in tcp mode (as they should be for ssl), so a layer 7 rule wont work.
for acl to work, disable tcp mode then set up ssl on the servers on your backend(hence the ssl keyword)
frontend https *:443
acl https_test_acl path_beg -i /test
use_backend https_test if https_test_acl
default_backend https_default
backend https_test
balance roundrobin
server httpstest 10.10.10.10:443 ssl check
backend https_default
balance roundrobin
server httpsdefault 10.10.10.10:443 ssl check
Alternatively instead of having to setup ssl on both your backend servers; use private IPS in the backend servers and make sure ports on the backend servers arent open to the world
backend https_test
balance roundrobin
server httpstest some_private_ip:8000 check