This guide is to provide an introduction on installing, configuring and utilizing HAProxy as a proxy for Mattermost. This is just the way I have HAProxy currently configured, so if there are any issues with this guide please leave a comment and I will do my best to update it.
HTTP/2 support is coming to HAProxy in version 1.8
frontend www-https
bind *:443 ssl crt /etc/haproxy/certs/{domain-name}/{domain-name}.pem alpn http/1.1,h2
mode http
Installing HAProxy Server
In a production setting, use a proxy server for greater security and performance of Mattermost.
The main benefits of using a proxy are as follows:
- SSL Termination
- HTTP to HTTPS redirect
- Port mapping
:80
to:8065
- Standard request logs
To install HAProxy on Ubuntu Server:
-
Log in to the server that will host the proxy and open a terminal window.
-
Install HAProxy.
sudo apt-get install haproxy
-
After the installation is complete, verify that HAProxy is running.
sudo systemctl status haproxy
Note:
You can stop, start and restart HAProxy with the following commands:
sudo service systemctl stop haproxy
sudo service systemctl start haproxy
sudo service systemctl restart haproxy
What to do next
- Map a fully qualified domain name (FQDN) such as
mattermost.example.com
to point to the HAProxy server. - Configure HAProxy to proxy connections from the internet to the mattermost Server.
Configuring HAProxy as a proxy for Mattermost Server
HAProxy is configured using a file in the /etc/haproxy/
directory. You need to edit the haproxy.cfg
file. When editing the file, you need the IP address of your Mattermost server and fully qualifed domain (FQDN) of your Mattermost website.
To configure HAProxy as a proxy
-
Login in to the server that hosts HAProxy and open a terminal window.
-
Open the file
/etc/haproxy/haproxy.cfg
as root in a text editor and add the following lines at the end of the file. Make sure that you use your own values for the Mattermost server IP address and FQDN for server_name.frontend www-http bind :80 mode http default_backend mattermost backend mattermost mode http server 10.10.10.2:8065 check
-
Restart HAProxy
On Ubuntu 14.04 and RHEL 6.6:
sudo service haproxy restart
On Ubuntu 16.04, Debian Jessie, and RHEL 7.1:
sudo systemctl restart haproxy
-
Verify you can see Mattermost through the proxy.
curl http://<mattermost_server>
If everything is working, you will see the HTML for the Mattermost signup page.
- Restrict access to port 8065.
By default, the Mattermost server accepts connections on port 8065 from every machine on the network. Use your firewall to deny connections on port 8065 to all machines except the machine that hosts HAProxy and the machine that you use to administer Mattermost server. If you’re installing on Amazon Web Services, you can use security groups to restrict access.
Now that HAProxy is installed and running, you can configure it to use SSL, which allows you to use HTTPS connections and the HTTP/2 protocol.
Configuring HAProxy with SSL
Using SSL gives greater security by ensuring that communications between Mattermost clients and the Mattermost server are encrypted. It also allows you to configure HAProxy to use the HTTP/2 protocol.
Although you can configure HTTP/2 without SSL, both Firefox and Chrome browsers support HTTP/2 on secure connections only.
You can use any certificate that you want, but these instructions show you how to download and install certificates from Let’s Encrypt, a free certificate authority.
To configure SSL:
-
Log in to the server that hosts HAProxy and open a terminal window.
-
Install git.
If you are using Ubuntu or Debian:
sudo apt-get install git
If you are using RHEL:
sudo yum install git
-
Clone the Let’s Encrypt repository on GitHub.
git clone https://github.com/letsencrypt/letsencrypt
-
Change to the
letsencrypt
directory.cd letsencrypt
-
Stop HAProxy.
On Ubuntu 14.04 and RHEL 6.6:
sudo service haproxy stop
On Ubuntu 16.04 and RHEL 7.1:
sudo systemctl stop haproxy
-
Run
netstat
to make sure that nothing is listening on port 80.netstat -na | grep ':80.*LISTEN'
-
Run the Let’s Encrypt installer.
./letsencrypt-auto certonly --standalone
When prompted, enter your domain name. After the installation is complete, you can find the certificate in the /etc/letsencrypt/live
directory.
-
Open the file
/etc/haproxy/haproxy.cfg
as root in a text editor and update the server section to incorporate the highlighted lines in the following sample. Make sure to replace {domain-name} with your own domain name, in 2 places.frontend www-http redirect scheme https code 301 if !{ ssl_fc } frontend www-https bind *:443 ssl crt /etc/haproxy/certs/{domain-name}/{domain-name}.pem default_backend mattermost
-
Restart HAProxy.
On Ubuntu 14.04 and RHEL 6.6:
sudo service haproxy start
On Ubuntu 16.04 and RHEL 7.1:
sudo systemctl start haproxy
-
Check that your SSL certificate is set up correctly.
- Test the SSL certificate by visiting a site such as SSL Server Test (Powered by Qualys SSL Labs)
- If there’s an error about the missing chain or certificate path, there is likely an intermediate certificate missing that needs to be included.
-
Configure a Let’s Encrypt backend
backend letsencrypt server 127.0.0.1:54321
-
Restart HAProxy.
On Ubuntu 14.04 and RHEL 6.6:
sudo service haproxy start
On Ubuntu 16.04 and RHEL 7.1:
sudo systemctl start haproxy
-
Open the file
/etc/letsencrypt/renewal/{domain-name}.conf
as root in a text editor and update thehttp01_port
section to incorporate the highlighted lines in the following sample.http01_port = 54321
Run a --dry-run
so nothing gets renewed.
sudo certbot renew --dry-run
- Create a script called
renew.sh
to renew and generate a.pem
for HAProxy.
In the following script, use your own domain name in place of {domain-name}
SITE={domain-name}
# move to the correct let's encrypt directory
cd /etc/letsencrypt/live/$SITE
# cat files to make combined .pem for haproxy
cat fullchain.pem privkey.pem > /etc/haproxy/certs/$SITE.pem
#reload haproxy
service haproxy reload
Make the script executable
sudo chmod u+x /usr/local/bin/renew.sh
-
Configure
cron
so that the certificate will automatically renew every month.crontab -e
In the following line, use your own domain name in place of {domain-name}
``@monthly /usr/bin/certbot renew --renew-hook "/usr/local/bin/renew.sh" >> /var/log/haproxy/cert-renewal.log``