diff options
| author | 2024-01-31 21:04:56 +0000 | |
|---|---|---|
| committer | 2024-01-31 21:04:56 +0000 | |
| commit | 2426cd0f7a3aa7a181d4e9ba3447dd4471350af0 (patch) | |
| tree | fc0a22e282117f7bfab5d1d557b9fcd706db57e9 | |
| parent | 2ac490aca1be78d5cb01eeeb9639c6d02ccf40e5 (diff) | |
| download | blossom-2426cd0f7a3aa7a181d4e9ba3447dd4471350af0.tar.gz blossom-2426cd0f7a3aa7a181d4e9ba3447dd4471350af0.tar.bz2 blossom-2426cd0f7a3aa7a181d4e9ba3447dd4471350af0.zip  | |
remove xmpp article
Diffstat (limited to '')
| -rw-r--r-- | blog/ejabberd.md | 513 | 
1 files changed, 0 insertions, 513 deletions
diff --git a/blog/ejabberd.md b/blog/ejabberd.md deleted file mode 100644 index 7831432..0000000 --- a/blog/ejabberd.md +++ /dev/null @@ -1,513 +0,0 @@ -+++ -title = "cozy ejabberd xmpp chat server" -published_at = "2023-09-16T21:07:40+0100"  -tags = ["tech", "sysadmin"] -+++ - -today we are going to do the **ultimate** *cozy* ejabberd server guide. the only prerequisites for this guide are, one, having already set up some form of server, whether it be a vps, or an old laptop behind your fridge, it doesn't matter, because this isn't the email network, and two, ownership of a domain name, e.g. `blos.sm`. - -we shall begin with a single virtualhost[^1]. for example purposes, we will use `example.slay` (let's imagine this is a real tld because why not) as the domain. just replace all instances of `example.slay` with your own domain.  - -[^1]: virtualhosts allow more than one xmpp service to be run on one server. for example, you could have one xmpp service with the domain `example.slay` and another xmpp service with the domain `example.flop`, both somewhat separated from each other as if they were run on different servers. - -<div> -<div class="panel checklist"> -checklist!:  -<input type="checkbox" id="hide-checklist"><label for="hide-checklist">hide</label> - -- [ ] add dns records -- [ ] open firewall ports -- [ ] set up web server -- [ ] get ssl certificates -- [ ] install ejabberd -- [ ] set up postgres database -- [ ] write/edit configuration -- [ ] start service -- [ ] create admin user -- [ ] change loglevel - -</div> - -## step 1: set up your dns records - -you will need dns A/AAAA records and srv records for each service on your xmpp server. - -you will need a records for: - -- `example.slay` -- `muc.example.slay` (for group chats) -- `upload.example.slay` (for http file upload) -- `pubsub.example.slay` (for the pubsub node) -- `proxy.example.slay` (for file transfer proxy) -- `turn.example.slay` (for stun/turn) - -each pointing to the ip address of your server that is going to run ejabberd. the last two are technically optional, but i would recommend them. - -as well as srv records for each, pointing to a domain that resolves to your server, as so: - -(all records are in the form -`_service._proto.name IN SRV priority weight port target`) - -``` -_xmpp-client._tcp   IN SRV  5 0 5222 example.slay. -_xmpps-client._tcp  IN SRV  5 0 5223 example.slay. -_xmpp-server._tcp   IN SRV  5 0 5269 example.slay. -_xmpps-server._tcp  IN SRV  5 0 5270 example.slay. -``` - -and  - -``` -_xmpp-client._tcp.muc   IN SRV  5 0 5222 example.slay. -_xmpps-client._tcp.muc  IN SRV  5 0 5223 example.slay. -_xmpp-server._tcp.muc   IN SRV  5 0 5269 example.slay. -_xmpps-server._tcp.muc  IN SRV  5 0 5270 example.slay. -``` - -for each of the subdomains (starting with muc). exclude `turn.example.slay`. - -you will then have to add one last set of srv records for stun/turn. - -``` -_stun._udp   IN SRV  5 0 3478 turn.example.slay. -_stun._tcp   IN SRV  5 0 3478 turn.example.slay. -_stuns._tcp  IN SRV  5 0 5349 turn.example.slay. - -_turn._udp   IN SRV  5 0 3478 turn.example.slay. -_turn._tcp   IN SRV  5 0 3478 turn.example.slay. -_turns._tcp  IN SRV  5 0 5349 turn.example.slay. -``` - -extra info: as a result of these records, you could technically play around with hosting xmpp on a server other than the one at `example.slay` (i.e. if you were splitting services across servers on one domain) by using the srv delegation. further info can be found at [XEP-0368](https://xmpp.org/extensions/xep-0368.html).  - -## step 2: open your firewall ports - -open ports: - -tcp: `80` `443` `5222` `5223` `5269` `5270` `3478` `5349` `49152-65535` - -udp: `3478` `49152-65535` - -`80` & `443` are for the web server, `5222`, `5223`, `5269` and `5270` are for xmpp, and the rest are for stun/turn. - -## step 3: set up your web server and get your ssl certificates - -you need to: - -- get (an) ssl certificate(s) for your domain, as well as several subdomains, all in all: -  - `example.slay` -  - `muc.example.slay` -  - `upload.example.slay` -  - `pubsub.example.slay` -  - `proxy.example.slay` -  - `turn.example.slay` -- proxypass http://127.0.0.1:5443 through to: -  - https://example.slay/xmpp -  - https://example.slay/.well-known/host-meta -  - https://example.slay/.well-known/host-meta.json - -  make sure that for /xmpp you have what is necessary to proxy websockets too. if you're using nginx, increase `client_max_body_size` for http uploads. -- make sure the certificate files are readable and/or in a place that is readable by the `ejabberd` user - -you can technically avoid using something like nginx + certbot, and use the built-in [ejabberd acme module](https://docs.ejabberd.im/admin/configuration/basic/#acme), thereby skipping this, but i am assuming you may also want to host other web services on your system, in which case you would want to reverse proxy each http service to a single https web service. - -## step 4: install ejabberd - -now you should finally install the [system package](https://docs.ejabberd.im/admin/installation/#operating-system-packages). make sure that your build has postgresql support. - -make sure that the file `/etc/ejabberd/ejabberd.yml` exists, and of course, is readable by the user that runs ejabberd (almost definitely `ejabberd`), by, if necessary, copying over the example `ejabberd.yml` or `wget`/`curl`ing it from the [github repo](https://github.com/processone/ejabberd/blob/master/ejabberd.yml.example). if you are getting it from the repo, make sure the version corresponds to the version of ejabberd packaged by your os.  - -## step 5: set up postgres database - -we will be creating a separate database for each virtualhost, as i feel this makes things clearer, and also it easier to migrate individual virtualhosts in the future. however, there is also now the ability to only have one, as described [here](https://docs.ejabberd.im/admin/configuration/database/#default-and-new-schemas).  - -you should follow standard postgresql installation instructions for your OS. once this has been done, you should connect to your database as an admin and: - -1. create an ejabberd database user with `CREATE USER ejabberd WITH PASSWORD 'your_password';`. don't forget to change the password, and note it down. -2. create a database for your virtualhost with `CREATE DATABASE ejabberd_example OWNER ejabberd;`. replace `example` with something corresponding to your virtualhost. -3. quit psql, and import the database schema from github with the command `curl -s https://raw.githubusercontent.com/processone/ejabberd/master/sql/pg.sql | sudo -u ejabberd psql ejabberd_example` (once again replace `example`). - -## step 6: ejabberd configuration - -begin by replacing `localhost` under `hosts` with your virtualhost (e.g. `example.slay`), then list the certfiles you have obtained under `certfiles`. - -``` -hosts: -  - example.slay - -certfiles: -  - "/etc/ejabberd/certs/*/*" -``` - -now set `default_db: sql` at the root level of the yaml file. this should be followed by `host_config` and the database configuration for your virtualhost, as shown below. customise each value to your setup. - -``` -host_config: -  example.slay: -    sql_type: pgsql -    sql_server: "localhost" -    sql_port: 5432 -    sql_username: "ejabberd" -    sql_password: "postgres_password" -    sql_database: "ejabberd_example" -    auth_method: sql -    auth_password_format: scram -``` - -under `listen`, ensure all the correct services are enabled on each port, including tls s2s on port `5270` (not default): - -``` -listen: -  - -    port: 5222 -    module: ejabberd_c2s -    max_stanza_size: 262144 -    shaper: c2s_shaper -    access: c2s -    starttls_required: true -  - -    port: 5223 -    tls: true -    module: ejabberd_c2s -    max_stanza_size: 262144 -    shaper: c2s_shaper -    access: c2s -    starttls_required: true -  - -    port: 5269 -    module: ejabberd_s2s_in -    max_stanza_size: 524288 -  - -    port: 5270 -    tls: true -    module: ejabberd_s2s_in -    max_stanza_size: 524288 -``` - -we will also be enabling the http server and the stun/turn server modules. make sure you have set `turn_ipv4_address` and `ip` to your server's ipv4 address. tls will be off for the http server as we are reverse proxying it through our web server. - -``` -  - -    port: 5443 -    module: ejabberd_http -    request_handlers: -      /xmpp/admin: ejabberd_web_admin -      /xmpp/bosh: mod_bosh -      /xmpp/upload: mod_http_upload -      /xmpp/ws: ejabberd_http_ws -      /.well-known/host-meta: mod_host_meta -      /.well-known/host-meta.json: mod_host_meta -  - -    port: 3478 -    transport: udp -    module: ejabberd_stun -    use_turn: true -    turn_min_port: 49152 -    turn_max_port: 65535 -    # The server's public IPv4 address: -    turn_ipv4_address: 0.0.0.0 -  - -    port: 5349 -    transport: tcp -    module: ejabberd_stun -    use_turn: true -    tls: true -    turn_min_port: 49152 -    turn_max_port: 65535 -    ip: 0.0.0.0 -    turn_ipv4_address: 0.0.0.0 -``` - -now set `s2s_use_starttls: required` at the root. - -at this point you can set up some ACLs. `acls` are just the access control lists, you can also set up `access_rules` corresponding to your needs, which will be what are passed to module settings. you should at the minimum add an admin user. example: - -``` -acl: -  admin: -    user: admin@example.slay -  flop: -    - user: flop@example.slay -  clown: -    - user: clown@example.slay - -access_rules: -  queens:  -    allow: flop -    allow: clown -``` - -next, we will be adding some modules under `modules` and changing some settings. - -add abuse addresses under `mod_disco`. you can also add other contact addresses according to [XEP-0157](https://xmpp.org/extensions/xep-0157.html): - -``` -modules: -# ... -  mod_disco: -    server_info: -    - -      modules: all -      name: "abuse-addresses" -      urls: ["mailto:abuse@example.slay"] -``` - -add `mod_host_meta`: - -``` -  mod_host_meta: -    bosh_service_url: "https://@HOST@/xmpp/bosh" -    websocket_url: "wss://@HOST@/xmpp/ws" -``` - -edit `mod_mam`, and change `assume_mam_usage` to `false` and `default` to `never` if you wish not to archive messages on the server: - -``` -  mod_mam: -    db_type: sql -    assume_mam_usage: never -    default: never -``` - -add `mod_stun_disco` to advertise the stun service to clients, changing `0.0.0.0` and `example.slay` to your server's ip and hostname respectively: - -``` -  mod_stun_disco:  -    credentials_lifetime: 12h -    services: -        - -          host: 0.0.0.0 -          port: 3478 -          type: stun -          transport: udp -          restricted: false -        - -          host: 0.0.0.0 -          port: 3478 -          type: turn -          transport: udp -          restricted: true -        - -          host: turn.example.slay -          port: 5349 -          type: stuns -          transport: tcp -          restricted: false -        - -          host: turn.example.slay -          port: 5349 -          type: turns -          transport: tcp -          restricted: true -``` - -now it is time to enable MUCs (multi-user chatrooms), file proxy, http upload, and pubsub. - -### mucs: - -make sure that you set the host to your muc subdomain, otherwise it will attempt to use `conference.example.slay`. you can also set `mam: false` in `default_room_options` to disable server-side message archiving by default.  - -``` -  mod_muc: -    host: muc.example.slay -    access: -      - allow -    access_admin: -      - allow: admin -    access_create: muc_create -    access_persistent: muc_create -    access_mam: -      - allow -    default_room_options: -      mam: false -``` - -### file proxy: - -``` -  mod_proxy65: -    access: local -    max_connections: 5 -``` - -### http file upload: - -``` -  mod_http_upload: -    put_url: https://@HOST@/xmpp/upload -    docroot: /var/www/ejabberdupload -    max_size: 1073741824 -    custom_headers: -      "Access-Control-Allow-Origin": "https://@HOST@" -      "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS" -      "Access-Control-Allow-Headers": "Content-Type" -``` - -create the folder for the `docroot`, and make sure it is owned by the `ejabberd` user. you can also change `max_size` (the max upload size) to whatever you prefer. - -### pubsub: - -``` -  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 -``` - -## step 7: start server and create admin user  - -start the ejabberd server!  - -use `sudo -u ejabberd ejabberdctl register admin example.slay password` to register `admin@example.slay` with the password `password`. - -there is a compliance tester at [compliance.conversations.im](https://compliance.conversations.im) if you wish to test your server. once you are done and believe everything has been set up correctly, you can optionally change the [`loglevel`](https://docs.ejabberd.im/admin/configuration/toplevel/#loglevel) at the root of the config. - -there will be an admin page accessible at [https://example.slay/xmpp/admin](https://example.slay/xmpp/admin). - -</div> - -<hr> - -# extra goodies! - -## web client - -you can set up conversejs using [`mod_conversejs`](https://docs.ejabberd.im/admin/configuration/modules/#mod-conversejs). you will also need to possibly update your web server config to proxy the new endpoint, as so: - -``` -listen: -  - -    port: 5443 -    module: ejabberd_http -    request_handlers: -      /xmpp/bosh: mod_bosh -      /xmpp/ws: ejabberd_http_ws -      /chat: mod_conversejs - -modules: -  mod_conversejs: -    websocket_url: "ws://@HOST@/xmpp/ws" -    bosh_service_url: "https://@HOST@/xmpp/bosh" -``` - -## further virtualhosts? - -for further virtualhosts you should create a new database for each, and add them to the database part of the config. e.g.: - -``` -host_config: -  example.slay: -    sql_type: pgsql -    sql_server: "localhost" -    sql_port: 5432 -    sql_username: "ejabberd" -    sql_password: "postgres_password" -    sql_database: "ejabberd_slay" -    auth_method: sql -    auth_password_format: scram -  example.flop: -    sql_type: pgsql -    sql_server: "localhost" -    sql_port: 5432 -    sql_username: "ejabberd" -    sql_password: "postgres_password" -    sql_database: "ejabberd_flop" -    auth_method: sql -    auth_password_format: scram -``` - -there cannot be conflicts between declarations in the config file, so if you have `mod_muc`, `mod_proxy65`, `mod_http_upload` and `mod_pubsub` declared under `modules` at the root, they (as well as other configuration differences between virtualhosts) must be deleted and replicated for each virtualhost under `append_host_config` at the root. example as so: - -``` -append_host_config: -  example.flop: -    modules: -      mod_muc: -        host: muc.example.flop -        access_create: flops -        access_persistent: flops -        access: -          - allow -        access_admin: -          - allow: admin -        default_room_options: -          mam: false -      mod_proxy65: -        access: flops -        max_connections: 5 -      mod_http_upload: -        access: flops -        put_url: https://@HOST@/xmpp/upload -        docroot: /var/www/ejabberdupload -        max_size: 1073741824 -        custom_headers: -          "Access-Control-Allow-Origin": "https://@HOST@" -          "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS" -          "Access-Control-Allow-Headers": "Content-Type" -      mod_pubsub: -        access_createnode: flops -        plugins: -          - flat -          - pep -        force_node_config: -          ## Avoid buggy clients to make their bookmarks public -          storage:bookmarks: -            access_model: whitelist -  example.flop: -    modules: -      mod_muc: -        hosts:  -          - muc.example.flop -        access_create: local -        access_persistent: local -        access: -          - allow -        access_admin: -          - allow: admin -        default_room_options: -          mam: false -      mod_proxy65: -        access: local -        max_connections: 5 -      mod_http_upload: -        put_url: https://@HOST@/xmpp/upload -        docroot: /var/www/ejabberdupload -        max_size: 1073741824 -        custom_headers: -          "Access-Control-Allow-Origin": "https://@HOST@" -          "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS" -          "Access-Control-Allow-Headers": "Content-Type" -      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 -``` - -as you can see above, you may also want to disable access to certain services per virtualhost using ACLs, in order to e.g. prevent users on `example.slay` from creating MUCs on `muc.example.flop`. - -## separate turn server (coturn) - -in this case, change `mod_stun_disco` to this, and don't enable the `listen` opts for stun/turn. generate an auth secret and share it with your turn server instance. - -```  -  mod_stun_disco: -    secret: "auth_secret" -    services: -      - -        host: turn.example.slay -        type: stun -      - -        host: turn.example.slay -        type: turn -``` -  | 
