This commit is contained in:
commit
30ce0dafc2
195 changed files with 8902 additions and 0 deletions
26
services/synapse/database.nix
Normal file
26
services/synapse/database.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
pgsqlEnable = config.machine.postgresql.enable;
|
||||
inherit (config.machine.synapse) enable;
|
||||
in
|
||||
with lib; mkIf enable {
|
||||
services.postgresql = with lib; mkIf pgsqlEnable {
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "matrix-synapse";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
ensureDatabases = [ "matrix-synapse" ];
|
||||
};
|
||||
services.matrix-synapse.settings.database = {
|
||||
name = if pgsqlEnable then "psycopg2" else "sqlite3";
|
||||
args = with lib; mkIf pgsqlEnable {
|
||||
host = "/run/postgresql";
|
||||
};
|
||||
};
|
||||
}
|
||||
13
services/synapse/default.nix
Normal file
13
services/synapse/default.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
imports = [
|
||||
./database.nix
|
||||
./element.nix
|
||||
./mail.nix
|
||||
./nginx.nix
|
||||
./options.nix
|
||||
./redis.nix
|
||||
./secrets.nix
|
||||
./synapse.nix
|
||||
./turn.nix
|
||||
];
|
||||
}
|
||||
64
services/synapse/element.nix
Normal file
64
services/synapse/element.nix
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (config.machine.synapse.element) domain enable;
|
||||
elementConfig = {
|
||||
default_server_config = {
|
||||
"m.homeserver" = with config.services.matrix-synapse.settings; {
|
||||
base_url = public_baseurl;
|
||||
inherit server_name;
|
||||
};
|
||||
"m.identity_server" = {
|
||||
base_url = "";
|
||||
};
|
||||
};
|
||||
disable_custom_urls = false;
|
||||
disable_guests = true;
|
||||
disable_login_language_selector = false;
|
||||
disable_3pid_login = false;
|
||||
brand = "Element";
|
||||
default_country_code = "US";
|
||||
show_labs_settings = true;
|
||||
features = {
|
||||
feature_video_rooms = true;
|
||||
feature_group_calls = true;
|
||||
feature_element_call_video_rooms = true;
|
||||
feature_new_device_manager = true;
|
||||
feature_wysiwyg_composer = true;
|
||||
};
|
||||
default_federate = true;
|
||||
room_directory = with config.services.matrix-synapse.settings; {
|
||||
servers = [
|
||||
server_name
|
||||
"matrix.org"
|
||||
];
|
||||
};
|
||||
setting_defaults = {
|
||||
breadcrumbs = true;
|
||||
"MessageComposerInput.autoReplaceEmoji" = true;
|
||||
sendTypingNotifications = true;
|
||||
showTypingNotifications = true;
|
||||
showReadReceipts = true;
|
||||
showJoinLeaves = false;
|
||||
urlPreviewsEnabled = true;
|
||||
};
|
||||
sso_redirect_options = {
|
||||
immediate = false;
|
||||
on_welcome_page = true;
|
||||
};
|
||||
};
|
||||
in
|
||||
with lib; mkIf enable {
|
||||
services.nginx.virtualHosts.${domain} = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
root = pkgs.element-web.override (_old: {
|
||||
conf = elementConfig;
|
||||
});
|
||||
};
|
||||
}
|
||||
39
services/synapse/mail.nix
Normal file
39
services/synapse/mail.nix
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
sec,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (config.machine.synapse)
|
||||
enable
|
||||
domain
|
||||
;
|
||||
address = "noreply@${domain}";
|
||||
in
|
||||
with lib; mkIf (enable && config.machine.mail.enable) {
|
||||
services.matrix-synapse = {
|
||||
settings = {
|
||||
admin_contact = address;
|
||||
registrations_require_3pid = [ "email" ];
|
||||
email = {
|
||||
smtp_host = config.machine.mail.fqdn;
|
||||
smtp_port = 465;
|
||||
smtp_user = address;
|
||||
require_transport_security = true;
|
||||
enable_tls = true;
|
||||
notif_from = "RuJect Matrix <${address}>";
|
||||
app_name = "RuJect Matrix";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mailserver = {
|
||||
domains = [ domain ];
|
||||
accounts.${address} = {
|
||||
hashedPasswordFile = sec."mail/serviceHashedPassword".path;
|
||||
aliases = [ ];
|
||||
sendOnly = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
98
services/synapse/nginx.nix
Normal file
98
services/synapse/nginx.nix
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
inherit (config.machine.synapse) domain port;
|
||||
maxUploadSize = config.services.matrix-synapse.settings.max_upload_size;
|
||||
in
|
||||
{
|
||||
systemd.services.nginx.serviceConfig.SupplementaryGroups = [ "matrix-synapse" ];
|
||||
|
||||
services.nginx = {
|
||||
appendHttpConfig = ''
|
||||
limit_req_zone $binary_remote_addr zone=matrix_login:10m rate=1r/s;
|
||||
limit_req_zone $binary_remote_addr zone=matrix_register:10m rate=1r/m;
|
||||
limit_req_zone $binary_remote_addr zone=matrix_api:10m rate=20r/s;
|
||||
limit_req_zone $binary_remote_addr zone=matrix_media:10m rate=10r/s;
|
||||
limit_req_zone $binary_remote_addr zone=matrix_federation:10m rate=50r/s;
|
||||
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
|
||||
'';
|
||||
upstreams."matrix-synapse".servers = {
|
||||
"unix:/run/matrix-synapse/matrix-synapse.sock" = { };
|
||||
};
|
||||
virtualHosts.${domain} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
|
||||
locations = {
|
||||
# Synapse client API
|
||||
"/_matrix/client" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
extraConfig = ''
|
||||
limit_req zone=matrix_api burst=50 nodelay;
|
||||
client_max_body_size ${maxUploadSize};
|
||||
'';
|
||||
};
|
||||
|
||||
# Login endpoint with stricter rate limiting
|
||||
"~ ^/_matrix/client/(r0|v3)/login$" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
extraConfig = ''
|
||||
limit_req zone=matrix_login burst=3 nodelay;
|
||||
'';
|
||||
};
|
||||
|
||||
# Registration with very strict rate limiting
|
||||
"~ ^/_matrix/client/(r0|v3)/register" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
extraConfig = ''
|
||||
limit_req zone=matrix_register burst=2 nodelay;
|
||||
'';
|
||||
};
|
||||
|
||||
# Sync endpoint with longer timeout
|
||||
"~ ^/_matrix/client/(r0|v3|unstable)/sync" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
extraConfig = ''
|
||||
limit_req zone=matrix_api burst=50 nodelay;
|
||||
proxy_read_timeout 600s;
|
||||
'';
|
||||
};
|
||||
|
||||
# Media
|
||||
"/_matrix/media" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
extraConfig = ''
|
||||
limit_req zone=matrix_media burst=100 nodelay;
|
||||
client_max_body_size ${maxUploadSize};
|
||||
'';
|
||||
};
|
||||
|
||||
# Federation
|
||||
"/_matrix/federation" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
extraConfig = ''
|
||||
limit_req zone=matrix_federation burst=100 nodelay;
|
||||
client_max_body_size 50M;
|
||||
'';
|
||||
};
|
||||
|
||||
"/_matrix/key" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
extraConfig = ''
|
||||
limit_req zone=matrix_federation burst=50 nodelay;
|
||||
'';
|
||||
};
|
||||
|
||||
# Health check
|
||||
"= /health" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
extraConfig = ''
|
||||
access_log off;
|
||||
'';
|
||||
};
|
||||
|
||||
# Block admin API from public
|
||||
"/_synapse/admin".return = "404";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
37
services/synapse/options.nix
Normal file
37
services/synapse/options.nix
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
{
|
||||
options.machine.synapse = {
|
||||
enable = mkEnableOption "Synapse";
|
||||
element = {
|
||||
enable = mkEnableOption "Elemenet web";
|
||||
domain = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "chat.${config.machine.synapse.domain}";
|
||||
description = "Domain name.";
|
||||
};
|
||||
};
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
default = "example.com";
|
||||
description = "Domain name.";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 8008;
|
||||
description = "Listen port.";
|
||||
};
|
||||
metrics = {
|
||||
enable = mkEnableOption "Synapse metrics";
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 9000;
|
||||
description = "Listen port.";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
19
services/synapse/redis.nix
Normal file
19
services/synapse/redis.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
redisEnable = config.machine.redis.enable;
|
||||
inherit (config.machine.synapse) enable;
|
||||
in
|
||||
with lib; mkIf (redisEnable && enable) {
|
||||
services.redis.servers.matrix-synapse = {
|
||||
enable = true;
|
||||
};
|
||||
systemd.services.matrix-synapse.serviceConfig.SupplementaryGroups = [ "redis-matrix-synapse" ];
|
||||
services.matrix-synapse.settings.redis = {
|
||||
enabled = true;
|
||||
path = config.services.redis.servers.matrix-synapse.unixSocket;
|
||||
};
|
||||
}
|
||||
46
services/synapse/secrets.nix
Normal file
46
services/synapse/secrets.nix
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (config.machine.synapse)
|
||||
enable
|
||||
;
|
||||
in
|
||||
with lib; mkIf enable {
|
||||
sops.secrets = {
|
||||
"matrix/registrationSharedSecret" = {
|
||||
sopsFile = ./../../secrets/common.yaml;
|
||||
owner = config.users.users.matrix-synapse.name;
|
||||
inherit (config.users.users.matrix-synapse) group;
|
||||
restartUnits = [ "matrix-synapse.service" ];
|
||||
};
|
||||
"matrix/signingKey" = {
|
||||
sopsFile = ./../../secrets/common.yaml;
|
||||
owner = config.users.users.matrix-synapse.name;
|
||||
inherit (config.users.users.matrix-synapse) group;
|
||||
restartUnits = [ "matrix-synapse.service" ];
|
||||
};
|
||||
"turn/authSecret" = {
|
||||
sopsFile = ./../../secrets/common.yaml;
|
||||
owner = config.users.users.turnserver.name;
|
||||
inherit (config.users.users.turnserver) group;
|
||||
restartUnits = [ "coturn.service" ];
|
||||
};
|
||||
};
|
||||
sops.templates.matrix-synapse-config = {
|
||||
owner = config.users.users.matrix-synapse.name;
|
||||
inherit (config.users.users.matrix-synapse) group;
|
||||
restartUnits = [ "matrix-synapse.service" ];
|
||||
content = ''
|
||||
registration_shared_secret: ${config.sops.placeholder."matrix/registrationSharedSecret"}
|
||||
turn_shared_secret: ${config.sops.placeholder."turn/authSecret"}
|
||||
mail:
|
||||
smtp_pass: ${config.sops.placeholder."mail/servicePassword"}
|
||||
'';
|
||||
};
|
||||
services.matrix-synapse.extraConfigFiles = with lib; mkIf config.machine.synapse.enable [
|
||||
config.sops.templates.matrix-synapse-config.path
|
||||
];
|
||||
}
|
||||
94
services/synapse/synapse.nix
Normal file
94
services/synapse/synapse.nix
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
sec,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (config.machine.synapse)
|
||||
domain
|
||||
enable
|
||||
port
|
||||
metrics
|
||||
;
|
||||
in
|
||||
with lib; mkIf enable {
|
||||
services.matrix-synapse = {
|
||||
inherit enable;
|
||||
enableRegistrationScript = true;
|
||||
settings = {
|
||||
server_name = domain;
|
||||
public_baseurl = "https://${domain}";
|
||||
signing_key_path = sec."matrix/signingKey".path;
|
||||
listeners = [
|
||||
{
|
||||
inherit port;
|
||||
bind_addresses = [ "127.0.0.1" ];
|
||||
type = "http";
|
||||
tls = false;
|
||||
x_forwarded = true;
|
||||
resources = [
|
||||
{
|
||||
compress = true;
|
||||
names = [
|
||||
"client"
|
||||
"federation"
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
]
|
||||
++ (optionals metrics.enable [
|
||||
{
|
||||
inherit (metrics) port;
|
||||
bind_addresses = [ "127.0.0.1" ];
|
||||
type = "metrics";
|
||||
tls = false;
|
||||
resources = [
|
||||
{
|
||||
names = [ "metrics" ];
|
||||
}
|
||||
];
|
||||
}
|
||||
]);
|
||||
|
||||
enable_metrics = metrics.enable;
|
||||
|
||||
enable_registration = true;
|
||||
enable_registration_without_verification = false;
|
||||
|
||||
allow_public_rooms_over_federation = true;
|
||||
federation_domain_whitelist = [ ];
|
||||
|
||||
allow_public_rooms_without_auth = true;
|
||||
|
||||
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"
|
||||
"169.254.0.0/16"
|
||||
"::1/128"
|
||||
"fe80::/10"
|
||||
"fc00::/7"
|
||||
];
|
||||
|
||||
dynamic_thumbnails = true;
|
||||
max_upload_size = "50M";
|
||||
media_retention = {
|
||||
local_media_lifetime = "90d";
|
||||
remote_media_lifetime = "14d";
|
||||
};
|
||||
|
||||
retention = {
|
||||
enabled = true;
|
||||
default_policy.max_lifetime = "180d";
|
||||
purge_jobs = [
|
||||
{ interval = "1d"; }
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
18
services/synapse/turn.nix
Normal file
18
services/synapse/turn.nix
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (config.machine.coturn) enable;
|
||||
in
|
||||
with lib; mkIf (enable && config.machine.coturn.enable) {
|
||||
services.matrix-synapse.settings = with config.services.coturn; {
|
||||
turn_uris = [
|
||||
"turn:${realm}:3478?transport=udp"
|
||||
"turn:${realm}:3478?transport=tcp"
|
||||
];
|
||||
turn_user_lifetime = "1h";
|
||||
turn_allow_guests = false;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue