Expose service in a path using Marathon-lb - load-balancing

I want to expose on a path
I use HAPROXY_{n}_PATH, according to docs I have to use a VHHOST.
When I use both, I get this:
frontend marathon_http_in
bind *:80
mode http
acl host_foo_bar hdr(host) -i foo.bar.com
acl path_foo_bar path_beg /foo-bar
use_backend foo_bar if host_foo_bar path_foo_bar
What I need is something like this:
frontend marathon_http_in
bind *:80
mode http
acl host_foo_bar hdr(host) -i foo.bar.com
acl path_foo_bar path_beg /foo-bar
use_backend foo_bar if host_foo_bar or path_foo_bar

Related

How to use multi-condition with if in use_backend (Haproxy)?

I am using Haproxy to separate http and https with different domain setting,
but domain limitation with http not working well. My setting as following.
Any idea?
frontend ha_8080
mode tcp
bind *:8080
tcp-request content accept if { req_ssl_hello_type 1 }
tcp-request inspect-delay 100ms
tcp-request content accept if HTTP
acl is_using_ssl req.ssl_hello_type gt 0
acl is_abc hdr_dom(host) -i abc.com
use_backend http_server if !is_using_ssl is_abc #it works and only works on abc.com,
use_backend local_server1 if is_using_ssl is_abc #https will not working
use_backend local_server1 if is_using_ssl #it works, but I need it work only on abc.com
hdr_dom(host) not work for https(ssl).
I should change to using req_ssl_sni.
My final setting as following.
frontend ha_8080
mode tcp
bind *:8080
tcp-request content accept if { req_ssl_hello_type 1 }
tcp-request inspect-delay 100ms
tcp-request content accept if HTTP
acl is_abc hdr_dom(host) -i abc.com
acl is_abc_ssl req_ssl_sni -i abc.com
use_backend http_server if is_abc
use_backend local_server1 if is_abc_ssl

HAProxy unable to redirect to HTTPS when terminating

I wanted to setup HAProxy for two servers - one with passthroug one with termination. I was able to do it with no previous experience of HAProxy, but I am unable to make HTTPS redirect for the terminating one - I get 502. Here is the config:
#Upgrades the passthrough and check for Let's Encrypt
frontend http_front
bind :80
option forwardfor
acl host_s1 hdr(host) -i s1.example.com
acl path_le path_beg -i /.well-known/acme-challenge/
redirect scheme https code 301 if host_s1 !path_le
use_backend acmetool if path_le
default_backend http-back
#Handles the passthrough and loopsback to itself for other domains
frontend passthrough
mode tcp
bind :443
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend service1 if { req_ssl_sni -i s1.example.com }
default_backend https-back
#Loopback to handle the termination domains
frontend https-front
bind 127.0.0.1:8443 ssl crt s2.example.com.pem
option forwardfor
reqdel X-Forwarded-Proto
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
use_backend service2 if { req_ssl_sni -i s2.example.com }
default_backend service2
#returns for second pass from HTTP
backend http-back
server https-front 127.0.0.1:8443
#returns for second pass from HTTPS
backend https-back
mode tcp
server https-front 127.0.0.1:8443
backend service1
mode tcp
server service1 127.0.0.1:8888
backend service2
#redirect scheme https code 301 if !{ ssl_fc }
server server2 server2:80
backend acmetool
server acmetool 127.0.0.1:81
Not sure if I need those reqdel/reqadd in https-front. Or if I have to do tcp-request again on the second pass for HTTPS.
Uncommenting the redirect on the backend does not help either.
I was able to figure it out with some help from the HAProxy community.
Here is the final setup with updated names to better reflect the logic behind each one:
#Upgrades to HTTPS unless it's Let's Encrypt
frontend http
bind :80
option forwardfor
redirect scheme https code 301 if !{ path_beg -i /.well-known/acme-challenge/ }
default_backend acmetool
#Handles the passthrough and loopsback for termination
frontend passthrough
mode tcp
bind :443
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend service1 if { req_ssl_sni -i s1.example.com }
default_backend loopback
#Handles the termination domains on second pass
frontend termination
bind 127.0.0.1:8443 ssl crt s2.example.com.pem
option forwardfor
reqdel X-Forwarded-Proto
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
use_backend service2 if { ssl_fc_sni -i s2.example.com }
default_backend service2
#Loopback for second pass
backend loopback
mode tcp
server https-front 127.0.0.1:8443
backend service1
mode tcp
server service1 127.0.0.1:8888
backend service2
server server2 server2:80
backend acmetool
server acmetool 127.0.0.1:81

How to redirect url using haproxy

