How to bind HAProxy with a certificate conditionally - haproxy

I have this HAProxy configuration in place
frontend requests_in
bind *:443 ssl crt /etc/pki/tls/private/mycert.pem
Then few acl and backends attached to it.
We have two consumers of this frontend - One needs the cert the other doesn't
How can I make this cert bind only valid for certain acls ? Is there a way to do it in the bind line or would I need to create another frontend listening on 443 (if at all possible) ?
Thanks in advance !

You can try to use crt-list to define how haproxy should behave with different TLS/SSL settings

Related

HAProxy - Configure Name and Port Proxies for different backends

Background: We have a series of interconnected applications SSL and all that we need to test putting a load balancer in front of. We're looking to publicly expose '443' to the end-users but have HAProxy proxy/redirect to the required internally exposed tcp-listeners. We're testing this implementation with haproxy and thought it would be a bit easier than either it is or we're making it to be.
https://example.com/app1 -> backend of 6 different hosts (or the
internal fqdn (not sure which would be correct)) on 30001
https://example.com/app2 -> backend of 6 different hosts (or the
internal fqdn (not sure which would be correct))on 8443
...
We've tried a number of different frontend/backend configs but can't seem to make it work as we intend. If anyone can tell me what I'm doing wrong, I'd appreciate it. Also we do not want SSL to terminate on the HAproxy which is why we aren't providing certs in the bind statement.
test1:
frontend test
bind *:443
acl path_spgen path_beg -i /app1
use_backend be_spgen if path_spgen
backend be_spgen
server host-01 x.x.x.x:30001
test2:
frontend test
bind *:443
acl path_spgen path_beg -i /app1
http-request redirect scheme https code 301 if !{ ssl_fc }
http-request redirect code 301 location https://example:30001 if path_spgen
backend be_spgen
server host-01 x.x.x.x:30001
any help would be greatly appreciated.

how can i use wso2 behind haproxy

i use dockerized wso2 https://github.com/wso2/docker-apim.
i want use api manager behind haproxy.
my config is:
frontend app
bind *:443 ssl crt /etc/ssl/wso2.pem
default_backend wso2
backend wso2
server node1 api-manager:9443 check ssl verify none
but after config it when open https://127.0.0.1/ in browser, it redirects to https://127.0.0.1:9443/publisher/.
how can i fix it ?
You can set the proxy ports in catalina-server.xml in repository/conf/tomcat location [1]. For 9443 port you can set the port 443 and restart the server.
[1] - https://docs.wso2.com/display/Carbon440/Adding+a+Custom+Proxy+Path

JWT Validation in HAProxy

I have an HAProxy configured to accept requests to *.mysubdomain.com. The HAProxy will parse the subdomain (prod or dev from prod.mysubdomain.com or dev.mysubdomain.com) and forward to the correct backend. Two backends exist, one for prod and one for dev. Each backend contains two server entries pointing towards Marathon LB instances on each subdomain.
The subdomains require a JWT cookie for authentication on the backend. I have the public key to check the validity of the JWT, but would like to do so in the HAProxy. Is there a way to add my own code to perform the JWT validity check within the HAProxy configuration?
The HAProxy configuration file is as follows:
global
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:80
mode http
# Returns true when one of the headers contains one of the strings either isolated or delimited by dots. This is used to perform domain name matching.
acl host_dev hdr_dom(host) -i dev
acl host_prod hdr_dom(host) -i prod
acl jwtPresent req.cook(JWT) -m found
use_backend prod_domain if jwtPresent host_prod
use_backend dev_domain if jwtPresent host_dev
default_backend prod_domain
backend prod_domain
balance roundrobin
server prodDomain1 "${MARATHON_LB_PROD_1}" maxconn 32 check
server prodDomain2 "${MARATHON_LB_PROD_2}" maxconn 32 check
backend dev_domain
balance roundrobin
server devDomain1 "${MARATHON_LB_DEV_1}" maxconn 32 check
server devDomain2 "${MARATHON_LB_DEV_2}" maxconn 32 check
HAProxy can act as an API gateway and validate JWT tokens against a public key. They have written a blog post and provided sample code to show you how.
The post is here: https://www.haproxy.com/blog/using-haproxy-as-an-api-gateway-part-2-authentication/
The sample lua code is here: https://github.com/haproxytech/haproxy-lua-jwt
As the other answer pointed out, you have to use Lua script. You can use existing implementations from lua-resty-jwt or Kong.
Notes:
Those code-bases are not concise. A simple copy & paste won't work. So you have to extract the bare minimum you need.
You can't have dependencies in your Lua script. Only plain vanilla Lua. So you have to get rid of all require statements.
The tricky part is the HMAC implementation.
Avoid any I/O operation in your Lua script, e.g. file, database, network operations.
It's not an easy undertaking. Good luck! It's something worth sharing.
As far as I could tell, HAProxy does not have the functionality to perform the logic for validating the JWT. Instead, I implemented a script in Lua for haproxy.cfg to call to perform the validation:
global
maxconn 256
lua-load /choose_backend.lua
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:80
http-request set-header X-SSL-Client-DN %{+Q}[ssl_c_s_dn]
http-request set-var(txn.backend_name) lua.backend_select()
use_backend %[var(txn.backend_name)]
backend prod_domain
balance roundrobin
server prodDomain1 "${MARATHON_LB_PROD_1}" maxconn 32 check
server prodDomain2 "${MARATHON_LB_PROD_2}" maxconn 32 check
backend dev_domain
balance roundrobin
server devDomain1 "${MARATHON_LB_DEV_1}" maxconn 32 check
server devDomain2 "${MARATHON_LB_DEV_2}" maxconn 32 check

