1 { pkgs, lib, config, hosts, ... }:
3 inherit (config.services) prosody;
4 inherit (hosts.mermet.config.services) coturn;
5 domain = config.networking.domain;
6 commas = lib.concatMapStringsSep "," toString;
12 networking.nftables.ruleset = ''
15 tcp dport { xmpp-client, xmpp-server } counter accept comment "prosody: XMPP"
16 tcp dport {${commas (with prosody.settings; c2s_direct_tls_ports ++ s2s_direct_tls_ports)}} counter accept comment "prosody: XMPPS"
17 tcp dport {${commas prosody.settings.proxy65_ports}} counter accept comment "prosody: XMPP XEP-0065 File Transfer Proxy"
18 tcp dport {${commas prosody.settings.https_ports}} counter accept comment "prosody: HTTPS"
21 skuid ${prosody.user} counter accept comment "prosody"
26 services.upnpc.redirections =
28 { description = "XMPP";
29 externalPort = 5222; protocol = "TCP";
31 service.wantedBy = ["prosody.service"];
32 service.partOf = ["prosody.service"];
34 { description = "XMPP";
35 externalPort = 5269; protocol = "TCP";
37 service.wantedBy = ["prosody.service"];
38 service.partOf = ["prosody.service"];
40 { description = "XMPP-FTP";
41 externalPort = 5000; protocol = "TCP";
43 service.wantedBy = ["prosody.service"];
44 service.partOf = ["prosody.service"];
46 ] ++ map (externalPort: {
47 description = "XMPP-HTTPS";
48 inherit externalPort; protocol="TCP";
50 service.wantedBy = ["prosody.service"];
51 service.partOf = ["prosody.service"];
52 }) prosody.settings.https_ports;
55 services.tor.relay.hiddenServices."${domain}/xmpp".map = with prosody.settings; c2s_direct_tls_ports ++ s2s_direct_tls_ports ++ proxy65_ports ++ https_ports;
57 users.groups.acme.members = [ prosody.user ];
58 security.acme.certs."${domain}" = {
59 postRun = "systemctl try-restart prosody";
61 fileSystems."/var/lib/prosody" = {
62 device = "rpool/var/prosody";
65 services.sanoid.datasets = {
66 "rpool/var/prosody" = {
67 use_template = [ "snap" ];
71 systemd.services.prosody = {
72 wants = [ "acme-selfsigned-${domain}.service" "acme-${domain}.service" ];
73 after = [ "acme-selfsigned-${domain}.service" ];
75 # sudo -u prosody prosodyctl check
78 xmppComplianceSuite = true;
80 "biboumi.${domain}" = {
82 component_secret = "useless-secret-on-loopback";
85 "proxy65.${domain}" = {
88 proxy65_address = "proxy65.${domain}";
89 proxy65_acl = [ domain ];
92 "pubsub.${domain}" = {
96 #"pubsub_alertmanager"
100 "pubsub_text_interface"
103 autocreate_on_subscribe = false;
104 autocreate_on_publish = false;
105 pubsub_max_items = 256;
106 pubsub_summary_templates = {
107 "http://www.w3.org/2005/Atom" = "{summary|or{{author/name|and{{author/name} posted }}{title}}}";
111 "salons.${domain}" = {
121 name = "Prosody Chatrooms";
122 restrict_room_creation = "local";
123 max_history_messages = 42;
124 muc_room_locking = true;
125 muc_room_lock_timeout = 600;
126 muc_tombstones = true;
127 muc_tombstone_expiry = 31 * 24 * 60 * 60;
128 muc_room_default_public = true;
129 muc_room_default_members_only = false;
130 muc_room_default_moderated = true;
131 muc_room_default_public_jids = false;
132 muc_room_default_change_subject = true;
133 muc_room_default_history_length = 42;
134 muc_room_default_language = "fr";
137 muc_log_by_default = true;
138 muc_log_presences = false;
139 log_all_rooms = false;
140 muc_log_expires_after = "1w";
141 muc_log_cleanup_interval = 4 * 60 * 60;
143 http_muc_log_show_images = true;
144 #http_muc_log_default_view = "latest";
145 http_muc_log_list_order = [
146 "test@salons.${domain}"
151 module = "http_file_share";
153 size_limit = 100 * 1024 * 1024; # 100 MiB
154 daily_quota = 200 * 1024 * 1024; # 200 MiB per day per user
155 global_quota = 1 * 1024 * 1024 * 1024; # 1 GiB total
156 expires_after = 7 * 24 * 60 * 60; # 7 days
160 virtualHosts.${domain} = {
161 useACMEHost = domain;
170 site_name = "soucephile.fr";
172 #abuse = [ "mailto:abuse@${domain}", "xmpp:abuse@${domain}" ];
173 #admin = [ "mailto:admin@${domain}", "xmpp:admin@${domain}" ];
174 #feedback = [ "http://${domain}/feedback.php", "mailto:feedback@${domain}", "xmpp:feedback@${domain}" ];
175 #sales = [ "xmpp:bard@${domain}" ];
176 #security = [ "xmpp:security@${domain}" ];
177 #support = [ "http://${domain}/support.php", "xmpp:support@${domain}" ];
180 allow_registration = true;
181 registration_invite_only = true;
182 authentication = "internal_hashed";
184 # Listen only in IPv4 until hosting provider's IPv6 works well.
185 interfaces = [ "0.0.0.0" ];
186 c2s_interfaces = [ "0.0.0.0" ];
187 c2s_ports = [ 5222 ];
188 c2s_direct_tls_ports = [ 5223 ];
189 c2s_direct_tls_ssl = {
190 key = "/var/lib/acme/${domain}/key.pem";
191 certificate = "/var/lib/acme/${domain}/fullchain.pem";
193 c2s_require_encryption = true;
194 s2s_require_encryption = true;
195 s2s_secure_auth = true;
196 s2s_ports = [ 5269 ];
197 s2s_direct_tls_ports = [ 5270 ];
198 s2s_direct_tls_ssl = {
199 key = "/var/lib/acme/${domain}/key.pem";
200 certificate = "/var/lib/acme/${domain}/fullchain.pem";
202 ssl.key = "/var/lib/acme/${domain}/key.pem";
203 ssl.certificate = "/var/lib/acme/${domain}/fullchain.pem";
205 https_ports = [ 5281 ];
206 proxy65_ports = [ 5000 ];
211 "Gateway to IRC (Internet Relay Chat) servers"
223 archive = "xmlarchive";
224 muc_log = "xmlarchive";
227 archive_expires_after = "3m"; # months
228 archive_cleanup_interval = 4 * 60 * 60;
229 default_archive_policy = "roster";
242 csi_important_payloads = {
243 # Anything in this namespace:
244 #"{urn:example:important-namespace}"
245 # Specific element name and namespace:
246 #"{urn:example:xmpp:priority}super-important"
250 planet_jabber = "https://planet.jabber.org/atom.xml";
251 haskellweekly = "https://haskellweekly.news/newsletter.atom";
252 #prosody_blog = "http://blog.prosody.im/feed/atom.xml";
259 #"cloud_notify_encrypted"
270 "server_contact_info"
279 "cloud_notify" # not encrypted even with OMEMO
287 smacks_enabled_s2s = true;
288 smacks_s2s_resend = true;
290 turn_external_secret = coturn.static-auth-secret;
291 #turn_external_secret = "ENV_TURN_EXTERNAL_SECRET";
292 turn_external_host = "turn.${domain}";
293 turn_external_port = 3478;
294 turn_external_ttl = 86400;
296 # http_files_dir = "/var/lib/prosody/files"
297 # http_external_url = "https://tmp.${domain}:5281"
298 # https_certificate = "/var/lib/acme/${domain}/fullchain.pem"
299 # https_key = "/var/lib/acme/${domain}/key.pem"
300 # certificates = "/var/lib/acme"
304 package = pkgs.prosody.override {
305 withCommunityModules = [
309 #"pubsub_alertmanager"
313 "pubsub_text_interface"