diff --git a/modules/default.nix b/modules/default.nix index 2e6c80a..906ff43 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -30,6 +30,8 @@ ./security/gpg.nix ./security/pass.nix ./services/borgmatic + ./services/coturn + ./services/matrix ./shell/git ./shell/zsh ]; diff --git a/modules/services/coturn/default.nix b/modules/services/coturn/default.nix new file mode 100644 index 0000000..e8a8bf9 --- /dev/null +++ b/modules/services/coturn/default.nix @@ -0,0 +1,59 @@ +{ config, lib, pkgs, inputs, ... }: + +with lib; + +let + cfg = config.modules.services.coturn; + domain = "vimium.com"; +in { + options.modules.services.coturn = { + enable = mkOption { + default = false; + example = true; + }; + }; + + config = { + age.secrets."passwords/services/coturn/secret" = { + file = "${inputs.secrets}/passwords/services/coturn/secret.age"; + }; + + networking.firewall = { + allowedTCPPorts = [ + 5349 # STUN TLS + 5350 # STUN TLS alt + ]; + allowedUDPPortRanges = [ + { from = 49152; to = 49999; } # TURN relay + ]; + }; + + services.coturn = { + enable = true; + lt-cred-mech = true; + use-auth-secret = true; + static-auth-secret = ""; # TODO: Pass as extraConfig + realm = "turn.${domain}"; + relay-ips = [ + "198.244.190.160" + ]; + no-tcp-relay = true; + extraConfig = '' + cipher-list="HIGH" + no-loopback-peers + no-multicast-peers + ''; + secure-stun = true; + cert = "/var/lib/acme/turn.${domain}/fullchain.pem"; + pkey = "/var/lib/acme/turn.${domain}/key.pem"; + min-port = 49152; + max-port = 49999; + }; + + security.acme.certs = { + "turn.${domain}" = { + reloadServices = [ "coturn" ]; + }; + }; + }; +} diff --git a/modules/services/matrix/default.nix b/modules/services/matrix/default.nix new file mode 100644 index 0000000..6d4661f --- /dev/null +++ b/modules/services/matrix/default.nix @@ -0,0 +1,120 @@ +{ config, lib, pkgs, inputs, ... }: + +with lib; + +let + cfg = config.modules.services.matrix; + domain = "vimium.com"; + clientConfig = { + "m.homeserver" = { + base_url = "https://matrix.${domain}"; + server_name = domain; + }; + "m.identity_server" = {}; + }; + serverConfig."m.server" = "matrix.${domain}:443"; + mkWellKnown = data: '' + more_set_headers 'Content-Type: application/json'; + return 200 '${builtins.toJSON data}'; + ''; +in { + options.modules.services.matrix = { + enable = mkOption { + default = false; + example = true; + }; + coturn = mkOption { + default = config.services.coturn.enable; + example = true; + }; + elementWeb = mkOption { + default = true; + example = true; + }; + }; + + config = mkIf cfg.enable { + networking.firewall = { + allowedTCPPorts = [ + 8448 # Matrix federation + ]; + }; + + services.nginx = { + virtualHosts = { + "${domain}" = { + # Assume this listener is already setup + locations."= /.well-known/matrix/server".extraConfig = (mkWellKnown serverConfig); + locations."= /.well-known/matrix/client".extraConfig = (mkWellKnown clientConfig); + }; + "matrix.${domain}" = { + forceSSL = true; + useACMEHost = "matrix.${domain}"; + listen = [ + { addr = "0.0.0.0"; port = 443; ssl = true; } + { addr = "0.0.0.0"; port = 80; } + { addr = "0.0.0.0"; port = 8448; ssl = true; } + { addr = "[::1]"; port = 443; ssl = true; } + { addr = "[::1]"; port = 80; } + { addr = "[::1]"; port = 8448; ssl = true; } + ]; + locations = { + "/" = { + proxyPass = "http://localhost:8008"; + extraConfig = '' + proxy_set_header X-Forwarded-For $remote_addr; + ''; + }; + "/_matrix" = { + proxyPass = "http://localhost:8008"; + extraConfig = '' + proxy_set_header X-Forwarded-For $remote_addr; + client_max_body_size ${services.matrix-synapse.settings.max_upload_size}; + ''; + }; + "/_synapse/client".proxyPass = "http://localhost:8008"; + }; + }; + "chat.${domain}" = mkIf cfg.elementWeb { + forceSSL = true; + useACMEHost = "matrix.${domain}"; + root = pkgs.element-web.override { + conf = { + default_server_config = clientConfig; + brand = "Vimium Chat"; + branding = { + auth_header_logo_url = "https://vimium.com/images/logo.svg"; + auth_footer_links = [ + { text = "Vimium.com"; url = "https://www.vimium.com"; } + ]; + }; + }; + }; + }; + }; + }; + + services.matrix-synapse = { + enable = true; + settings = { + database.name = "sqlite3"; + enable_registration = false; + server_name = domain; + turn_shared_secret_file = mkIf cfg.coturn config.age.secrets."passwords/services/coturn/secret".path; + turn_uris = mkIf cfg.coturn [ + "turn:${config.services.coturn.realm}:5349?transport=udp" + "turn:${config.services.coturn.realm}:5350?transport=udp" + "turn:${config.services.coturn.realm}:5349?transport=tcp" + "turn:${config.services.coturn.realm}:5350?transport=tcp" + ]; + }; + }; + + security.acme.certs = { + "matrix.${domain}" = { + extraDomainNames = mkIf cfg.elementWeb [ "chat.${domain}" ]; + reloadServices = [ "matrix-synapse" ]; + }; + }; + }; +}