From 66ab861d63fb19faacb55a5bb2ce5ed83461ee39 Mon Sep 17 00:00:00 2001 From: Awiteb Date: Sat, 13 Apr 2024 17:33:38 +0300 Subject: [PATCH] first commit --- Justfile | 30 +++++++++ LICENSE | 21 ++++++ README.md | 141 ++++++++++++++++++++++++++++++++++++++++ data/4rs.nl.log.config | 39 +++++++++++ data/4rs.nl.signing.key | 1 + data/homeserver.yaml | 67 +++++++++++++++++++ docker-compose.yml | 25 +++++++ generate_signing_key | 27 ++++++++ 8 files changed, 351 insertions(+) create mode 100644 Justfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 data/4rs.nl.log.config create mode 100644 data/4rs.nl.signing.key create mode 100644 data/homeserver.yaml create mode 100644 docker-compose.yml create mode 100644 generate_signing_key diff --git a/Justfile b/Justfile new file mode 100644 index 0000000..bbfd6d7 --- /dev/null +++ b/Justfile @@ -0,0 +1,30 @@ +@_default: + {{just_executable()}} -f {{justfile()}} --list + +# Run the instance [aliases: r] +@run: + sudo docker-compose up -d + +# Stop the instance [aliases: s] +@stop: + sudo docker-compose rm -f -s + +# Restart the instance +@restart: + sudo docker-compose restart + +# Create Backup file [aliases: b] +@backup backup_name: stop && run + #!/usr/bin/env bash + FILES="data postgresdata Justfile docker-compose.yml README.md" + 7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -mhe=on -p {{backup_name}}.7z $FILES + echo "Backup done..." + + +[private] +alias r := run +[private] +alias s := stop +[private] +alias b := backup + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9d67435 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2024, Awiteb + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f2edc56 --- /dev/null +++ b/README.md @@ -0,0 +1,141 @@ +# 4rs matrix homeserver + +This is my personal matrix homeserver. You can clone this repository and run the homeserver with docker-compose. + +## Overview +In this repository I use `4rs.nl` (my domain) as an example. You should replace this with your own domain. +After reading this README you should have a `/.well-known/matrix/server` and `/.well-known/matrix/client` file on your domain (4rs.nl) and your matrix subdomain (matrix.4rs.nl). The client will use `matrix.4rs.nl` as the homeserver and the displayed homeserver will be `4rs.nl`. + +## Requirements +- docker +- docker-compose +- nginx + +## Domain requirements +- Have a `/.well-known/matrix/server` file on your domain that points to your homeserver. This is required for federation to work. +The content of the file should be: +``` +{ + "m.server": "matrix.4rs.nl:443" +} +``` +- Have a `/.well-known/matrix/client` file on your domain that points to your homeserver. This is required for the client to work. +The content of the file should be: +``` +{ + "m.homeserver": { + "base_url": "https://matrix.4rs.nl" + } +} +``` + +For me, I created the files in my static blog and then deployed it in GitHub pages. See the [justfile that I use to deploy the files to the domain](https://git.4rs.nl/awiteb/blog/src/branch/master/Justfile#L15-L17). You can use any other method to deploy the files and make them accessible on your domain, as long as they are accessible at `/.well-known/matrix/server` and `/.well-known/matrix/client`. + + +## Nginx configuration of the matrix subdomain +You should have a nginx configuration for the matrix subdomain at `/etc/nginx/sites-available/matrix.4rs.nl` and symlinked to `/etc/nginx/sites-enabled/matrix.4rs.nl`, Also include it in the `nginx.conf` file with `include /etc/nginx/sites-enabled/*;` (the include is already in the `nginx.conf` file when you install nginx). + +You also need to have a certificate for the domain. You can get a free certificate from [Let's Encrypt](https://letsencrypt.org/). You can use [Certbot](https://certbot.eff.org/) to get a certificate. (Generate a certificate for `4rs.nl` and `*.4rs.nl`) + +The configuration should look like this (replace `4rs.nl` with your domain) +``` +server { + server_name matrix.4rs.nl; + listen 80; + listen [::]:80; + location / { + return 301 https://$server_name$request_uri; + } +} + +server { + server_name matrix.4rs.nl; + listen 443 ssl http2; + listen [::]:443 ssl http2; + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log warn; + + ssl_session_timeout 1d; + ssl_session_cache shared:MozSSL:10m; + ssl_session_tickets off; + + ssl_trusted_certificate /etc/letsencrypt/live/4rs.nl/chain.pem; + ssl_certificate /etc/letsencrypt/live/4rs.nl/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/4rs.nl/privkey.pem; + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; + ssl_prefer_server_ciphers off; + ssl_stapling on; + ssl_stapling_verify on; + + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/activity+json application/atom+xml; + + ignore_invalid_headers off; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + client_body_timeout 5s; + client_header_timeout 5s; + + location /.well-known/matrix/server { + return 200 '{"m.server": "matrix.4rs.nl:443"}'; + default_type application/json; + add_header Access-Control-Allow-Origin *; + } + location /.well-known/matrix/client { + return 200 '{"m.homeserver": {"base_url": "https://matrix.4rs.nl}}'; + default_type application/json; + add_header Access-Control-Allow-Origin *; + } + location / { + proxy_pass http://localhost:8008; + proxy_set_header X-Forwarded-For $remote_addr; + client_max_body_size 200M; + } +} +``` +After you have created the configuration file, reload nginx with `sudo systemctl reload nginx`. You should now be able to access the homeserver at `matrix.4rs.nl`. + +Now you end up the Nginx configuration for the matrix subdomain. The next step is to clone this repository and run the homeserver. + +## Clone the repository +After you have set up the domain and the nginx configuration, you can clone this repository with `git clone https://4rs.nl/awiteb/synapse-config.git`. You should now have a directory called `synapse-config`. + +## Configuration +After you have cloned the repository, replace all `4rs.nl` with your domain also the files in the `./data` directory. + +There is tow things only you need to change it, the first one is the secrets in `./data/homeserver.yaml` and the second one is the signing key in `./data/4rs.nl.signing.key`. + +### Homeserver.yaml +After replacing all `4rs.nl` with your domain, you need to generate a secret for each secret in the `homeserver.yaml` file. You can generate a secret with `openssl rand -base64 32`. Replace the secret with the generated secret. + +### Signing key + +> **Note:** You need `signedjson` dependency to generate a signing key. You can install it with `pip3 install signedjson`. + +Change the content of the `4rs.nl.signing.key` file with a generated key. You can generate a key with `generate_signing_key` script in root of the repository. Run `python3 generate_signing_key` and replace the content of the `4rs.nl.signing.key` file with the generated key. + + +## Run the homeserver and create the admin user +After all above steps, you can run the homeserver with `docker-compose up -d`. You should now have a running homeserver on `matrix.4rs.nl`. + +Now you need to create an admin user with `docker exec -it synapse register_new_matrix_user http://localhost:8008 -c /data/homeserver.yaml` and follow the instructions. You should now have an admin user on the homeserver and you can login with it on the client using the homeserver `matrix.4rs.nl`. Enjoy your homeserver! + +## Backup + +> **Note:** You need [`just`](https://just.systems/) to backup the homeserver. You can install it with `cargo install just`. + +You can backup the homeserver with `just backup `. And it's will stored as encrypted AES256 7z file. + +## Any questions? +If you have any questions, you can contact with me at `@awiteb:4rs.nl` and I will try to help you. Have fun with your homeserver! diff --git a/data/4rs.nl.log.config b/data/4rs.nl.log.config new file mode 100644 index 0000000..832f0fa --- /dev/null +++ b/data/4rs.nl.log.config @@ -0,0 +1,39 @@ +version: 1 + +formatters: + precise: + + format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' + + +handlers: + + + console: + class: logging.StreamHandler + formatter: precise + +loggers: + # This is just here so we can leave `loggers` in the config regardless of whether + # we configure other loggers below (avoid empty yaml dict error). + _placeholder: + level: "INFO" + + + + synapse.storage.SQL: + # beware: increasing this to DEBUG will make synapse log sensitive + # information such as access tokens. + level: INFO + + + + +root: + level: INFO + + + handlers: [console] + + +disable_existing_loggers: false \ No newline at end of file diff --git a/data/4rs.nl.signing.key b/data/4rs.nl.signing.key new file mode 100644 index 0000000..a23e685 --- /dev/null +++ b/data/4rs.nl.signing.key @@ -0,0 +1 @@ +Paste `generate_signing_key` script output here (REMOVE THIS LINE) diff --git a/data/homeserver.yaml b/data/homeserver.yaml new file mode 100644 index 0000000..7af6396 --- /dev/null +++ b/data/homeserver.yaml @@ -0,0 +1,67 @@ +# Configuration file for Synapse. +# +# For more information on how to configure Synapse, including a complete accounting of +# each option, go to docs/usage/configuration/config_documentation.md or +# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html + +server_name: "4rs.nl" +pid_file: /data/homeserver.pid +listeners: + - port: 8008 + tls: false + type: http + x_forwarded: true + resources: + - names: [client, federation] + compress: false + +database: + name: psycopg2 + args: + user: synapse + password: somepassword + host: postgresql + database: synapse + cp_min: 5 + cp_max: 10 + +log_config: "/data/4rs.nl.log.config" +media_store_path: /data/media_store +signing_key_path: "/data/4rs.nl.signing.key" + +# Run `openssl rand -base64 32` for each one +registration_shared_secret: "" +macaroon_secret_key: "" +form_secret: "" + +enable_registration: false +url_preview_enabled: true +url_preview_ip_range_blacklist: + - '127.0.0.0/8' + - '10.0.0.0/8' + - '172.16.0.0/12' + - '192.168.0.0/16' + - '100.64.0.0/10' + - '192.0.0.0/24' + - '169.254.0.0/16' + - '192.88.99.0/24' + - '198.18.0.0/15' + - '192.0.2.0/24' + - '198.51.100.0/24' + - '203.0.113.0/24' + - '224.0.0.0/4' + - '::1/128' + - 'fe80::/10' + - 'fc00::/7' + - '2001:db8::/32' + - 'ff00::/8' + - 'fec0::/10' + +presence: + enabled: false +report_stats: false +trusted_key_servers: + - server_name: "matrix.org" + +delete_stale_devices_after: 1y +admin_contact: 'mailto:a@4rs.nl' diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..bcec60e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,25 @@ +version: "3.3" +services: + synapse: + image: "matrixdotorg/synapse:latest" + container_name: "synapse" + volumes: + - "./data:/data" + environment: + - VIRTUAL_HOST=matrix.4rs.nl + - VIRTUAL_PORT=8008 + - SYNAPSE_SERVER_NAME=4rs.nl + - SYNAPSE_REPORT_STATS=no + ports: + - "8008:8008/tcp" + - "8448:8448/tcp" + postgresql: + image: postgres:latest + restart: always + environment: + POSTGRES_PASSWORD: somepassword + POSTGRES_USER: synapse + POSTGRES_DB: synapse + POSTGRES_INITDB_ARGS: "--encoding='UTF8' --lc-collate='C' --lc-ctype='C'" + volumes: + - "./postgresdata:/var/lib/postgresql" diff --git a/generate_signing_key b/generate_signing_key new file mode 100644 index 0000000..9ad9ce5 --- /dev/null +++ b/generate_signing_key @@ -0,0 +1,27 @@ +# Generate a signing key for synapse from the command line +# +# Usage: python3 generate_signing_key +# +# You must have the signedjson package installed: +# apt install python3-signedjson +# pip3 install signedjson +# +# Author: Abel Luck +# Created: April 25 2019 +# Updated: October 11 2021 + +import random +import string +import io +from signedjson.key import generate_signing_key, write_signing_keys + + +def random_string(length): + return ''.join(random.choice(string.ascii_letters) for _ in range(length)) + + +key_id = "a_" + random_string(4) +with io.StringIO() as f: + write_signing_keys(f, (generate_signing_key(key_id),),) + f.seek(0) + print(f.read())