diff --git a/hosts/nachtigall/apps/matrix/matrix-log-config.yaml b/hosts/nachtigall/apps/matrix/matrix-log-config.yaml
new file mode 100644
index 0000000..555f3aa
--- /dev/null
+++ b/hosts/nachtigall/apps/matrix/matrix-log-config.yaml
@@ -0,0 +1,40 @@
+version: 1
+
+formatters:
+ precise:
+ format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'
+
+filters:
+ context:
+ (): synapse.util.logcontext.LoggingContextFilter
+ request: ""
+
+handlers:
+ console:
+ class: logging.StreamHandler
+ formatter: precise
+ filters: [context]
+
+loggers:
+ synapse:
+ level: WARNING
+
+ synapse.storage.SQL:
+ # beware: increasing this to DEBUG will make synapse log sensitive
+ # information such as access tokens.
+ level: WARNING
+
+ synapse.http.matrixfederationclient:
+ level: CRITICAL
+ synapse.federation.sender.per_destination_queue:
+ level: CRITICAL
+ synapse.handlers.device:
+ level: CRITICAL
+ synapse.replication.tcp.handler:
+ level: CRITICAL
+ shared_secret_authenticator:
+ level: INFO
+
+root:
+ level: WARNING
+ handlers: [console]
diff --git a/hosts/nachtigall/apps/matrix/mautrix-telegram.nix b/hosts/nachtigall/apps/matrix/mautrix-telegram.nix
new file mode 100644
index 0000000..f286bd0
--- /dev/null
+++ b/hosts/nachtigall/apps/matrix/mautrix-telegram.nix
@@ -0,0 +1,211 @@
+{ flake, lib, config, pkgs, ... }:
+{
+ age.secrets."matrix-mautrix-telegram-env-file" = {
+ file = "${flake.self}/secrets/matrix-mautrix-telegram-env-file.age";
+ mode = "400";
+ owner = "matrix-synapse";
+ };
+
+ services.mautrix-telegram = {
+ enable = true;
+ environmentFile = "/run/agenix/matrix-mautrix-telegram-env-file";
+ settings = {
+ homeserver = {
+ # TODO: Use the port from synapse config
+ address = "http://localhost:8008";
+ domain = "test.pub.solar";
+ verify_ssl = true;
+ };
+ appservice = {
+ address = "http://localhost:8009";
+ bot_avatar = "mxc://maunium.net/tJCRmUyJDsgRNgqhOgoiHWbX";
+ bot_displayname = "Telegram bridge bot";
+ bot_username = "telegrambot";
+ # TODO: See if we can use postgresql
+ database = "sqlite:////var/lib/mautrix-telegram/sqlite.db";
+ hostname = "0.0.0.0";
+ id = "telegram";
+ max_body_size = 1;
+ port = 8009;
+ provisioning = {
+ enabled = false;
+ prefix = "/_matrix/provision/v1";
+ shared_secret = "generate";
+ };
+ public = {
+ enabled = true;
+ external = "https://matrix.test.pub.solar/c3c3f34b-29fb-5feb-86e5-98c75ec8214b";
+ prefix = "/c3c3f34b-29fb-5feb-86e5-98c75ec8214b";
+ };
+ };
+ bridge = {
+ alias_template = "telegram_{groupname}";
+ allow_matrix_login = true;
+ # Animated stickers conversion requires additional packages in the
+ # service's path.
+ # If this isn't a fresh installation, clearing the bridge's uploaded
+ # file cache might be necessary (make a database backup first!):
+ # delete from telegram_file where \
+ # mime_type in ('application/gzip', 'application/octet-stream')
+ animated_sticker = {
+ args = {
+ background = "'020202'"; # only for gif, transparency not supported
+ fps = 30; # only for webm
+ height = 256;
+ width = 256;
+ };
+ target = "gif";
+ };
+ bot_messages_as_notices = true;
+ bridge_notices = {
+ default = false;
+ exceptions = [];
+ };
+ command_prefix = "!tg";
+ delivery_error_reports = true;
+ delivery_receipts = false;
+ displayname_max_length = 100;
+ displayname_preference = [
+ "full name"
+ "username"
+ "phone number"
+ ];
+ displayname_template = "'{displayname} (Telegram)'";
+ emote_format = "'* $mention $formatted_body'";
+ encryption = {
+ allow = false;
+ database = "default";
+ default = false;
+ key_sharing = {
+ allow = false;
+ require_cross_signing = false;
+ require_verification = true;
+ };
+ };
+ federate_rooms = true;
+ filter = {
+ list = [];
+ mode = "blacklist";
+ };
+ image_as_file_size = 10;
+ initial_power_level_overrides = {
+ group = {};
+ user = {};
+ };
+ inline_images = false;
+ max_document_size = 100;
+ max_initial_member_sync = 10;
+ max_telegram_delete = 10;
+ message_formats = {
+ "m.audio" = "'$sender_displayname sent an audio file: $message'";
+ "m.emote" = "'* $sender_displayname $message'";
+ "m.file" = "'$sender_displayname sent a file: $message'";
+ "m.image" = "'$sender_displayname sent an image: $message'";
+ "m.location" = "'$sender_displayname sent a location: $message'";
+ "m.notice" = "'$sender_displayname: $message'";
+ "m.text" = "'$sender_displayname: $message'";
+ "m.video" = "'$sender_displayname sent a video: $message'";
+ };
+ parallel_file_transfer = false;
+ plaintext_highlights = false;
+ private_chat_portal_meta = false;
+ public_portals = true;
+ relaybot = {
+ authless_portals = true;
+ group_chat_invite = [];
+ ignore_own_incoming_events = true;
+ ignore_unbridged_group_chat = true;
+ private_chat = {
+ invite = [];
+ message = "This is a Matrix bridge relaybot and does not support direct chats";
+ state_changes = true;
+ };
+ whitelist = [];
+ whitelist_group_admins = true;
+ };
+ resend_bridge_info = false;
+ skip_deleted_members = true;
+ startup_sync = true;
+ state_event_formats = {
+ join = "$displayname joined the room.";
+ leave = "$displayname left the room.";
+ name_change = "$prev_displayname changed their name to $displayname";
+ };
+ sync_channel_members = false;
+ sync_dialog_limit = 30;
+ sync_direct_chats = false;
+ sync_matrix_state = true;
+ sync_with_custom_puppets = true;
+ telegram_link_preview = true;
+ username_template = "telegram_{userid}";
+
+ permissions = {
+ "test.pub.solar" = "full";
+ };
+ };
+
+ logging = {
+ formatters= {
+ precise = {
+ format = "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s";
+ };
+ };
+ handlers = {
+ console = {
+ class = "logging.StreamHandler";
+ formatter = "precise";
+ };
+ };
+ loggers={
+ aiohttp.level = "WARNING";
+ mau.level = "WARNING";
+ telethon.level = "WARNING";
+ };
+ root = {
+ handlers = [ "console" ];
+ level = "WARNING";
+ };
+ version = 1;
+ };
+
+ telegram = {
+ connection = {
+ flood_sleep_threshold = 60;
+ request_retries = 5;
+ retries = 5;
+ retry_delay = 1;
+ timeout = 120;
+ };
+ device_info = {
+ app_version = "auto";
+ device_model = "auto";
+ lang_code = "en";
+ system_lang_code = "en";
+ system_version = "auto";
+ };
+ proxy = {
+ address = "127.0.0.1";
+ password = "''";
+ port = 1080;
+ rdns = true;
+ type = "disabled";
+ username = "''";
+ };
+ server = {
+ dc = 2;
+ enabled = false;
+ ip = "149.154.167.40";
+ port = 80;
+ };
+ };
+ };
+ };
+
+ systemd.services.mautrix-telegram.path = with pkgs; [
+ lottieconverter # for animated stickers conversion, unfree package
+ ffmpeg # if converting animated stickers to webm (very slow!)
+ ];
+ systemd.services.mautrix-telegram.serviceConfig = {
+ User = "matrix-synapse";
+ };
+}
diff --git a/hosts/nachtigall/apps/matrix/synapse.nix b/hosts/nachtigall/apps/matrix/synapse.nix
new file mode 100644
index 0000000..d0b2fe2
--- /dev/null
+++ b/hosts/nachtigall/apps/matrix/synapse.nix
@@ -0,0 +1,236 @@
+{ flake, config, pkgs, ... }:
+let
+ publicDomain = "matrix.test.pub.solar";
+ serverDomain = "test.pub.solar";
+in {
+ age.secrets."matrix-synapse-signing-key" = {
+ file = "${flake.self}/secrets/matrix-synapse-signing-key.age";
+ mode = "400";
+ owner = "matrix-synapse";
+ };
+
+ age.secrets."matrix-synapse-secret-config.yaml" = {
+ file = "${flake.self}/secrets/matrix-synapse-secret-config.yaml.age";
+ mode = "400";
+ owner = "matrix-synapse";
+ };
+
+ services.matrix-synapse = {
+ enable = true;
+ settings = {
+ server_name = serverDomain;
+ public_baseurl = "https://matrix.test.pub.solar/";
+ database = {
+ name = "psycopg2";
+ args = {
+ host = "/run/postgresql";
+ cp_max = 10;
+ cp_min = 5;
+ database = "matrix";
+ };
+ allow_unsafe_locale = false;
+ txn_limit = 0;
+ };
+
+ account_threepid_delegates.msisdn = "";
+ alias_creation_rules = [{
+ action = "allow";
+ alias= "*";
+ room_id = "*" ;
+ user_id = "*";
+ }];
+ allow_guest_access = false;
+ allow_public_rooms_over_federation = false;
+ allow_public_rooms_without_auth = false;
+ auto_join_rooms = [
+ "#community:${serverDomain}"
+ "#general:${serverDomain}"
+ ];
+
+ autocreate_auto_join_rooms = true;
+ caches.global_factor = 0.5;
+
+ default_room_version = "10";
+ disable_msisdn_registration = true;
+ email = {
+ app_name = "Matrix";
+ client_base_url = "https://chat.pub.solar";
+ enable_notifs = true;
+ enable_tls = true;
+ # FUTUREWORK: Maybe we should change this
+ invite_client_location = "https://app.element.io";
+ notif_for_new_users = true;
+ notif_from = "Matrix ";
+ require_transport_security = false;
+ smtp_host = "matrix-mailer";
+ smtp_port = 8025;
+ };
+
+ enable_media_repo = true;
+ enable_metrics = true;
+ enable_registration = false;
+ enable_registration_captcha = false;
+ enable_registration_without_verification = false;
+ enable_room_list_search = true;
+ encryption_enabled_by_default_for_room_type = "off";
+ event_cache_size = "100K";
+ federation_rr_transactions_per_room_per_second = 50;
+ forget_rooms_on_leave = true;
+ include_profile_data_on_invite = true;
+ instance_map = {};
+ limit_profile_requests_to_users_who_share_rooms = false;
+
+ log_config = ./matrix-log-config.yaml;
+
+ max_spider_size = "10M";
+ max_upload_size = "50M";
+ media_storage_providers = [];
+
+ password_config = {
+ enabled = false;
+ localdb_enabled = false;
+ pepper = "";
+ };
+
+ presencee.enabled = true;
+ push.include_content = false;
+
+ rc_admin_redaction= {
+ burst_count = 50;
+ per_second = 1;
+ };
+ rc_federation= {
+ concurrent = 3;
+ reject_limit = 50;
+ sleep_delay = 500;
+ sleep_limit = 10;
+ window_size = 1000;
+ };
+ rc_invites= {
+ per_issuer= {
+ burst_count = 10;
+ per_second = 0.3;
+ };
+ per_room= {
+ burst_count = 10;
+ per_second = 0.3;
+ };
+ per_user= {
+ burst_count = 5;
+ per_second = 0.003;
+ };
+ };
+ rc_joins= {
+ local= {
+ burst_count = 10;
+ per_second = 0.1;
+ };
+ remote= {
+ burst_count = 10;
+ per_second = 0.01;
+ };
+ };
+ rc_login= {
+ account= {
+ burst_count = 3;
+ per_second = 0.17;
+ };
+ address= {
+ burst_count = 3;
+ per_second = 0.17;
+ };
+ failed_attempts= {
+ burst_count = 3;
+ per_second = 0.17;
+ };
+ };
+ rc_message= {
+ burst_count = 10;
+ per_second = 0.2;
+ };
+ rc_registration= {
+ burst_count = 3;
+ per_second = 0.17;
+ };
+ redaction_retention_period = "7d";
+ redis.enabled = false;
+ registration_requires_token = false;
+ registrations_require_3pid = ["email"];
+ report_stats = false;
+ require_auth_for_profile_requests = false;
+ room_list_publication_rules = [{
+ action = "allow";
+ alias = "*";
+ room_id = "*";
+ user_id = "*";
+ }];
+
+ signing_key_path = "/run/agenix/matrix-synapse-signing-key";
+
+ stream_writers = {};
+ trusted_key_servers = [{ server_name = "matrix.org";}];
+ turn_allow_guests = false;
+ turn_uris = [
+ "turn:matrix.pub.solar?transport=udp"
+ "turn:matrix.pub.solar?transport=tcp"
+ ];
+ url_preview_accept_language = [
+ "en-US"
+ "en"
+ ];
+ 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"
+ ];
+
+ user_directory = {
+ prefer_local_users = false;
+ search_all_users = false;
+ };
+ user_ips_max_age = "28d";
+
+ app_service_config_files = [
+ "/var/lib/matrix-synapse/telegram-registration.yaml"
+ # "/matrix-appservice-irc-registration.yaml"
+ # "/matrix-appservice-slack-registration.yaml"
+ # "/hookshot-registration.yml"
+ # "/matrix-mautrix-signal-registration.yaml"
+ # "/matrix-mautrix-telegram-registration.yaml"
+ ];
+ };
+
+ extraConfigFiles = [
+ "/run/agenix/matrix-synapse-secret-config.yaml"
+
+ # The registration file is automatically generated after starting the
+ # appservice for the first time.
+ # cp /var/lib/mautrix-telegram/telegram-registration.yaml \
+ # /var/lib/matrix-synapse/
+ # chown matrix-synapse:matrix-synapse \
+ # /var/lib/matrix-synapse/telegram-registration.yaml
+ "/var/lib/matrix-synapse/telegram-registration.yaml"
+ ];
+
+ plugins = [
+ config.services.matrix-synapse.package.plugins.matrix-synapse-shared-secret-auth
+ ];
+ };
+}
diff --git a/hosts/nachtigall/default.nix b/hosts/nachtigall/default.nix
index 451acde..d452af5 100644
--- a/hosts/nachtigall/default.nix
+++ b/hosts/nachtigall/default.nix
@@ -10,6 +10,7 @@
./nix.nix
./apps/nginx.nix
+ ./apps/forgejo.nix
./apps/keycloak.nix
./apps/mailman.nix
./apps/mastodon.nix
@@ -18,6 +19,8 @@
./apps/nginx-website.nix
./apps/opensearch.nix
./apps/postgresql.nix
- ./apps/forgejo.nix
+
+ ./apps/matrix/mautrix-telegram.nix
+ ./apps/matrix/synapse.nix
];
}
diff --git a/secrets/matrix-mautrix-telegram-env-file.age b/secrets/matrix-mautrix-telegram-env-file.age
new file mode 100644
index 0000000..2497dfd
Binary files /dev/null and b/secrets/matrix-mautrix-telegram-env-file.age differ
diff --git a/secrets/matrix-synapse-secret-config.yaml.age b/secrets/matrix-synapse-secret-config.yaml.age
new file mode 100644
index 0000000..eb1dc12
Binary files /dev/null and b/secrets/matrix-synapse-secret-config.yaml.age differ
diff --git a/secrets/matrix-synapse-signing-key.age b/secrets/matrix-synapse-signing-key.age
new file mode 100644
index 0000000..51eab61
--- /dev/null
+++ b/secrets/matrix-synapse-signing-key.age
@@ -0,0 +1,28 @@
+age-encryption.org/v1
+-> ssh-ed25519 iDKjwg DIYhq76lfISisIR1cF5QRAHpUOcY73wh2AAIveZzQEU
+AaISTQUQHKZPfI3eOmez1LsANCwMiLae6wNDtdGyrk4
+-> ssh-ed25519 uYcDNw aWo4SN3rJXLWjeQFmHWQsWvq6TZysarvk2/ymPNjSW0
+Z8dFM+4R/rCzVsAQtmeO/ANFdeqkcOixgcfp5Pe9FIY
+-> ssh-rsa kFDS0A
+fNc11rAe6fUi7DaxEGbU84nJ99DCwv2oSs0EXUtXYU7kSQnPzEMvBUmDtsjc/yJK
+JrER6X3EZpStvveHs12T2bD8sC7qvpGDM0/yxQaD/g2sebdl/PSdly3PcKZPmFJn
+5a8bdFz6auLoxPtV9Ew83rai7/zSGWomD9MtISmtzofQ6ZUMCTHkyv+JFrSGMlDR
+/wAPP4AthjlysLgVnpbFixcFaZKA1825H7yk+i+TvIHIZ5YNhcTlvyos5BnKTbjI
+JJffhvEz4I3c+v6Nb6tssFs/WcnuylDQZa3YqHT8zaL/pXWKZKwSTMkXMXdN5/V6
+bKwwyuSepbKgcdnYt3qnSRZcGobAD3LISrkyPuh3/6v6mPxX9eriv8A+cCTVFR+H
+tx2EEa0PQpgQX7erCxu8n3marv43e6tF58ULJHoBtEcUs0ov5ereNWJBRL5NcZcZ
+1jAg3tJtWFcplghJ8oS4ePrCj87ibNeHUW50zTmpoCWnSdl5coKzPtFRjjWJNf0U
+mUAqnoCOVSkpy+5tUbCdo3IhxXPwQp70SkBTKqJhLw7AqmqCSEt8IzO7Nmh8Cra7
+CpRvcqLvOjDNKLpc3FZWcJdZyFoQUd+hjqO3GsmYE+0HQm4Prb9bDqRIyUiGa2y8
+8Z/Ae7T/X2hvr/h8by/JI+f67fj9n88LMBIc2+VF17M
+-> ssh-ed25519 YFSOsg 7VxASO8bBrWC66jWnFDr/E4uLrE9Eduk1DrxqKBNeAA
+ADu0wFcdyO2+Jzb8nbcBl9RArUrA11+Olr+5wT1NpxI
+-> ssh-ed25519 iHV63A 5its014WusI08tPQDHHPngzWaMWwbTFXUr3uRSjmgU4
+PjhSqHE9QtLQsOvkTh44TYsf4dlBxlHA+0hbY0P34rI
+-> ssh-ed25519 BVsyTA /0Lg7IgQ+ziQPB8zW/g+b9B5MBUmxl44zHKlPC2qgiM
+/nGP+6j9jDh/I0ZW4+nkhVtIRf7rqv0RG+sPoGXq/84
+-> fd]-grease "J/'r
+1Gqo8aWuDf5XWFLB+OxHs3sNKf/4Kwv8dXBEtn40oL0uk8UZyUkNaLWZ2/GfdO0t
+dT7bm5ihzq/7wJsIoNUgGBDprFAZgcEExno
+--- zpUnJCx+HoeJm0KW3PIwljBvp/94VsyKfDQ2GRSOd+4
+1I#C[|)܁:dd 3X'qAokCTT3aBt'k\c&a|:R5
\ No newline at end of file
diff --git a/secrets/secrets.nix b/secrets/secrets.nix
index c988a21..cb06356 100644
--- a/secrets/secrets.nix
+++ b/secrets/secrets.nix
@@ -20,22 +20,19 @@ let
nachtigall-host
];
in {
-
"mastodon-secret-key-base.age".publicKeys = nachtigallKeys ++ baseKeys;
-
"mastodon-otp-secret.age".publicKeys = nachtigallKeys ++ baseKeys;
-
"mastodon-vapid-private-key.age".publicKeys = nachtigallKeys ++ baseKeys;
-
"mastodon-vapid-public-key.age".publicKeys = nachtigallKeys ++ baseKeys;
-
"mastodon-smtp-password.age".publicKeys = nachtigallKeys ++ baseKeys;
-
"mastodon-extra-env-secrets.age".publicKeys = nachtigallKeys ++ baseKeys;
"keycloak-database-password.age".publicKeys = nachtigallKeys ++ baseKeys;
"forgejo-database-password.age".publicKeys = nachtigallKeys ++ baseKeys;
-
"forgejo-mailer-password.age".publicKeys = nachtigallKeys ++ baseKeys;
+
+ "matrix-mautrix-telegram-env-file.age".publicKeys = nachtigallKeys ++ baseKeys;
+ "matrix-synapse-signing-key.age".publicKeys = nachtigallKeys ++ baseKeys;
+ "matrix-synapse-secret-config.yaml.age".publicKeys = nachtigallKeys ++ baseKeys;
}