I want to redirect https://myserver/myapplication/ to https://myserver.domain.com/myapplication/ using haproxy.
This is my haproxy configuration
frontend LB_http
bind 10.123.122.112:80
reqadd X-Forwarded-Proto:\ http
default_backend LB
frontend LB_https
bind 10.123.122.112:443 ssl crt /usr/local/apache2/conf/server.pem
reqadd X-Forwarded-Proto:\ https
default_backend LB
backend LB
redirect scheme https if !{ ssl_fc }
mode http
stats enable
stats hide-version
stats uri /stats
stats realm Haproxy\ Statistics
stats auth haproxy:redhat # Credentials for HAProxy Statistic report page.
balance roundrobin # Load balancing will work in round-robin process.
option httpchk
option httpclose
option forwardfor
server myserver.domain.com myserver.domain.com:80 # backend server.
I have edited the config file by adding the below two lines
acl no_domain hdr(host) -i myserver
http-request redirect code 301 prefix %[hdr(host)].domain.com%[path] if no_domain
But now, when I try
myserver/myapplication/
the url is redirecting multiple times I guess. It is redirecting me to very long url like this
https://myserver/myapplication/myserver.domain.com/myapplication/myserver.domain.com/myapplication/myserver.domain.com/myapplication/myserver.domain.com/myapplication/myserver.domain.com/myapplication/myserver.domain.com/myapplication/
What am I missing?
I have modified the code as below and it started working as expected
frontend LB_http
bind 10.123.122.112:80
reqadd X-Forwarded-Proto:\ http
default_backend LB
frontend LB_https
bind 10.123.122.112:443 ssl crt /usr/local/apache2/conf/server.pem
reqadd X-Forwarded-Proto:\ https
default_backend LB
backend LB
acl no_domain hdr(host) -i myserver
http-request redirect code 301 prefix https:\/\/myserver.domain.com if no_domain
redirect scheme https if !{ ssl_fc }
mode http
stats enable
stats hide-version
stats uri /stats
stats realm Haproxy\ Statistics
stats auth haproxy:redhat # Credentials for HAProxy Statistic report page.
balance roundrobin # Load balancing will work in round-robin process.
option httpchk
option httpclose
option forwardfor
server myserver.domain.com myserver.domain.com:80 # backend server.
Now when I give
myserver/myapplication
it redirects to
https://myserver.domain.com/myapplication

How to stop HAProxy from stripping auth header

So I'm having an issue with HAProxy stripping the authorization header from from my call when redirecting to a separate URL. Specifically, I want to hit an AWS lambda, based on the URL path.
subdomain.domain/mo/api should be routed to the lambda, and it is based on this configuration, but I receive this response back from the lambda (using postman):
{
"message": "Missing Authentication Token"
}
hitting the lambda url (bypassing HAProxy) works as expected, all headers are exactly the same.
Proxy config:
global
log /dev/log local0
log /dev/log local1 notice
maxconn 20000
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 2048
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
ssl-default-bind-options no-sslv3 no-tls-tickets
ssl-default-server-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
ssl-default-server-options no-sslv3 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
monitor-uri /index.html
stats enable
stats uri /stats
stats realm Haproxy\ Statistics
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend http
bind *:80
#Defining ACL based on a string in URI
acl dm_in_uri path_sub dm
acl mo_in_uri path_sub mo
acl lab_host hdr(host) -i subdomain.domain.com
reqadd X-Forwarded-Proto:\ http
#Special route which matches both hostname and string acl
use_backend lab_mo_api if lab_host mo_in_uri api_in_uri
use_backend lab_portal if lab_host
frontend https
bind *:443 ssl crt /etc/ssl/<blah>.pem
#Defining ACL based on a string in URI
acl api_in_uri path_sub api
acl dm_in_uri path_sub dm
acl mo_in_uri path_sub mo
acl lab_host hdr(host) -i subdomain.domain.com
reqadd X-Forwarded-Proto:\ https
#Special route which matches both hostname and string acl
use_backend lab_mo_api if lab_host mo_in_uri api_in_uri
use_backend lab_portal if lab_host
backend lab_mo_api
reqrep (.*)\/mo\/api(\/.*) \1\ /lab\/
redirect prefix https://<aws_lambda_url> code 301

HAProxy SSL Redirect for HTTP but not WebSockets

I have HAProxy as a load balancer and dynamic redirector to my webserver and websocket server so that they can run over the same port. My web socket server requires SSL temination at ha proxy.
I want to configure HAProxy so that http traffic is redirected to https but websockets work on bot port 80 and 443 (ws and wss). Is this possible?
My current config is:
global
maxconn 50000
user root
group root
stats socket /tmp/haproxy
node lb1
nbproc 1
#daemon
#debug
defaults
log global
retries 3
option dontlog-normal
timeout connect 10000ms
timeout client 10000ms
timeout server 10000ms
timeout tunnel 24h
maxconn 50000
mode http
option http-server-close
backend wwwServers
mode http
balance roundrobin
option httpchk HEAD / HTTP/1.1
server www1 127.0.0.1:1138 check
backend wsServers
server ws1 127.0.0.1:1137 check
frontend secured
bind :443 ssl crt /cert/cert.pem
reqadd X-Forwarded-Proto:\ https
default_backend wwwServers
frontend unsecured
bind :80
acl is_websocket hdr(Upgrade) -i WebSocket
use_backend wsServers if is_websocket
redirect scheme https if !{ ssl_fc }
default_backend wwwServers
but this redirects the websocket connection before the upgrade because ha proxy does the following when I run it:
a 'redirect' rule placed after a 'use_backend' rule will still be processed before.
Any help would be appreciated.
Thanks,
The solution was as follows:
frontend secured
bind :443 ssl crt /path/to/certificate.pem
reqadd X-Forwarded-Proto:\ https
acl is_websocket hdr(Upgrade) -i WebSocket
use_backend wsServers if is_websocket
default_backend wwwServers
frontend unsecured
bind :81,:80
acl is_websocket hdr(Upgrade) -i WebSocket
redirect scheme https if !{ ssl_fc } !is_websocket
use_backend wsServers if is_websocket
default_backend wwwServers
if a non ssl non websocket connection is made it is redirected.