Πως να στήσετε έναν πλήρη XMPP server

Σε αυτόν τον οδηγό θα σας δείξω βήμα προς βήμα πως να στήσετε έναν πλήρη XMPP server. Σε αντίθεση με πολλούς οδηγούς που εξηγούν τα βασικά για το στήσιμο ενός server, αυτός ο οδηγός στοχεύει στο να βοηθήσει νέους sysadmins να στήσουν έναν XMPP server ο οποίος συμμορφώνεται έως και 100% στα πρωτόκολλο του XMPP.

Ενώ υπάρχουν πολλοί XMPP servers, αυτός ο οδηγός επικεντρώνεται στο Prosody, ο οποίος είναι από τους πιο δημοφιλείς. Επιπλέον, οι οδηγίες δίνονται για servers οι οποίοι τρέχουν Debian (η διανομές βασισμένες στο Debian). Αν χρησιμοποιείτε άλλη διανομή για τον server σας, χρησιμοποιήστε τις κατάλληλες εντολές για τον package manager σας και συμβουλευτείτε την τεκμηρίωση του λογισμικού που θέλετε να χρησιμοποιήσετε.

Τι είναι το XMPP

Το XMPP (γνωστό και ως Jabber) είναι ένα πρωτόκολλο για άμεση επικοινωνία. Σε σχέση με άλλες υπηρεσίες IM, το XMPP είναι αποκεντρωμένο και υπάρχουν πολλοί διαφορετικοί servers σε αντίθεση με τις αντίστοιχες υπηρεσίες οι οποίες βασίζονται σε έναν κεντρικό server.

Τι χρειαζόμαστε για τον server

Για το στήσιμο ενός XMPP server χρειάζονται:

  • Ένας server (ένα παλιότερο μηχάνημα ή ένα βασικό VPS αρκεί)

  • Ένα domain, καθώς θα χρειαστεί να δημιουργηθούν μερικά DNS records

  • Ένα πιστοποιητικό SSL, ή παραπάνω, ανάλογα με τις ρυθμίσεις του server σας. Αν δεν έχετε ήδη κάποιο πιστοποιητικό, μπορείτε να δημιουργήσετε όσα χρειάζονται με το Certbot.

  • Ένας web server. Δεν θα χρειαστεί για το XMPP ως έχει, αλλά για κάποια modules. Σε αυτόν τον οδηγό θα χρησιμοποιήσουμε το Nginx.

  • Και φυσικά το Prosody.

Εγκατάσταση και ρύθμιση του Prosody

Για να εγκαταστήσουμε το Prosody, τρέχουμε:

sudo apt install prosody prosody-modules mercurial

Με αυτόν τον τρόπο κατεβάζουμε το Prosody μαζί με μερικά modules, τα οποία θα είναι πολύ χρήσιμα στη συνέχεια. Το mercurial θα χρειαστεί για να κατεβάσουμε κάποια community modules τα οποία θα χρειαστούν.

Για να κατεβάσουμε τα community packages, τρέχουμε:

hg clone https://hg.prosody.im/prosody-modules/ prosody-modules

(Προσωπικά το prosody-modules το έχω στο /usr/lib/prosody/modules για ευκολία, μπορείτε να το έχετε σε όποιο directory θέλετε.)

Για να ρυθμίσουμε το Prosody, επεξεργαζόμαστε με τον text editor της επιλογής μας το αρχείο /etc/prosody/prosody.cfg.lua ως root.

Θα χρειαστεί να ρυθμίσουμε τα εξής:

  • Δίνουμε το JID (Jabber ID) των χρηστών οι οποίοι θα έχουν δικαιώματα admin (μπορείτε να ορίσετε πάνω από έναν admin).

admins = { "username@domain.tld" }

  • Ορίζουμε τα plugin paths, για τα modules τα οποία προσθέσαμε προηγουμένως. Μπορείτε να ορίσετε το path των modules, καθώς και του prosody-modules directory.

plugin_paths = { "/usr/lib/prosody/modules", "/dir/of/prosody-modules" }

  • Ορίζουμε τα modules που θέλουμε να έχουμε ενεργοποιημένα. Μερικά από αυτά είναι ενεργοποιημένα ως προεπιλογή

modules_enabled {
-- Γενικώς απαραίτητα
"roster";
"saslauth";
"tls";
"dialback";
"disco";

-- Δεν είναι απαραίτητα, αλλά προτείνονται
"carbons";
"pep";
"private";
"blocklist";
"vcard4";
"vcard_legacy";

-- Καλό να υπάρχουν
"version";
"uptime";
"time";
"ping";
"register";
"mam";
"csi_simple";

-- Admin interfaces
"admin_adhoc";
--"admin_telnet";
-- HTTP modules
"bosh";
--"websocket";
"http_files";

-- Άλλες συγκεκριμένες λειτουργίες
"posix";
[...]
"proxy65";

-- Προσθέστε αν έχετε κατεβάσει τα community modules
"cloud_notify";
"smacks";
"turncredentials";
"vcard_muc";
"external_services";
"bookmarks";
"server_contact_info";
"http_upload_external";
}

