diff options
| -rw-r--r-- | ejabberd.nix | 497 |
1 files changed, 228 insertions, 269 deletions
diff --git a/ejabberd.nix b/ejabberd.nix index d207ee7..4a19440 100644 --- a/ejabberd.nix +++ b/ejabberd.nix @@ -1,284 +1,243 @@ -{ fqdn }:{ config, lib, pkgs, ... }: +{ fqdn }: { config, lib, pkgs, ... }: let + inherit (builtins) toJSON; + inherit (pkgs) writeText; + inherit (pkgs.lib.lists) foldl'; + inherit (pkgs.lib.attrsets) mapAttrs' nameValuePair; + inherit (config.networking) domain; + certs = config.security.acme.certs; - certDirectory = "${certs.${fqdn}.directory}"; -in -{ - services.ejabberd = - { - enable = true; - imagemagick = true; - configFile = "/etc/ejabberd.yml"; - package = pkgs.ejabberd.override { - withZlib = true; - withTools = true; + certDirectory = certs.${fqdn}.directory; +in { + services.ejabberd = { + enable = true; + imagemagick = true; + configFile = let + toPaths = s: mapAttrs' (n: v: nameValuePair "/${n}" v) s; + dhfile = config.security.dhparams.params.nginx.path; + toACLs = map (x: { acl = x; }); + in writeText "ejabberd.yml" (toJSON { + hosts = [ fqdn ]; + loglevel = 4; + s2s_cafile = "/etc/ssl/certs/ca-certificates.crt"; + ca_file = "/etc/ssl/certs/ca-certificates.crt"; + certfiles = [ "${certDirectory}/*.pem" ]; + listen = map (x: x // { ip = "10.25.1.3"; }) [ + { + inherit dhfile; + port = 5222; + module = "ejabberd_c2s"; + max_stanza_size = 262144; + shaper = "c2s_shaper"; + access = "c2s"; + starttls_required = true; + } + { + inherit dhfile; + port = 5223; + tls = true; + module = "ejabberd_c2s"; + max_stanza_size = 262144; + shaper = "c2s_shaper"; + access = "c2s"; + starttls_required = true; + } + { + inherit dhfile; + port = 5269; + module = "ejabberd_s2s_in"; + max_stanza_size = 524288; + } + { + inherit dhfile; + port = 5443; + module = "ejabberd_http"; + tls = true; + request_handlers = toPaths { + admin = "ejabberd_web_admin"; + api = "mod_http_api"; + bosh = "mod_bosh"; + captcha = "ejabberd_captcha"; + upload = "mod_http_upload"; + ws = "ejabberd_http_ws"; + }; + } + { + inherit dhfile; + port = 5280; + module = "ejabberd_http"; + request_handlers = toPaths { + admin = "ejabberd_web_admin"; + ".well-known/acme-challenge" = "ejabberd_acme"; + }; + } + { + port = 3478; + transport = "udp"; + module = "ejabberd_stun"; + use_turn = true; + turn_ipv4_address = "193.16.42.36"; + } + { + port = 1883; + module = "mod_mqtt"; + backlog = 1000; + } + ]; + s2s_use_starttls = "required"; + acl = { + local.user_regexp = ""; + loopback.ip = [ + "127.0.0.1/8" + "::1/128" + ]; + admin.user = [ "crash@${fqdn}" ]; + }; + access_rules = { + c2s = { + deny = "blocked"; + allow = "all"; + }; + } // mapAttrs' (n: v: nameValuePair n { allow = v; }) { + local = "local"; + announce = "admin"; + configure = "admin"; + muc_create = "local"; + pubsub_createnode = "local"; + trusted_network = "loopback"; + }; + api_permissions = { + "console commands" = { + from = [ "ejabberd_ctl" ]; + who = "all"; + what = "*"; + }; + "admin access" = { + who = { + access.allow = toACLs [ + "local" + "admin" + ]; + oauth = { + scope = "ejabberd:admin"; + access.allow = toACLs [ + "loopback" + "admin" + ]; + }; + }; + what = [ + "*" + "!stop" + "!start" + ]; + }; + "public commands" = { + who.ip = "127.0.0.1/8"; + what = [ + "status" + "connected_users_number" + ]; + }; + }; + shaper = { + normal = { + rate = 3000; + burst_size = 20000; + }; + fast = 100000; + }; + shaper_rules = { + max_user_sessions = 10; + max_user_offline_messages = { + "5000" = "admin"; + "100" = "all"; + }; + c2s_shaper = { + none = "admin"; + normal = "all"; + }; + s2s_shaper = "fast"; }; + modules = mapAttrs' (n: v: nameValuePair "mod_${n}" v) ({ + announce.access = "announce"; + http_upload = { + put_url = "https://@HOST@:5443/upload"; + custom_headers = { + Access-Control-Allow-Origin = "https://@HOST@"; + Access-Control-Allow-Methods = "GET,HEAD,PUT,OPTIONS"; + Access-Control-Allow-Headers = "Content-Type"; + }; + }; + mam = { + assume_mam_usage = true; + default = "always"; + }; + muc = { + access = [ "allow" ]; + access_admin = [ { allow = "admin"; } ]; + access_create = "muc_create"; + access_persistent = "muc_create"; + access_mam = [ "allow" ]; + default_room_options.mam = true; + }; + offline.access_max_user_messages = "max_user_offline_messages"; + proxy65 = { + access = "local"; + max_connections = 5; + }; + pubsub = { + access_createnode = "pubsub_createnode"; + plugins = [ + "flat" + "pep" + ]; + force_node_config."storage:bookmarks".access_model = "whitelist"; + }; + register.ip_access = "trusted_network"; + roster.versioning = true; + stream_mgmt.resend_on_timeout = "if_offline"; + version.show_os = false; + } // foldl' (a: x: a // { ${x} = {}; }) {} [ + "adhoc" "admin_extra" "avatar" + "blocking" "bosh" + "caps" "carboncopy" "client_state" "configure" + "disco" + "fail2ban" + "http_api" + "last" + "mqtt" "muc_admin" + "ping" "privacy" "private" "push" "push_keepalive" + "s2s_dialback" "shared_roster" "stun_disco" + "vcard" "vcard_xupdate" + ]); + }); + package = pkgs.ejabberd.override { + withZlib = true; + withTools = true; }; + }; security.acme.certs.${fqdn} = { + extraDomainNames = map (x: "${x}.xmpp.${fqdn}") [ + "pubsub" + "proxy" + "upload" + "conference" + ]; group = "ejabberd-cert"; postRun = "systemctl restart ejabberd.service"; }; users.groups.ejabberd-cert.members = [ "ejabberd" "nginx" ]; - - environment.etc."ejabberd.yml" = { - user = "ejabberd"; - mode = "0600"; - text = '' -### -### ejabberd configuration file -### -### The parameters used in this configuration file are explained at -### -### https://docs.ejabberd.im/admin/configuration -### -### The configuration file is written in YAML. -### ******************************************************* -### ******* !!! WARNING !!! ******* -### ******* YAML IS INDENTATION SENSITIVE ******* -### ******* MAKE SURE YOU INDENT SECTIONS CORRECTLY ******* -### ******************************************************* -### Refer to http://en.wikipedia.org/wiki/YAML for the brief description. -### - -hosts: - - "crashoverburn.com - -loglevel: info - -## If you already have certificates, list them here -certfiles: - - ${certDirectory}/full.pem - - ${certDirectory}/key.pem - -listen: - - - port: 5222 - ip: "::" - module: ejabberd_c2s - max_stanza_size: 262144 - shaper: c2s_shaper - access: c2s - starttls_required: true - - - port: 5223 - ip: "::" - tls: true - module: ejabberd_c2s - max_stanza_size: 262144 - shaper: c2s_shaper - access: c2s - starttls_required: true - - - port: 5269 - ip: "::" - module: ejabberd_s2s_in - max_stanza_size: 524288 - - - port: 5443 - ip: "::" - module: ejabberd_http - tls: true - request_handlers: - /admin: ejabberd_web_admin - /api: mod_http_api - /bosh: mod_bosh - /captcha: ejabberd_captcha - /upload: mod_http_upload - /ws: ejabberd_http_ws - - - port: 5280 - ip: "::" - module: ejabberd_http - request_handlers: - /admin: ejabberd_web_admin - /.well-known/acme-challenge: ejabberd_acme - - - port: 3478 - ip: "::" - transport: udp - module: ejabberd_stun - use_turn: true - ## The server's public IPv4 address: - # turn_ipv4_address: "203.0.113.3" - ## The server's public IPv6 address: - # turn_ipv6_address: "2001:db8::3" - - - port: 1883 - ip: "::" - module: mod_mqtt - backlog: 1000 - -s2s_use_starttls: optional - -acl: - local: - user_regexp: "" - loopback: - ip: - - 127.0.0.0/8 - - ::1/128 - acl: - admin: - user: - - "crash@crashoverburn.com" - -access_rules: - local: - allow: local - c2s: - deny: blocked - allow: all - announce: - allow: admin - configure: - allow: admin - muc_create: - allow: local - pubsub_createnode: - allow: local - trusted_network: - allow: loopback - -api_permissions: - "console commands": - from: - - ejabberd_ctl - who: all - what: "*" - "admin access": - who: - access: - allow: - - acl: loopback - - acl: admin - oauth: - scope: "ejabberd:admin" - access: - allow: - - acl: loopback - - acl: admin - what: - - "*" - - "!stop" - - "!start" - "public commands": - who: - ip: 127.0.0.1/8 - what: - - status - - connected_users_number -acme: - contact:"mailto:crash@crashoverburn.com" -shaper: - normal: - rate: 3000 - burst_size: 20000 - fast: 100000 - -shaper_rules: - max_user_sessions: 10 - max_user_offline_messages: - 5000: admin - 100: all - c2s_shaper: - none: admin - normal: all - s2s_shaper: fast - -modules: - mod_adhoc: {} - mod_admin_extra: {} - mod_announce: - access: announce - mod_avatar: {} - mod_blocking: {} - mod_bosh: {} - mod_caps: {} - mod_carboncopy: {} - mod_client_state: {} - mod_configure: {} - mod_disco: {} - mod_fail2ban: {} - mod_http_api: {} - mod_http_upload: - put_url: https://@HOST@:5443/upload - custom_headers: - "Access-Control-Allow-Origin": "https://@HOST@" - "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS" - "Access-Control-Allow-Headers": "Content-Type" - mod_last: {} - mod_mam: - ## Mnesia is limited to 2GB, better to use an SQL backend - ## For small servers SQLite is a good fit and is very easy - ## to configure. Uncomment this when you have SQL configured: - ## db_type: sql - assume_mam_usage: true - default: always - mod_mqtt: {} - mod_muc: - access: - - allow - access_admin: - - allow: admin - access_create: muc_create - access_persistent: muc_create - access_mam: - - allow - default_room_options: - mam: true - mod_muc_admin: {} - mod_offline: - access_max_user_messages: max_user_offline_messages - mod_ping: {} - mod_privacy: {} - mod_private: {} - mod_proxy65: - access: local - max_connections: 5 - mod_pubsub: - access_createnode: pubsub_createnode - plugins: - - flat - - pep - force_node_config: - ## Avoid buggy clients to make their bookmarks public - storage:bookmarks: - access_model: whitelist - mod_push: {} - mod_push_keepalive: {} - mod_register: - ## Only accept registration requests from the "trusted" - ## network (see access_rules section above). - ## Think twice before enabling registration from any - ## address. See the Jabber SPAM Manifesto for details: - ## https://github.com/ge0rg/jabber-spam-fighting-manifesto - ip_access: trusted_network - mod_roster: - versioning: true - mod_s2s_dialback: {} - mod_shared_roster: {} - mod_stream_mgmt: - resend_on_timeout: if_offline - mod_stun_disco: {} - mod_vcard: {} - mod_vcard_xupdate: {} - mod_version: - show_os: false - -### Local Variables: -### mode: yaml -### End: -### vim: set filetype=yaml tabstop=8 - - }; security.dhparams = { enable = true; - params.nginx = { }; + params.nginx = {}; }; networking.firewall.allowedTCPPorts = [ - 5222 # xmpp-client - 5269 # xmpp-server - 5280 # xmpp-bosh - 5443 # https + 5222 # xmpp-client + 5223 # xmpp-client + 5269 # xmpp-server + 5280 # xmpp-bosh + 5443 # https + 3478 # xmpp-stun ]; } |
