HAProxy - Configure HTTP frontend to listen on multiple ports - haproxy

I have an HAProxy HTTP Frontend in my HAProxy config like so:
frontend myaddress.net :10098
bind :80,:8080
mode http
log global
option http-server-close
timeout client 14400000
timeout connect 60000
timeout tunnel 14400000
timeout http-request 14400000
capture request header User-Agent len 64
capture request header Accept-language len 64
capture request header x-forward len 15
capture request header host len 64
capture request header X-Orig-Base len 64
capture request header X-Orig-Host len 64
capture request header X-Orig-Proto len 64
reqadd X-Original-host:\ myaddress.net
acl is-ssl hdr(X-Orig-Proto) https
acl is-http hdr(X-Orig-Proto) http
redirect code 301 prefix https://myaddress.net if is-http
default_backend BACKEND_myaddress.net:catchall
It points to a backend defined like so:
backend BACKEND_myaddress.net:catchall
timeout server 4h
balance leastconn
server myserver myserver:8080 check inter 5s rise 3 fall 1
I've got it working to listen on port 80, then forward to 8080 on the backend server, but now I'm trying to make it also listen on port 8080 on the frontend (don't ask me why, it's a lame requirement).
As you can see, I've got a line that says bind :80,:8080. I thought that would make the frontend also listen on port 8080, but it's not appearing to listen on port 8080.
Is there something I'm missing in this configuration? How can I make a frontend listen on port 8080 and 80, which then forwards to the backend server on port 8080?

Try this in your frontend section:
bind :80
bind :8080

bind 0.0.0.0:80
bind 0.0.0.0:8080
Works for me !

Related

Config balance haproxy with use tags in header on request

I have a question about config balance with use haproxy.
I want config balance with use header tags on requests.
I have 2 tag - kasko, osago and default_backend.
How I can config balance for tags
- if I have one tag in header request - balance backend osago,
- if second tag - balance backend kasko,
- if don't have tag - use default backend?
I tried use hdr_val how wrote on this instructions https://www.haproxy.com/documentation/aloha/9-5/traffic-management/lb-layer7/acls/
and this
https://blog.armbruster-it.de/2015/08/neo4j-and-haproxy-some-best-practices-and-tricks/
but it don't work.
frontend web_80
bind *:80
mode http
option httplog
acl acl_osago hdr_val(Calculation-Type:OSAGO) eq 1
acl acl_kasko hdr_val(Calculation-Type:KASKO) eq 1
use_backend osago if acl_osago
use_backend kasko if acl_kasko
default_backend web_80
backend osago
mode http
server server5_7003 server5:7003 check port 7001
backend kasko
mode http
server server6_7003 server6:7003 check port 7001
backend web_80
mode http
balance leastconn
option httpchk GET /ibss-checker/threads/info/queue-length
http-check expect rstring ^(0?[0-9]?[0-9]|1[0-1][0-9])$
server server1_7003 server1:7003 check port 7001
server server2_7003 server2:7003 check port 7001
server server3_7003 server3:7003 check port 7001
server server4_7003 server4:7003 check port 7001
Helped dev recompiling programm and this config
acl acl_osago hdr_val(Calculation-Type:OSAGO) eq 1
worked

How to link frontend to backend when the path request are different?

