diff --git a/docs/configuring-playbook-own-webserver.md b/docs/configuring-playbook-own-webserver.md index 26773436..a543b1b3 100644 --- a/docs/configuring-playbook-own-webserver.md +++ b/docs/configuring-playbook-own-webserver.md @@ -53,6 +53,9 @@ Once you've followed the [Preparation](#preparation) guide above, you can take a After following the [Preparation](#preparation) guide above, you can take a look at the [examples/caddy](../examples/caddy) directory for a sample configuration. +## Using your own HAproxy reverse proxy +After following the [Preparation](#preparation) guide above, you can take a look at the [examples/haproxy](../examples/haproxy) directory for a sample configuration. In this case HAproxy is used as a reverse proxy and a simple Nginx container is used to serve statically `.well-known` files. + ## Using another external webserver Feel free to look at the [examples/apache](../examples/apache) directory, or the [template files in the matrix-nginx-proxy role](../roles/matrix-nginx-proxy/templates/conf.d/). diff --git a/examples/haproxy/Dockerfile b/examples/haproxy/Dockerfile new file mode 100644 index 00000000..8c7db989 --- /dev/null +++ b/examples/haproxy/Dockerfile @@ -0,0 +1,12 @@ +# Pull nginx base image +FROM nginx:latest + +# Expost port 80 +EXPOSE 80 + +# Copy custom configuration file from the current directory +COPY nginx.conf /etc/nginx/nginx.conf + +# Start up nginx server +CMD ["nginx"] + diff --git a/examples/haproxy/README.md b/examples/haproxy/README.md new file mode 100644 index 00000000..24a433b9 --- /dev/null +++ b/examples/haproxy/README.md @@ -0,0 +1,25 @@ +# HAproxy reverse-proxy + +This directory contains sample files that show you how to do reverse-proxying using HAproxy. + +This is for when you wish to have your own HAproxy instance sitting in front of Matrix services installed by this playbook. +See the [Using your own webserver, instead of this playbook's nginx proxy](../../docs/configuring-playbook-own-webserver.md) documentation page. + +To use your own HAproxy reverse-proxy, you first need to disable the integrated Nginx server. +You do that with the following custom configuration (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_nginx_proxy_enabled: false +``` + +You can then use the configuration files from this directory as an example for how to configure your HAproxy reverse proxy. + +**NOTE**: this is just an example and may not be entirely accurate. It may also not cover other use cases or performance needs. + +### Configuration + +HAproxy, unlike Apache, Nginx and others, does not provide you with a webserver to serve static files (i.e., `/.well-known/` directory). For this reason, in this folder you can find an example on how to use HAproxy together with a simple Nginx container whose only task is to serve those files. + +* Build the Docker image. `docker build -t local/nginx .` +* Start the container. `docker-compose up -d`. Note that if you want to run Nginx on a different port, you will have to change the port both in the `docker-compose.yml` and in `haproxy.cfg` files. +* Start HAproxy with the proposed configuration. \ No newline at end of file diff --git a/examples/haproxy/docker-compose.yml b/examples/haproxy/docker-compose.yml new file mode 100644 index 00000000..ea833c9b --- /dev/null +++ b/examples/haproxy/docker-compose.yml @@ -0,0 +1,8 @@ +version: '3' +services: + neginx: + image: local/nginx + ports: + - 40888:80 + volumes: + - /matrix/static-files:/var/www/:rw diff --git a/examples/haproxy/haproxy.cfg b/examples/haproxy/haproxy.cfg new file mode 100644 index 00000000..7782f34c --- /dev/null +++ b/examples/haproxy/haproxy.cfg @@ -0,0 +1,96 @@ +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 redispatch + 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 https-frontend + bind *:80 + # HAproxy wants the full chain and the private key in one file. For Letsencrypt manually generated certs (e.g., wildcard certs) you can use + # cat /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem > /etc/haproxy/certs/star-example.com.pem + bind *:443 ssl crt /etc/haproxy/certs/star-example.com.pem + reqadd X-Forwarded-Proto:\ https + option httplog + option http-server-close + # + # Matrix + # + # matrix.example.com + acl matrix_domain hdr_dom(host) -i matrix.example.com + acl static_files path -i -m beg /.well-known/matrix + use_backend nginx-static if static_files + # /_matrix/identity and /_matrix/client/r0/user_directory/search + acl matrix_identity path -i -m beg /_matrix/identity + acl matrix_search path -i -m beg /_matrix/client/r0/user_directory/search + # Send to :8090 + use_backend matrix-supporting if matrix_identity or matrix_search + # /_matrix and /_synapse/admin + acl matrix_path path -i -m beg /_matrix + acl synapse_admin path -i -m beg /_synapse/admin + # Send to :8008 + use_backend matrix-main if matrix_path or synapse_admin + # riot.example.com + acl riot_domain hdr_dom(host) -i riot.example.com + # Send to 8765 + use_backend riot if riot_domain + # If nothing else match, just send to default matrix backend + use_backend matrix-main if matrix_domain + #default_backend matrix-main + +frontend matrix-federation + bind *:8448 ssl crt /etc/haproxy/certs/star-example.com.pem + reqadd X-Forwarded-Proto:\ https + option httplog + option http-server-close + default_backend synapse + +backend matrix-supporting + server matrix-supporting 127.0.0.1:8090 check + +backend matrix-main + server matrix-main 127.0.0.1:8008 check + +backend synapse + server synapse 127.0.0.1:8048 check + +backend nginx-static + capture request header origin len 128 + http-response add-header Access-Control-Allow-Origin * + rspadd Access-Control-Allow-Methods:\ GET,\ HEAD,\ OPTIONS,\ POST,\ PUT if { capture.req.hdr(0) -m found } + rspadd Access-Control-Allow-Credentials:\ true if { capture.req.hdr(0) -m found } + rspadd Access-Control-Allow-Headers:\ Origin,\ Accept,\ X-Requested-With,\ Content-Type,\ Access-Control-Request-Method,\ Access-Control-Request-Headers,\ Authorization if { capture.req.hdr(0) -m found } + server nginx 127.0.0.1:40888 check + +backend riot + server riot 127.0.0.1:8765 check + diff --git a/examples/haproxy/nginx.conf b/examples/haproxy/nginx.conf new file mode 100644 index 00000000..29807eec --- /dev/null +++ b/examples/haproxy/nginx.conf @@ -0,0 +1,18 @@ +worker_processes auto; + +daemon off; + +events { + worker_connections 1024; +} + +http { + server_tokens off; + server { + listen 80; + index index.html; + root /var/www; + + } + +}