Make HAProxy forward requests to a hostname instead of IP address. - mapping

I have 3 virtual hosts on a single IP address.Host_a, Host_b and Host_c all mapping to 192.168.1.10.
My HAProxy configuration is as follows:
frontend http
.
.
.
acl host_one path_end -i /ABC/application
acl host_two path_end -i /XYZ/application
acl host_three path_end -i /PQR/application
use_backend be_host1 if host_one
use_backend be_host2 if host_two
use_backend be_host3 if host_three
backend be_host1
server channel Host_a
backend be_host2
server channel Host_b
backend be_host3
server channel Host_c
Now for example, HAproxy forwards request to 192.168.1.10/ABC/application in case it matches an incoming URL ending with /ABC/application. Is there a way I could forward it to http://Host_a/ABC/application instead ? It is important for me that they use the hostname instead of its corresponding IP address.

The hostname is a part of the HTTP request, and that means you can use the HAProxy option reqirep to set it to whatever you want.
reqirep ^Host: Host:\ Host_a
You can use this type of option in all three of your backends.

Related

Issues proxying request with HAproxy

We're trying to set up HAproxy enterprise for reverse proxying requests to our internal microservices. The configuration we have created accepts all traffic on port 80 and has multiple backends to proxy requests to. But the requests are not getting proxied all the time in a stable manner. We have around 10 URLs and everytime we restart the hapee service some of the URLs stop working.
frontend example.com
bind *:80
mode http
acl ACL_abc hdr(host) -i abc.example.com
acl ACL_url1 hdr(host) -i abc.example.com && path /url1
acl ACL_def hdr(host) -i def.example.com
acl ACL_pqr hdr(host) -i pqr.example.com
use backend abc if ACL_abc
use backend url1 if ACL_url1
use backend def if ACL_def
use backend pqr if ACL_pqr
backend abc
http-request set-header Host abc.internal.com
server server1 abc.internal.com
backend url1
http-request set-header Host url1.internal.com
server server1 url1.internal.com
backend def
http-request set-header Host def.internal.com
server server1 def.internal.com
backend pqr
http-request set-header Host pqr.internal.com
server server1 pqr.internal.com

How Install SSL Certificate on ha proxy dockerfile using letsencrypt

I am using haproxy to route the domains and subdomains and it is deployed on port 80. I want that all the domains should be https or using SSL certificate.
global
log xx.xx.90.28 local0
log xx.xx.90.28 local1 notice
maxconn 2048
defaults
log global
mode http
option httplog
option dontlognull
option redispatch
option forwardfor
option http-server-close
retries 3
timeout connect 5000
timeout client 10000
timeout server 10000
frontend balancer
bind *:80
mode http
stats enable
stats uri /stats
stats refresh 15s
stats show-node
stats auth admin:admin
acl domain hdr_dom(host) -i www.example.com
acl subdomain hdr_dom(host) -i app.example.com
acl subdomain1 hdr_dom(host) -i examplecom
use_backend go_app_1 if domain
use_backend go_app_2 if subdomain
use_backend go_app_3 if subdomain1
backend go_app_1
balance roundrobin
mode http
option forwardfor
server go xx.xx.90.28:8081 check
backend go_app_2
balance roundrobin
mode http
option forwardfor
server go xx.xx.90.28:8082 check
backend go_app_3
balance roundrobin
mode http
option forwardfor
server go xx.xx.90.28:8081 check
And here is the DockerFile
FROM haproxy:2.1
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
Now I want to use letsencrypt to secure these URL please guide me how I can do this?
I think we need to setup letsencrypt locally first.
And inject the result setting to the container via volume mount.
Example command from Docker Hub:
docker run -d --name my-running-haproxy -v /path/to/etc/haproxy:/usr/local/etc/haproxy:ro haproxy:1.7
Something like below:
-v /my/letsencrypt/setting/:/etc/ssl/

HaProxy forward proxy works on HTTP but gives 503 on HTTPS

I'm expecting the following config to receive HTTPS requests, do the SSL offloading and send HTTP requests to my backends, however with HTTPS I get "503 service unavailable".
all ACLs work correctly on HTTP and the stats page shows them as online
The stats page works correctly on HTTPS
These are all in a docker compose file, docker is doing the name resolution to internal IP correctly
Perhaps I'm missing something obvious? Quite new to attempting this so any help is appreciated.
global
tune.ssl.default-dh-param 2048
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
backend certbot
option httpchk GET /
default-server init-addr libc,none
server certbot_server certbot check port 80
backend client
option httpchk HEAD /
server client_server client check port 80
backend api
option httpchk OPTIONS /api/healthcheck
server api_server api check port 80
frontend app
bind *:80
bind *:443 ssl crt /certs/productpedia.co.uk.pem
use_backend certbot if { path_beg -i /.well-known/acme-challenge/ }
use_backend api if { path_beg /api }
default_backend client
stats enable
stats uri /stats
stats refresh 10s
stats admin if LOCALHOST
EDIT:
Attached a wireshark trace of the the 503 request, looks like server is resetting the connection, but not sure where I can go from here, or what would be causing this?
After a full day of debugging, it looks like simply specifying port 80 did the trick, although I would have expected the default port to be 80 perhaps it carries through a default port of 443? I could also get rid of the port 80 after check after this change which was the original trigger hint that something might be off there.
backend certbot
option httpchk GET /
default-server init-addr libc,none
server certbot_server certbot:80 check
backend client
option httpchk HEAD /
server client_server client:80 check
backend api
option httpchk OPTIONS /api/healthcheck
server api_server api:80 check

Haproxy public jenkin webhook only

I want to allow Bitbucket access to my Jenkins callback [Private IP]:[PORT]/bitbucket-hook without public it entire port (/login, /jobs..) via haproxy.
Found it, can use path_end to forward the request or use reqirep to modify when backend path is different with frontend path.
frontend http-in
bind :444
acl is-jenkin-callback path_end -i /bitbucket-hook
use_backend jenkin-bitbucket-webhook if is-jenkin-callback

Redirect URI on kibana with HAProxy

I want to use the same host to get to my 2 diffenrents Kibana :
https://test.com/kibana1/app/kibana
and
https://test.com/kibana2/app/kibana
Each of the kibana can be assessible with https://aaa/app/kibana
Here is my HAProxy script :
acl k1 path_beg -m sub -i /kibana1
acl k2 path_beg -m sub -i /kibana2
use_backend KIBANA1 if k1
use_backend KIBANA2 if k2
redirect location /kibana1/app/kibana if k1
redirect location /kibana2/app/kibana if k2
But when I redirect, it doesn't know the URL.
How can I do to ignore kibana1 in the URL ?
How can I do it with HA Proxy ?
Id recommend looking into using the roundrobin setting on your backend. That will loadbalance between your two kibana instances. Also, you would have it a lot better if you also simply routed by DNS name, and utilized DNS load balancing on your KB instances. Im assuming you are loading from the same elastic instance/data set.
The reason for why it not loading is your ACL isnt loading the backend.

Resources