I have an Haproxy set with https offloadin, and I'm trying to correctly point the requests made to frontend to it's corresponding backend, but bumped into some obstacles.
I have a backend server on http://:9000/abc (NOT in root of the webserver) and when I set a frontend with https:///abc the pointing works as expected and I see the login page.
But I also have another backend server, which is on http://:8888 (IN the root of webserver, it makes it's own redirect to http://:8888/def) and I want it to be accessible by https:///def. But in this case the pointing doesn't work.
How can I make https:///def point to http://:8888 ? Heres is my .cfg
Using HAproxy 1.7
# Automaticaly generated, dont edit manually.
# Generated on: 2019-01-28 13:59
global
maxconn 1000
stats socket /tmp/haproxy.socket level admin
uid 80
gid 80
nbproc 1
hard-stop-after 15m
chroot /tmp/haproxy_chroot
daemon
tune.ssl.default-dh-param 2048
server-state-file /tmp/haproxy_server_state
listen HAProxyLocalStats
bind 127.0.0.1:2200 name localstats
mode http
stats enable
stats refresh 10
stats admin if TRUE
stats show-legends
stats uri /haproxy/haproxy_stats.php?haproxystats=1
timeout client 5000
timeout connect 5000
timeout server 5000
frontend shared-frontend-merged
bind 200.129.168.14:443 name 200.129.168.14:443 no-sslv3 ssl crt-list /var/etc/haproxy/shared-frontend.crt_list
mode http
log global
option http-keep-alive
option forwardfor
acl https ssl_fc
http-request set-header X-Forwarded-Proto http if !https
http-request set-header X-Forwarded-Proto https if https
timeout client 30000
acl aclcrt_shared-frontend var(txn.txnhost) -m reg -i ^ifamcmc\.ddns\.net(:([0-9]){1,5})?$
acl ACL1 var(txn.txnpath) -m sub -i abc
acl ACL2 var(txn.txnpath) -m sub -i def
http-request set-var(txn.txnhost) hdr(host)
http-request set-var(txn.txnpath) path
use_backend glpi_ipvANY if ACL1
use_backend ciweb_ipvANY if ACL2
frontend http-to-https
bind 200.129.168.14:80 name 200.129.168.14:80
mode http
log global
option http-keep-alive
timeout client 30000
http-request redirect scheme https
backend abc_ipvANY
mode http
id 102
log global
timeout connect 30000
timeout server 30000
retries 3
option httpchk OPTIONS /
server abc 10.100.0.30:9000 id 103 check inter 1000
backend def_ipvANY
mode http
id 104
log global
timeout connect 30000
timeout server 30000
retries 3
option httpchk OPTIONS /
server def 10.100.0.40:8888 id 105 check inter 1000
I expect that access to https:///def correctly points to the backend at http://:8888
https://<my.address.com>/abc ------> http://<internal_ip>:9000/abc (OK)
https://<my.address.com>/def ------> http://<internal_ip_2>:8888 (NOT OK)
Have your HAProxy system do initially forwarding based on ports, and then wildcards on your directory.
Please see below:
frontend a-frontend-conf
# Declare an ACL using path_beg (Path Begins)
acl path_images path_beg /images
# Use backend server1 if acl condition path_images is fulfilled
use_backend server1 if path_images
backend server1
[...]
Source: https://serverfault.com/questions/659793/haproxy-how-to-balance-traffic-within-directory-reached

Why does HAProxy show that a server's check URL is a 404 when running curl on this URL is successful?

I'm setting up HAProxy to load-balance a resource between 3 back-ends. Here is the HAProxy config : (In the following snippets I replaced the actual domain name by example.net)
global
log 127.0.0.1 local2
log-send-hostname
maxconn 2000
pidfile /var/run/haproxy.pid
stats socket /var/run/haproxy.sock mode 600 level admin
stats timeout 30s
daemon
# SSL ciphers
...
defaults
mode http
option forwardfor
option contstats
option http-server-close
option log-health-checks
option redispatch
timeout connect 5000
timeout client 10000
timeout server 10000
...
frontend front
bind *:443 ssl crt /usr/local/etc/haproxy/front.pem
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
stats uri /haproxy?stats
option httpclose
option forwardfor
default_backend back
balance source
backend back
balance roundrobin
option httpchk GET /healthcheck HTTP/1.0
server server1 xxx.xxx.xxx.xxx:80 check inter 5s fall 2 rise 1
server server2 yyy.yyy.yyy.yyy:8003 check backup
server mysite example.net:80 check backup
The issue is the following: even though the first 2 servers respond correctly, the domain-based one always shows as a 404:
What is counter-intuitive to me is that if I use curl to access this same healthcheck, I get an HTTP 200 (like I would expect to see in the HAProxy stats) :
curl -I http://example.net/healthcheck
HTTP/1.1 200 OK
When I ping my site, I get:
# ping example.net
PING example.net (217.160.0.195) 56(84) bytes of data.
64 bytes from 217-160-0-195.elastic-ssl.ui-r.com (217.160.0.195): icmp_seq=1 ttl=50 time=45.7 ms
Is it because the IP of my domain is shared with other domains (1&1 shared hosting) that HAProxy can't access it? Why is that and how to make HAProxy reach it correctly?

