nix-config/common/server/matrix.nix
2021-05-23 09:05:23 -04:00

209 lines
6.0 KiB
Nix

{ 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;
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.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.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";
'';
services.jitsi-meet = lib.mkIf cfg.jitsi-meet.enable {
enable = true;
hostName = cfg.jitsi-meet.host;
nginx.enable = true;
config = {
enableInsecureRoomNameWarning = true;
fileRecordingsEnabled = false;
liveStreamingEnabled = false;
prejoinPageEnabled = true;
preferH264 = true;
disableH264 = false;
desktopSharingFrameRate = {
min = 5;
max = 30;
};
startScreenSharing = true;
videoQuality = {
disabledCodec = "VP8";
preferredCodec = "H264";
enforcePreferredCodec = true;
};
p2p = {
enabled = true;
preferH264 = true;
disabledCodec = "VP8";
preferredCodec = "H264";
disableH264 = false;
};
requireDisplayName = false;
disableThirdPartyRequests = true;
localRecording = {
enabled = false;
};
doNotStoreRoom = true;
};
};
};
}