Instalare ejabberd cu docker (alternativa whatsapp)
=====================
Ejabberd este un server XMPP foarte lightweight prin intermediul caruia cu o aplicatie pe telefoanele Android aveti o solutie similara whatsapp cu care puteti vorbi prin chat,
puteti trimite poze si filmulete si evident puteti face audio si video call. Solutia este criptata la modul ca pana si o organizatie guvernamentala va depune eforturi uriase sa va detecteze,
in umila mea parere este practic imposibil acest lucru pt ca voi aveti control 100% asupra serverului. De fapt chatul foloseste encriptie OMEMO care pana acum nu a fost sparta de
nimeni, exista teoretic doar scenariul ca audio si video call sa poata fi cumva interceptat desi este criptat. Daca nu stiati, nu exista nicio aplicatie cunoscuta cu call criptat!!!!
Environmentul este complet inchis, absolut toti userii care vor folosi acest server se vor crea manual de catre voi: familie, prieteni samd. Exista metode automatizate insa pt o securitate
sporita eu am ales sa il folosesc complet inchis.
Nu vreau sa intru aici in detalii, pana si signal poate fi interceptat (chatul), de call nici nu mai zic, pt cineva cu solid knowledge si cu ceva interes e floare la ureche.
Daca tineti la privacy, cu solutia asta aveti garantia ca nu va spioneaza nimeni si nu ajungeti prin stenograme pe la tv :))
In locatia unde instalezi ejabberd server(cu docker) trebuie sa ai ip public si un DNS. Ex: example.com
Trebuie sa creati in zona DNS 5 inregistrari toate catre acelasi IP public cum aveti, sa zicem 11.22.33.44:
A example.com 11.22.33.44 #DNS pt example.com
A pubsub.example.com 11.22.33.44 #DNS pt servicii aditionale
A proxy.example.com 11.22.33.44 #DNS pt servicii aditionale
A upload.example.com 11.22.33.44 #DNS pt servicii aditionale
A conference.example.com 11.22.33.44 #DNS pt servicii aditionale
Se presupune ca pe masina aveti ip de retea deci se forwardeaza din router urmatoarele porturi, se poate vedea exact in documentatie ce face fiecare:
TCP 3478
UDP 3478
TCP 5349
UDP 5349
UDP 49152-65535 (ip range, stiu ca sunt multe dar asa trebuie)
TCP 5443
TCP 5222
TCP 5269
Eu am pus totul cu root, recomandat este sa se foloseasca totusi un user separat.
Se da allow din firewall pe masina la aceste porturi (iptables, ufw, depinde ce ai).
Exemplu basic iptables pt custom ports exista
aici
Se instaleaza docker pe linuxul respectiv unde pui acest server ejabberd:
$ apt install docker.io -y
(deci daca ai ubuntu/debian pachetul este docker.io, daca ai fedora/centos exista repo special pt docker-ce)
Se face folderul /root/ejabberd si in el se pune totul
$ mkdir /root/ejabberd
$ cd /root/ejabberd #si ramaneti permanent in acest folder
$ mkdir upload database ssl
$ chmod 777 upload database (pt database cred ca merge si 755)
$ chmod 755 ssl (f important)
Fisierul start.sh cu care practic se porneste containerul cu toti parametri:
$ nano start.sh
docker run -itd --name ejabberd --network=host \
-v $(pwd)/ejabberd.yml:/opt/ejabberd/conf/ejabberd.yml \
-v $(pwd)/database:/opt/ejabberd/database \
-v $(pwd)/upload:/opt/ejabberd/upload \
-v $(pwd)/ssl:/home/ejabberd/ssl \
ghcr.io/processone/ejabberd:23.04
Observati ca am folosit
network=host si nu network bridge cum e default si in felul asta e mult mai rapid plus ca nu mai specific porturile.
Reteaua bridge a dockerului din pacate nu merge la fel ca reteaua nativa a linuxului, indeferent de situatie!
Observati de asemeni nise volume, un fisier de configurare si niste certificate.
Deci in /root/ejabberd trebuie sa fie ejabberd.yml, start.sh si folderele ssl, upload, database:
*
ejabberd.yml este fisierul de configurare la care m-am chinuit foarte mult pana l-am adus la o forma functionala cu tot ce trebuie.
fisierul in puteti lua de
aici si il editati dupa cum urmeaza:
-linia 4 (hosts), find and replace example.com cu domeniul vostru, este in mai multe locuri in fisier
-liniile 58 si 69 (turn_ipv4_address), puneti ip-ul public de la server, se poate vedea cu
curl ip.sigmelu.com
-linia 146 (ip) puneti ipul de retea al serverului. Ex: 10.0.0.185. il vedeti cu
ip a
By default serverul suporta federation ca si matrix adica poti comunica cu alt server. Mai exact pe acest server sa zicem ca se creaza userul
[email protected]
care poate discuta cu
[email protected] unde exista un server XMPP instalat. Eu recomand sa dezactivati acest feature pt a evita eventual spam.
Exista posibilitatea sa nu functioneze corect encriptarea deci chiar recomand sa dezactivati.
-asadar in acelasi fisier comentati liniile 34 pana la 37 inclusiv cu un # in fata fiecarei linii, sectiunea respectiva arata asa:
-
port: 5269
module: ejabberd_s2s_in
max_stanza_size: 524288
*
folderul ssl in acest folder trebuie certificatul pt "example.com" LetsEncrypt generat cu certbot (2 fisiere), certificatul pt "*.example.com" (2 fisiere) si inca unul self signed (1 fisier).
Eu am folosit un certificat wildcard care sa faca match pt toate celelalte 4 certificate pt DNS-urile de mai sus insa le puteti genera si separat.
Instalati certbot mai intai:
$ apt install certbot
Rulati comanda urmatoare exact cu parametri respectivi, fara preferred-chain-ul respectiv, certificatul se genereaza prost.:
$ certbot certonly --preferred-chain "ISRG Root X1" --manual --preferred-challenges dns
Se introduce domeniul de la tastatura cum aveti domeniul gen example.com si apoi in zona DNS creati o inregistrare TXT exact cum va sugereaza.
Verificati aici pe server intr-o alta sesiune ca s-a creat cu succes acea inregistrare DNS si verificati cu comanda:
$ nslookup -type=TXT _acme.challenge.example.com
Dati Enter in fereastra cu certbot daca s-a updatat, va genereaza certificatele si le puneti in acest folder ssl. Fisierele sunt fullchain.pem si privkey.pem.
Generati exact cu aceeasi procedura wildcard sau 4 certificate separate insa de la tastatura scrieti *.example.com la generare (pt wildcard) sau pe rand.
Fisierele trebuie sa se numeasca fullwild.pem si privwild.pem in cazul in care ati facut un singur certificat wildcard.
Dupa ce s-a rezolvat cu certificatele LetsEncrypt, mai trebuie generat si un certificat self signed, asta ramane permanent, nu mai trebuie refacut la 3 luni:
$ openssl dhparam -out /root/ejabberd/ssl/dh4096.pem 4096
Generarea acestui certificat self signed dureaza aprox juma de ora pe un vps 1 core cu 1 Gb RAM, sau mai putin daca aveti mai multe resurse.
Pt fisierele LetsEncrypt si cel self signed trebuie chmod 644 pt ca in container aplicatia ruleaza cu userul ejabberd si vrea drepturi.
$ chmod 644 ssl/*.pem
*
folderele upload si database trebuie sa fie goale si sa aiba permisiunile specificate mai sus
FOARTE IMPORTANT, inainte de a porni containerul, trebuie neaparat sa schimbati hostname-ul la server sa fie exact domeniul vostru:
$ hostnamectl set-hostname example.com
$ bash
$ hostname
Dupa ce ati facut tot ce s-a explicat aici, porniti containerul si verificati daca functioneaza:
$ ./start.sh
$ docker ps
Intotdeauna in loguri vedeti ce nu functioneaza, o sa observati ca si in cazul nostru sunt niste warninguri, cumva le ignora si merge totul perfect:
$ docker logs ejabberd
2023-11-25 10:08:14.215585+00:00 [info] Loading configuration from /opt/ejabberd/conf/ejabberd.yml
2023-11-25 10:08:14.576750+00:00 [info] Configuration loaded successfully
2023-11-25 10:08:14.714965+00:00 [info] Got no NOTIFY_SOCKET, notifications disabled
2023-11-25 10:08:14.820572+00:00 [info] Loading modules for example.com
2023-11-25 10:08:14.823688+00:00 [warning] Mnesia backend for mod_mam is not recommended: it's limited to 2GB and often gets corrupted when reaching this limit. SQL backend is recommended. Namely, for small servers SQLite is a preferred choice because it's very easy to configure.
2023-11-25 10:08:14.989261+00:00 [warning] The option captcha_cmd is not configured, but some module wants to use the CAPTCHA feature.
2023-11-25 10:08:15.026755+00:00 [info] Waiting for Mnesia synchronization to complete
2023-11-25 10:08:15.088724+00:00 [info] ejabberd 23.4.0 is started in the node ejabberd@localhost in 0.97s
2023-11-25 10:08:15.089937+00:00 [info] Start accepting UDP connections at 0.0.0.0:3478 for ejabberd_stun
2023-11-25 10:08:15.089949+00:00 [info] Start accepting TCP connections at 0.0.0.0:5222 for ejabberd_c2s
2023-11-25 10:08:15.089954+00:00 [info] Start accepting TLS connections at 0.0.0.0:5349 for ejabberd_stun
2023-11-25 10:08:15.090046+00:00 [info] Start accepting TLS connections at 0.0.0.0:5443 for ejabberd_http
2023-11-25 10:08:15.090036+00:00 [info] Start accepting TCP connections at 10.0.0.185:7777 for mod_proxy65_stream
Este imperativ ca certificatele LetsEncrypt sa fie citit corect sa nu apara in loguri ceva de genul:
2023-11-25 09:49:35.851248+00:00 [warning] Invalid certificate in /home/ejabberd/ssl/fullchain.pem: at line 60: certificate is signed by unknown CA
Mai pe romaneste cu eroare la certificat nu este nimic safe, nu stii daca e encriptat sau nu! Asa aparea la mine cu certificatul generat fara --preferred-chain "ISRG Root X1"
In felul asta puteti restarta containerul daca este necesar si eventual sa verificati din nou logurile :
$ docker stop ejabberd
$ docker rm ejabberd
$ ./start.sh
$ docker logs ejabberd
Trebuie verificat certificatul LetsEncrypt de pe alta masina, de oricunde aveti un alt linux, nu conteaza, ar trebui sa arate cam asa:
$ curl -vvv https://example.com:5349
* Trying 11.22.33.44:5349...
* Connected to example.com (11.22.33.44) port 5349 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
* subject: CN=example.com
* start date: Nov 25 09:05:38 2023 GMT
* expire date: Feb 23 09:05:37 2024 GMT
* common name: example.com
* issuer: CN=R3,O=Let's Encrypt,C=US
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: example.com:5349
> Accept: */*
Similar trebuie verificate si restul de sus pe porturile 5349 si 5443. De ex https://conference.example.com:5443
Creare user administrator (din interiorul containerului):
$ docker exec -it ejabberdd sh
# ejabberdctl register admin example.com 3@97*82#ksGjhUf%^PH4$FJ!U
(asa creezi userul admin cu tot cu parola in aceeasi linie de comanda)
Este imperativ sa utilizati o parola f lunga si f complicata cu cifre, litere mari si mici si caractere speciale!
Deschizi browser
https://example.com:5443/admin/ si folosesti userul asta admin cu parola declarata. Ulterior din aceasta interfata se creeaza userii care vor folosi acest server.
* Hint: Daca nu poti sa te logezi ca admin pt ca nu mai tii minte parola, fix asa o schimbi din container:
# ejabberdctl change-password admin example.com D#cl@rPar0laNoua
(deci asa schimbi parola userului admin)
Utilizare
Cel mai bun client posibil pe Android este Conversations

