HaProxy as HttpProxy with list of underlying proxies - proxy

Is it possible to configure haproxy as a real http proxy which can forward requests to other proxies?
What I want to do: I have a list of working proxies. I want to configure haproxy to proxy via these proxies.
I thought about such case:
frontend proxy
bind *:80
default_backend proxyBackend
option http_proxy
backend proxyBackend
option http_proxy
server server1 35.199.76.79:80
server server2 198.1.122.29:80
balance roundrobin
Example:
curl --proxy localhost:80 http://check-host.net/ip
I thought that request will go throw proxy server1 or server2. But it fails.
Is it possible? Or who can recommend good solutions?

I found a solution:
global
daemon
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen stats
bind *:9999
stats enable
stats hide-version
stats uri /stats
frontend proxy
bind *:80
default_backend proxyBackend
option http_proxy
option http-use-proxy-header
backend proxyBackend
server serverName1 35.199.76.79:80
server serverName2 198.1.122.29:80
server serverName3 129.213.76.9:3128
balance roundrobin
For such configuration we have proxy list rotation using haproxy. So great.

Related

What env var to send requests to a HAProxy instance?

I have a HAProxy configured that works as expected when sending requests directly to the proxy host and port that the proxy is listening on. The proxy is running in TCP mode.
frontend tcp-in-mssql
bind :5650
mode tcp
use_backend mssql
backend mssql
mode tcp
server mssql01.mydomain.com mssql01.mydomain.com:5650 check
When I try to send requests to the proxy by using the SOCKS_PROXY or ALL_PROXY env vars, the proxy isn't used and the connection is made directly.
example:
SOCKS_PROXY=socks://localhost:5650 my_command --target=mssql01.mydomain.com:5650
ALL_PROXY=socks://localhost:5650 my_command --target=mssql01.mydomain.com:5650
The proxy is bypassed and a TCP connection is made directly to the target host. Though if do something like my_command --target=localhost:5650 the TCP connection goes through the proxy and is made successfully to the backend target server.
How can I route traffic to the proxy?
Socks is a specific protocol to be spoken by client and proxy (https://en.wikipedia.org/wiki/SOCKS). Socks allows the client to specify which server to connect to on which port. To do so, the client establishes a connection to the socks proxy, the socks proxy then establishes a connection to the server and forwards the traffic from client to server and vice versa.
Example:
client -> socks proxy (port: 1080) -> server1 (port: clients choice)
-> server2 (port: clients choice)
-> serverN (port: clients choice)
-> server (clients choice)
Your HAProxy configuration configures the haproxy to serve as a reverse proxy for tcp connections on port 5650. Tcp traffic received on port 5650 will then be forwarded to one of the destination servers configured in backend section.
Example:
client -> reverse proxy (port 5650) -> backend (server and port
as defined in haproxy config)
So you already have a working solution for proxying the connection to the mssql backend. Just configure the mssql client to connect to the hapoxy on port 5650.
If you need a socks proxy to suit your use case, you have to replace the haproxy with a dedicated, socks capable proxy solution

Dropped WebSocket connection in Rancher's LoadBalancer

I have simple WebSocket connection from my browser to a service inside Rancher.
I tried to connect to the service in 2 ways:
1) directly to the service:
browser ---> service
2) via Rancher's Load Balancer:
browser ---> Load Balancer ---> service
In the first case everything is fine: the connection is established and the messages are sent through it.
In the 2nd case the connection is dropped in after ~50s. Messages are send through the connection correctly in both directions.
What is the reason?
EDIT: I tested in on ws and wss protocol. In both cases there is the same issue.
Rancher Load Balancer internally uses HAProxy, which can be customized to your needs.
Here is an example HAProxy config for websockets:
global
maxconn 4096
ssl-server-verify none
defaults
mode http
balance roundrobin
option redispatch
option forwardfor
timeout connect 5s
timeout queue 5s
timeout client 36000s
timeout server 36000s
frontend http-in
mode http
bind *:443 ssl crt /etc/haproxy/certificate.pem
default_backend rancher_servers
# Add headers for SSL offloading
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Ssl on if { ssl_fc }
acl is_websocket hdr(Upgrade) -i WebSocket
acl is_websocket hdr_beg(Host) -i ws
use_backend rancher_servers if is_websocket
backend rancher_servers
server websrv1 <rancher_server_1_IP>:8080 weight 1 maxconn 1024
server websrv2 <rancher_server_2_IP>:8080 weight 1 maxconn 1024
server websrv3 <rancher_server_3_IP>:8080 weight 1 maxconn 1024
Reference: https://rancher.com/docs/rancher/v1.6/en/installing-rancher/installing-server/basic-ssl-config/#example-haproxy-configuration
Only the relevant config can be used in "Custom haproxy.cfg" section of the LB.
See screenshot:
Here is the link for more documentation for custom haproxy in Rancher: https://rancher.com/docs/rancher/v1.6/en/cattle/adding-load-balancers/#custom-haproxy-configuration

