summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ejabberd.nix497
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
];
}