Change kubernetes pod namespace dynamically in HA proxy - kubernetes

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>

Related

How to replace domain in haproxy request?

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?

HAProxy to Istio Ingress

Currently, I am trying to configure a load balancer from where the traffic will be sent to a Kubernetes cluster. At the edge of the cluster, Istio ingress is serving the cluster's external request. HAProxy version 1.8
I can access the service using the below command from outside the cluster.
curl -k -HHost:httpbin.example.com --resolve httpbin.example.com:32009:192.168.50.10 https://httpbin.example.com:32009/status/418:
Below is my HAProxy configuration:
Frontend:
frontend https
bind *:443 ssl crt /etc/ssl/certs/site.pem
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
default_backend httpbin
Backend:
backend httpbin
balance roundrobin
mode tcp
acl httpbin_app req_ssl_sni -i httpbin.example.com
use-server master if httpbin_app
server master 192.168.50.10:32009 check ssl verify none
http-request set-header Host httpbin.example.com
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
Using HAProxy I am getting 503 always. Also during startup, HAProxy is saying the below line:
haproxy[14260]: backend httpbin has no server available!
Can you please help to find out the right configuration for backend?
Finally with the help of HAProxy community I have found the right configuration for Istio Ingress. This is very basic. Please update the settings as per your needs. Below is the link for the configuration.
https://gist.github.com/emamulandalib/2a613f5308c29518fcbcdc6b3bad3900

haproxy randomly responses status code 503

I know there are many questions with this title, but I tried all solutions without any luck.
I have haproxy in front of 2 apache and another third standalone server in debian 9.
when I try mysite.com (backend_g1 in the config file) with https, it is always responding 200. but when I access it using http (that I replace it to https in the haproxy config file), there are 503
responses randomly ! this is my haproxy.cfg:
global
log /dev/log local0 notice
log /dev/log local1 notice
log 127.0.0.1 local2 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
maxconn 512
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
maxconn 512
timeout connect 5000
timeout client 600000
timeout server 600000
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
# HTTP Auth
userlist basic-auth-list
group is-admin
# Plaintext password
user admin password $5$GnrqkuBdodw$./ groups is-admin
frontend stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats admin if LOCALHOST
frontend http-in
bind *:80
bind *:443 ssl crt /etc/ssl/mysite.com/mysite.com.pem
mode http
acl no_https ssl_fc,not
http-request redirect scheme https code 307 if no_https
acl g0_path path -i str /265952.txt
acl g0_path path -i str /registerInfo.php
acl g0_path path -i str /register
acl g0_path path -i str /register/
acl g0_path path_beg /icon/g0/
acl g0_path path_beg /css/g0/
acl g0_path path_beg /image/g0/
acl g0_path path_beg /icon/favicon/
acl g0_path path_beg /tool/
acl g0_path path_beg /lib/
acl g0_path path_beg /libs/
acl g0_path path_beg /asset/
acl g0_path path_beg /.well-known/
acl g0_path path_beg /pay/
acl g0_path path -i str /testing987.php
acl mysite_shop_id path,map_str(/etc/haproxy/maps/mysite_shop_id.map) -m found
http-request set-path /page?id=%[path,map(/etc/haproxy/maps/mysite_shop_id.map)] if { ssl_fc } mysite_shop_id
acl app_android_myshop path -i str /app/android/mysite-myshop.apk
http-request set-path /download/mobile/android/mysite-myshop.apk if app_android_myshop
acl g0_path path_beg /download/
acl mysite_admin1234567890 path_beg /mysite_admin1234567890/
use_backend backend_g0 if g0_path || app_android_myshop
# use_backend backend_nama if nama_path
use_backend backend_mysite_admin1234567890 if mysite_admin1234567890
default_backend backend_g1
backend backend_g0
balance roundrobin
cookie SERVERID insert
option http-keep-alive
timeout http-keep-alive 10s
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server g0 127.0.0.1:800 cookie g0
backend backend_mysite_admin1234567890
acl devops-auth http_auth_group(basic-auth-list) is-admin
http-request auth realm mysite_admin1234567890 unless devops-auth
option forwardfor
server mysite_admin1234567890 127.0.0.1:19999
http-request set-path %[path,regsub(^/mysite_admin1234567890/,/)]
http-request set-header Host %[src]
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Forwarded-Port %[dst_port]
http-request set-header Connection "keep-alive"
backend backend_g1
cookie SERVERID insert
option http-keep-alive
timeout http-keep-alive 20s
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server g1 127.0.0.1:8080 cookie g1
Maybe a mistake:
...
backend backend_g0
balance roundrobin # only on app at the end of this block
cookie SERVERID insert
option http-keep-alive
timeout http-keep-alive 10s
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server g0 127.0.0.1:800 cookie g0 # only one app
...
Maybe you should remove balance roundrobin if you have only one app after
And then
server g0 127.0.0.1:800 cookie g0 # wrong port ?
server g1 127.0.0.1:8080 cookie g1

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