Trivial HAProxy UrlRewrite

I would like all traffic to an arbitrary domain, let's call it www.example.com, to be url-rewritten to www.google.com so that when I hit http://www.example.com/search?q=haproxy doesn't result in a 404. Is this even possible?
Here is my .cfg file's content:
global
defaults
mode http
timeout connect 5000ms
timeout client 5000ms
timeout server 5000ms
frontend http-in
bind *:80
default_backend my_backend
reqrep ^([^\ :]*)\ /\d+/(.+)/? \1\ /\2
backend my_backend
server forwardsvr www.google.com:80 check
Thanks in advance for any help!

Appending Path to Host HAPROXY

I am new to haproxy (actually proxy'ing in general) and I can't figure out how to add a path to my backend. I have my backend defined as:
server server1 ns.foo.com:7170 check
I want to add /web such that the request is directed to https://ns.foo.com:7170/web.
Thanks,
Mark
What you need is HTTP rewriting
https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#rewriting-http-urls
Adding this to your backend should solve your problem:
acl p_root path -i /
http-request set-path /web if p_root
If you would like to send a request coming in a given port to a specific path,
you can modify the request either in the frontend or backend configuration by specifying a http-request rule using the set-path action
For example if you would like to send any request to a /web then you should write
http-request set-path /web
into your backend configuration
Otherwise if you would like to prepend the incoming request path with /web
(so for example
localhost:[port]/somepath
should go to
serverhost:[serverport]/web/somepath) as Mawardy asked.
Then you should also use the %[path] variable like this
http-request set-path /web/%[path]
I have created a proof of concept of a spring server running with 2 instances in docker
which are loadbalanced with a HA proxy in docker that also modifies the path depending on which server won the loadbalancing.
For this the ha proxy is configured to loadbalance between its own frontends which has their own backend with their modified path
The configuration looks like this
defaults
retries 3
maxconn 20
timeout connect 5s
timeout client 6s
timeout server 6s
frontend http-in
bind *:9002
mode http
use_backend proxy-backend
backend proxy-backend
balance roundrobin
mode http
option forwardfor
http-response set-header X-Forwarded-Port %[dst_port]
http-response set-header X-ProxyServer %s
server proxy-server-1 localhost:9000
server proxy-server-2 localhost:9001
frontend proxy-in1
bind *:9000
mode http
use_backend poc-server2
frontend http-in2
bind *:9001
mode http
use_backend poc-server1
backend poc-server1
mode http
http-response set-header X-Server %s
http-request set-path /api/one/%[path]
server poc-server-1 proxypochost1:9000
backend poc-server2
mode http
http-response set-header X-Server %s
http-request set-path /api/two/%[path]
server poc-server-2 proxypochost2:9001
For more information you can check the whole project with some additional information in its readme here: ha-proxy-poc

haproxy keep session after server fail?

I have 2 HAProxys that are load balancing user requests with roundrobin algorithm successfully to my 2 WebServers.
When a webserver fails, HAProxy sends the request to the next available server, but for some reason I'm not able to keep the user session, and therefore information isn't displayed properly.
How can I make it so the session is saved during a failover?
Here's my haproxy.cfg:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 2000
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
timeout connect 5000
timeout client 10000
timeout server 1000
listen app 192.168.1.100:80
mode http
stats enable
stats uri /haproxy?stats
stats realm Strictly\ Private
stats auth admin:admin
balance roundrobin
cookie LSW_WEB insert
option httpclose
option forwardfor
option httpchk HEAD / HTTP/1.0
server server1 192.168.1.93:80 cookie LSW_WEB01 check
server server2 192.168.1.94:80 cookie LSW_WEB02 check
This has to do with how you share sessions between your servers not with haproxy itself.
The problem lies in your application or how you are storing sessions.

Resources