disponibil contra cost pe google play sau gratis pe F-Droid. Link
aici. Folositi stable, nu versiuni beta!
Nu o sa insist prea mult pe partea de client, se instaleaza si userii fac login cu custom server adica
[email protected] cum aveti domeniul.
Ce este de retinut este faptul ca orice user isi poate schimba parola. Voi ca admini ii creati cont cu o parola f simpla, omul se logeaza pe tel si apoi isi schimba parola: Manage accounts, clic pe cont ex
[email protected] dupa care tot de la meniul cu 3 punctulete exista si optiunea Change password. Exista optiuni pt Battery optimizations, cu restrictii exagerate este posibil sa mai ratati din notificari, e valabil la orice aplicatie android.
Exista de asemeni setari pt calitatea pozelor si filmuletelor pe care le vezi trimite, aplicatia are ceva background.
Cel mai cunoscut client si mai stabil pt desktop este Gajim

dar nu stie call, pt call pe desktop/laptop eu am folosit https://dino.im

Mi s-a parut decent.
Exista si un client web (converse.js) pe care am reusit sa il implementez, insa din pacate este foarte slab, nu recomand.
Aveti grija de fiecare data in orice client
sa aveti OMEMO encryption activat!
Sunt solutii open source, mai au cateodata mici buguri insa overall merg neasteptat de bine. Am scris si la inceput, vreti privacy, va orientati catre solutii de genul celei prezentate aici sau catre Matrix, de asemeni f bun (solutie onprem evident) insa Matrix este mai greu de setat, poate pe viitor voi face un tutorial si cu matrix, are niste avantaje insa configul este mult mai complicat si necesita server ceva mai puternic. Pt ejabberd, un VPS cu 1 core si 1 Gb RAM tine lejer cateva sute de insi fara probleme.
Pe cei care spun ca e complicat si nu merita efortul, ii invit sa foloseasca in continuare mizeriile de whatsapp si facebook messenger sa vada Facebook tot ce fac. Nici telegram, viber, skype si chiar si signal nu sunt prea breze, au servere modificate special pe colectare de date, asta e scopul, sa colecteze date nu sa furnizeze niste servicii misto ca sunt ei baieti buni.
Ramane la alegerea fiecaruia cum gestioneaza treburile astea, cu signup closed nu se inghesiue lumea pt ca nu intelege conceptul de privacy.
Mentenanta
ejabberd spre deosebire de matrix scot cam doua versiuni pe an, eu am folosit pana astazi o versiune de acum 2 ani deci nu prea aduc mari imbunatatiri.
Version history puteti vedea aici, dar nu sunt toate versiuni stable: https://github.com/processone/ejabberd/releases.
Ultima versiune care este compatibila cu acest setup este 24.02, de la 24.06 in sus, s-a schimbat api-ul si multe comenzi ejabberdctl nu mai merg deci este necesar sa se modifice fisierul de configurare. Concret nu face nimic in plus, insa apar versiuni noi de conversations si am zis sa am totusi o versiune mai noua la server.
Upgrade-ul de la 23.04 la 24.02 nu implica absolut nimic, doar se schimba imaginea si aparent merge totul perfect.
matrix in schimb scot 2 versiuni stable pe luna si e o intreaga bataie de cap sa faci toate updateurile pachetelor, plus clientul web based samd. Nu mai zic ca acolo in afara de
LetsEncrypt trebuie si certificat Zero SSL, cu docker nu am avut rabdare samd.
Aici pe serverul ejabberd in timp spatiul de pe OS se va reduce pt ca fisierele pe care si le trimit clientii intre ei raman pe server. in folderul upload sunt absolut toate fisierele dar sunt criptate si nu le puteti deschide. Ca admin nu puteti vedea ce vorbesc userii, nu puteti decat sa vedeti de pe ce IP s-au logat, nimic altceva.
Sunt niste optiuni si din interfata de administrare insa cel mai cinstit este sa stergeti din fisierele care se stocheaza in folderul upload ca sa nu ramaneti fara spatiu.
ejabberd foloseste mnesia, un DB mai putin cunoscut care este integrat direct in imagine, nu necesita container separat. Se poate crea un cluster de servere care sa tina milioane de utilizatori, daca nu stiati whatsapp foloseste o versiune ejabberd la origini insa foarte mult modificata pe colectare de date samd de cand e Meta (facebook) in spate.
Insa ce trebuie retinut este faptul ca solutia este f light, nu degeaba whatsapp au pornit cu ejabberd.
Repet, solutia e f light si merge perfect cu mnesia DB, se poate folosi si postgreSQL insa nu am inteles ce avantaje aduce, acest mnesia DB este f ok.
Am insistat sa il pun cu docker pt ca se poate muta ABSOLUT TOT pe un server/VPS nou cu copy paste si se pastreaza si baza de date si fisiere trimise si tot ce trebuie.
Luati pur si simplu tot folderul /root/ejabberd, il puneti pe un server nou in fix aceeasi locatie, instalati docker si il porniti. Mai simplu decat atat nu se poate!
In general ceva mai complex necesita mai multe containere cu DB separat cel putin, unele au si RP, deci 3, 4 containere iar asta e unul singur. Efectiv BANAL!
O mica mentiune aici, oracle cloud dau din ianuarie 2022 servere gratis, cu un cont free pe langa 2 masini x64 ai si o masina arm cu 4 core, 24 Gb RAM si bandwidth 2 gbps. Eu am fix pe o astfel de masina serverul meu, da, imaginea ejabberd este facuta si pt arm, un mare avantaj!
Enjoy!
Last update 11 Feb 2025.