haproxy sni ssl_fc_has_sni always 0

I am trying to create an SNI based frontend/backend setup in HAProxy. It seems that ssl_fc_has_sni is always evaluating to 0 in my log and I haven't been able to figure out why.
This is a simplified version of the config I've been testing with:
global
user haproxy
group haproxy
daemon
log /dev/log local0
defaults
timeout connect 5s
timeout client 30s
timeout server 30s
timeout tunnel 1h
log-format frontend:%f\ %b/%s\ client_ip:%Ci\ client_port:%Cp\ SSL_version:%sslv\ SSL_cypher:%sslc\ SNI:%[ssl_fc_has_sni]\ %ts
frontend public_ssl
bind :443
log global
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend be_sni if { ssl_fc_has_sni }
default_backend be_no_sni
backend be_sni
server fe_sni 127.0.0.1:10444 weight 1 send-proxy
frontend fe_sni
#terminate with a cert that matches the sni host
bind 127.0.0.1:10444 ssl crt /mycertdir/certs accept-proxy no-sslv3
default_backend be_default
frontend fe_no_sni
#terminate with a generic cert
bind 127.0.0.1:10443 ssl crt /myothercertdir/default_pub_keys.pem accept-proxy no-sslv3
default_backend be_default
# backend for when sni does not exist, or ssl term needs to happen on the edge
backend be_no_sni
server fe_no_sni 127.0.0.1:10443 weight 1 send-proxy
backend be_default
mode http
option forwardfor
option http-pretend-keepalive
server the_backend 127.0.0.1:8080
Other items of note:
haproxy -vv shows OpenSSL library supports SNI : yes
I am running haproxy version 1.5.9 on fedora 20 through vagrant
the log always shows SNI:0 haproxy[17807]: frontend:public_ssl be_no_sni/fe_no_sni client_ip:<ip> client_port:42285 SSL_version:- SSL_cypher:- SNI:0 --
I'm testing with openssl s_client -servername www.example.com -connect <ip>:443.
I feel like I'm missing something obvious since there is no ssl version, cypher, or sni.
Looks like ssl_fc_has_sni is meant to be used post termination. Checking for the existence of the SNI host can be accomplished with:
frontend public_ssl
bind :443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend be_sni if { req.ssl_sni -m found }
default_backend be_no_sni

Redirecting to backend based on port

I'm fairly new to HAProxy so just looking for a little direction here. Here's a log of the problem and the config for that as well. I'm trying to force specific destination ports to use a specific backend and it's not working.
Dec 18 18:49:34 localhost HAPLB[8405]: x.x.x.x:64725 [18/Dec/2014:18:49:27.157] 890_imappop_25 890_imappop_25-smtp/<NOSRV> -1/-1/7084 187 PR 225/35/35/0/3 0/0
backend 890_imappop_25-smtp
balance roundrobin
option redispatch
stick-table type ip size 60k peers mypeers
server filter1-mail 192.168.115.38:25 check
server filter2-mail 192.168.115.39:25 check
listen 890_imappop_25
bind 192.168.115.100:25
mode tcp
balance roundrobin
option redispatch
option tcplog
log 127.0.0.1 local0 debug
stick-table type ip size 60k peers mypeers
acl smtp_25 dst_port 25
acl smtp_225 dst_port 225
acl smtp_587 dst_port 587
use_backend 890_imappop_25-smtp if smtp_25
use_backend 890_imappop_225-smtp if smtp_225
use_backend 890_imappop_587-smtp if smtp_587
server imappop1-mail 192.168.115.42:25 check
server imappop2-mail 192.168.115.43:25 check
The fix was to add mode tcp to the backend section, so in this case it was defaulting to HTTP which obviously SMTP doesn't know how to talk to. Can't believe I forgot that.
backend 890_imappop_25-smtp
balance roundrobin
mode tcp
option redispatch
stick-table type ip size 60k peers mypeers
server filter1-mail 192.168.115.38:25 check
server filter2-mail 192.168.115.39:25 check