diff --git a/common/common.nix b/common/common.nix index 5396da9..3cda1f3 100644 --- a/common/common.nix +++ b/common/common.nix @@ -12,7 +12,7 @@ ./server/mumble.nix ./server/icecast.nix ./server/nginx-stream.nix - ./server/vscode/modules/vscode-server + ./server/matrix.nix ./pc/de.nix ]; diff --git a/common/server/matrix.nix b/common/server/matrix.nix new file mode 100644 index 0000000..3a1c7ad --- /dev/null +++ b/common/server/matrix.nix @@ -0,0 +1,176 @@ +{ lib, config, pkgs, ... }: + +let + cfg = config.services.matrix; + certs = config.security.acme.certs; +in { + options.services.matrix = { + enable = lib.mkEnableOption "enable matrix"; + element-web = { + enable = lib.mkEnableOption "enable matrix web client"; + host = lib.mkOption { + type = lib.types.str; + description = "the https host to serve"; + }; + }; + jitsi-meet = { + enable = lib.mkEnableOption "enable jisti meet + matrix integration"; + host = lib.mkOption { + type = lib.types.str; + description = "the https host to serve"; + }; + }; + turn = { + host = lib.mkOption { + type = lib.types.str; + description = "the https host to serve"; + }; + port = lib.mkOption { + type = lib.types.int; + default = 25999; + description = "turn server port"; + }; + min-port = lib.mkOption { + type = lib.types.int; + default = 26000; + description = "min turn server port"; + }; + max-port = lib.mkOption { + type = lib.types.int; + default = 26100; + description = "max turn server port"; + }; + secret = lib.mkOption { + type = lib.types.str; + description = "the turn server secret"; + }; + }; + host = lib.mkOption { + type = lib.types.str; + description = "name of the matrix-synapse server"; + }; + enable_registration = lib.mkEnableOption "enable new user signup"; + port = lib.mkOption { + type = lib.types.int; + default = 45022; + description = "internal matrix-synapse port"; + }; + }; + config = lib.mkIf cfg.enable { + services.matrix-synapse = { + enable = true; + server_name = cfg.host; + database_type = "sqlite3"; + enable_registration = cfg.enable_registration; + listeners = [ { + bind_address = "127.0.0.1"; + port = cfg.port; + tls = false; + resources = [ { + compress = true; + names = [ "client" "webclient" "federation" ]; + } ]; + } ]; + turn_uris = [ + "turn:${cfg.turn.host}:${toString cfg.turn.port}?transport=udp" + "turn:${cfg.turn.host}:${toString cfg.turn.port}?transport=tcp" + ]; + turn_shared_secret = cfg.turn.secret; + turn_user_lifetime = "1h"; + }; + + services.coturn = { + enable = true; + no-cli = true; + min-port = cfg.turn.min-port; + max-port = cfg.turn.max-port; + use-auth-secret = true; + static-auth-secret = cfg.turn.secret; + realm = cfg.turn.host; + cert = "${certs.${cfg.turn.host}.directory}/full.pem"; + pkey = "${certs.${cfg.turn.host}.directory}/key.pem"; + extraConfig = '' + # ban private IP ranges + denied-peer-ip=10.0.0.0-10.255.255.255 + denied-peer-ip=127.0.0.0-127.255.255.255 + denied-peer-ip=172.16.0.0-172.31.255.255 + denied-peer-ip=192.88.99.0-192.88.99.255 + denied-peer-ip=192.168.0.0-192.168.255.255 + denied-peer-ip=244.0.0.0-224.255.255.255 + denied-peer-ip=255.255.255.255-255.255.255.255 + ''; + }; + + networking.firewall.allowedUDPPorts = [ cfg.turn.port ]; + networking.firewall.allowedTCPPorts = [ cfg.turn.port 8448 ]; + networking.firewall.allowedUDPPortRanges = [ + { from = cfg.turn.min-port; to = cfg.turn.max-port; } + ]; + networking.firewall.allowedTCPPortRanges = [ + { from = cfg.turn.min-port; to = cfg.turn.max-port; } + ]; + + users.users.nginx.extraGroups = [ "turnserver" ]; + security.acme.certs.${cfg.turn.host} = { + postRun = "systemctl restart coturn.service"; + group = "turnserver"; + }; + + services.nginx = { + enable = true; + + virtualHosts.${cfg.host} = { + enableACME = true; + forceSSL = true; + listen = [ + { + addr = "0.0.0.0"; + port = 8448; + ssl = true; + } + { + addr = "0.0.0.0"; + port = 443; + ssl = true; + } + ]; + locations."/".proxyPass = "http://localhost:${toString cfg.port}"; + }; + virtualHosts.${cfg.turn.host} = { # get TLS cert for TURN server + enableACME = true; + forceSSL = true; + }; + + virtualHosts.${cfg.irc-bridge.host} = { + enableACME = true; + forceSSL = true; + locations."/".proxyPass = "http://localhost:${toString cfg.irc-bridge.port}"; + }; + + virtualHosts.${cfg.element-web.host} = lib.mkIf cfg.element-web.enable { + enableACME = true; + forceSSL = true; + locations."/".root = pkgs.element-web.override { + conf = { + default_server_config = { + "m.homeserver" = { + "base_url" = "https://${cfg.host}"; + "server_name" = cfg.host; + }; + "m.identity_server" = { + "base_url" = "https://vector.im"; + }; + }; + jitsi.preferredDomain = lib.mkIf cfg.jitsi-meet.enable cfg.jitsi-meet.host; + }; + }; + }; + }; + + services.jitsi-meet = lib.mkIf cfg.jitsi-meet.enable { + enable = true; + hostName = cfg.jitsi-meet.host; + nginx.enable = true; + }; + }; +} \ No newline at end of file diff --git a/machines/neet.dev/configuration.nix b/machines/neet.dev/configuration.nix index fa9f5f6..007dc06 100644 --- a/machines/neet.dev/configuration.nix +++ b/machines/neet.dev/configuration.nix @@ -54,6 +54,21 @@ domain = "voice.neet.space"; }; - services.vscode-server.enable = true; + services.matrix = { + enable = true; + host = "neet.space"; + enable_registration = false; + element-web = { + enable = true; + host = "chat.neet.space"; + }; + jitsi-meet = { + enable = true; + host = "meet.neet.space"; + }; + turn = { + host = "turn.neet.space"; + secret = "a8369a0e96922abf72494bb888c85831b"; + }; + }; } -