main
1{
2 config,
3 ...
4}:
5{
6 # XMPP server with Prosody - simplified configuration
7 # VPN-only access at xmpp.sbr.pm (10.100.0.49)
8
9 services.prosody = {
10 enable = true;
11 admins = [ "vincent@xmpp.sbr.pm" ];
12
13 # SSL/TLS configuration
14 ssl = {
15 cert = "/var/lib/acme/xmpp.sbr.pm/fullchain.pem";
16 key = "/var/lib/acme/xmpp.sbr.pm/key.pem";
17 };
18
19 # Virtual host configuration
20 virtualHosts."xmpp.sbr.pm" = {
21 enabled = true;
22 domain = "xmpp.sbr.pm";
23 ssl = {
24 cert = "/var/lib/acme/xmpp.sbr.pm/fullchain.pem";
25 key = "/var/lib/acme/xmpp.sbr.pm/key.pem";
26 };
27 };
28
29 # Disable XEP-0423 compliance checking for now
30 xmppComplianceSuite = false;
31
32 # Security settings
33 c2sRequireEncryption = true; # Force TLS for client connections
34 allowRegistration = false; # Disable public registration
35 };
36
37 # ACME configuration
38 security.acme.acceptTerms = true;
39 security.acme.defaults.email = "vincent@sbr.pm";
40
41 # SSL certificates via ACME with Gandi DNS-01 challenge
42 security.acme.certs."xmpp.sbr.pm" = {
43 domain = "xmpp.sbr.pm";
44 dnsProvider = "gandiv5";
45 dnsResolver = "1.1.1.1:53"; # Use Cloudflare DNS for DNS-01 challenge
46 environmentFile = config.age.secrets."gandi.env".path;
47 group = "prosody"; # Allow prosody to read certificates
48 reloadServices = [ "prosody.service" ]; # Reload prosody when certificates are renewed
49 server = "https://acme-v02.api.letsencrypt.org/directory"; # Use Let's Encrypt production
50 };
51
52 # Age secret for Gandi API (shared with rhea for DNS-01 challenge)
53 age.secrets."gandi.env" = {
54 file = ../../secrets/rhea/gandi.env.age;
55 mode = "400";
56 };
57
58 # Firewall configuration - XMPP ports
59 networking.firewall.allowedTCPPorts = [
60 5222 # C2S (client-to-server) - main XMPP port
61 ];
62}