GatewayNode

Setting up a restricted Matrix home server in AWS EC2 for Dev

Note

Seriously, this isn't meant to be a guide to setting up a public facing server. Not prod ready rant at the end.

So I took the shortcut (of course I did, I'm in developer mode now). First I got a new elastic IP to use. I setup DNS in Route53 to handle the SRV record and a A record to matrix.gatewaynode.com. I created new EC2 access keys for this instance, downloaded them and started a login script using them. In AWS I created a security group locked to inbound from my home IP address for ports 22, 443 and 8448. The I spun up a t2micro in EC2 using the verified Debian image (stretch). I logged into SSH and ran general updates and upgrades using sudo apt-get update; sudo apt-get upgrade -y. Pretty standard stuff.

Now we need to add the Matrix repos as they add official .deb packages. So I created a new file /etc/apt/sources.list.d/synapse.list and added these two repos each on it's own line deb http://matrix.org/packages/debian/ stretch main and deb-src http://matrix.org/packages/debian/ stretch main. We'll need to run apt-get update again to get the repo packages. And then installing a running, daemonized install of synapse server is as simple as sudo apt-get install matrix-synapse.

Almost done, we still need a cert. So sudo apt-get install certbot and we can use "let's encrypt" to finish this.

sudo certbot certonly --standalone -d matrix.gatewaynode.com

<snip big long message> Timeout during connect (likely firewall problem)...

Yep, "let's encrypt" needs to verify the domain on port 80 inbound. So just quickly go back to the AWS panel, open your security group and add port 80 inbound from 0.0.0.0. Run the previous certbot command again and you are set. Close the port and move on.

I recommend copying the certs necessary from /etc/letsencrypt/live/DOMAIN_NAME/cert.pem and /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem to the /etc/matrix-synapse/ folder and updating the /etc/matrix-synapse/homeserver.yaml config file and fixing the permissions so Synapse can read them. But if you want to point the config to the letsencrypt folder have fun.

Restart the server or service and you should be running. This is a minimal setup and should be sufficient for dev work but not likely a good setup for running your own home server. Next steps are to snap an image and spin up and down as necessary to do dev work (and script that nonsense, no need to play typing tutor to pretend like you're 1337).

Not Production Ready Rant

There is so much wrong with this build that this should never ever be used to host a publicly facing Matrix home server. Here is a non exhaustive list:

  • The Operating System

    • Debian is pretty secure by default, but we could harden it quite a bit. A better approach would be to start with a more minimal OS like Alpine with a decent secure by default base install.

    • Or go serverless, let somebody else keep things up to date.

      • Remember. "There is no cloud, it's just someone else's computer."
  • The Dependencies

    • So many... Matrix is a hefty beast. This setup really needs a full build pipeline with regular and triggered builds to update everything. Debian unattended upgrades just doesn't cut it.
  • The Application

    • The dirty, dirty user input

      • Basically the app is potentially vulnerable to ALL the bad things given that it's primary purpose is dealing with free form user input and files. SQLi, XSS, CMDi, CSRF, XSRF, SSFI, are all potentially exploitable.
    • A locally installed database...

      • Yeah, you really want to separate this into a different server (RDS preferably) and load the credentials directly into the application from AWS secrets manager or the like.
  • Ephemeral storage

    • This is not just bad for production, it's failure waiting to happen. If the instance is ever terminated all your data goes bye bye.
  • Certs are built locally

    • Just no. It was easy sure, but for production, never.
  • No WAF or RASP

    • Web Application Firewalls and Realtime Application Self Protection systems are critical in production systems as additional layers of defense that can protect you when a Matrix dev injects an exploitable bug in the codebase.
  • No monitoring

    • Nothing's wrong if we can't see anything, right?

Yeah, don't do this in prod kids.

Ouroboros, you know the snake that eats itself...