I have tried searching for a similar solution to the problem I am having, but could not find anything.
I have setup some LXD containers, one is HAProxy which is recieving port 80 traffic from the host's public IP address. HAProxy thens sends the traffic to the correct container depending on the domain.
The issue I am having is, even though I have set The domain_specific_subdomain
ACL rule for subdomain.example.com
, the other domain_root
ACL rule takes precedant.
Containers:
Question: How can I have this so the naked domain example.com
and all other subdomains (e.g. www., dev., etc) go to this backend backend_web1
except for subdomain.example.com
which should go to the: backend_web2
backend.
This is my config file:
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
# 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
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
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
# Frontend
frontend www_frontend
bind *:80 # Bind to port 80 (www) on the container
# Covers naked domain and all subdomains
acl domain_root hdr(host) -i example.com
# Specific sub-domain
acl domain_specific_subdomain hdr(host) -i subdomain.example.com
# Redirect the connection to the proper server cluster, depending on the match.
use_backend backend_web1 if domain_root
use_backend backend_web2 if domain_specific_subdomain
# Domain dependent containers
backend backend_web1
balance leastconn
# We set the X-Client-IP HTTP header. This is useful if we want the web server to know the real client IP.
http-request set-header X-Client-IP %[src]
# This backend, named here "backend_web1", directs to container "lxd-container-web1.lxd" (hostname).
server web1 lxd-container-web1:80 check
backend backend_web2
balance leastconn
http-request set-header X-Client-IP %[src]
server web2 lxd-container-web2.lxd:80 check
From the haproxy docs:
There may be as many "use_backend" rules as desired. All of these rules are evaluated in their declaration order, and the first one which matches will assign the backend.
So if you switch the use_backend
line ordering, it should work.
# Redirect the connection to the proper server cluster, depending on the match.
use_backend backend_web2 if domain_specific_subdomain
use_backend backend_web1 if domain_root
Or better yet, maybe default_backend
would be better here:
# Use backend_web2 if ACL matches
use_backend backend_web2 if domain_specific_subdomain
# Otherwise, default to backend_web1
default_backend backend_web1