Force HTTPS in Neo4j configuration

Is is possible force HTTPS URLs even when the X-Forwarded-Host header is not present?
Update:
We are using HAProxy in front of the Neo4j server. The configuration is
frontend proxy-ssl
bind 0.0.0.0:1591 ssl crt /etc/haproxy/server.pem
reqadd X-Forwarded-Proto:\ https
default_backend neo-1
This works well when every connection contains only one request. However, for Neo4j drivers which uses keep-alive (like Py2neo), the header is added only to the first request.
Without the X-Forwarded-Proto header, the generated URLs are http://host:1591, instead of https://host:1591.
According to the HAProxy documentation, this is the normal behavior:
since HAProxy's HTTP engine does not support keep-alive, only headers
passed during the first request of a TCP session will be seen. All subsequent
headers will be considered data only and not analyzed. Furthermore, HAProxy
never touches data contents, it stops analysis at the end of headers.
The workaround is to add option http-server-close in the frontend, so it will force that every request is in its own connection, but it will be nicer if we can support keep-alive.
Put something like Apache or Nginx in front of your Neo4j server to perform that task.
In terms of py2neo, I can add some functionality to cater for this situation quite easily. What if I were to include X-Forwarded-Proto: https for all https connections? Would that cause a problem in cases where a proxy isn't used?

SSL offloading / redirecting specific URLs using HAproxy?

I have a working setup using a hardware load balancer that controls redirection in such a fashion that all requests to http://example.com/login/* are redirected (using HTTP 302) to https://example.com/login/* and all requests that are NOT for /login are inversely redirected from HTTPS to HTTP.
This allows me to wrap the login functions and user/password exchange in SSL but otherwise avoid slowing connections with encryption and also solving some problems with embedded content mixed content warnings in some browsers.
The load balance, however, is end of life and I am looking for a replacement solution, preferably in software.
I think HAproxy is going to be able to serve as my load balacing solution, but I have only been able to find configuration examples and documentation for redirecting everything from HTTP to HTTPS, or vice versa.
Is it possible to do what I am proposing using HAproxy or should I look for a different solution?
I realize I will need to use the development version of HAproxy to support SSL at all.
I would suggest you do not use a DEV build for your production environment.
To answer your question, I would assume you're going to use HAProxy version 1.4:
Is it possible to do what I am proposing using HAProxy or should I look for a different solution?
Yes. It is possible but you have to use another software to handle the HTTPS traffic. Stunnel is proven to be good in this. So I'd say the setup is going to be:
HAProxy 1.4
# Redirect http://../login to https://../login
frontend HTTPSRedirect
bind 1.2.3.4:80
default_backend AppServers
redirect prefix https://www.domain.com/login if { path_beg -i /login }
# Handler for requests coming from Stunnel4.
frontend HTTPReceiver
bind 5.6.7.8:80
default_backend AppServers
Stunnel4
[https]
accept=443
connect=5.6.7.8:80 (HAProxy IP)