{ config, pkgs, modulesPath, unstable, sops, ... }: let matrixDomain = "matrix2.swarsel.win"; in { services.xserver = { layout = "us"; xkbVariant = "altgr-intl"; }; nix.settings.experimental-features = ["nix-command" "flakes"]; proxmoxLXC.manageNetwork = true; # manage network myself proxmoxLXC.manageHostName = false; # manage hostname myself networking.useDHCP = true; networking.enableIPv6 = false; services.openssh = { enable = true; settings.PermitRootLogin = "yes"; listenAddresses = [{ port = 22; addr = "0.0.0.0"; }]; }; users.users.root.openssh.authorizedKeys.keyFiles = [ ../../../secrets/keys/authorized_keys ]; system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change environment.shellAliases = { nswitch = "cd /.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;"; }; imports = [ (modulesPath + "/virtualisation/proxmox-lxc.nix") ./hardware-configuration.nix # we import here a service that is not available yet on normal nixpkgs # this module is hence not in the modules list, we add it ourselves ]; networking.hostName = "matrix"; # Define your hostname. networking.firewall.enable = false; environment.systemPackages = with pkgs; [ git gnupg ssh-to-age matrix-synapse lottieconverter ffmpeg ]; sops.age.sshKeyPaths = [ "/etc/ssh/sops" ]; sops.defaultSopsFile = "/.dotfiles/secrets/matrix/secrets.yaml"; sops.validateSopsFiles = false; sops.secrets.matrixsharedsecret = {owner="matrix-synapse";}; sops.templates."matrix_user_register.sh".content = '' register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008 ''; sops.templates.matrixshared.owner = "matrix-synapse"; sops.templates.matrixshared.content = '' registration_shared_secret: ${config.sops.placeholder.matrixsharedsecret} ''; sops.secrets.mautrixtelegram_as = {owner="matrix-synapse";}; sops.secrets.mautrixtelegram_hs = {owner="matrix-synapse";}; sops.secrets.mautrixtelegram_api_id = {owner="matrix-synapse";}; sops.secrets.mautrixtelegram_api_hash = {owner="matrix-synapse";}; sops.templates.mautrixtelegram.owner = "matrix-synapse"; sops.templates.mautrixtelegram.content = '' MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=${config.sops.placeholder.mautrixtelegram_as} MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=${config.sops.placeholder.mautrixtelegram_hs} MAUTRIX_TELEGRAM_TELEGRAM_API_ID=${config.sops.placeholder.mautrixtelegram_api_id} MAUTRIX_TELEGRAM_TELEGRAM_API_HASH=${config.sops.placeholder.mautrixtelegram_api_hash} ''; # sops.secrets.mautrixwhatsapp_shared = {owner="matrix-synapse";}; # sops.templates.mautrixwhatsapp.owner = "matrix-synapse"; # sops.templates.mautrixwhatsapp.content = '' # MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET=${config.sops.placeholder.mautrixwhatsapp_shared} # ''; services.postgresql.enable = true; services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" '' CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C"; CREATE ROLE "mautrix-telegram" WITH LOGIN PASSWORD 'telegram'; CREATE DATABASE "mautrix-telegram" WITH OWNER "mautrix-telegram" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C"; CREATE ROLE "mautrix-whatsapp" WITH LOGIN PASSWORD 'whatsapp'; CREATE DATABASE "mautrix-whatsapp" WITH OWNER "mautrix-whatsapp" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C"; CREATE ROLE "mautrix-signal" WITH LOGIN PASSWORD 'signal'; CREATE DATABASE "mautrix-signal" WITH OWNER "mautrix-signal" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C"; ''; services.matrix-synapse = { settings.app_service_config_files = [ "/var/lib/matrix-synapse/telegram-registration.yaml" "/var/lib/matrix-synapse/whatsapp-registration.yaml" "/var/lib/matrix-synapse/signal-registration.yaml" "/var/lib/matrix-synapse/doublepuppet.yaml" ]; enable = true; settings.server_name = matrixDomain; settings.public_baseurl = "https://${matrixDomain}"; extraConfigFiles = [ config.sops.templates.matrixshared.path ]; settings.listeners = [ { port = 8008; bind_addresses = [ "0.0.0.0" ]; type = "http"; tls = false; x_forwarded = true; resources = [ { names = [ "client" "federation" ]; compress = true; } ]; } ]; }; services.mautrix-telegram = { enable = true; environmentFile = config.sops.templates.mautrixtelegram.path; settings = { homeserver = { address = "http://localhost:8008"; domain = matrixDomain; }; appservice = { address= "http://localhost:29317"; hostname = "0.0.0.0"; port = "29317"; provisioning.enabled = true; id = "telegram"; # ephemeral_events = true; # not needed due to double puppeting public = { enabled = false; }; database = "postgresql:///mautrix-telegram?host=/run/postgresql"; }; bridge = { # login_shared_secret_map = { # matrixDomain = "as_token:doublepuppet"; # }; relaybot.authless_portals = true; allow_avatar_remove = true; allow_contact_info = true; sync_channel_members = true; startup_sync = true; sync_create_limit = 0; sync_direct_chats = true; telegram_link_preview = true; permissions = { "*" = "relaybot"; "@swarsel:${matrixDomain}" = "admin"; }; # 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 = { target = "gif"; args = { width = 256; height = 256; fps = 30; # only for webm background = "020202"; # only for gif, transparency not supported }; }; }; }; }; systemd.services.mautrix-telegram.path = with pkgs; [ lottieconverter # for animated stickers conversion, unfree package ffmpeg # if converting animated stickers to webm (very slow!) ]; services.mautrix-whatsapp = { enable = true; # environmentFile = config.sops.templates.mautrixwhatsapp.path; settings = { homeserver = { address = "http://localhost:8008"; domain = matrixDomain; }; appservice = { address= "http://localhost:29318"; hostname = "0.0.0.0"; port = 29318; database = { type = "postgres"; uri = "postgresql:///mautrix-whatsapp?host=/run/postgresql"; }; }; bridge = { displayname_template = "{{or .FullName .PushName .JID}} (WA)"; history_sync = { backfill = true; max_initial_conversations = -1; message_count = -1; request_full_sync = true; full_sync_config = { days_limit = 900; size_mb_limit = 5000; storage_quota_mb = 5000; }; }; login_shared_secret_map = { matrixDomain = "as_token:doublepuppet"; }; sync_manual_marked_unread = true; send_presence_on_typing = true; parallel_member_sync = true; url_previews = true; caption_in_message = true; extev_polls = true; permissions = { "*" = "relaybot"; "@swarsel:${matrixDomain}" = "admin"; }; }; }; }; services.mautrix-signal = { enable = true; # environmentFile = config.sops.templates.mautrixwhatsapp.path; settings = { homeserver = { address = "http://localhost:8008"; domain = matrixDomain; }; appservice = { address= "http://localhost:29328"; hostname = "0.0.0.0"; port = 29328; database = { type = "postgres"; uri = "postgresql:///mautrix-signal?host=/run/postgresql"; }; }; bridge = { displayname_template = "{{or .ContactName .ProfileName .PhoneNumber}} (Signal)"; login_shared_secret_map = { matrixDomain = "as_token:doublepuppet"; }; caption_in_message = true; permissions = { "*" = "relaybot"; "@swarsel:${matrixDomain}" = "admin"; }; }; }; }; # restart the bridges daily. this is done for the signal bridge mainly which stops carrying # messages out after a while. systemd.timers."restart-bridges" = { wantedBy = [ "timers.target" ]; timerConfig = { OnBootSec = "1d"; OnUnitActiveSec = "1d"; Unit = "restart-bridges.service"; }; }; systemd.services."restart-bridges" = { script = '' systemctl restart mautrix-whatsapp.service systemctl restart mautrix-signal.service systemctl restart mautrix-telegram.service ''; serviceConfig = { Type = "oneshot"; User = "root"; }; }; }