I was setting up a server for the company I work at that required both a Wordpress website as well as Nextcloud. Now of course, these services require much less thinking if you leave them on their native ports 80 and 443, and you donāt have to tell your employees to go to port 8443 to visit the company cloud! That meant my solution was to do a reverse proxy, and I chose to do HAProxy. This is a good use case if you want to run separate services on different machines on the local network, VMs or containers. My rig is set up as follows:
OS: Ubuntu Server 16.04
LXD containers inside a ZFS pool
Here are my 3 containers:
- Ubuntu 16.04 container using LAMP and Wordpress
- Ubuntu 16.04 container using LAMP and Nextcloud
- Ubuntu 16.04 container with just HAProxy
Install your SSL certificates on your Nextcloud and other machines (if you have them) to allow HAProxy to pass the SSL traffic to the server. There is an SSL Termination configuration available too, but these configurations only focus on the pass through configuration.
If you donāt know much about reverse proxies (like me), be sure to forward ports 80 and 443 on your router to your HAProxy containerās IP address since that machine will be handling the incoming traffic from the web and passing it to the backend. This configuration also utilizes the TLS SNI feature so specifying the ServerName in your apache (or nginx or whatever youāre using) configuration files.
In my case I am using Wordpress and Nextcloud, but you can use whatever you want following the template of these configurations.
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
maxconn 4096
user haproxy
group haproxy
daemon
defaults
log global
mode tcp
option tcplog
option dontlognull
timeout connect 15s
timeout client 15s
timeout server 15s
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 localhost80 #Front end for port 80, does a redirect to port 443
bind *:80
mode http
redirect scheme https code 301 if !{ ssl_fc }
frontend localhost443 #Listens on port 443
bind *:443
option tcplog
mode tcp
acl tls req.ssl_hello_type 1
tcp-request inspect-delay 5s
tcp-request content accept if tls
acl is_wordpress req.ssl_sni -i domain1.com # ACL specifying domain1
acl is_nextcloud req.ssl_sni -i www.domain2.com # ACL specifying domain2
acl is_nextcloud2 req.ssl_sni -i domain2.com # ACL specifying www.domain2
# I had to make a separate ACL for www.domain2.com because that's my nextcloud's SNI, domain2.com is the alias to it, had to specify both for it to work for me
use_backend nextcloud_cluster if is_nextcloud #points the ACL to the backend
use_backend nextcloud_cluster if is_nextcloud2
use_backend wordpress_cluster if is_wordpress
backend wordpress_cluster
mode tcp
option ssl-hello-chk
# Provide your server's <ip_addr>:443. You can have many servers in your backend since HAProxy does loadbalancing
server is_wordpress 10.0.0.165:443 check
backend nextcloud_cluster
mode tcp
option ssl-hello-chk
server is_nextcloud 10.0.0.160:443 check
Since HAProxy can also do load balancing, you can scale Nextcloud across multiple computers for load balancing. The Nextcloud documentation has a page on this which could come in handy if you need this
https://docs.nextcloud.com/server/9/admin_manual/operations/scaling_multiple_machines.html
To start HAProxy, check to see if there are any instances of HAProxy running and kill them:
top -u haproxy
To start HAProxy, I ran this command:
/usr/sbin/haproxy -db -f /etc/haproxy/haproxy.cfg -D -p /var/run/haproxy.pi
Hopefully this helps people out! I ended up having to sift through tens of different configurations to get my setup to work so YMMV, but this is what worked for me after about a week of head bashing
UPDATE:
Iām providing an update for the folks who wish to do this with FreeBSD. I recently switched my environment to this Ubuntu setup to FreeBSD, and the differences are mild. First, make sure you have HAProxy installed. The config script will have a full path of /usr/local/etc/haproxy.conf. Also make sure you added the line haproxy_enable="YES"
in your /etc/rc.conf file.
The config file will follow all the same configs, but for each backend, make sure you do NOT have option ssl-hello-chk
.
Finally, FreeBSD has some really nice HAProxy integration. So, once you have your config file set up the way you like it, itās as simple as running service haproxy start
and you should be good!
UPDATE 2:
If you want to pass through all HTTP/HTTPS connections to your webserver and let your webserver do the redirect to port 443 instead of HAProxy, you can do this for the port 80 rules:
frontend localhost80
bind *:80
log global
mode http
acl is_nextcloud hdr(host) -i domain2.com
acl is_wordpress hdr(host) -i domain1.com
use_backend nextcloud_cluster if is_nextcloud
use_backend wordpress_cluster if is_wordpress
A reason why you might want to do this is to more easily do Letās Encrypt verifications.