initial commit
Some checks failed
Nix CI / build (push) Failing after 31s

This commit is contained in:
Rustam Efimov 2026-04-01 08:50:01 +03:00
commit 30ce0dafc2
No known key found for this signature in database
195 changed files with 8902 additions and 0 deletions

View file

@ -0,0 +1,8 @@
{
imports = [
./firewall.nix
./nginx.nix
./options.nix
./service.nix
];
}

View file

@ -0,0 +1,38 @@
{
config,
lib,
...
}:
let
inherit (config.machine.prosody)
enable
;
in
with lib; mkIf enable {
networking.firewall = {
allowedTCPPorts = [
# HTTP filer
80
443
# C2S
5222
5223
# S2S
5269
5270
# WebSockets / BOSH
5280
5281
]
++ concatLists (
with config.services.prosody;
[
httpPorts
httpsPorts
]
);
};
}

View file

@ -0,0 +1,54 @@
{
config,
lib,
...
}:
let
inherit (config.machine.prosody)
enable
domain
;
localhost = "http://localhost:5280";
in
with lib; mkIf enable {
security.acme.certs."${domain}".extraDomainNames = [
"conference.${domain}"
"upload.${domain}"
];
users.groups.acme.members = [
"prosody"
];
services.nginx.virtualHosts = with lib; mkIf (domain != null) {
"${domain}".locations = {
"= /xmpp-websocket" = {
proxyPass = localhost;
proxyWebsockets = true;
};
"= /http-bind".proxyPass = localhost;
"/push".proxyPass = localhost;
"= /.well-known/host-meta".proxyPass = localhost;
"= /.well-known/host-meta.json".proxyPass = localhost;
};
"conference.${domain}" = {
http3 = true;
quic = true;
forceSSL = true;
kTLS = true;
useACMEHost = domain;
sslCertificate = "${config.security.acme.certs.${domain}.directory}/fullchain.pem";
sslCertificateKey = "${config.security.acme.certs.${domain}.directory}/key.pem";
locations."/".proxyPass = localhost;
};
"upload.${domain}" = {
http3 = true;
quic = true;
forceSSL = true;
kTLS = true;
useACMEHost = domain;
sslCertificate = "${config.security.acme.certs.${domain}.directory}/fullchain.pem";
sslCertificateKey = "${config.security.acme.certs.${domain}.directory}/key.pem";
locations."/".proxyPass = localhost;
};
};
}

View file

@ -0,0 +1,17 @@
{ lib, ... }:
with lib;
{
options.machine.prosody = {
enable = mkEnableOption "Prosody";
domain = mkOption {
type = types.nullOr types.str;
default = null;
description = "Domain name. If not set, will be disabled, and use the localhost.";
};
port = mkOption {
type = types.port;
default = 4000;
description = "Listen port.";
};
};
}

View file

@ -0,0 +1,104 @@
{
config,
pkgs,
lib,
...
}:
let
inherit (config.machine.prosody)
enable
domain
;
sslCertDir = config.security.acme.certs."${domain}".directory;
in
with lib; mkIf enable {
services.prosody = {
inherit enable;
package = pkgs.prosody.override {
withCommunityModules = [
"sasl2"
"sasl2_bind2"
"sasl_ssdp"
"sasl2_fast"
"sasl_ssdp"
"csi_battery_saver"
"muc_notifications"
];
};
admins = [
"admin@${domain}"
];
allowRegistration = true;
s2sSecureAuth = true;
c2sRequireEncryption = true;
modules = {
http_files = true;
limits = true;
server_contact_info = true;
bosh = true;
motd = true;
announce = true;
welcome = true;
admin_adhoc = true;
websocket = true;
watchregistrations = true;
};
extraModules = [
"turn_external"
];
xmppComplianceSuite = true;
checkConfig = false;
ssl = {
cert = "${sslCertDir}/fullchain.pem";
key = "${sslCertDir}/key.pem";
};
virtualHosts.${domain} = {
inherit domain;
enabled = enable;
ssl = {
cert = "${sslCertDir}/fullchain.pem";
key = "${sslCertDir}/key.pem";
};
};
muc = [
{
domain = "conference.${domain}";
restrictRoomCreation = "local";
}
];
httpFileShare = {
domain = "upload.${domain}";
http_host = domain;
expires_after = "never";
size_limit = 32 * 1024 * 1024;
};
extraConfig = ''
storage = "sql"
sql = {
driver = "SQLite3";
database = "prosody.sqlite";
}
-- Keep messages
archive_expires_after = "never"
muc_log_presences = true
muc_log_expires_after = "never"
-- Recommended by Monal dev
smacks_max_queue_size = 4000
c2s_direct_tls_ports = { 5223 };
s2s_direct_tls_ports = { 5270 };
trusted_proxies = { "127.0.0.1", "::1" };
http_external_url = "https://${domain}/"
consider_bosh_secure = true;
consider_websocket_secure = true;
statistics = "internal";
statistics_interval = "manual";
'';
};
}