[GUIDE] Using HAProxy with Mattermost

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:

  1. Log in to the server that will host the proxy and open a terminal window.

  2. Install HAProxy.

    sudo apt-get install haproxy

  3. 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

  1. Map a fully qualified domain name (FQDN) such as mattermost.example.com to point to the HAProxy server.
  2. 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

  1. Login in to the server that hosts HAProxy and open a terminal window.

  2. 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
    
  3. 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

  4. 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.

  1. 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:

  1. Log in to the server that hosts HAProxy and open a terminal window.

  2. Install git.

    If you are using Ubuntu or Debian:

    sudo apt-get install git

    If you are using RHEL:

    sudo yum install git

  3. Clone the Let’s Encrypt repository on GitHub.

    git clone https://github.com/letsencrypt/letsencrypt

  4. Change to the letsencrypt directory.

    cd letsencrypt

  5. 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

  6. Run netstat to make sure that nothing is listening on port 80.

    netstat -na | grep ':80.*LISTEN'

  7. 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.

  1. 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
    
  2. 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

  3. 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.
  1. Configure a Let’s Encrypt backend

    backend letsencrypt
    server 127.0.0.1:54321
    
  2. 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

  3. Open the file /etc/letsencrypt/renewal/{domain-name}.conf as root in a text editor and update the http01_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
  1. 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
  1. 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``
2 Likes

This is fantastic!! Huge thanks @kjkeane :slight_smile:

Unfortunately this misses the setup for websocket connections.