Multiple domains - sub domains - and servers from one IP with Hhaproxy
-
Some preface;
Currently SSL and http-https redirect is handled on the webserver. The webserver also proxies to other services on the network that need to me accessed from the web because I am using NAT for forward 80/443 to the webserver. This obviously isn't great, because everything relies on the webserver, so if the main server goes down then everything is down.Currently Im using the DNS forwarder, with host overrides so I can access these services within my LAN, again, a bit clunky to set up.
HAproxy looks like the solution, and I have tried to set it up and failed. Basically:
- Server A: domain1.com subdomain.domain1.com domain2.com domain3.com domain4.ca -SSL with Letsencrypt, http->https
- Server B: subdomain2.domain1.com -using apache to forward
- Server C: subdomain3.domain1.com -using apache to forward
- Server D: subdomain4.domain1.com - new server, not accessable
So, I setup an ACME certificate in PFsense, removed the NAT rule, created a new allow all wan rule, (80, 443) moved the pfsense webconfig port, disabled the SSL sites in Apache2, and removed the SSL stuff from the sites-available. Set up a couple frontends and backends and enable Haproxy.
- Server D: Subdomain4.domain1.com - works! servs over https and theres no SSL on the server! nice! (pc.daynewaterlow.com)
- Server A, B, and C - all go to the "Default Ubuntu Apache2 Page" - Which makes me feel like the headers aren't getting sent from HAproxy to the backend.
I tried everything from
host-matches *.domain1.comtohost ends with domain1.comin the front end.I tried to add things like:
http-request set-header Host %[hdr(host)]into frontend passthrough, or backend passthrough (grasping at straws)I gave up and reverted everything after hours of googling and tweaking frontend and backend settings. I don't understand !
Maybe there is a better solution? Or maybe I'm missing something simple.
Here is the my last try HAproxy Config from 1 in the morning (Copied from "show config"):
# Automaticaly generated, dont edit manually. # Generated on: 2026-03-30 01:02 global maxconn 100 stats socket /tmp/haproxy.socket level admin expose-fd listeners uid 80 gid 80 nbthread 1 hard-stop-after 15m chroot /tmp/haproxy_chroot daemon server-state-file /tmp/haproxy_server_state listen HAProxyLocalStats bind 127.0.0.1:2200 name localstats mode http stats enable 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 hackserv-merged bind *myWANip*:443 name *myWANip*:443 ssl crt-list /var/etc/haproxy/hackserv.crt_list bind *myWANip*:80 name *myWANip*:80 mode http log global option http-keep-alive timeout client 30000 http-request set-header Host %[hdr(host)] acl luckfox var(txn.txnhost) -m str -i pc.daynewaterlow.com acl matrix2 var(txn.txnhost) -m str -i matrix2.daynewaterlow.com acl headscale var(txn.txnhost) -m str -i headscale.daynewaterlow.com acl daynewaterlow var(txn.txnhost) -m end -i daynewaterlow.com acl waterlowphotography var(txn.txnhost) -m end -i waterlowphotography.com acl titsnbeans var(txn.txnhost) -m end -i titsnbeans.com acl gfarc var(txn.txnhost) -m end -i gfarc.ca acl kettlerivercycling var(txn.txnhost) -m end -i kettlerivercycling.com acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^([^\.]*)\.daynewaterlow\.com(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^([^\.]*)\.dwhacks\.com(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^([^\.]*)\.gfarc\.ca(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^([^\.]*)\.kettlerivercycling\.com(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^([^\.]*)\.titsnbeans\.com(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^([^\.]*)\.waterlowphotography\.com(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^daynewaterlow\.com(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^dwhacks\.com(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^gfarc\.ca(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^kettlerivercycling\.com(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^titsnbeans\.com(:([0-9]){1,5})?$ acl aclcrt_hackserv var(txn.txnhost) -m reg -i ^waterlowphotography\.com(:([0-9]){1,5})?$ http-request set-var(txn.txnhost) hdr(host) use_backend luckFox_ipvANY if luckfox use_backend hackserv_ipvANY if daynewaterlow aclcrt_hackserv use_backend matrixbtw_ipvANY if matrix2 aclcrt_hackserv use_backend hackserv_ipvANY if waterlowphotography aclcrt_hackserv use_backend hackserv_ipvANY if titsnbeans aclcrt_hackserv use_backend hackserv_ipvANY if gfarc aclcrt_hackserv use_backend hackserv_ipvANY if kettlerivercycling aclcrt_hackserv use_backend headscale_ipvANY if headscale aclcrt_hackserv use_backend hackserv_ipvANY if aclcrt_hackserv backend luckFox_ipvANY mode http id 105 log global timeout connect 30000 timeout server 30000 retries 3 load-server-state-from-file global server luckFox 192.168.2.219:80 id 103 check inter 1000 backend hackserv_ipvANY mode http id 102 log global http-check send meth OPTIONS timeout connect 30000 timeout server 30000 retries 3 load-server-state-from-file global option httpchk server Hackserv 192.168.2.7:80 id 103 check inter 1000 backend matrixbtw_ipvANY mode http id 100 log global http-check send meth OPTIONS timeout connect 30000 timeout server 30000 retries 3 load-server-state-from-file global option httpchk server matrixbtw 192.168.2.87:8008 id 101 check inter 1000 backend headscale_ipvANY mode http id 104 log global timeout connect 30000 timeout server 30000 retries 3 load-server-state-from-file global server headscale 192.168.2.201:443 id 103 ssl verify none -
Holy Friggin HECK, what a nightmare! Guess what? Reboot pfsense....
Not sure why, or what config changes require a reboot, so if anyone has an insight that would be excellent.
Found the solution here: Solution