(σημείωση: στη γλώσσα προγραμματισμού Lua, οι δύο παύλες μπροστά σε μια γραμμή δηλώνουν ότι η γραμμή είναι σχόλιο)

  • Ορίζουμε αν επιτρέπεται η εγγραφή στον server.

allow_registration = false

Αν ο server είναι δημόσιος και να επιτρέπεται η εγγραφή από τους χρήστες, τότε μπορείτε να το ορίσετε ως true.

  • Ορίζουμε το authentication

authentication = "internal_hashed"

  • Ορίζουμε το storage

storage = "internal"

Μπορείτε να χρησιμοποιήσετε κάποια βάση δεδομένων SQL αν το επιθυμείτε.

  • Ορίζουμε το directory των πιστοποιητικών

certificates = "certs"

Έτσι ορίζουμε ότι τα πιστοποιητικά βρίσκονται στο /etc/prosody/certs.

  • Ρυθμίζουμε το VirtualHost με domain και τα subdomains που χρειαζόμαστε
VirtualHost "domain.tld"
    ssl = {
        key = "certs/domain.tld.key"
        certificate = "certs/domain.tld.key"
    }
    disco_items = {
        { "upload.domain.tld", "File upload" };
        { "muc.domain.tld", "MUC" };
    }
}
  • Προσθέτουμε μερικές επιλογές για το BOSH (χρήσιμο για web clients)
consider_bosh_secure = true;
cross_domain_bosh = true;
https_ssl = {
    certificate = "/etc/letsencrypt/live/domain.tld/fullchain.pem";
    key = "/etc/letsencrypt/live/domain.tld/privkey.pem";
}
  • Προσθέτουμε στοιχεία επικοινωνίας (προαιρετικά)
contact_info = {
    abuse = { "mailto:abuse@domain.tld" };
    admin = { "mailto:admin@domain.tld" };
    feedback = { "mailto:feedback@domain.tld" };
}
  • Προαιρετικά προσθέτουμε τα components που χρειαζόμαστε

MUC:

Component "muc.domain.tld" "muc"
    restrict_room_creation = false
    modules_enabled = {
        "vcard_muc",
        "muc_mam",
    }

Uploads:

Component "upload.domain.tld" "http_upload_external"
    http_upload_external_base_url = "https://upload.domain.tld/"
    http_upload_external_secret = "mystiko"
    http_upload_external_file_size_limit = 104857600 -- 100 MiB
  • Ρυθμίζουμε τα external services για τον turnserver (για κλήσεις και βιντεοκλήσεις):
external_services = {
    {
        type = "stun",
        transport = "udp",
        host = "turn.domain.tld",
        port = 3478
   }, {
        type = "turn",
        transport = "udp",
        host = "turn.domain.tld",
        port = 3478,
        secret = "mystiko"
    }
}
  • Αποθηκεύουμε το αρχείο

  • Δημιουργούμε το admin account τρέχοντας την εντολή:

sudo prosodyctl adduser username@domain.tld

Με τον ίδιο τρόπο δημιουργούμε και απλά accounts εφόσον είναι απενεργοποιημένη η εγγραφή.

  • Εφόσον υπάρχει κάποιο πιστοποιητικό, τρέχουμε την εντολή sudo prosodyctl –root cert import /etc/letsencrypt/live. Αλλιώς, δημιουργούμε οποιοδήποτε πιστοποιητικό χρειάζεται με το certbot.

  • Στο διαχειριστικό DNS του domain, προσθέτουμε τα _xmpp και _xmpps SRV records όπως αναφέρονται εδώ. Επίσης φτιάχνουμε SRV records για όποια subdomains χρειάζονται, π.χ. για το MUC. (Για τα uploads και τον turnserver αναφέρεται παρακάτω η διαδικασία). Ίσως χρειαστούν λίγα λεπτά για να γίνουν deploy τα records. Επίσης κάνουμε forward τα ports (μόνο TCP) στο router και ρυθμίζουμε αντιστοίχως το firewall, αν υπάρχει.

Εφόσον έγιναν τα παραπάνω βήματα, κάνουμε enable την υπηρεσία prosody με το systemd και την ξεκινάμε με τις παρακάτω εντολές:

sudo systemctl enable prosody
sudo systemctl start prosody

