1let
2 cert =
3 pkgs:
4 pkgs.runCommand "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
5 openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=example.com/CN=muc.example.com/CN=matrix.example.com' -days 36500
6 mkdir -p $out
7 cp key.pem cert.pem $out
8 '';
9in
10import ../make-test-python.nix (
11 { pkgs, ... }:
12 {
13 name = "ejabberd";
14 meta = with pkgs.lib.maintainers; {
15 maintainers = [ ];
16 };
17 nodes = {
18 client =
19 { nodes, pkgs, ... }:
20 {
21 security.pki.certificateFiles = [ "${cert pkgs}/cert.pem" ];
22 networking.extraHosts = ''
23 ${nodes.server.networking.primaryIPAddress} example.com
24 '';
25
26 environment.systemPackages = [
27 (pkgs.callPackage ./xmpp-sendmessage.nix {
28 connectTo = nodes.server.networking.primaryIPAddress;
29 })
30 ];
31 };
32 server =
33 { config, pkgs, ... }:
34 {
35 security.pki.certificateFiles = [ "${cert pkgs}/cert.pem" ];
36 networking.extraHosts = ''
37 ${config.networking.primaryIPAddress} example.com
38 ${config.networking.primaryIPAddress} matrix.example.com
39 '';
40
41 services.ejabberd = {
42 enable = true;
43 configFile = "/etc/ejabberd.yml";
44 };
45
46 systemd.services.ejabberd.serviceConfig.TimeoutStartSec = "15min";
47 environment.etc."ejabberd.yml" = {
48 user = "ejabberd";
49 mode = "0600";
50 text = ''
51 loglevel: 3
52
53 hosts:
54 - "example.com"
55
56 listen:
57 -
58 port: 5222
59 module: ejabberd_c2s
60 zlib: false
61 max_stanza_size: 65536
62 shaper: c2s_shaper
63 access: c2s
64 starttls: true
65 -
66 port: 5269
67 ip: "::"
68 module: ejabberd_s2s_in
69 -
70 port: 8448
71 module: ejabberd_http
72 tls: true
73 request_handlers:
74 "/_matrix": mod_matrix_gw
75 -
76 port: 5347
77 ip: "127.0.0.1"
78 module: ejabberd_service
79 access: local
80 shaper: fast
81 -
82 port: 5444
83 module: ejabberd_http
84 request_handlers:
85 "/upload": mod_http_upload
86
87 certfiles:
88 - ${cert pkgs}/key.pem
89 - ${cert pkgs}/cert.pem
90
91 ## Disabling digest-md5 SASL authentication. digest-md5 requires plain-text
92 ## password storage (see auth_password_format option).
93 disable_sasl_mechanisms: "digest-md5"
94
95 ## Outgoing S2S options
96 ## Preferred address families (which to try first) and connect timeout
97 ## in seconds.
98 outgoing_s2s_families:
99 - ipv4
100 - ipv6
101
102 ## auth_method: Method used to authenticate the users.
103 ## The default method is the internal.
104 ## If you want to use a different method,
105 ## comment this line and enable the correct ones.
106 auth_method: internal
107
108 ## Store the plain passwords or hashed for SCRAM:
109 ## auth_password_format: plain
110 auth_password_format: scram
111
112 ###' TRAFFIC SHAPERS
113 shaper:
114 # in B/s
115 normal: 1000000
116 fast: 50000000
117
118 ## This option specifies the maximum number of elements in the queue
119 ## of the FSM. Refer to the documentation for details.
120 max_fsm_queue: 1000
121
122 ###' ACCESS CONTROL LISTS
123 acl:
124 ## The 'admin' ACL grants administrative privileges to XMPP accounts.
125 ## You can put here as many accounts as you want.
126 admin:
127 user:
128 - "root": "example.com"
129
130 ## Local users: don't modify this.
131 local:
132 user_regexp: ""
133
134 ## Loopback network
135 loopback:
136 ip:
137 - "127.0.0.0/8"
138 - "::1/128"
139 - "::FFFF:127.0.0.1/128"
140
141 ###' SHAPER RULES
142 shaper_rules:
143 ## Maximum number of simultaneous sessions allowed for a single user:
144 max_user_sessions: 10
145 ## Maximum number of offline messages that users can have:
146 max_user_offline_messages:
147 - 5000: admin
148 - 1024
149 ## For C2S connections, all users except admins use the "normal" shaper
150 c2s_shaper:
151 - none: admin
152 - normal
153 ## All S2S connections use the "fast" shaper
154 s2s_shaper: fast
155
156 ###' ACCESS RULES
157 access_rules:
158 ## This rule allows access only for local users:
159 local:
160 - allow: local
161 ## Only non-blocked users can use c2s connections:
162 c2s:
163 - deny: blocked
164 - allow
165 ## Only admins can send announcement messages:
166 announce:
167 - allow: admin
168 ## Only admins can use the configuration interface:
169 configure:
170 - allow: admin
171 ## Only accounts of the local ejabberd server can create rooms:
172 muc_create:
173 - allow: local
174 ## Only accounts on the local ejabberd server can create Pubsub nodes:
175 pubsub_createnode:
176 - allow: local
177 ## In-band registration allows registration of any possible username.
178 ## To disable in-band registration, replace 'allow' with 'deny'.
179 register:
180 - allow
181 ## Only allow to register from localhost
182 trusted_network:
183 - allow: loopback
184
185 ## ===============
186 ## API PERMISSIONS
187 ## ===============
188 ##
189 ## This section allows you to define who and using what method
190 ## can execute commands offered by ejabberd.
191 ##
192 ## By default "console commands" section allow executing all commands
193 ## issued using ejabberdctl command, and "admin access" section allows
194 ## users in admin acl that connect from 127.0.0.1 to execute all
195 ## commands except start and stop with any available access method
196 ## (ejabberdctl, http-api, xmlrpc depending what is enabled on server).
197 ##
198 ## If you remove "console commands" there will be one added by
199 ## default allowing executing all commands, but if you just change
200 ## permissions in it, version from config file will be used instead
201 ## of default one.
202 ##
203 api_permissions:
204 "console commands":
205 from:
206 - ejabberd_ctl
207 who: all
208 what: "*"
209
210 language: "en"
211
212 ###' MODULES
213 ## Modules enabled in all ejabberd virtual hosts.
214 modules:
215 mod_adhoc: {}
216 mod_announce: # recommends mod_adhoc
217 access: announce
218 mod_blocking: {} # requires mod_privacy
219 mod_caps: {}
220 mod_carboncopy: {}
221 mod_client_state: {}
222 mod_configure: {} # requires mod_adhoc
223 ## mod_delegation: {} # for xep0356
224 mod_disco: {}
225 #mod_irc:
226 # host: "irc.@HOST@"
227 # default_encoding: "utf-8"
228 ## mod_bosh: {}
229 ## mod_http_fileserver:
230 ## docroot: "/var/www"
231 ## accesslog: "/var/log/ejabberd/access.log"
232 mod_http_upload:
233 thumbnail: false # otherwise needs the identify command from ImageMagick installed
234 put_url: "http://@HOST@:5444/upload"
235 ## # docroot: "@HOME@/upload"
236 #mod_http_upload_quota:
237 # max_days: 14
238 mod_last: {}
239 ## XEP-0313: Message Archive Management
240 ## You might want to setup a SQL backend for MAM because the mnesia database is
241 ## limited to 2GB which might be exceeded on large servers
242 mod_mam: {}
243 mod_muc:
244 host: "muc.@HOST@"
245 access:
246 - allow
247 access_admin:
248 - allow: admin
249 access_create: muc_create
250 access_persistent: muc_create
251 mod_muc_admin: {}
252 mod_muc_log: {}
253 mod_offline:
254 access_max_user_messages: max_user_offline_messages
255 mod_ping: {}
256 ## mod_pres_counter:
257 ## count: 5
258 ## interval: 60
259 mod_privacy: {}
260 mod_private: {}
261 mod_roster:
262 versioning: true
263 mod_shared_roster: {}
264 mod_stats: {}
265 mod_time: {}
266 mod_vcard:
267 search: false
268 mod_vcard_xupdate: {}
269 ## Convert all avatars posted by Android clients from WebP to JPEG
270 mod_avatar: {}
271 # convert:
272 # webp: jpeg
273 mod_version: {}
274 mod_stream_mgmt: {}
275 ## The module for S2S dialback (XEP-0220). Please note that you cannot
276 ## rely solely on dialback if you want to federate with other servers,
277 ## because a lot of servers have dialback disabled and instead rely on
278 ## PKIX authentication. Make sure you have proper certificates installed
279 ## and check your accessibility at https://check.messaging.one/
280 mod_s2s_dialback: {}
281 mod_pubsub:
282 plugins:
283 - "pep"
284 mod_push: {}
285 mod_matrix_gw:
286 key_name: key1
287 key: MATRIX_SECRET
288 '';
289 };
290
291 systemd.services.ejabberd.serviceConfig.EnvironmentFile = pkgs.writeText "ejabberd.env" ''
292 EJABBERD_MACRO_MATRIX_SECRET=SU4mu/j8b8A1i1EdyxIcKlFlrp+eSRBIlZwGyHP7Mfo=
293 '';
294 networking.firewall.enable = false;
295 };
296 };
297
298 testScript =
299 { nodes, ... }:
300 ''
301 ejabberd_prefix = "su ejabberd -s $(which ejabberdctl) "
302
303 server.wait_for_unit("ejabberd.service")
304
305 assert "status: started" in server.succeed(ejabberd_prefix + "status")
306
307 server.succeed("curl https://matrix.example.com:8448/_matrix/key/v2/server")
308
309 server.succeed(
310 ejabberd_prefix + "register azurediamond example.com hunter2",
311 ejabberd_prefix + "register cthon98 example.com nothunter2",
312 )
313 server.fail(ejabberd_prefix + "register asdf wrong.domain")
314 client.succeed("send-message")
315 server.succeed(
316 ejabberd_prefix + "unregister cthon98 example.com",
317 ejabberd_prefix + "unregister azurediamond example.com",
318 )
319 '';
320 }
321)