# XMPP server (Gajim, OMEO encryption, ejabberd .onion setup) In this tutorial we're going to cover how to setup an XMPP chatting service over Tor. _Disclaimer:_ If you want this service to remain anonymous, make sure you at least keep [TOR between you and the service](../sensitiveremotevshome/index.md) from the [VPS acquisition](../anonymousremoteserver/index.md) to actual service usage. ## **Initial Setup** First let's install the required packages, and then run the xmpp server using docker (you can check the documentation [here](https://github.com/processone/docker-ejabberd/blob/master/ecs/README.md)), we'll follow [Lukesmith's tutorial](https://landchad.net/ejabberd/) specifically: apt install ejabberd -y Now we need the following domain names to point to your server: nowhere.moe - Your XMPP hostname xmpp.nowhere.moe - For mod_muc, Multi User Chats (MUCs) upload.nowhere.moe - For mod_http_upload, file upload support proxy.nowhere.moe - For mod_proxy65, SOCKS5 proxy support pubsub.nowhere.moe - For mod_pubsub, publish-subscribe support (A fancier RSS) Then we edit the ejabberd config file accordingly: [ Datura ] [ /dev/pts/10 ] [/srv] → vim /etc/ejabberd/ejabberd.yml [...] hosts: - nowhere.moe [...] mod_muc: host: xmpp.nowhere.moe [...] Next we need to obtain the TLS certificate for the xmpp.nowhere.moe domain, to do so we'll use acme.sh: [ Datura ] [ /dev/pts/10 ] [~] → systemctl stop nginx ; acme.sh --issue --standalone -d xmpp.nowhere.moe -k 4096 ; systemctl start nginx [Sun Jun 9 07:12:21 PM CEST 2024] Using CA: https://acme-v02.api.letsencrypt.org/directory [Sun Jun 9 07:12:21 PM CEST 2024] Standalone mode. [Sun Jun 9 07:12:21 PM CEST 2024] Creating domain key [Sun Jun 9 07:12:23 PM CEST 2024] The domain key is here: /root/.acme.sh/xmpp.nowhere.moe/xmpp.nowhere.moe.key [Sun Jun 9 07:12:23 PM CEST 2024] Single domain='xmpp.nowhere.moe' [Sun Jun 9 07:12:25 PM CEST 2024] Getting webroot for domain='xmpp.nowhere.moe' [Sun Jun 9 07:12:25 PM CEST 2024] Verifying: xmpp.nowhere.moe [Sun Jun 9 07:12:25 PM CEST 2024] Standalone mode server [Sun Jun 9 07:12:26 PM CEST 2024] Pending, The CA is processing your order, please just wait. (1/30) [Sun Jun 9 07:12:30 PM CEST 2024] Pending, The CA is processing your order, please just wait. (2/30) [Sun Jun 9 07:12:33 PM CEST 2024] Pending, The CA is processing your order, please just wait. (3/30) [Sun Jun 9 07:12:37 PM CEST 2024] Success [Sun Jun 9 07:12:37 PM CEST 2024] Verify finished, start to sign. [Sun Jun 9 07:12:37 PM CEST 2024] Lets finalize the order. [Sun Jun 9 07:12:37 PM CEST 2024] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/1581078457/276884921497' [Sun Jun 9 07:12:38 PM CEST 2024] Downloading cert. [Sun Jun 9 07:12:38 PM CEST 2024] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/03a21dfde3a1a017ddaec55ef3c43a3cae0c' [Sun Jun 9 07:12:39 PM CEST 2024] Cert success. [...] [Sun Jun 9 07:12:39 PM CEST 2024] Your cert is in: /root/.acme.sh/xmpp.nowhere.moe/xmpp.nowhere.moe.cer [Sun Jun 9 07:12:39 PM CEST 2024] Your cert key is in: /root/.acme.sh/xmpp.nowhere.moe/xmpp.nowhere.moe.key [Sun Jun 9 07:12:39 PM CEST 2024] The intermediate CA cert is in: /root/.acme.sh/xmpp.nowhere.moe/ca.cer [Sun Jun 9 07:12:39 PM CEST 2024] And the full chain certs is there: /root/.acme.sh/xmpp.nowhere.moe/fullchain.cer [ Datura ] [ /dev/pts/10 ] [~] → chown -R ejabberd:ejabberd /root/.acme.sh/xmpp.nowhere.moe [ Datura ] [ /dev/pts/10 ] [~] → cat /etc/ejabberd/ejabberd.yml [...] certfiles: - "/root/.acme.sh/xmpp.nowhere.moe/fullchain.cer" [...] Then we add the admin user in ejabberd.yml: [ Datura ] [ /dev/pts/10 ] [~] → cat /etc/ejabberd/ejabberd.yml [...] acl: admin: user: - "nihilist" [...] We also add the File Uploads: [ Datura ] [ /dev/pts/10 ] [~] → cat /etc/ejabberd/ejabberd.yml [...] mod_http_upload: put_url: https://@HOST@:5443/upload docroot: /srv/xmpp/upload/ custom_headers: "Access-Control-Allow-Origin": "https://@HOST@" "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS" "Access-Control-Allow-Headers": "Content-Type" [...] [ Datura ] [ /dev/pts/10 ] [~] → mkdir /srv/xmpp/upload/ -p [ Datura ] [ /dev/pts/10 ] [~] → chown -R ejabberd:ejabberd /srv/xmpp/upload/ We enable message archives too: [ Datura ] [ /dev/pts/10 ] [~] → cat /etc/ejabberd/ejabberd.yml [...] 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 [...] Next, you setup a coturn service for the VOIP [here](https://landchad.net/coturn/), but in this case we'll use the same coturn service that we previously setup for the [matrix server](../matrixnew/index.md) [ Datura ] [ /dev/pts/10 ] [~] → cat /etc/ejabberd/ejabberd.yml [...] mod_stun_disco: secret: "DAWDDWADWADAWDWAWDDWAADWADWDWADWADWAAWDDWAWAD" services: - host: m.nowhere.moe type: stun - host: m.nowhere.moe type: turn [...] Then we restart the ejabberd service: [ Datura ] [ /dev/pts/10 ] [~] → systemctl restart ejabberd [ Datura ] [ /dev/pts/10 ] [~] → systemctl status ejabberd ● ejabberd.service - robust, scalable and extensible realtime platform (XMPP server + MQTT broker + SIP service) Loaded: loaded (/lib/systemd/system/ejabberd.service; enabled; preset: enabled) Active: active (running) since Sun 2024-06-09 21:21:41 CEST; 6s ago Docs: https://www.process-one.net/en/ejabberd/docs/ Main PID: 3664214 (sh) Tasks: 116 (limit: 77002) Memory: 111.9M CPU: 3.022s CGroup: /system.slice/ejabberd.service Now that the ejabberd service has restarted successfully, we can register the admin user: [ Datura ] [ /dev/pts/10 ] [~] → ejabberdctl register nihilist nowhere.moe P@SSW0RD User nihilist@contact.nowhere.moe successfully registered ## **Setup** Now the xmpp server is active, along with your nihilist user, so let's connect to it from a XMPP client like gajim: [ mainpc ] [ /dev/pts/8 ] [~] → sudo apt install gajim -y ![](1.png) ![]() ![]() ![]() ## **Setup**