Αφού ενεργοποιηθεί το Prosody, δοκιμάστε να συνδεθείτε με το JID και τον κωδικό σας σε έναν XMPP client (προτείνω το Dino σε desktop/laptop και το Conversations σε Android). Εφόσον μπορείτε να συνδεθείτε στον server σας, σημαίνει πως όλα πήγαν καλά. Αλλιώς, τρέξτε την εντολή sudo prosodyctl check. Μέσα από εκεί μπορείτε να δείτε τυχόν προβλήματα στο Prosody.

Εφόσον ο server λειτουργεί, προτείνω να ρίξετε μια ματια στο https://compliance.conversations.im όπου μπορείτε να δείτε το ποσοστό συμμόρφωσης του server σας με το πρωτόκολλο του XMPP. Προτείνεται να δημιουργήσετε ένα δοκιμαστικό account, το οποίο θα είναι χρήσιμο αργότερα.

Ρύθμιση upload server

Το Prosody δεν έχει από προεπιλογή κάποιον τρόπο για να στείλει κάποιος αρχεία. Γι’ αυτό θα χρειαστούν μερικές επιπλέον ρυθμίσεις.

Παραπάνω προσθέσαμε στο configuration το upload component και το http_upload_external module. Το συγκεκριμένο module έχει πολλαπλές υλοποιήσεις, όπως μπορείτε να δείτε εδώ. Εδώ θα χρησιμοποιήσουμε την υλοποίηση στη γλώσσα Go, καθώς είναι η ευκολότερη στη ρύθμιση.

  • Αρχικά εγκαθιστούμε το golang στο σύστημά μας με την εντολή sudo apt install golang, αν δεν υπάρχει στο σύστημα.

  • Κάνουμε clone το Prosody Filer από το git με την εντολή git clone https://github.com/ThomasLeister/prosody-filer.

  • Μπαίνουμε στο prosody-filer directory και τρέχουμε το build.sh για να κάνουμε compile το Prosody Filer.

  • Αντιγράφουμε το prosody-filer και το config.example.toml σε ένα directory της επιλογής μας, π.χ. στο /var/www/upload.

  • Μετονομάζουμε το config.example.toml με την εντολή sudo mv config.example.toml config.toml.

  • Το config.toml το επεξεργαζόμαστε ως εξής:

listenport = "[::]:5050"
secret = "mystiko"
storeDir = "/var/www/upload/uploads/"
uploadSubDir=""

Το config.toml περιλαμβάνει την τεκμηρίωση για τις παραπάνω ρυθμίσεις.

  • Δημιουργούμε την υπηρεσία για το Prosody Filer στο systemd στο directory /etc/systemd/system/prosody-filer.service και γράφουμε τα εξής:
[Unit]
Description=Prosody file upload server

[Service]
Type=simple
ExecStart=/home/prosody-filer/prosody-filer
Restart=always
WorkingDirectory=/home/prosody-filer

[Install]
WantedBy=multi-user.target
  • Τρέχουμε τις εξής εντολές:

sudo systemctl reload-daemon
sudo systemctl enable prosody-filer
sudo systemctl start prosody-filer

Μπορείτε να ελέγξετε αν τρέχει το prosody-filer με την εντολή sudo systemctl status prosody-filer.

  • Δημιουργούμε ένα configuration file στο /etc/nginx/sites-available/xmpp-upload και γράφουμε τα εξής:

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name uploads.myserver.tld;

    ssl_certificate /etc/letsencrypt/live/uploads.myserver.tld/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/uploads.myserver.tld/privkey.pem;

    client_max_body_size 50m;

    location /upload/ {
        if ( $request_method = OPTIONS ) {
            add_header Access-Control-Allow-Origin '*';
            add_header Access-Control-Allow-Methods 'PUT, GET, OPTIONS, HEAD';
            add_header Access-Control-Allow-Headers 'Authorization, Content-Type';
            add_header Access-Control-Allow-Credentials 'true';
            add_header Content-Length 0;
            add_header Content-Type text/plain;
            return 200;
        }
        proxy_pass http://[::]:5050/upload/;
        proxy_request_buffering off;
    }
}
  • Δημιουργούμε ένα symlink του configuration τρέχοντας sudo ln -s /etc/nginx/sites-available/xmpp-upload /etc/nginx/sites-enabled

  • Ενεργοποιούμε και ξεκινάμε το nginx με τις παρακάτω εντολές:

sudo systemctl enable nginx
sudo systemctl start nginx

Εφόσον δεν υπάρχουν τυχόν σφάλματα, κάνετε επανεκκίνηση του prosody με την εντολή sudo systemctl restart prosody. Έπειτα μπορείτε να δοκιμάσετε την αποστολή αρχείων στον XMPP client σας.

