How to replace domain in haproxy request? - haproxy

is it possible to change/rewrite/replace the domain name in the request before you pass it through to the backend server?
I have 1 frontend:
frontend https-dev
maxconn 2000
option forwardfor header X-Real-IP
http-request set-header X-Real-IP %[src]
default_backend be-dev-cdn
# BEGIN CORS
http-response set-header Access-Control-Allow-Origin "*"
http-response set-header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization, JSNLog-RequestId, activityId, applicationId, applicationUserId, channelId, senderId, sessionId"
http-response set-header Access-Control-Max-Age 3628800
http-response set-header Access-Control-Allow-Methods "GET, DELETE, OPTIONS, POST, PUT"
# END CORS
bind *:443 ssl crt domain.pem
reqadd X-Forwarded-Proto:\ https
# set X-SSL in case of ssl_fc <- explained below
http-request set-header X-SSL %[ssl_fc]
And 1 backend with multiple hosts:
backend be-dev-cdn
balance roundrobin
server dev-cdn01.domain.com 192.168.101.1:80 check
server dev-cdn02.domain.com 192.168.101.2:80 check
server dev-cdn03.domain.com 192.168.101.3:80 check
server dev-cdn04.domain.com 192.168.101.4:80 check
server dev-cdn05.domain.com 192.168.101.5:80 check
The user would input the domain www.domain.com and I would then rewrite/replace this domain to a new domain name based on the backend server to which the request is forwarded. For example:
www.domain.com -> haproxy -> backend server dev-cdn05.domain.com; rewrite the request.
My goal is that I would just like to route the requests through haproxy server but not the response
Is this possible with haproxy?

Related

Change kubernetes pod namespace dynamically in HA proxy

How can I change kubernetes pod namespace dynamically in a backend of HA proxy? Basically, what I need is the reference to the 2nd matched pattern group of reqrep to be used as the namespace in server or extract the namespace from the Referer, say if the referer is https://example.name.net/abc/app/v1, the namespace should be abc.
backend My_Web_Server
balance roundrobin
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
acl fail-validation req.fhdr(X-Haproxy-ACL) -m found
http-request deny if fail-validation
reqrep ^([^\\ ]*)\\ (.*)/app/(.*) \\1\\ /app/\\3
server <server-name> <kubernetes-pod-name>.<namespace>:<port>

HAProxy - Http-request redirect to backend host?

I would like incoming queries in haproxy example: http://haproxy/test are redirected to one of the backends in a 301 redirection:
http://server-a/test or
http://server-b/test or
http://server-c/test or
…
my backend:
backend cluster_redirect
http mode
random balance
server server-a:80
server server-b:80
server server-c:80
my frontend:
front-end www
bind:80
http-request redirect code 301 location http://%bi%[capture.req.uri]
use_backend cluster_redirect
%bi is not interpreted!. URL for redirect is : “location: http:///test”
If i use a set-header for debug: http-response set-header X-Debug http://%bi%[capture.req.uri]
the header is : X-Debug: http://10.1.1.1/test.
10.1.1.1 is the IP for haproxy.
Thank you

How to access a backend ressource on / from a /SOMETHING/ path

