---
title: Configurazione di un server XMPP
date: 2024-05-04
tags:
    - xmpp
    - docker
    - container
    - im
---

# Snikket

Si tratta di un progetto che, tramite l'utilizzo di container Docker, permette di installare un servizio su un server fisico o virtuale per configurarlo in modo da riuscire a gestire autonomamente la messaggistica tramite il protocollo XMPP.

## DNS

```bash
# Domain           TTL  Class  Type  Target
chat.example.com.  300  IN     A     203.0.113.123
groups.chat.example.com  300  IN     CNAME  chat.example.com.
share.chat.example.com   300  IN     CNAME  chat.example.com.
```

## Docker

```bash
apt update && apt upgrade
```

Per Debian, seguire le istruzioni alla pagina [ufficiale](https://docs.docker.com/install/linux/docker-ce/debian/). In particolare:

```bash
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

# To install the latest version, run:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Verify that the installation is successful by running the hello-world image:
sudo docker run hello-world
```

## Installazione di Snikket

```bash
mkdir /etc/snikket
cd /etc/snikket

# And then download our docker-compose.yml file:
curl -o docker-compose.yml https://snikket.org/service/resources/docker-compose
```

Quindi creare il file di configurazione di Snikket:

```bash
vim /etc/snikket

# The primary domain of your Snikket instance
SNIKKET_DOMAIN=chat.example.com

# An email address where the admin can be contacted
# (also used to register your Let's Encrypt account to obtain certificates)
SNIKKET_ADMIN_EMAIL=you@example.com
```

### Firewall

```bash
ufw default allow outgoing && ufw default deny incoming
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 5222/tcp
ufw allow 5269/tcp
ufw allow 5000/tcp
ufw allow 3478
ufw allow 3479
ufw allow 5349
ufw allow 5350
ufw allow 49152:65535/udp
```
Questo il risultato:

```bash
 > ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                   ALLOW IN    Anywhere
[ 2] 80/tcp                     ALLOW IN    Anywhere
[ 3] 443/tcp                    ALLOW IN    Anywhere
[ 4] 5222/tcp                   ALLOW IN    Anywhere
[ 5] 5269/tcp                   ALLOW IN    Anywhere
[ 6] 5000/tcp                   ALLOW IN    Anywhere
[ 7] 3478                       ALLOW IN    Anywhere
[ 8] 3479                       ALLOW IN    Anywhere
[ 9] 5349                       ALLOW IN    Anywhere
[10] 5350                       ALLOW IN    Anywhere
[11] 49152:65535/udp            ALLOW IN    Anywhere
[12] 1222/tcp (v6)              ALLOW IN    Anywhere (v6)
[13] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
[14] 443/tcp (v6)               ALLOW IN    Anywhere (v6)
[15] 5222/tcp (v6)              ALLOW IN    Anywhere (v6)
[16] 5269/tcp (v6)              ALLOW IN    Anywhere (v6)
[17] 5000/tcp (v6)              ALLOW IN    Anywhere (v6)
[18] 3478 (v6)                  ALLOW IN    Anywhere (v6)
[19] 3479 (v6)                  ALLOW IN    Anywhere (v6)
[20] 5349 (v6)                  ALLOW IN    Anywhere (v6)
[21] 5350 (v6)                  ALLOW IN    Anywhere (v6)
[22] 49152:65535/udp (v6)       ALLOW IN    Anywhere (v6)
```

In particolare:

**TCP only**
|||
|--------|---------------------------------------------------------------------|
| 80/443 | Web Interface And Group File Sharing Service (HTTP(S))              |
| 5222   | Client App Connections (Client to Server) (XMPP-c2s)                |
| 5269   | Federation With Other Snikket Servers (Server to Server) (XMPP-s2s) |
| 5000   | File Transfer Proxy (proxy65)                                       |

**TCP and UDP**
|||
|-----------|------------------------------------------------------------------------------------|
| 3478/3479 | Audio/Video Data Proxy Negotiation and IP discovery (STUN/TURN)                    |
| 5349/5350 | Audio/Video Data Proxy Negotiations and IP Discovery over TLS (STUN/TURN over TLS) |

**UDP only**
|||
|-------------|-----------------------------------------------|
| 49152-65535 | Audio/Video Data Proxy (Turn Data, see below) |

Avviare il servizio col comando:

```bash
docker compose up -d
```

### Creazione utente admin

```bash
docker exec snikket create-invite --admin --group default

Viene generato un link utilizzabile una sola volta. Tutti gli altri utenti possono essere creati dal pannello di controllo una volta eseguito l’accesso. 
```

## Troubleshooting

[https://snikket.org/service/help/setup/troubleshooting/](https://snikket.org/service/help/setup/troubleshooting/)

```bash
# Checking for errors
cd /etc/snikket
docker-compose exec snikket_certs cat /var/log/letsencrypt/errors.log

# Force the renewal of certificates
cd /etc/snikket
docker-compose exec snikket_certs su letsencrypt -- -c "certbot renew --config-dir /snikket/letsencrypt --cert-path /etc/ssl/certbot --force-renew"
```

## Analisi docker-compose.yml

```bash
 > cat /etc/snikket/docker-compose.yml

version: "3.3"

services:
  # nome del servizio
  snikket_proxy:
    container_name: snikket-proxy
    image: snikket/snikket-web-proxy:beta
    # file con le variabili
    env_file: snikket.conf
    # Se si usa la modalità di rete host per un container, lo stack di rete del container non è isolato dall'host e al container non viene assegnato un proprio indirizzo IP. Per esempio, se si esegue un container che si lega alla porta 80 e si usa la rete host, l'applicazione del container è disponibile sulla porta 80 dell'indirizzo IP dell'host.
    network_mode: host
    # I volumi memorizzano e gestiscono i dati persistenti generati dai container effimeri. Consentono la persistenza dei dati anche dopo la rimozione o l’aggiornamento di un container.
    volumes:
    # Il volume snikket_data viene montato nella directory /snikket del container snikket_proxy
      - snikket_data:/snikket
      - acme_challenges:/var/www/html/.well-known/acme-challenge
    # La clausola restart: "unless-stopped" indica il comportamento di riavvio del servizio in caso di interruzione o arresto.
    # Nel caso di restart: "unless-stopped", Docker riavvierà automaticamente il container a meno che non venga esplicitamente arrestato dall'utente. Questa opzione è utile per garantire che il servizio torni in esecuzione automaticamente dopo eventuali problemi o riavvii del sistema. Tuttavia, se l'utente decide di arrestare manualmente il container, questa istruzione impedisce il riavvio automatico.
    restart: "unless-stopped"

  snikket_certs:
    container_name: snikket-certs
    image: snikket/snikket-cert-manager:beta
    env_file: snikket.conf
    volumes:
      - snikket_data:/snikket
      - acme_challenges:/var/www/.well-known/acme-challenge
    restart: "unless-stopped"

  snikket_portal:
    container_name: snikket-portal
    image: snikket/snikket-web-portal:beta
    network_mode: host
    env_file: snikket.conf
    restart: "unless-stopped"

  snikket_server:
    container_name: snikket
    image: snikket/snikket-server:beta
    network_mode: host
    volumes:
      - snikket_data:/snikket
    env_file: snikket.conf
    restart: "unless-stopped"

volumes:
  acme_challenges:
  snikket_data:
```

### cli dei volumi

```bash
 > docker volume help

Usage:	docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes
```

## Comandi docker compose (in riferimento ai volumi)

Docker Compose fornisce diversi comandi che aiutano a gestire in modo efficace l’applicazione e le sue risorse. Nel dettaglio questi comandi e il loro rapporto con i volumi:

- `docker compose up`: crea e avvia l’applicazione, compresi i servizi, le reti e i volumi. Se si definisce un volume denominato nel file docker-compose.yml prima che esista, questo comando lo creerà automaticamente.
- `docker compose down`: arresta e rimuove i servizi e le reti dell’applicazione. Per impostazione predefinita, non rimuove i volumi denominati. Per rimuovere i volumi denominati, usare il flag `--volumes` o `-v`.
- `docker compose ps`: elenca i container e il loro stato attuale, comprese le informazioni relative ai volumi.
- `docker compose config`: convalida e visualizza la configurazione effettiva generata dal file docker-compose.yml, comprese le definizioni dei volumi.

## Update Snikket

```bash
cd /etc/snikket
docker compose down
docker compose pull
docker compose up -d
```

Per maggiori dettagli: [https://snikket.org/service/help/setup/upgrading/](https://snikket.org/service/help/setup/upgrading/)

## Riferimenti

- [https://clarintuxmail.eu.org/articles/server3.html](https://clarintuxmail.eu.org/articles/server3.html)
- [https://snikket.org/service/quickstart/](https://snikket.org/service/quickstart/)
- [https://docs.lugbz.org/install-snikket.html](https://docs.lugbz.org/install-snikket.html)
- [https://wiki.xmpp-it.net/index.php/Installazione_di_un_server_Snikket](https://wiki.xmpp-it.net/index.php/Installazione_di_un_server_Snikket)
- [https://snikket.org/service/help/advanced/firewall/](https://snikket.org/service/help/advanced/firewall/)
- [https://snikket.org/](https://snikket.org/)
