diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ea92d7 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Synapse-Ubuntu-ZFS +Server configurations for Ubuntu 22.04 running Synapse + +This configuration does not include a lot of hardening configurations, as most of those are maintained [here](https://github.com/tommytran732/Linux-Setup-Scripts/blob/main/Ubuntu-22.04-Server.sh). + +**Note**: +- snap ufw blocks Docker by default. ArcticFoxes's Matrix server uses .deb ufw instead. +- A lot of these configuration files use ArcticFoxes's domain. If you are adopting this to your own system, make sure that you replace them. +- The Certbot-OCSP-Fetcher script can be found [here](https://github.com/GrapheneOS/infrastructure/blob/main/certbot-ocsp-fetcher) +- The repolists of PostgreSQL and Docker have been modified so that they read GPG keys from `/usr/share/keyring` by default. Make sure that when you follow upstream's documentation on adding their GPG keys, you adjust the location. For PostgreSQL's GPG key, run `curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /usr/share/keyrings/postgresql-debian-repo.gpg >/dev/null` diff --git a/TLSA.sh b/TLSA.sh new file mode 100644 index 0000000..847f6b8 --- /dev/null +++ b/TLSA.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +cat <" + + # app_name defines the default value for '%(app)s' in notif_from and email + # subjects. It defaults to 'Matrix'. + # + app_name: Matrix + + # Uncomment the following to enable sending emails for messages that the user + # has missed. Disabled by default. + # + #enable_notifs: true + + # Uncomment the following to disable automatic subscription to email + # notifications for new users. Enabled by default. + # + #notif_for_new_users: false + + # Custom URL for client links within the email notifications. By default + # links will be based on "https://matrix.to". + # + # (This setting used to be called riot_base_url; the old name is still + # supported for backwards-compatibility but is now deprecated.) + # + client_base_url: "https://element.arcticfoxes.net" + + # Configure the time that a validation email will expire after sending. + # Defaults to 1h. + # + #validation_token_lifetime: 15m + + # The web client location to direct users to during an invite. This is passed + # to the identity server as the org.matrix.web_client_location key. Defaults + # to unset, giving no guidance to the identity server. + # + invite_client_location: https://element.arcticfoxes.net + + # Subjects to use when sending emails from Synapse. + # + # The placeholder '%(app)s' will be replaced with the value of the 'app_name' + # setting above, or by a value dictated by the Matrix client application. + # + # If a subject isn't overridden in this configuration file, the value used as + # its example will be used. + # + #subjects: + + # Subjects for notification emails. + # + # On top of the '%(app)s' placeholder, these can use the following + # placeholders: + # + # * '%(person)s', which will be replaced by the display name of the user(s) + # that sent the message(s), e.g. "Alice and Bob". + # * '%(room)s', which will be replaced by the name of the room the + # message(s) have been sent to, e.g. "My super room". + # + # See the example provided for each setting to see which placeholder can be + # used and how to use them. + # + # Subject to use to notify about one message from one or more user(s) in a + # room which has a name. + #message_from_person_in_room: "[%(app)s] You have a message on %(app)s from %(person)s in the %(room)s room..." + # + # Subject to use to notify about one message from one or more user(s) in a + # room which doesn't have a name. + #message_from_person: "[%(app)s] You have a message on %(app)s from %(person)s..." + # + # Subject to use to notify about multiple messages from one or more users in + # a room which doesn't have a name. + #messages_from_person: "[%(app)s] You have messages on %(app)s from %(person)s..." + # + # Subject to use to notify about multiple messages in a room which has a + # name. + #messages_in_room: "[%(app)s] You have messages on %(app)s in the %(room)s room..." + # + # Subject to use to notify about multiple messages in multiple rooms. + #messages_in_room_and_others: "[%(app)s] You have messages on %(app)s in the %(room)s room and others..." + # + # Subject to use to notify about multiple messages from multiple persons in + # multiple rooms. This is similar to the setting above except it's used when + # the room in which the notification was triggered has no name. + #messages_from_person_and_others: "[%(app)s] You have messages on %(app)s from %(person)s and others..." + # + # Subject to use to notify about an invite to a room which has a name. + #invite_from_person_to_room: "[%(app)s] %(person)s has invited you to join the %(room)s room on %(app)s..." + # + # Subject to use to notify about an invite to a room which doesn't have a + # name. + #invite_from_person: "[%(app)s] %(person)s has invited you to chat on %(app)s..." + + # Subject for emails related to account administration. + # + # On top of the '%(app)s' placeholder, these one can use the + # '%(server_name)s' placeholder, which will be replaced by the value of the + # 'server_name' setting in your Synapse configuration. + # + # Subject to use when sending a password reset email. + #password_reset: "[%(server_name)s] Password reset" + # + # Subject to use when sending a verification email to assert an address's + # ownership. + #email_validation: "[%(server_name)s] Validate your email" \ No newline at end of file diff --git a/etc/matrix-synapse/conf.d/log.yaml b/etc/matrix-synapse/conf.d/log.yaml new file mode 100644 index 0000000..4df5bf5 --- /dev/null +++ b/etc/matrix-synapse/conf.d/log.yaml @@ -0,0 +1,75 @@ +# Log configuration for Synapse. +# +# This is a YAML file containing a standard Python logging configuration +# dictionary. See [1] for details on the valid settings. +# +# Synapse also supports structured logging for machine readable logs which can +# be ingested by ELK stacks. See [2] for details. +# +# [1]: https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema +# [2]: https://matrix-org.github.io/synapse/latest/structured_logging.html + +version: 1 + +formatters: + precise: + format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' + +handlers: + file: + class: logging.handlers.TimedRotatingFileHandler + formatter: precise + filename: /var/log/matrix-synapse/homeserver.log + when: midnight + backupCount: 3 # Does not include the current log file. + encoding: utf8 + + # Default to buffering writes to log file for efficiency. + # WARNING/ERROR logs will still be flushed immediately, but there will be a + # delay (of up to `period` seconds, or until the buffer is full with + # `capacity` messages) before INFO/DEBUG logs get written. + buffer: + class: synapse.logging.handlers.PeriodicallyFlushingMemoryHandler + target: file + + # The capacity is the maximum number of log lines that are buffered + # before being written to disk. Increasing this will lead to better + # performance, at the expensive of it taking longer for log lines to + # be written to disk. + # This parameter is required. + capacity: 10 + + # Logs with a level at or above the flush level will cause the buffer to + # be flushed immediately. + # Default value: 40 (ERROR) + # Other values: 50 (CRITICAL), 30 (WARNING), 20 (INFO), 10 (DEBUG) + flushLevel: 30 # Flush immediately for WARNING logs and higher + + # The period of time, in seconds, between forced flushes. + # Messages will not be delayed for longer than this time. + # Default value: 5 seconds + period: 5 + + # A handler that writes logs to stderr. Unused by default, but can be used + # instead of "buffer" and "file" in the logger handlers. + console: + class: logging.StreamHandler + formatter: precise + +loggers: + synapse.storage.SQL: + # beware: increasing this to DEBUG will make synapse log sensitive + # information such as access tokens. + level: INFO + +root: + level: INFO + + # Write logs to the `buffer` handler, which will buffer them together in memory, + # then write them to a file. + # + # Replace "buffer" with "console" to log to stderr instead. + # + handlers: [buffer] + +disable_existing_loggers: false \ No newline at end of file diff --git a/etc/matrix-synapse/conf.d/media_store.yaml b/etc/matrix-synapse/conf.d/media_store.yaml new file mode 100644 index 0000000..119891a --- /dev/null +++ b/etc/matrix-synapse/conf.d/media_store.yaml @@ -0,0 +1,25 @@ +media_store_path: /var/lib/matrix-synapse/media +media_retention: + local_media_lifetime: 1y + remote_media_lifetime: 1y +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' \ No newline at end of file diff --git a/etc/matrix-synapse/conf.d/password_config.yaml b/etc/matrix-synapse/conf.d/password_config.yaml new file mode 100644 index 0000000..6268614 --- /dev/null +++ b/etc/matrix-synapse/conf.d/password_config.yaml @@ -0,0 +1,50 @@ +password_config: + # Uncomment to disable password login + # + #enabled: false + + # Uncomment to disable authentication against the local password + # database. This is ignored if `enabled` is false, and is only useful + # if you have other password_providers. + # + #localdb_enabled: false + + # Uncomment and change to a secret random string for extra security. + # DO NOT CHANGE THIS AFTER INITIAL SETUP! + # + pepper: "REDACTED" + + # Define and enforce a password policy. Each parameter is optional. + # This is an implementation of MSC2000. + # + policy: + # Whether to enforce the password policy. + # Defaults to 'false'. + # + enabled: true + + # Minimum accepted length for a password. + # Defaults to 0. + # + minimum_length: 8 + + # Whether a password must contain at least one digit. + # Defaults to 'false'. + # + require_digit: true + + # Whether a password must contain at least one symbol. + # A symbol is any character that's not a number or a letter. + # Defaults to 'false'. + # + require_symbol: true + + # Whether a password must contain at least one lowercase letter. + # Defaults to 'false'. + # + require_lowercase: true + + # Whether a password must contain at least one uppercase letter. + # Defaults to 'false'. + # + require_uppercase: true \ No newline at end of file diff --git a/etc/matrix-synapse/conf.d/registration.yaml b/etc/matrix-synapse/conf.d/registration.yaml new file mode 100644 index 0000000..d1e2278 --- /dev/null +++ b/etc/matrix-synapse/conf.d/registration.yaml @@ -0,0 +1,246 @@ +## Registration ## +# +# Registration can be rate-limited using the parameters in the "Ratelimiting" +# section of this file. + +# Enable registration for new users. +# +enable_registration: true + +# Time that a user's session remains valid for, after they log in. +# +# Note that this is not currently compatible with guest logins. +# +# Note also that this is calculated at login time: changes are not applied +# retrospectively to users who have already logged in. +# +# By default, this is infinite. +# +#session_lifetime: 24h + +# Time that an access token remains valid for, if the session is +# using refresh tokens. +# For more information about refresh tokens, please see the manual. +# Note that this only applies to clients which advertise support for +# refresh tokens. +# +# Note also that this is calculated at login time and refresh time: +# changes are not applied to existing sessions until they are refreshed. +# +# By default, this is 5 minutes. +# +#refreshable_access_token_lifetime: 5m + +# Time that a refresh token remains valid for (provided that it is not +# exchanged for another one first). +# This option can be used to automatically log-out inactive sessions. +# Please see the manual for more information. +# +# Note also that this is calculated at login time and refresh time: +# changes are not applied to existing sessions until they are refreshed. +# +# By default, this is infinite. +# +#refresh_token_lifetime: 24h + +# Time that an access token remains valid for, if the session is NOT +# using refresh tokens. +# Please note that not all clients support refresh tokens, so setting +# this to a short value may be inconvenient for some users who will +# then be logged out frequently. +# +# Note also that this is calculated at login time: changes are not applied +# retrospectively to existing sessions for users that have already logged in. +# +# By default, this is infinite. +# +#nonrefreshable_access_token_lifetime: 24h + +# The user must provide all of the below types of 3PID when registering. +# +#registrations_require_3pid: +# - email +# - msisdn + +# Explicitly disable asking for MSISDNs from the registration +# flow (overrides registrations_require_3pid if MSISDNs are set as required) +# +#disable_msisdn_registration: true + +# Mandate that users are only allowed to associate certain formats of +# 3PIDs with accounts on this server. +# +#allowed_local_3pids: +# - medium: email +# pattern: '^[^@]+@matrix\.org$' +# - medium: email +# pattern: '^[^@]+@vector\.im$' +# - medium: msisdn +# pattern: '\+44' + +# Enable 3PIDs lookup requests to identity servers from this server. +# +#enable_3pid_lookup: true + +# Require users to submit a token during registration. +# Tokens can be managed using the admin API: +# https://matrix-org.github.io/synapse/latest/usage/administration/admin_api/registration_tokens.html +# Note that `enable_registration` must be set to `true`. +# Disabling this option will not delete any tokens previously generated. +# Defaults to false. Uncomment the following to require tokens: +# +#registration_requires_token: true + +# If set, allows registration of standard or admin accounts by anyone who +# has the shared secret, even if registration is otherwise disabled. +# +registration_shared_secret: "REDACTED" + +# Set the number of bcrypt rounds used to generate password hash. +# Larger numbers increase the work factor needed to generate the hash. +# The default number is 12 (which equates to 2^12 rounds). +# N.B. that increasing this will exponentially increase the time required +# to register or login - e.g. 24 => 2^24 rounds which will take >20 mins. +# +#bcrypt_rounds: 12 + +# Allows users to register as guests without a password/email/etc, and +# participate in rooms hosted on this server which have been made +# accessible to anonymous users. +# +allow_guest_access: true + +# The identity server which we suggest that clients should use when users log +# in on this server. +# +# (By default, no suggestion is made, so it is left up to the client. +# This setting is ignored unless public_baseurl is also explicitly set.) +# +#default_identity_server: https://matrix.org + +# Handle threepid (email/phone etc) registration and password resets through a set of +# *trusted* identity servers. Note that this allows the configured identity server to +# reset passwords for accounts! +# +# Be aware that if `email` is not set, and SMTP options have not been +# configured in the email config block, registration and user password resets via +# email will be globally disabled. +# +# Additionally, if `msisdn` is not set, registration and password resets via msisdn +# will be disabled regardless, and users will not be able to associate an msisdn +# identifier to their account. This is due to Synapse currently not supporting +# any method of sending SMS messages on its own. +# +# To enable using an identity server for operations regarding a particular third-party +# identifier type, set the value to the URL of that identity server as shown in the +# examples below. +# +# Servers handling the these requests must answer the `/requestToken` endpoints defined +# by the Matrix Identity Service API specification: +# https://matrix.org/docs/spec/identity_service/latest +# +account_threepid_delegates: + #email: https://example.com # Delegate email sending to example.com + #msisdn: http://localhost:8090 # Delegate SMS sending to this local process + +# Whether users are allowed to change their displayname after it has +# been initially set. Useful when provisioning users based on the +# contents of a third-party directory. +# +# Does not apply to server administrators. Defaults to 'true' +# +#enable_set_displayname: false + +# Whether users are allowed to change their avatar after it has been +# initially set. Useful when provisioning users based on the contents +# of a third-party directory. +# +# Does not apply to server administrators. Defaults to 'true' +# +#enable_set_avatar_url: false + +# Whether users can change the 3PIDs associated with their accounts +# (email address and msisdn). +# +# Defaults to 'true' +# +#enable_3pid_changes: false + +# Users who register on this homeserver will automatically be joined +# to these rooms. +# +# By default, any room aliases included in this list will be created +# as a publicly joinable room when the first user registers for the +# homeserver. This behaviour can be customised with the settings below. +# If the room already exists, make certain it is a publicly joinable +# room. The join rule of the room must be set to 'public'. +# +#auto_join_rooms: +# - "#example:example.com" + +# Where auto_join_rooms are specified, setting this flag ensures that the +# the rooms exist by creating them when the first user on the +# homeserver registers. +# +# By default the auto-created rooms are publicly joinable from any federated +# server. Use the autocreate_auto_join_rooms_federated and +# autocreate_auto_join_room_preset settings below to customise this behaviour. +# +# Setting to false means that if the rooms are not manually created, +# users cannot be auto-joined since they do not exist. +# +# Defaults to true. Uncomment the following line to disable automatically +# creating auto-join rooms. +# +#autocreate_auto_join_rooms: false + +# Whether the auto_join_rooms that are auto-created are available via +# federation. Only has an effect if autocreate_auto_join_rooms is true. +# +# Note that whether a room is federated cannot be modified after +# creation. +# +# Defaults to true: the room will be joinable from other servers. +# Uncomment the following to prevent users from other homeservers from +# joining these rooms. +# +#autocreate_auto_join_rooms_federated: false + +# The room preset to use when auto-creating one of auto_join_rooms. Only has an +# effect if autocreate_auto_join_rooms is true. +# +# This can be one of "public_chat", "private_chat", or "trusted_private_chat". +# If a value of "private_chat" or "trusted_private_chat" is used then +# auto_join_mxid_localpart must also be configured. +# +# Defaults to "public_chat", meaning that the room is joinable by anyone, including +# federated servers if autocreate_auto_join_rooms_federated is true (the default). +# Uncomment the following to require an invitation to join these rooms. +# +#autocreate_auto_join_room_preset: private_chat + +# The local part of the user id which is used to create auto_join_rooms if +# autocreate_auto_join_rooms is true. If this is not provided then the +# initial user account that registers will be used to create the rooms. +# +# The user id is also used to invite new users to any auto-join rooms which +# are set to invite-only. +# +# It *must* be configured if autocreate_auto_join_room_preset is set to +# "private_chat" or "trusted_private_chat". +# +# Note that this must be specified in order for new users to be correctly +# invited to any auto-join rooms which have been set to invite-only (either +# at the time of creation or subsequently). +# +# Note that, if the room already exists, this user must be joined and +# have the appropriate permissions to invite new members. +# +#auto_join_mxid_localpart: system + +# When auto_join_rooms is specified, setting this flag to false prevents +# guest accounts from being automatically joined to the rooms. +# +# Defaults to true. +# +#auto_join_rooms_for_guests: false \ No newline at end of file diff --git a/etc/matrix-synapse/conf.d/report_stats.yaml b/etc/matrix-synapse/conf.d/report_stats.yaml new file mode 100644 index 0000000..d818422 --- /dev/null +++ b/etc/matrix-synapse/conf.d/report_stats.yaml @@ -0,0 +1,5 @@ +# This file is autogenerated, and will be recreated on upgrade if it is deleted. +# Any changes you make will be preserved. + +# Whether to report homeserver usage statistics. +report_stats: fals \ No newline at end of file diff --git a/etc/matrix-synapse/conf.d/retention.yaml b/etc/matrix-synapse/conf.d/retention.yaml new file mode 100644 index 0000000..a9c99bb --- /dev/null +++ b/etc/matrix-synapse/conf.d/retention.yaml @@ -0,0 +1,69 @@ +# Message retention policy at the server level. +# +# Room admins and mods can define a retention period for their rooms using the +# 'm.room.retention' state event, and server admins can cap this period by setting +# the 'allowed_lifetime_min' and 'allowed_lifetime_max' config options. +# +# If this feature is enabled, Synapse will regularly look for and purge events +# which are older than the room's maximum retention period. Synapse will also +# filter events received over federation so that events that should have been +# purged are ignored and not stored again. +# +retention: + # The message retention policies feature is disabled by default. Uncomment the + # following line to enable it. + # + enabled: true + + # Default retention policy. If set, Synapse will apply it to rooms that lack the + # 'm.room.retention' state event. Currently, the value of 'min_lifetime' doesn't + # matter much because Synapse doesn't take it into account yet. + # + default_policy: + min_lifetime: 1d + max_lifetime: 1y + + # Retention policy limits. If set, and the state of a room contains a + # 'm.room.retention' event in its state which contains a 'min_lifetime' or a + # 'max_lifetime' that's out of these bounds, Synapse will cap the room's policy + # to these limits when running purge jobs. + # + allowed_lifetime_min: 1d + allowed_lifetime_max: 1y + + # Server admins can define the settings of the background jobs purging the + # events which lifetime has expired under the 'purge_jobs' section. + # + # If no configuration is provided, a single job will be set up to delete expired + # events in every room daily. + # + # Each job's configuration defines which range of message lifetimes the job + # takes care of. For example, if 'shortest_max_lifetime' is '2d' and + # 'longest_max_lifetime' is '3d', the job will handle purging expired events in + # rooms whose state defines a 'max_lifetime' that's both higher than 2 days, and + # lower than or equal to 3 days. Both the minimum and the maximum value of a + # range are optional, e.g. a job with no 'shortest_max_lifetime' and a + # 'longest_max_lifetime' of '3d' will handle every room with a retention policy + # which 'max_lifetime' is lower than or equal to three days. + # + # The rationale for this per-job configuration is that some rooms might have a + # retention policy with a low 'max_lifetime', where history needs to be purged + # of outdated messages on a more frequent basis than for the rest of the rooms + # (e.g. every 12h), but not want that purge to be performed by a job that's + # iterating over every room it knows, which could be heavy on the server. + # + # If any purge job is configured, it is strongly recommended to have at least + # a single job with neither 'shortest_max_lifetime' nor 'longest_max_lifetime' + # set, or one job without 'shortest_max_lifetime' and one job without + # 'longest_max_lifetime' set. Otherwise some rooms might be ignored, even if + # 'allowed_lifetime_min' and 'allowed_lifetime_max' are set, because capping a + # room's policy to these values is done after the policies are retrieved from + # Synapse's database (which is done using the range specified in a purge job's + # configuration). + # + purge_jobs: + # - longest_max_lifetime: 3d + # interval: 12h + # - shortest_max_lifetime: 3d + # interval: 1d + - interval: 1d \ No newline at end of file diff --git a/etc/matrix-synapse/conf.d/server_name.yaml b/etc/matrix-synapse/conf.d/server_name.yaml new file mode 100644 index 0000000..19cb838 --- /dev/null +++ b/etc/matrix-synapse/conf.d/server_name.yaml @@ -0,0 +1,9 @@ +# This file is autogenerated, and will be recreated on upgrade if it is deleted. +# Any changes you make will be preserved. + +# The domain name of the server, with optional explicit port. +# This is used by remote servers to connect to this server, +# e.g. matrix.org, localhost:8080, etc. +# This is also the last part of your UserID. +# +server_name: arcticfoxes.net \ No newline at end of file diff --git a/etc/matrix-synapse/conf.d/server_notices.yaml b/etc/matrix-synapse/conf.d/server_notices.yaml new file mode 100644 index 0000000..a846f58 --- /dev/null +++ b/etc/matrix-synapse/conf.d/server_notices.yaml @@ -0,0 +1,5 @@ +server_notices: + system_mxid_localpart: notices + system_mxid_display_name: "ArcticFoxes Notices" + system_mxid_avatar_url: "mxc://arcticfoxes.net/YTYUCCfupbUPUiYTxcUlgUZn" + room_name: "ArcticFoxes Notices" \ No newline at end of file diff --git a/etc/matrix-synapse/conf.d/turn.yaml b/etc/matrix-synapse/conf.d/turn.yaml new file mode 100644 index 0000000..ca6ce49 --- /dev/null +++ b/etc/matrix-synapse/conf.d/turn.yaml @@ -0,0 +1,27 @@ +## TURN ## + +# The public URIs of the TURN server to give to clients +# +turn_uris: [ "turns:turn.arcticfoxes.net?transport=udp", "turns:turn.arcticfoxes.net?transport=tcp" ] + +# The shared secret used to compute passwords for the TURN server +# +turn_shared_secret: "REDACTED" + +# The Username and password if the TURN server needs them and +# does not use a token +# +#turn_username: "TURNSERVER_USERNAME" +#turn_password: "TURNSERVER_PASSWORD" + +# How long generated TURN credentials last +# +turn_user_lifetime: 86400000 + +# Whether guests should be allowed to use the TURN server. +# This defaults to True, otherwise VoIP will be unreliable for guests. +# However, it does introduce a slight security risk as it allows users to +# connect to arbitrary endpoints without having first signed up for a +# valid account (e.g. by passing a CAPTCHA). +# +turn_allow_guests: false \ No newline at end of file diff --git a/etc/matrix-synapse/conf.d/user_directory.yaml b/etc/matrix-synapse/conf.d/user_directory.yaml new file mode 100644 index 0000000..ed35d28 --- /dev/null +++ b/etc/matrix-synapse/conf.d/user_directory.yaml @@ -0,0 +1,35 @@ +# User Directory configuration +# +user_directory: + # Defines whether users can search the user directory. If false then + # empty responses are returned to all queries. Defaults to true. + # + # Uncomment to disable the user directory. + # + #enabled: false + + # Defines whether to search all users visible to your HS when searching + # the user directory. If false, search results will only contain users + # visible in public rooms and users sharing a room with the requester. + # Defaults to false. + # + # NB. If you set this to true, and the last time the user_directory search + # indexes were (re)built was before Synapse 1.44, you'll have to + # rebuild the indexes in order to search through all known users. + # These indexes are built the first time Synapse starts; admins can + # manually trigger a rebuild via API following the instructions at + # https://matrix-org.github.io/synapse/latest/usage/administration/admin_api/background_updates.html#run + # + # Uncomment to return search results containing all known users, even if that + # user does not share a room with the requester. + # + search_all_users: true + + # Defines whether to prefer local users in search query results. + # If True, local users are more likely to appear above remote users + # when searching the user directory. Defaults to false. + # + # Uncomment to prefer local over remote users in user directory search + # results. + # + prefer_local_users: true \ No newline at end of file diff --git a/etc/matrix-synapse/homeserver.yaml b/etc/matrix-synapse/homeserver.yaml new file mode 100644 index 0000000..6607a7b --- /dev/null +++ b/etc/matrix-synapse/homeserver.yaml @@ -0,0 +1,38 @@ +# Configuration file for Synapse. +# +# This is a YAML file: see [1] for a quick introduction. Note in particular +# that *indentation is important*: all the elements of a list or dictionary +# should have the same indentation. +# +# [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html +# +# 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://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html +# +# This is set in /etc/matrix-synapse/conf.d/server_name.yaml for Debian installations. +# server_name: "SERVERNAME" +pid_file: "/var/run/matrix-synapse.pid" +listeners: + - port: 8008 + tls: false + type: http + x_forwarded: true + bind_addresses: ['::1', '127.0.0.1'] + resources: + - names: [client, federation] + compress: false +database: + name: psycopg2 + args: + user: synapse + password: REDACTED + host: 127.0.0.1 + database: synapse + port: 5432 + cp_min: 5 + cp_max: 10 +log_config: "/etc/matrix-synapse/log.yaml" +signing_key_path: "/etc/matrix-synapse/homeserver.signing.key" +trusted_key_servers: + - server_name: "matrix.org" \ No newline at end of file diff --git a/etc/netplan/10-custom.conf b/etc/netplan/10-custom.conf new file mode 100644 index 0000000..5dd74e4 --- /dev/null +++ b/etc/netplan/10-custom.conf @@ -0,0 +1,15 @@ +network: + version: 2 + renderer: networkd + ethernets: + enp4s0: + addresses: + - 144.76.184.28/32 + - 2a01:4f8:200:6206::1/64 + routes: + - to: default + via: 144.76.184.1 + on-link: true + - to: default + via: "fe80::1" + on-link: true \ No newline at end of file diff --git a/etc/nginx/conf.d/default.conf b/etc/nginx/conf.d/default.conf new file mode 100644 index 0000000..9fb9489 --- /dev/null +++ b/etc/nginx/conf.d/default.conf @@ -0,0 +1,17 @@ +server { + listen 80; + listen [::]:80; + server_name localhost; + + return 301 https://element.arcticfoxes.net; +} + +server { + listen 443; + listen [::]:443; + server_name localhost; + + include /etc/nginx/ssl.conf; + + return 301 https://element.arcticfoxes.net; +} \ No newline at end of file diff --git a/etc/nginx/conf.d/element.conf b/etc/nginx/conf.d/element.conf new file mode 100644 index 0000000..5e8a4f5 --- /dev/null +++ b/etc/nginx/conf.d/element.conf @@ -0,0 +1,24 @@ +server { + listen 443 ssl; + listen [::]:443 ssl; + + server_name element.arcticfoxes.net; + + include /etc/nginx/ssl.conf; + include /etc/nginx/proxy.conf; + include /etc/nginx/headers.conf; + add_header Content-Security-Policy "default-src 'none'; connect-src 'self' https://arcticfoxes.net https://matrix.arcticfoxes.net; font-src 'self'; img-src 'self' https://arcticfoxes.net https://matrix.arcticfoxes.net blob: data:; manifest-src 'self'; media-src 'self' https://matrix.arcticfoxes.net; script-src 'self' 'unsafe-eval' https://www.recaptcha.net https://www.gstatic.com; style-src 'self' 'unsafe-inline'; frame-src 'self' https://www.recaptcha.net blob:; frame-ancestors 'self'; upgrade-insecure-requests; block-all-mixed-content; base-uri 'none'"; + + client_max_body_size 0; + + location / { + set $upstream_app 127.0.0.1; + set $upstream_port 81; + set $upstream_proto http; + proxy_pass $upstream_proto://$upstream_app:$upstream_port; + + proxy_set_header Range $http_range; + proxy_set_header If-Range $http_if_range; + } + +} \ No newline at end of file diff --git a/etc/nginx/conf.d/http2.conf b/etc/nginx/conf.d/http2.conf new file mode 100644 index 0000000..4b6dcdf --- /dev/null +++ b/etc/nginx/conf.d/http2.conf @@ -0,0 +1 @@ +http2 on; \ No newline at end of file diff --git a/etc/nginx/conf.d/matrix-to.conf b/etc/nginx/conf.d/matrix-to.conf new file mode 100644 index 0000000..bc1844f --- /dev/null +++ b/etc/nginx/conf.d/matrix-to.conf @@ -0,0 +1,24 @@ +server { + listen 443 ssl; + listen [::]:443 ssl; + + server_name invite.arcticfoxes.net; + + include /etc/nginx/ssl.conf; + include /etc/nginx/proxy.conf; + include /etc/nginx/headers.conf; + add_header Content-Security-Policy "default-src 'none'; connect-src *; img-src *; script-src 'self' 'unsafe-inline'; style-src 'self', upgrade-insecure-requests; block-all-mixed-content; base-uri 'none'"; + + client_max_body_size 0; + + location / { + set $upstream_app 127.0.0.1; + set $upstream_port 5000; + set $upstream_proto http; + proxy_pass $upstream_proto://$upstream_app:$upstream_port; + + proxy_set_header Range $http_range; + proxy_set_header If-Range $http_if_range; + } + +} \ No newline at end of file diff --git a/etc/nginx/conf.d/synapse.conf b/etc/nginx/conf.d/synapse.conf new file mode 100644 index 0000000..d0bb4da --- /dev/null +++ b/etc/nginx/conf.d/synapse.conf @@ -0,0 +1,40 @@ +server { + listen 443 ssl; + listen [::]:443 ssl; + + # For the federation port + listen 8448 ssl; + listen [::]:8448 ssl; + + server_name matrix.arcticfoxes.net; + + include /etc/nginx/ssl.conf; + include /etc/nginx/proxy.conf; + include /etc/nginx/headers.conf; + + client_max_body_size 0; + + location ~ ^/_matrix/client/r0/rooms/([^/]*)/report/(.*)$ { + # Abuse reports should be sent to Mjölnir. + + # Add CORS, otherwise a browser will refuse this request. + include /etc/nginx/headers.conf; + add_header 'Access-Control-Allow-Credentials' 'true' always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since' always; + add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; + add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days + + # Alias the regexps, to ensure that they're not rewritten. + set $room_id $1; + set $event_id $2; + proxy_pass http://127.0.0.1:8081/api/1/report/$room_id/$event_id; + } + + location / { + set $upstream_app 127.0.0.1; + set $upstream_port 8008; + set $upstream_proto http; + proxy_pass $upstream_proto://$upstream_app:$upstream_port; + } +} \ No newline at end of file diff --git a/etc/nginx/proxy.conf b/etc/nginx/proxy.conf new file mode 100644 index 0000000..5c0ff37 --- /dev/null +++ b/etc/nginx/proxy.conf @@ -0,0 +1,35 @@ +## Version 2022/09/01 - Changelog: https://github.com/linuxserver/docker-swag/commits/master/root/defaults/nginx/proxy.conf.sample + +# Timeout if the real server is dead +proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; + +# Proxy Connection Settings +proxy_buffers 32 4k; +proxy_connect_timeout 240; +proxy_headers_hash_bucket_size 128; +proxy_headers_hash_max_size 1024; +proxy_http_version 1.1; +proxy_read_timeout 240; +proxy_redirect http:// $scheme://; +proxy_send_timeout 240; + +# Proxy Cache and Cookie Settings +proxy_cache_bypass $cookie_session; +#proxy_cookie_path / "/; Secure"; # enable at your own risk, may break certain apps +proxy_no_cache $cookie_session; + +# Proxy Header Settings +#proxy_set_header Connection $connection_upgrade; +proxy_set_header Early-Data $ssl_early_data; +proxy_set_header Host $host; +proxy_set_header Proxy ""; +#proxy_set_header Upgrade $http_upgrade; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-Host $host:$server_port; +proxy_set_header X-Forwarded-Method $request_method; +proxy_set_header X-Forwarded-Proto $scheme; +proxy_set_header X-Forwarded-Server $host; +proxy_set_header X-Forwarded-Ssl on; +proxy_set_header X-Forwarded-Uri $request_uri; +proxy_set_header X-Original-URL $scheme://$http_host$request_uri; +proxy_set_header X-Real-IP $remote_addr; diff --git a/etc/nginx/ssl.conf b/etc/nginx/ssl.conf new file mode 100644 index 0000000..962d9cf --- /dev/null +++ b/etc/nginx/ssl.conf @@ -0,0 +1,16 @@ +ssl_certificate /etc/letsencrypt/live/matrix.arcticfoxes.net/fullchain.pem; +ssl_certificate_key /etc/letsencrypt/live/matrix.arcticfoxes.net/privkey.pem; +ssl_trusted_certificate /etc/letsencrypt/live/matrix.arcticfoxes.net/chain.pem; + +ssl_session_timeout 1d; +ssl_session_cache shared:MozSSL:10m; # about 40000 sessions +ssl_session_tickets off; + +ssl_protocols TLSv1.2 TLSv1.3; +ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256; +ssl_prefer_server_ciphers on; +ssl_conf_command Options PrioritizeChaCha; + +ssl_stapling on; +ssl_stapling_verify on; +ssl_stapling_file /var/cache/certbot-ocsp-fetchermatrix.arcticfoxes.net.der; diff --git a/etc/postgresql/15/main/conf.d/10-custom.conf b/etc/postgresql/15/main/conf.d/10-custom.conf new file mode 100644 index 0000000..9e5b149 --- /dev/null +++ b/etc/postgresql/15/main/conf.d/10-custom.conf @@ -0,0 +1 @@ +full_page_writes = off diff --git a/etc/postgresql/15/main/pg_hba.conf b/etc/postgresql/15/main/pg_hba.conf new file mode 100644 index 0000000..9b068f1 --- /dev/null +++ b/etc/postgresql/15/main/pg_hba.conf @@ -0,0 +1,104 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: +# - "local" is a Unix-domain socket +# - "host" is a TCP/IP socket (encrypted or not) +# - "hostssl" is a TCP/IP socket that is SSL-encrypted +# - "hostnossl" is a TCP/IP socket that is not SSL-encrypted +# - "hostgssenc" is a TCP/IP socket that is GSSAPI-encrypted +# - "hostnogssenc" is a TCP/IP socket that is not GSSAPI-encrypted +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, or a comma-separated list thereof. The "all" +# keyword does not match "replication". Access to replication +# must be enabled in a separate record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", or a +# comma-separated list thereof. In both the DATABASE and USER fields +# you can also write a file name prefixed with "@" to include names +# from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", +# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". +# Note that "password" sends passwords in clear text; "md5" or +# "scram-sha-256" are preferred since they send encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# This file is read on server startup and when the server receives a +# SIGHUP signal. If you edit the file on a running system, you have to +# SIGHUP the server for the changes to take effect, run "pg_ctl reload", +# or execute "SELECT pg_reload_conf()". +# +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + + + + +# DO NOT DISABLE! +# If you change this first entry you will need to make sure that the +# database superuser can access the database using some other method. +# Noninteractive access to all databases is required during automatic +# maintenance (custom daily cronjobs, replication, and similar tasks). +# +# Database administrative login by Unix domain socket +local all postgres peer + +# TYPE DATABASE USER ADDRESS METHOD + +# "local" is for Unix domain socket connections only +local all all scram-sha-256 +# IPv4 local connections: +host all all 127.0.0.1/32 scram-sha-256 +# IPv6 local connections: +host all all ::1/128 scram-sha-256 +# Allow replication connections from localhost, by a user with the +# replication privilege. +local replication all peer +host replication all 127.0.0.1/32 scram-sha-256 +host replication all ::1/128 scram-sha-256 \ No newline at end of file diff --git a/etc/systemd/system/certbot-ocsp-fetcher.service b/etc/systemd/system/certbot-ocsp-fetcher.service new file mode 100644 index 0000000..97f8d12 --- /dev/null +++ b/etc/systemd/system/certbot-ocsp-fetcher.service @@ -0,0 +1,14 @@ +[Unit] +Description=Automatic OCSP Fetcher +After=docker.service +Requires=network-online.target +Requires=docker.service + +[Service] +User=root +Group=root +ExecStart=/usr/local/bin/certbot-ocsp-fetcher -o /etc/nginx/ocsp-cache +Type=oneshot + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/etc/systemd/system/certbot-ocsp-fetcher.timer b/etc/systemd/system/certbot-ocsp-fetcher.timer new file mode 100644 index 0000000..6ca75e2 --- /dev/null +++ b/etc/systemd/system/certbot-ocsp-fetcher.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Fetch OCSP Daily + +[Timer] +OnCalendar=daily +AccuracySec=1h +Persistent=true +RandomizedDelaySec=6000 + +[Install] +WantedBy=timers.target \ No newline at end of file diff --git a/etc/systemd/system/container-updater.service b/etc/systemd/system/container-updater.service new file mode 100644 index 0000000..45d3d47 --- /dev/null +++ b/etc/systemd/system/container-updater.service @@ -0,0 +1,16 @@ +[Unit] +Description=Automatic Container Updater +After=docker.service +Requires=network-online.target +Requires=docker.service + +[Service] +User=root +Group=root +WorkingDirectory=/srv/Matrix-Docker-Compose +ExecStart=/usr/bin/docker compose pull +ExecStart=/usr/bin/docker compose up -d +Type=oneshot + +[Install] +WantedBy=multi-user.target diff --git a/etc/systemd/system/container-updater.timer b/etc/systemd/system/container-updater.timer new file mode 100644 index 0000000..4ca6a38 --- /dev/null +++ b/etc/systemd/system/container-updater.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Update Containers Daily + +[Timer] +OnCalendar=daily +AccuracySec=1h +Persistent=true +RandomizedDelaySec=6000 + +[Install] +WantedBy=timers.target diff --git a/etc/systemd/system/matrix-synapse.service.d/override.conf b/etc/systemd/system/matrix-synapse.service.d/override.conf new file mode 100644 index 0000000..4d6f520 --- /dev/null +++ b/etc/systemd/system/matrix-synapse.service.d/override.conf @@ -0,0 +1,29 @@ +[Service] +# The following directives give the synapse service R/W access to: +# - /var/lib/matrix-synapse +# - /var/log/matrix-synapse + +StateDirectory=matrix-synapse +LogsDirectory=matrix-synapse + +###################### +## Security Sandbox ## +###################### + +# Make sure that the service has its own unshared tmpfs at /tmp and that it +# cannot see or change any real devices +PrivateTmp=true +PrivateDevices=true + +# We give no capabilities to a service by default +#CapabilityBoundingSet= +#AmbientCapabilities= + +# Protect the following from modification: +# - The entire filesystem +# - sysctl settings and loaded kernel modules +# - No modifications allowed to Control Groups +# - Hostname +# - System Clock +ProtectSystem=strict +ProtectKernelTunables=true diff --git a/etc/systemd/system/mjolnir-module-updater.service b/etc/systemd/system/mjolnir-module-updater.service new file mode 100644 index 0000000..3aa6ee9 --- /dev/null +++ b/etc/systemd/system/mjolnir-module-updater.service @@ -0,0 +1,15 @@ +[Unit] +Description=Automatic Mjolnir Module Updater +After=docker.service +Requires=network-online.target +Requires=docker.service + +[Service] +User=root +Group=root +ExecStart=/opt/venvs/matrix-synapse/bin/pip install -U "git+https://github.com/matrix-org/mjolnir.git#egg=mjolnir&subdirectory=synapse_antispam" +ExecStart=/usr/bin/chmod -R o+rx /opt/venvs/matrix-synapse/lib/python3.10/site-packages/mjolnir +Type=oneshot + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/etc/systemd/system/mjolnir-module-updater.timer b/etc/systemd/system/mjolnir-module-updater.timer new file mode 100644 index 0000000..25a4ba0 --- /dev/null +++ b/etc/systemd/system/mjolnir-module-updater.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Update Mjolnir Module Daily + +[Timer] +OnCalendar=daily +AccuracySec=1h +Persistent=true +RandomizedDelaySec=6000 + +[Install] +WantedBy=timers.target \ No newline at end of file diff --git a/srv/Matrix-Docker-Compose/docker-compose.yml b/srv/Matrix-Docker-Compose/docker-compose.yml new file mode 100644 index 0000000..16c90c5 --- /dev/null +++ b/srv/Matrix-Docker-Compose/docker-compose.yml @@ -0,0 +1,78 @@ +version: '3' + +services: + + element: + image: vectorim/element-web:latest + container_name: element + restart: unless-stopped + volumes: + - ./element/config.json:/app/config.json:Z + networks: + - element + ports: + - "127.0.0.1:81:80" + read_only: true + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + cap_add: + - CHOWN + - SETGID + - SETUID + - CAP_NET_BIND_SERVICE + tmpfs: + - /var/run:size=50M,mode=0770,noexec,nosuid,nodev + - /var/cache/nginx:size=50M,mode=0770,noexec,nosuid,nodev + + matrix-to: + image: ghcr.io/tommytran732/matrix.to + container_name: matrix-to + restart: unless-stopped + networks: + - matrix-to + ports: + - "127.0.0.1:5000:5000" + user: 992:992 + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + + pantalaimon: + image: matrixdotorg/pantalaimon:latest + container_name: pantalaimon + restart: unless-stopped + volumes: + - ./pantalaimon:/data + networks: + - pantalaimon + read_only: true + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + + mjolnir: + image: matrixdotorg/mjolnir:latest + container_name: mjolnir + restart: unless-stopped + volumes: + - ./mjolnir:/data + depends_on: + - pantalaimon + networks: + - pantalaimon + ports: + - "127.0.0.1:8081:8081" + read_only: true + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + +networks: + element: + matrix-to: + pantalaimon: \ No newline at end of file diff --git a/srv/Matrix-Docker-Compose/element/config.json b/srv/Matrix-Docker-Compose/element/config.json new file mode 100644 index 0000000..95a982b --- /dev/null +++ b/srv/Matrix-Docker-Compose/element/config.json @@ -0,0 +1,41 @@ +{ + "default_server_config": { + "m.homeserver": { + "base_url": "https://matrix.arcticfoxes.net", + "server_name": "arcticfoxes.net" + } + }, + "disable_custom_urls": true, + "brand": "ArcticFoxes", + "branding": { + "welcomeBackgroundUrl": "https://arcticfoxes.net/external_images/background.jpg", + "auth_header_logo_url": "https://arcticfoxes.net/external_images/logo.png", + "auth_footer_links": [ + {"text": "Rules and Privacy Policy", "url": "https://arcticfoxes.net"}, + {"text": "GitHub", "url": "https://github.com/arcticfoxes-net"}, + {"text": "Gitea", "url": "https://git.tommytran.io/arcticfoxes-net"} + ] + }, + "integrations_ui_url": null, + "integrations_rest_url": null, + "integrations_widgets_urls": null, + "defaultCountryCode": "US", + "showLabsSettings": true, + "features": {}, + "default_federate": true, + "default_theme": "dark", + "roomDirectory": { + "servers": [ + "arcticfoxes.net", + "grapheneos.org", + "matrix.org" + ] + }, + "enable_presence_by_hs_url": { + "https://matrix.org": false, + "https://grapheneos.org": false + }, + "settingDefaults": { + "breadcrumbs": true + } +} \ No newline at end of file