I am trying to access my router web interface through my HAProxy server. So far, it looks easy! But after a heavy search party, I've come to put my destiny into your hands.
Environment:
Haproxy 1.8.8 which runs into a container.
Freebox Web Portal: https://192.168.1.254.
It should work with a specific path this way:
The User enter into a browser this url:
https://example.com/freebox
The HAProxy Configuration detects the path /freebox on port 443 then forward it to the corresponding backend.
The backend sees the /freebox path and strip it to / so the url looks like this: https://example.com/
This url match the backend url (meant without a specific path) so it should work but does not.
What works for me:
I can use SSL configuration on both sides.
I can detect the correct path and provide the right backend
I can change the detected path and provide the corresponding backend
Frontend: https://example.com/home --> Backend: https://192.168.1.2/domoticz
What I've tried to resolve my issue:
I've changed few thing before the request arrives into the backend:
Frontend www-https
...
acl path_freebox url_beg /freebox
http-request set-header X-Location-Path %[capture.req.uri] if path_freebox
http-request replace-header X-Location-Path /freebox / if path_freebox
http-request redirect location %[hdr(X-Location-Path)] if path_freebox
use_backend backend_freebox if path_freebox
...
I've strip the /freebox to / (FYI the "or" are on in the conf file):
backend backend_freebox
reqirep ^([^\ :]*)\ /freebox/(.*) \1\2
or
reqrep ^([^\ ]*\ /)freebox[/]?(.*) \1\2
or
reqirep ^([^\ :]*)\ /freebox/(.*) \1\ /\2
or
reqrep ^([^\ ]*\ /)freebox[/]?(.*) \1\/\2
or
http-request set-path %[path,regsub(^/freebox/?,/)]
or
http-request set-uri %[url,regsub(^/freebox,/,)]
server freebox 192.168.1.254:443 ssl verify none
I've set headers then strip the path:
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
reqirep ^([^\ :]*)\ /freebox/(.*) \1\2
server freebox 192.168.1.254:443 ssl verify none
I've changed the origin then strip the trailing path:
http-request set-header Orig-Path /freebox/
http-request set-header X-Script-Path /freebox/
http-request set-header Host example.com
or
http-request set-header Orig-Path /freebox
http-request set-header X-Script-Path /freebox
http-request set-header Host example.com
reqirep ^([^\ :]*)\ /freebox/(.*) \1\2
server freebox 192.168.1.254:443 ssl verify none
This one half worked, I could get a view of the portal with that method, but could not use it as "Error" was written on it.
My full HAProxy Configuration:
global
# Logging to rsyslog on localhost local2
log 127.0.0.1 local2 debug
# System Security
#chroot /var/lib/haproxy
#stats socket /run/haproxy/admin.sock mode 660 level admin
#stats timeout 30s
#user haproxy
#group haproxy
# Start as daemon
daemon
# Default SSL Ciphers
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3 no-tls-tickets
ssl-default-server-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
ssl-default-server-options no-sslv3 no-tls-tickets
tune.ssl.default-dh-param 2048
defaults
mode tcp
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
errorfile 400 /usr/local/etc/haproxy/errors/400.http
errorfile 403 /usr/local/etc/haproxy/errors/403.http
errorfile 408 /usr/local/etc/haproxy/errors/408.http
errorfile 500 /usr/local/etc/haproxy/errors/500.http
errorfile 502 /usr/local/etc/haproxy/errors/502.http
errorfile 503 /usr/local/etc/haproxy/errors/503.http
errorfile 504 /usr/local/etc/haproxy/errors/504.http
frontend www-https
# Bind this frontend to the port 443 with ssl configuration
bind *:443 ssl crt /etc/ssl/example.com
mode http
# Full logging to localhost
log 127.0.0.1 local2
option httplog
# Whitelist
#acl network_allowed src 20.30.40.50 8.9.9.0/27
#tcp-request connection reject if !network_allowed
# Pour forwarder l'identité des clients (To be verified)
reqadd X-Forwarded-Proto:\ http
reqadd X-Forwarded-Proto:\ https
# Default Backend
default_backend backend_trash
# ACLs to determine the backend defined on the path
acl path_domoticz url_beg /domoticz/
use_backend backend_domoticz if path_domoticz
acl path_gitlab url_beg /gitlab
use_backend backend_gitlab if path_gitlab
acl path_pihole url_beg /pihole
use_backend backend_pihole if path_pihole
acl path_freebox url_beg /freebox
use_backend backend_freebox if path_freebox
#acl path_orbi url_beg /orbi
#use_backend backend_orbi if path_orbi
# Backend Configuration
backend backend_domoticz
mode http
server domoticz 192.168.1.2:443 ssl verify none
backend backend_gitlab
mode http
server gitlab 192.168.1.6:443 ssl verify none
backend backend_pihole
mode http
reqirep ^([^\ :]*)\ /pihole/(.*) \1\ /hole/\2
server hole 192.168.1.8:443 ssl verify none
backend backend_freebox
mode http
#option forwardfor
#http-request set-header X-Forwarded-Port %[dst_port]
#http-request add-header X-Forwarded-Proto https if { ssl_fc }
#option httpchk HEAD / HTTP/1.1\r\nHost:localhost
#reqrep ^([^\ ]*\ /)freebox[/]?(.*) \1\2
#reqirep ^([^\ :]*)\ /freebox/(.*) \1\2
#http-request set-uri %[url,regsub(^/freebox,/,)]
#http-request set-path %[path,regsub(^/freebox/?,/)]
#http-request set-header Orig-Path /freebox/
#http-request set-header X-Script-Path /freebox/
#http-request set-header Host starfly.ovh
#reqirep ^([^\ :]*)\ /freebox/(.*) \1\ /\2
#reqrep ^([^\ ]*\ /)freebox[/]?(.*) \1\/\2
server freebox 192.168.1.254:443 ssl verify none
#backend backend_orbi
#(Not Working)
#mode http
#reqirep ^([^\ :]*)\ /orbi/(.*) \1\2
#server orbi 192.168.1.56:443 ssl verify none
backend backend_trash
mode http
http-request deny
Expected behavior:
I wish I could keep my trailing path /freebox and still access the backend on /.
I don't know if it is possible, may be you guys can help me figure it out ?
Thanks a lot !

