HAProxy forward client IP to backend - reverse-proxy

I am trying to forward client/source IP to my backend server using x-forwarded-for. I am using libwebsockets and the client IP is seen as 127.0.0.1.
I have tried looked at and tried various solutions and none have worked for me.
haproxy -vw
HA-Proxy version 1.6.3 2015/12/25
frontend firstbalance
bind *:443 ssl crt /etc/ssl/xip.io/temp/cert.pem
mode http
option forwardfor
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
capture request header X-Forwarded-For len 50
backend lws_traffic
balance roundrobin
mode http
option forwardfor
server lws00 127.0.0.1:8000 check

just try with this config :
frontend haproxynode
bind *:80
mode http
default_backend backendnodes
backend backendnodes
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 node1 backendserver:8080 check

Related

How to configure HAProxy to "proxy" two domain names to different ports in localhost

I have one server containing FE app and BE for it. FE listens port 80 and BE is deployed to Tomcat listening default port 8080. HAProxy is used to listen port 443 / handle ssl. Proxying to FE / port 80 works fine, but not to BE / Tomcat listening port 8080. Here's the configuration I'm using:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
maxconn 3072
tune.ssl.default-dh-param 2048
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/ssl.key
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
defaults
log global
mode http
option httpchk
option httplog
option dontlognull
option forwardfor
option http-server-close
option http-keep-alive
option abortonclose
option redispatch
retries 3
maxconn 3072
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
listen stats
bind 0.0.0.0:9000
mode http
frontend http-in
bind *:443 ssl crt /etc/ssl/private/bundle.pem
http-request set-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
# Define hosts
acl host_fe hdr(host) -i fe.domain.com
acl host_be hdr(host) -i be.domain.com
## figure out which one to use
use_backend fecluster if host_fe
use_backend becluster if host_be
backend fecluster
balance leastconn
option httpclose
option forwardfor
server node1 localhost:80 cookie A check
backend becluster
mode http
balance leastconn
option httpclose
option forwardfor
cookie JSESSIONID prefix
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
server node1 localhost:8080 maxconn 32 check inter 5000
cookie node1
Tomcat works fine using ip address directly, so that's not the case. So help is needed for the host_be / becluster.

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

SSL with Haproxy dont shows CSS

I have a Problem with my HaProxy
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
maxconn 2048
tune.ssl.default-dh-param 2048
# Default SSL material locations
#ca-base /etc/haprorxy/certs/ca_bundle.crt
#crt-base /etc/haproxy/certs/certificate.crt
# 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
defaults
log global
mode tcp
option httplog
option dontlognull
option forwardfor
option http-server-close
retries 3
option redispatch
timeout connect 5s
timeout client 5s
timeout server 5s
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_front
bind *:80
reqadd X-Forwarded-Proto:\ http
stats uri /haproxy?stats
default_backend wp7.xxxx.com
stats auth admin:test
frontend https_front
mode tcp
bind *:443 ssl crt /etc/haproxy/certs/wp7.xxxxx.com.pem
reqadd X-Forwarded-Proto:\ https
default_backend wp7.xxxxxxx.com
stats uri /haproxy?stats
stats auth admin:test
backend wp7.xxxx.com
redirect scheme https if !{ ssl_fc }
option httpclose
option forwardfor
balance roundrobin
server Backend Backend_IP:80 check
#server rproxy02 xx.xx.xxx.xx:443 check
But the Website doesn`t look like how it should on https: https://www.pic-upload.de/view-32841877/Untitled.png.html
This is how it should look like: https://www.pic-upload.de/view-32841910/Untitled.png.html
The Website should run a Wordpress installation. When I go through port 80 (http) everything is ok, but If I go through Port 443 (https like on the picture), it looks like in the Picture.
Can someone help or have an idea?
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
try these lines in frontend
https://serversforhackers.com/c/using-ssl-certificates-with-haproxy
Got same issue and resolved by this link. Hope this could help.

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.