Ρύθμιση Turnserver για κλήσεις και βιντεοκλήσεις

Για να κάνουμε τον XMPP server μας ένα κλικ καλύτερο, μπορούμε να ενεργοποιήσουμε τον turnserver για να μπορέσουμε να δεχόμαστε κλήσεις (και βιντεοκλήσεις) από τους φίλους μας.

  • Αρχικά εγκαθιστούμε το coturn τρέχοντας sudo apt install coturn.

  • Αλλάζουμε την τιμή TURNSERVER_ENABLED στο αρχείο /etc/default/coturn από 0 σε 1.

  • Ενεργοποιούμε το coturn τρέχοντας sudo systemctl start coturn.

  • Κάνουμε τις εξής αλλαγές στο /etc/turnserver.conf (κάνοντας uncomment τις συγκεκριμένες ρυθμίσεις):

listening-port=3478
listening-ip=0.0.0.0
external-ip=[η εξωτερική IP σας]
min-port=49152
max-port=65535
static-auth-secret=mystiko
server-name=turn.domain.tld
user=test:test123
realm=domain.tld

Το user εδώ είναι χρήσιμο σε περίπτωση δοκιμών. Επίσης το static-auth-secret πρέπει να είναι το ίδιο με αυτό που είχε οριστεί στο configuration του Prosody.

  • Επανεκκινούμε το coturn τρέχοντας sudo systemctl restart coturn.

  • Ανοίγουμε στο router τη θύρα 3478 (TCP και UDP) και ρυθμίζουμε κατάλληλα το firewall εφόσον είναι ενεργοποιημένο.

  • Δημιουργούμε στο διαχειριστικό του DNS ένα A record με host το turn.domain.tld, με value 127.0.0.1 και TTL 3600 (ή αυτόματο).

Μπορούμε να κάνουμε επανεκκίνηση το coturn και το Prosody και να δοκιμάσουμε τη δυνατότητα κλήσης με κάποιον άλλο χρήστη, π.χ. τον δοκιμαστικό, όπως ανέφερα νωρίτερα στον οδηγό.

Τελειώνοντας…

Αν όλη η διαδικασία έχει πάει καλά, αυτό σημαίνει ότι ο server σας είναι έτοιμος και συμμορφώνεται στο 100% με το πρωτόκολλο του XMPP. Βέβαια οι δυνατότητες του XMPP δεν σταματάνε εκεί, καθώς υπάρχουν ακόμη πολλές δυνατότητες που μπορεί κάποιος να προσθέσει.

6 «Μου αρέσει»

Ερωτήσεις:

  • Για την άμεση επικοινωνία ας πούμε από κινητό, θα πρέπει να έχουμε εγκατεστημένη μια εφαρμογή xmpp client στο κινητό;
    *Ο διαχειριστής και οι πιστοποιημένοι χρήστες, μέσω του xmpp με κάποιον τρόπο, έχουν πρόσβαση σε ολόκληρο τον server και τις εφαρμογές του, ας πούμε nextcloud, ή χρησιμοποιείται(ο xmpp) μόνο για επικοινωνία;
    *η εγκατάσταση ισχύει και για arm 64 αρχιτεκτονική(rpi4 κλπ);

ευχαριστούμε πολύ για τον οδηγό!
@getimiskon, τελευταία ερώτηση-διευκρίνιση: όπου domain.tld, βάζουμε το domain που έχουμε αγοράσει;

2 «Μου αρέσει»

Ναι. Προσωπικά, προτείνω το Conversations ή κάποιο από τα forks του (π.χ. blabber.im). Δεν ξέρω αν δουλεύει το conversejs (ένας browser XMPP client) με κινητά, δεν το έχω δοκιμάσει ακόμα.

Εξαρτάται από το πως θα στήσεις τον server. Οι οδηγίες μου είναι μόνο για τον XMPP server. Αν θέλεις να συνδέεσαι και σε άλλες εφαρμογές στον ίδιο server, εκεί πρέπει να στήσεις LDAP. Απ’ όσο ξέρω, το Prosody έχει ένα community module για υποστήριξη LDAP και μπορείς να δεις το documentation του εδώ.
Επιπλέον με ενδιαφέρει προσωπικά αυτό καθώς σκοπεύω να στήσω LDAP για κάποιες υπηρεσίες που κάνω host.

Ναι, νομίζω πως ισχύει και για ARM 64-bit.

1 «Μου αρέσει»

Ακριβώς. Προτίμησα να χρησιμοποιήσω κάτι γενικό, παρά π.χ. το δικό μου domain ως παράδειγμα.

1 «Μου αρέσει»