Have to restart Haproxy every few minutes

(Ubuntu 16.04, 6 cores, 24GB Ram, Haproxy 1.8.0)
I've read so much about how easy haproxy is, so we set it up, did some basic testing / load testing and things looked good. Put it into production last night, things look good, until we start getting production traffic. I have to restart haproxy every few minutes b/c sites just stop responding. The stats website isnt showing me any stats that look alarming, and the machine is hardly using any resources.
Basically here is what we see - We restart haproxy, everything works great, then a few minutes later we have to restart it again (under production load).
Looking at the stats page I see the backend gets to around 50k sessions and then stuff just stops working.
Here is my config, can you check it out and help me understand how I should tune it?
global
log 127.0.0.1:22514 local2 debug
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
timeout connect 50000000
timeout client 50000000
timeout server 50000000
maxconn 80000
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 loadbalanced_main
log global
bind *:80
mode http
redirect scheme https if !{ ssl_fc }
acl web1 hdr(host) -i -m sub 1.a.com
acl web2 hdr(host) -i -m sub 2.a.com
acl web3 hdr(host) -i -m sub 3.a.com
use_backend ordweb1 if web1
use_backend ordweb2 if web2
use_backend ordweb3 if web3
default_backend loadbalanced_nodes
frontend loadbalanced_main_ssl
log global
bind *:443 ssl crt /etc/ssl/private/a.com.pem crt /etc/ssl/private/b.com.pem
reqadd X-Forwarded-Proto:\ https
acl web1 hdr(host) -i -m sub 1.a.com
acl web1 hdr(host) -i -m sub 1.b.com
acl web2 hdr(host) -i -m sub 2.a.com
acl web2 hdr(host) -i -m sub 2.b.com
acl web3 hdr(host) -i -m sub 3.a.com
acl web3 hdr(host) -i -m sub 3.b.com
use_backend ordweb1 if web1
use_backend ordweb2 if web2
use_backend ordweb3 if web3
default_backend loadbalanced_nodes
backend ordweb1
mode http
redirect scheme https if !{ ssl_fc }
balance roundrobin
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
server ordweb1 10.154.18.100:80 cookie check
backend ordweb2
mode http
redirect scheme https if !{ ssl_fc }
balance roundrobin
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
server ordweb2 10.154.18.8:80 cookie check
backend ordweb3
mode http
redirect scheme https if !{ ssl_fc }
balance roundrobin
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
server ordweb3 10.154.18.9:80 cookie check
backend loadbalanced_nodes
mode http
redirect scheme https if !{ ssl_fc }
balance roundrobin
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
cookie SRV insert indirect nocache
server ordweb1 10.154.18.100:80 check cookie ordweb1
server ordweb2 10.154.18.8:80 check cookie ordweb2
server ordweb3 10.154.18.9:80 check cookie ordweb3
listen stats
bind *:1936
stats enable
stats uri /
stats hide-version
stats auth nope:blah

haproxy redirect scheme https if !$request_uri

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;
}