J. R. Swab

How To Install a Matrix Server (Synapse) on OpenBSD

Categories: [Technology], [How To], [OpenBSD]

After much trouble shooting for several days I finally got this working. :sweat_smile:

This setup uses Openbsd 7.1 and will use a reverse proxy via relayd.

SSL certs are not added directly into the synapse homeserver.yaml file in this setup.

Installation Steps

  1. Install synapse: doas pkg_add synapse
  2. Install postgresql and py3-psycopg2: pkg_add postgresql-server py3-psycopg2
  3. As root, go into /var/synapse, then execute the following (change "matrix.example.com to your matrix domain or sub domain): doas -u _synapse /usr/local/bin/python3.8 -m synapse.app.homeserver -c /var/synapse/homeserver.yaml --generate-config --server-name matrix.example.com --report-stats=no --generate-keys --keys-directory /var/synapse
  4. Read through the newly created homeserver.yaml file and make the appropriate changes. (Don't enable TLS here). Be sure to update the database section as documented here.
  5. doas rcctl enable postgresql && rcctl start postgresql
  6. doas rcctl enable synapse && rcctl start synapse
  7. Set up /etc/acme-client.conf as shown further down this post. (skip their httpd.conf example and use the one listed below in this post and stop at the title "Enable HTTPS and restart the daemon")
  8. Add 0 0 1 * * cp /etc/ssl/example.com.pem /etc/ssl/example.com.crt && rcctl restart relayd to the root's crontab -e (update the urls)
  9. Set up /etc/relayd.conf as shown below.
  10. doas rcctl restart httpd
  11. doas rcctl restart relayd
  12. doas rcctl restart synapse
  13. Check the url for the matrix server to verify that the "it's working" page displays.
  14. To add users when registration is turned off: doas -u _synapse /usr/local/share/synapse/register_new_matrix_user -c /var/synapse/homeserver.yaml http://localhost:8008
  15. For other commands and information, visit /usr/local/share/doc/pkg-readmes/synapse.

Configuration Files

/etc/httpd.conf:

prefork 5

server "example.com" {
    alias "chat.example.com"
    listen on * port 80
    location "/.well-known/acme-challenge/*" {
            root "/acme"
            request strip 2
    }
    location * {
            block return 301 "https://$HTTP_HOST$REQUEST_URI"
    }
}

server "example.com" {
    listen on * port 8080
    location * {
            root "/htdocs/www/public/"
    }
}

/etc/relayd.conf:

log state changes
log connection errors
prefork 5

table <httpd> { 127.0.0.1 }
table <synapse> { 127.0.0.1 }

http protocol "wwwsecure" {
    tls keypair "example.com"
    # Uncomment below if you have a different cert for a matrix subdomain.
    # tls keypair "chat.example.com"

    # Return HTTP/HTML error pages to the client
    return error
    # you may want to remove this depending on your use case
    #match request header set "Connection" value "close"

    # your web application might need these headers
    match request header set "X-Forwarded-For" value "$REMOTE_ADDR"
    match request header set "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"

    # set best practice security headers
    # use https://securityheaders.com to check
    # and modify as needed
    match response header remove "Server"
    match response header append "Strict-Transport-Security" value "max-age=31536000; includeSubDomains"
    match response header append "X-Frame-Options" value "SAMEORIGIN"
    match response header append "X-XSS-Protection" value "1; mode=block"
    match response header append "X-Content-Type-Options" value "nosniff"
    match response header append "Referrer-Policy" value "strict-origin"
    match response header append "Content-Security-Policy" value "default-src https:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'"
    match response header append "Permissions-Policy" value "accelerometer=(none), camera=(none), geolocation=(none), gyroscope=(none), magnetometer=(none), microphone=(none), payment=(none), usb=(none)"

    # set recommended tcp options
    tcp { nodelay, sack, socket buffer 65536, backlog 100 }

    pass  request  quick  header  "Host"  value  "example.com"       forward  to  <httpd>
    pass  request  quick  header  "Host"  value  "chat.example.com"  forward  to  <synapse>
}

relay "wwwsecure" {
    listen on 0.0.0.0 port 443 tls
    protocol wwwsecure
    forward to <httpd> port 8080
    forward to <synapse> port 8008
}
relay "wwwsecure6" {
    listen on :: port 443 tls
    protocol wwwsecure
    forward to <httpd> port 8080
    forward to <synapse> port 8008
}