Routing domains, always goes to default


#1

I’ve been goggling and looking for guides and tried piecing this together with lo luck whatsoever. What I need to do is direct web traffic to different servers depending on the domain (for now)… I’m using the latest HAProxy (1.7.9 running on an Ubuntu machine (virtual) and my router directs all traffic for port 80 to it.
I’ve been following what guides I could find to the best of my understanding and I finally have the service at least start without failure, but once running it seems it completely ignores all my hostmapping and just sends everything to the default backend.
I have 3 webservers running on 3 different machines with their own static IPs (2 Apache and 1 IIS) and this is the config I’ve come up with.

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 256

# 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/
# An alternative list with additional directives can be obtained from
#  https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
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

defaults
log global
mode http
option httplog
option dontlognull
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

# My stuff
stats enable
stats uri /hapstats
stats realm "HAProxy\ Statistics"
stats auth steiner:password
stats refresh 5s

frontend http-in
bind *:80

# Define hosts
acl host_tifozi hdr(host) -i tifozi.net
acl host_tabardinn hdr(host) -i yetabardinn.net
acl host_tacticus hdr(host) -i tacticus.org
acl host_secunet hdr(host) -i secunet.se
acl host_windhund hdr(host) -i windhund.biz

# Hostmapping
use_backend Srv_1 if host_tacticus
use_backend Srv_1 if host_windhund
use_backend Srv_2 if host_tifozi
use_backend Srv_2 if host_tabardinn
use_backend Srv_3 if host_secunet
default_backend Srv_1

backend Srv_1
option forwardfor
option httpclose
server Apache_1 10.84.42.4:80 check

backend Srv_2
option forwardfor
option httpclose
server Apache_2 10.84.42.15:80 check

backend Srv_3
option forwardfor
option httpclose
server IIS_1 10.84.42.14:80 check

Please someone help me figure this out and point me in the right direction, I would be immensely grateful!


#2

What happens if you remove the “default_backend” directive temporarily? Does the request still hit Srv_1 or do you get an error?


#3

I get an 503 error.
I can reach all the webservers directly by their LAN IP.
Also if I use for example http://tifozi.net instead of http://www.tifozi.net it routes to the correct server. So it ‘kinda’ works.


#4

I solved it (at least I think so) thanks to another post here! :slight_smile:

The important changes was doing this:

frontend http-in
bind *:80

# Define hosts
acl Host_Srv_1 hdr(host) -i -f /etc/haproxy/srv_1_urls
acl Host_Srv_2 hdr(host) -i -f /etc/haproxy/srv_2_urls
acl Host_Srv_3 hdr(host) -i -f /etc/haproxy/srv_3_urls

# Hostmapping
use_backend Srv_1 if Host_Srv_1
use_backend Srv_2 if Host_Srv_2
use_backend Srv_3 if Host_Srv_3
default_backend Srv_1

And then just listing all variant urls I want forwarded in those files. Seems to work just fine.


#5

Looking at it I just realized I can cut it down even further, to 2 ACLs and a default, because anything not defined in the Host_Srv_2 and Host_Srv_3 files will automatically go to the default backend.


#6

Its simpler than that. hdr(host) is an exact match on the Host header. So if you want to match both the main domain and the www. subdomain you just have to include the www. subdomain:

acl host_tifozi hdr(host) -i tifozi.net www.tifozi.net

If you want to include all subdomains, you can suffix match .domain.tld with hdr_end:

acl host_tifozi hdr(host) -i tifozi.net
acl host_tifozi hdr_end(host) -i .tifozi.net