-{ pkgs, lib, config, inputs, hosts, ipv4, ... }:
+{ pkgs, lib, config, hosts, ... }:
let
inherit (config.services) prosody;
inherit (hosts.mermet.config.services) coturn;
domain = config.networking.domain;
+ commas = lib.concatMapStringsSep "," toString;
in
{
-imports = [
- prosody/biboumi.nix
-];
-networking.nftables.ruleset = ''
- table inet filter {
- chain input-net {
- tcp dport { xmpp-client, xmpp-server } counter accept comment "prosody: XMPP"
- tcp dport 5000 counter accept comment "prosody: XMPP XEP-0065 File Transfer Proxy"
- tcp dport {${lib.concatMapStringsSep "," toString prosody.httpsPorts}} counter accept comment "prosody: HTTPS"
- }
- chain output-net {
- skuid ${prosody.user} counter accept comment "prosody"
+ imports = [
+ prosody/biboumi.nix
+ ];
+ networking.nftables.ruleset = ''
+ table inet filter {
+ chain input-net {
+ tcp dport { xmpp-client, xmpp-server } counter accept comment "prosody: XMPP"
+ tcp dport {${commas (with prosody.settings; c2s_direct_tls_ports ++ s2s_direct_tls_ports)}} counter accept comment "prosody: XMPPS"
+ tcp dport {${commas prosody.settings.proxy65_ports}} counter accept comment "prosody: XMPP XEP-0065 File Transfer Proxy"
+ tcp dport {${commas prosody.settings.https_ports}} counter accept comment "prosody: HTTPS"
+ }
+ chain output-net {
+ skuid ${prosody.user} counter accept comment "prosody"
+ }
}
- }
-'';
-/*
-services.upnpc.redirections =
- [
+ '';
+ /*
+ services.upnpc.redirections =
+ [
{ description = "XMPP";
externalPort = 5222; protocol = "TCP";
duration = 30 * 60;
service.wantedBy = ["prosody.service"];
service.partOf = ["prosody.service"];
}
- ] ++ map (externalPort: {
+ ] ++ map (externalPort: {
description = "XMPP-HTTPS";
inherit externalPort; protocol="TCP";
duration = 30 * 60;
service.wantedBy = ["prosody.service"];
service.partOf = ["prosody.service"];
- }) prosody.httpsPorts;
-*/
-/*
-services.tor.relay.hiddenServices."${domain}/xmpp".map = [ 5222 5269 5000 ] ++ prosody.httpsPorts;
-*/
-users.groups.acme.members = [ prosody.user ];
-security.acme.certs."${domain}" = {
- postRun = "systemctl restart prosody";
-};
-fileSystems."/var/lib/prosody" = {
- device = "rpool/var/prosody";
- fsType = "zfs";
-};
-services.sanoid.datasets = {
- "rpool/var/prosody" = {
- use_template = [ "snap" ];
- daily = 7;
+ }) prosody.settings.https_ports;
+ */
+ /*
+ services.tor.relay.hiddenServices."${domain}/xmpp".map = with prosody.settings; c2s_direct_tls_ports ++ s2s_direct_tls_ports ++ proxy65_ports ++ https_ports;
+ */
+ users.groups.acme.members = [ prosody.user ];
+ security.acme.certs."${domain}" = {
+ postRun = "systemctl try-restart prosody";
};
-};
-systemd.services.prosody = {
- wants = [ "acme-selfsigned-${domain}.service" "acme-${domain}.service"];
- after = [ "acme-selfsigned-${domain}.service" ];
-};
-# sudo -u prosody prosodyctl check
-services.prosody = {
- enable = true;
- xmppComplianceSuite = true;
- modules = {
- announce = true;
- blocklist = true;
- cloud_notify = false; # not encrypted even with OMEMO
- #cloud_notify_encrypted = true;
- groups = true;
- limits = false;
- motd = true;
- server_contact_info = true;
- watchregistrations = true;
- websocket = false;
- welcome = true;
- proxy65 = false;
+ fileSystems."/var/lib/prosody" = {
+ device = "rpool/var/prosody";
+ fsType = "zfs";
};
- extraModules = [
- "turn_external"
- #"turncredentials"
- #"net_multiplex"
- #"extdisco"
- ];
- extraConfig = ''
- log = {
- -- debug = "*syslog";
- info = "*syslog";
- warn = "*syslog";
- error = "*syslog";
- }
- -- Listen only in IPv4 until hosting provider's IPv6 works well.
- interfaces = { "0.0.0.0" }
- c2s_interfaces = { "0.0.0.0" }
- contact_info = {
- --abuse = { "mailto:abuse@${domain}", "xmpp:abuse@${domain}" };
- --admin = { "mailto:admin@${domain}", "xmpp:admin@${domain}" };
- --feedback = { "http://${domain}/feedback.php", "mailto:feedback@${domain}", "xmpp:feedback@${domain}" };
- --sales = { "xmpp:bard@${domain}" };
- --security = { "xmpp:security@${domain}" };
- --support = { "http://${domain}/support.php", "xmpp:support@${domain}" };
- }
- legacy_ssl_ports = { 5222 }
+ services.sanoid.datasets = {
+ "rpool/var/prosody" = {
+ use_template = [ "snap" ];
+ daily = 7;
+ };
+ };
+ systemd.services.prosody = {
+ wants = [ "acme-selfsigned-${domain}.service" "acme-${domain}.service" ];
+ after = [ "acme-selfsigned-${domain}.service" ];
+ };
+ # sudo -u prosody prosodyctl check
+ services.prosody = {
+ enable = true;
+ xmppComplianceSuite = true;
+ components = {
+ "biboumi.${domain}" = {
+ settings = {
+ component_secret = "useless-secret-on-loopback";
+ };
+ };
+ "proxy65.${domain}" = {
+ #module = "proxy65";
+ settings = {
+ proxy65_address = "proxy65.${domain}";
+ proxy65_acl = [ domain ];
+ };
+ };
+ "pubsub.${domain}" = {
+ module = "pubsub";
+ settings = {
+ modules_enabled = [
+ #"pubsub_alertmanager"
+ "pubsub_feeds"
+ #"pubsub_github"
+ "pubsub_summary"
+ "pubsub_text_interface"
+ ];
+ admins = { };
+ autocreate_on_subscribe = false;
+ autocreate_on_publish = false;
+ pubsub_max_items = 256;
+ pubsub_summary_templates = {
+ "http://www.w3.org/2005/Atom" = "{summary|or{{author/name|and{{author/name} posted }}{title}}}";
+ };
+ };
+ };
+ "salons.${domain}" = {
+ module = "muc";
+ settings = {
+ modules_enabled = [
+ "http_muc_log"
+ "muc_mam"
+ "vcard_muc"
+ #"muc_log"
+ #"muc_log_http"
+ ];
+ name = "Prosody Chatrooms";
+ restrict_room_creation = "local";
+ max_history_messages = 42;
+ muc_room_locking = true;
+ muc_room_lock_timeout = 600;
+ muc_tombstones = true;
+ muc_tombstone_expiry = 31 * 24 * 60 * 60;
+ muc_room_default_public = true;
+ muc_room_default_members_only = false;
+ muc_room_default_moderated = true;
+ muc_room_default_public_jids = false;
+ muc_room_default_change_subject = true;
+ muc_room_default_history_length = 42;
+ muc_room_default_language = "fr";
- -- turncredentials_host = "turn.${domain}"
- -- turncredentials_port = 3478
- -- turncredentials_secret = "${lib.removeSuffix "\n" (builtins.readFile (inputs.secrets + "/coturn/static-auth-secret"))}";
+ # mod_muc_mam
+ muc_log_by_default = true;
+ muc_log_presences = false;
+ log_all_rooms = false;
+ muc_log_expires_after = "1w";
+ muc_log_cleanup_interval = 4 * 60 * 60;
+ # mod_http_muc_log
+ http_muc_log_show_images = true;
+ #http_muc_log_default_view = "latest";
+ http_muc_log_list_order = [
+ "test@salons.${domain}"
+ ];
+ };
+ };
+ "tmp.${domain}" = {
+ module = "http_file_share";
+ settings = {
+ size_limit = 100 * 1024 * 1024; # 100 MiB
+ daily_quota = 200 * 1024 * 1024; # 200 MiB per day per user
+ global_quota = 1 * 1024 * 1024 * 1024; # 1 GiB total
+ expires_after = 7 * 24 * 60 * 60; # 7 days
+ };
+ };
+ };
+ virtualHosts.${domain} = {
+ useACMEHost = domain;
+ settings = {
+ enabled = true;
+ };
+ };
+ settings = {
+ admins = [
+ "julm@${domain}"
+ ];
+ site_name = "soucephile.fr";
+ contact_info = {
+ #abuse = [ "mailto:abuse@${domain}", "xmpp:abuse@${domain}" ];
+ #admin = [ "mailto:admin@${domain}", "xmpp:admin@${domain}" ];
+ #feedback = [ "http://${domain}/feedback.php", "mailto:feedback@${domain}", "xmpp:feedback@${domain}" ];
+ #sales = [ "xmpp:bard@${domain}" ];
+ #security = [ "xmpp:security@${domain}" ];
+ #support = [ "http://${domain}/support.php", "xmpp:support@${domain}" ];
+ };
- turn_external_secret = "${lib.removeSuffix "\n" (builtins.readFile (inputs.secrets + "/coturn/static-auth-secret"))}"
- turn_external_host = "turn.${domain}"
- turn_external_port = 3478
- turn_external_ttl = 86400
+ allow_registration = true;
+ registration_invite_only = true;
+ authentication = "internal_hashed";
- smacks_enabled_s2s = true;
- smacks_s2s_resend = true;
+ # Listen only in IPv4 until hosting provider's IPv6 works well.
+ interfaces = [ "0.0.0.0" ];
+ c2s_interfaces = [ "0.0.0.0" ];
+ c2s_ports = [ 5222 ];
+ c2s_direct_tls_ports = [ 5223 ];
+ c2s_direct_tls_ssl = {
+ key = "/var/lib/acme/${domain}/key.pem";
+ certificate = "/var/lib/acme/${domain}/fullchain.pem";
+ };
+ c2s_require_encryption = true;
+ s2s_require_encryption = true;
+ s2s_secure_auth = true;
+ s2s_ports = [ 5269 ];
+ s2s_direct_tls_ports = [ 5270 ];
+ s2s_direct_tls_ssl = {
+ key = "/var/lib/acme/${domain}/key.pem";
+ certificate = "/var/lib/acme/${domain}/fullchain.pem";
+ };
+ ssl.key = "/var/lib/acme/${domain}/key.pem";
+ ssl.certificate = "/var/lib/acme/${domain}/fullchain.pem";
+ http_ports = [ ];
+ https_ports = [ 5281 ];
+ proxy65_ports = [ 5000 ];
- --http_files_dir = "/var/lib/prosody/files"
- --http_external_url = "https://tmp.${domain}:5281"
- --https_certificate = "/var/lib/acme/${domain}/fullchain.pem"
- --https_key = "/var/lib/acme/${domain}/key.pem"
- --certificates = "/var/lib/acme"
+ disco_items = [
+ [
+ "biboumi.${domain}"
+ "Gateway to IRC (Internet Relay Chat) servers"
+ ]
+ ];
- proxy65_ports = 5000
- Component "proxy65.${domain}" "proxy65"
- proxy65_address = "proxy65.${domain}"
- proxy65_acl = { "${domain}" }
+ log = {
+ # debug = "*syslog";
+ info = "*syslog";
+ warn = "*syslog";
+ error = "*syslog";
+ };
- Component "biboumi.${domain}"
- component_secret = "useless-secret-on-loopback"
- '';
- httpFileShare = {
- domain = "tmp.${domain}";
- size_limit = 16*1024*1024; # 16 MiB
- daily_quota = 100*1024*1024; # 100 MiB per day per user
- global_quota = 1024*1024*1024; # 1 GiB total
- };
- #ports = {80};
- #ssl_ports = {443};
- c2sRequireEncryption = true;
- s2sRequireEncryption = true;
- s2sSecureAuth = true;
- muc = [
- {
- domain = "salons.${domain}";
- extraConfig = ''
- restrict_room_creation = "local"
- max_history_messages = 42
- muc_room_locking = true
- muc_room_lock_timeout = 600
- muc_tombstones = true
- muc_tombstone_expiry = 31 * 24 * 60 * 60
- muc_room_default_public = true
- muc_room_default_members_only = false
- muc_room_default_moderated = true
- muc_room_default_public_jids = false
- muc_room_default_change_subject = true
- muc_room_default_history_length = 42
- muc_room_default_language = "fr"
- '';
- }
- ];
- ssl.key = "/var/lib/acme/${domain}/key.pem";
- ssl.cert = "/var/lib/acme/${domain}/fullchain.pem";
- admins = [
- "julm@${domain}"
- ];
- virtualHosts."${domain}" = {
- enabled = true;
- domain = "${domain}";
- ssl.key = "/var/lib/acme/${domain}/key.pem";
- ssl.cert = "/var/lib/acme/${domain}/fullchain.pem";
- };
- allowRegistration = false;
- authentication = "internal_hashed";
- httpPorts = [];
- httpsPorts = [5281];
- disco_items = [
- { url = "biboumi.${domain}";
- description = "Passerelle vers des serveurs IRC (Internet Relay Chat)"; }
- ];
- package = pkgs.prosody.override {
- withCommunityModules = [
- "turncredentials"
- #"extdisco"
- ];
+ storage = {
+ archive = "xmlarchive";
+ muc_log = "xmlarchive";
+ };
+ # mod_mam
+ archive_expires_after = "3m"; # months
+ archive_cleanup_interval = 4 * 60 * 60;
+ default_archive_policy = "roster";
+
+ limits = {
+ c2s = {
+ rate = "3kb/s";
+ burst = "2s";
+ };
+ s2sin = {
+ rate = "10kb/s";
+ burst = "5s";
+ };
+ };
+
+ csi_important_payloads = {
+ # Anything in this namespace:
+ #"{urn:example:important-namespace}"
+ # Specific element name and namespace:
+ #"{urn:example:xmpp:priority}super-important"
+ };
+
+ feeds = {
+ code_gouv_fr = "https://code.gouv.fr/feed/feed.xml";
+ haskellweekly = "https://haskellweekly.news/newsletter.atom";
+ planet_jabber = "https://planet.jabber.org/atom.xml";
+ #prosody_blog = "http://blog.prosody.im/feed/atom.xml";
+ };
+
+ modules_enabled = [
+ "admin_shell"
+ "announce"
+ "blocklist"
+ #"cloud_notify_encrypted"
+ "csi_simple"
+ #"extdisco"
+ "groups"
+ "invites"
+ "invites_page"
+ "invites_register"
+ "limits"
+ "motd"
+ #"net_multiplex"
+ "register_apps"
+ "server_contact_info"
+ #"throttle_presence"
+ "turn_external"
+ "vcard4"
+ "watchregistrations"
+ "welcome"
+ "storage_xmlarchive"
+ ];
+ modules_disabled = [
+ "cloud_notify" # not encrypted even with OMEMO
+ "http_files"
+ "http_upload"
+ #"proxy65"
+ "vcard_legacy"
+ "websocket"
+ ];
+
+ smacks_enabled_s2s = true;
+ smacks_s2s_resend = true;
+
+ turn_external_secret = coturn.static-auth-secret;
+ #turn_external_secret = "ENV_TURN_EXTERNAL_SECRET";
+ turn_external_host = "turn.${domain}";
+ turn_external_port = 3478;
+ turn_external_ttl = 86400;
+
+ # http_files_dir = "/var/lib/prosody/files"
+ # http_external_url = "https://tmp.${domain}:5281"
+ # https_certificate = "/var/lib/acme/${domain}/fullchain.pem"
+ # https_key = "/var/lib/acme/${domain}/key.pem"
+ # certificates = "/var/lib/acme"
+ #ports = {80};
+ #ssl_ports = {443};
+ };
+ package = pkgs.prosody.override {
+ withCommunityModules = [
+ "http_muc_log"
+ #"log_auth"
+ #"offline_email"
+ #"pubsub_alertmanager"
+ "pubsub_feeds"
+ #"pubsub_github"
+ "pubsub_summary"
+ "pubsub_text_interface"
+ "register_apps"
+ "invites_page"
+ #"extdisco"
+ "storage_xmlarchive"
+ ];
+ };
};
-};
}