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

**URL:** <https://linux-user.gr/t/pws-na-sthsete-enan-plhrh-xmpp-server/4069>\
**Category:** Άρθρα και οδηγοί\
**Tags:** debian, server, xmpp, self\_host, howto\
**Created:** [Απρίλιος 11, 2022, 4:04μμ UTC](https://linux-user.gr/t/pws-na-sthsete-enan-plhrh-xmpp-server/4069 "2022-04-11T16:04:09Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![getimiskon](https://linux-user.gr/user_avatar/linux-user.gr/getimiskon/32/10657_2.png) [@getimiskon](https://linux-user.gr/u/getimiskon)\
**Post date:** [Απρίλιος 11, 2022, 4:04μμ UTC](https://linux-user.gr/t/pws-na-sthsete-enan-plhrh-xmpp-server/4069/1 "2022-04-11T16:04:09Z")

</div>

Σε αυτόν τον οδηγό θα σας δείξω βήμα προς βήμα πως να στήσετε έναν πλήρη 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 που θέλουμε να έχουμε ενεργοποιημένα. Μερικά από αυτά είναι ενεργοποιημένα ως προεπιλογή

```auto

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 που χρειαζόμαστε

```auto
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)

```auto
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";
}

```

- Προσθέτουμε στοιχεία επικοινωνίας (προαιρετικά)

```auto
contact_info = {
    abuse = { "mailto:abuse@domain.tld" };
    admin = { "mailto:admin@domain.tld" };
    feedback = { "mailto:feedback@domain.tld" };
}

```

- Προαιρετικά προσθέτουμε τα components που χρειαζόμαστε

MUC:

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

```

Uploads:

```auto
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 (για κλήσεις και βιντεοκλήσεις):

```auto
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 όπως αναφέρονται [εδώ](https://prosody.im/doc/dns). Επίσης φτιάχνουμε 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](https://compliance.conversations.im) όπου μπορείτε να δείτε το ποσοστό συμμόρφωσης του server σας με το πρωτόκολλο του XMPP. Προτείνεται να δημιουργήσετε ένα δοκιμαστικό account, το οποίο θα είναι χρήσιμο αργότερα.

## Ρύθμιση upload server

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

Παραπάνω προσθέσαμε στο configuration το upload component και το `http_upload_external` module. Το συγκεκριμένο module έχει πολλαπλές υλοποιήσεις, όπως μπορείτε να δείτε [εδώ](https://modules.prosody.im/mod_http_upload_external.html). Εδώ θα χρησιμοποιήσουμε την υλοποίηση στη γλώσσα 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` το επεξεργαζόμαστε ως εξής:

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

```

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

- Δημιουργούμε την υπηρεσία για το Prosody Filer στο systemd στο directory `/etc/systemd/system/prosody-filer.service` και γράφουμε τα εξής:

```auto
[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` και γράφουμε τα εξής:

```auto

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 τις συγκεκριμένες ρυθμίσεις):

```auto
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 δεν σταματάνε εκεί, καθώς υπάρχουν ακόμη πολλές δυνατότητες που μπορεί κάποιος να προσθέσει.

---

<div class="post-metadata">

**Author:** ![Asfodelus](https://linux-user.gr/user_avatar/linux-user.gr/asfodelus/32/11_2.png) [@Asfodelus](https://linux-user.gr/u/Asfodelus)\
**Post date:** [Απρίλιος 11, 2022, 4:07μμ UTC](https://linux-user.gr/t/pws-na-sthsete-enan-plhrh-xmpp-server/4069/2 "2022-04-11T16:07:32Z")

</div>



---

<div class="post-metadata">

**Author:** ![nikaskonstantinos](https://linux-user.gr/user_avatar/linux-user.gr/nikaskonstantinos/32/5071_2.png) [@nikaskonstantinos](https://linux-user.gr/u/nikaskonstantinos)\
**Post date:** [Απρίλιος 11, 2022, 7:16μμ UTC](https://linux-user.gr/t/pws-na-sthsete-enan-plhrh-xmpp-server/4069/3 "2022-04-11T19:16:52Z")

</div>

> [@getimiskon](#):
>
> Τι είναι το XMPP

Ερωτήσεις:

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

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

---

<div class="post-metadata">

**Author:** ![getimiskon](https://linux-user.gr/user_avatar/linux-user.gr/getimiskon/32/10657_2.png) [@getimiskon](https://linux-user.gr/u/getimiskon)\
**Post date:** [Απρίλιος 11, 2022, 7:32μμ UTC](https://linux-user.gr/t/pws-na-sthsete-enan-plhrh-xmpp-server/4069/4 "2022-04-11T19:32:19Z")

</div>

> [@nikaskonstantinos](#):
>
> Για την άμεση επικοινωνία ας πούμε από κινητό, θα πρέπει να έχουμε εγκατεστημένη μια εφαρμογή xmpp client στο κινητό;

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

> [@nikaskonstantinos](#):
>
> Ο διαχειριστής και οι πιστοποιημένοι χρήστες, μέσω του xmpp με κάποιον τρόπο, έχουν πρόσβαση σε ολόκληρο τον server και τις εφαρμογές του, ας πούμε nextcloud, ή χρησιμοποιείται(ο xmpp) μόνο για επικοινωνία;

Εξαρτάται από το πως θα στήσεις τον server. Οι οδηγίες μου είναι μόνο για τον XMPP server. Αν θέλεις να συνδέεσαι και σε άλλες εφαρμογές στον ίδιο server, εκεί πρέπει να στήσεις LDAP. Απ’ όσο ξέρω, το Prosody έχει ένα community module για υποστήριξη LDAP και μπορείς να δεις το documentation του [εδώ](https://modules.prosody.im/mod_lib_ldap.html).  
Επιπλέον με ενδιαφέρει προσωπικά αυτό καθώς σκοπεύω να στήσω LDAP για κάποιες υπηρεσίες που κάνω host.

> [@nikaskonstantinos](#):
>
> η εγκατάσταση ισχύει και για arm 64 αρχιτεκτονική(rpi4 κλπ);

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

---

<div class="post-metadata">

**Author:** ![getimiskon](https://linux-user.gr/user_avatar/linux-user.gr/getimiskon/32/10657_2.png) [@getimiskon](https://linux-user.gr/u/getimiskon)\
**Post date:** [Απρίλιος 11, 2022, 7:55μμ UTC](https://linux-user.gr/t/pws-na-sthsete-enan-plhrh-xmpp-server/4069/5 "2022-04-11T19:55:12Z")

</div>

> [@nikaskonstantinos](#):
>
> @getimiskon, τελευταία ερώτηση-διευκρίνιση: όπου domain.tld, βάζουμε το domain που έχουμε αγοράσει;

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