mermet: knot: autogeree.net: move from Gandi to LeBureau
[sourcephile-nix.git] / hosts / mermet / prosody.nix
index a33554e569587d1ece6b04edb8a2a851fb87f559..f5ec68639309a0fcc0f6a72a52d6cc8dc4b86d34 100644 (file)
@@ -1,28 +1,30 @@
-{ 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;
@@ -41,160 +43,280 @@ services.upnpc.redirections =
       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"
+      ];
+    };
   };
-};
 }