ejabberd: Installation und Betrieb eines XMPP-Servers

1. XMPPejabberd

Gemessen an der rasanten technischen Entwicklung ist das Extensible Messaging and Presence Protocol (XMPP) ein Urgestein, dessen Anfänge bis zum Jahr 1998 zurückreichen. XMPP ist ein offener Standard eines (Kommunikations-)Protokolles, das auf dem XML-Standard basiert und den Austausch von Informationen bzw. Daten ermöglicht.

Im vorliegenden Beitrag beschreibe ich die Installation und Inbetriebnahme eines ejabberd-XMPP-Servers, der folgende Optionen unterstützt:

  • Messaging: Übermittlung von Nachrichten zu einem Chatpartner bzw. Kontakt, wie wir es bspw. von WhatsApp kennen
  • Multi-User-Chat (MUC): Eine Art Konferenzraum, dem mehrere Benutzer beitreten können, um untereinander Nachrichten auszutauschen
  • Dateitransfer: Austausch von Dateien

Damit sind die grundlegenden Anforderungen erfüllt, die wir aus der Messenger-Welt kennen: Wir können mit (mehreren) Kontakten chatten und ebenfalls Dateien austauschen. Das XMPP-Protokoll ist allerdings so vielseitig, dass wir noch weitere Funktionen darüber abbilden könnten – diese stehen allerdings nicht im Fokus des vorliegenden Beitrages.

2. ejabberd

Ejabberd zählt zu den weitverbreitesten XMPP-Servern. Die Software steht unter der GPL, eine Lizenz für freie Software und baut auf der Programmiersprache Erlang auf. Unter anderem ist ejabberd für Windows, macOS, BSD-Derivate und GNU/Linux verfügbar.

Aufgrund seiner Zuverlässigkeit, Skalierbarkeit und Stabilität eignet sich ejabberd sowohl für den privaten Bereich als auch für das professionelle Umfeld. Unter anderem setzen mailbox.org oder die Piratenpartei auf ejabberd.

Unterstütze den Blog mit einem Dauerauftrag!

Unabhängig. Kritisch. Informativ. Praxisnah. Verständlich.

Die Arbeit von kuketz-blog.de wird vollständig durch Spenden unserer Leserschaft finanziert. Sei Teil unserer Community und unterstütze unsere Arbeit mit einer Spende.

Mitmachen ➡

2.1 Dokumentation

Für die Installation und den Betrieb einer Server-Software ist eine ausführliche und vollständige Dokumentation äußerst hilfreich. Die Dokumentation von ejabberd ist in Ordnung, allerdings könnte insbesondere die Beschreibung der Modul-Konfiguration etwas ausführlicher ausfallen. Insgesamt vermisse ich eine Art »Best practice« oder Beispielkonfiguration, die einen sicheren und datenschutzfreundlichen Betrieb ermöglicht. Der vorliegende Beitrag versucht diese Lücke zu schließen.

2.2 Hardware & Systemumgebung

Die Hardwareanforderungen sind abhängig von unterschiedlichen Faktoren, wie die Anzahl der anvisierten Nutzer und gleichzeitigen Verbindungen, die der Server(-verbund) verarbeiten soll. Generell benötigt ejabberd eher wenig CPU-Leistung. Der Hauptspeicher (RAM) sollte je nach Einsatzzweck dafür etwas großzügiger ausgelegt sein. Für den Betrieb einer ejabberd-Instanz mit 10.000 Nutzern gelten grob folgende Anforderungen:

  • 2 dedizierte Kerne
  • ab 4 GB RAM
  • Festplattenkapazität ab 40 GB (mit Option auf Erweiterung)
  • 1 GBit/s Netzwerkanbindung
  • feste IP-Adresse

Einen solchen Root-Server könnt ihr bereits ab 6-7 € pro Monat bei einem Hosting-Anbieter bekommen.

2.3 Beispielkonfiguration

Der dauerhafte Betrieb eines XMPP-Servers auf Basis von ejabberd erfordert ein hohes Maß an Verantwortung vom Betreiber. Grundlegende Kenntnisse in der Härtung eines Server-Systems sowie Notfall- bzw. Backupstrategien sollten zu eurem Repertoire gehören, bevor ihr es in Erwägung zieht, einen ejabberd-Server in den Föderationsverbund zu integrieren.

Die vorliegende Konfiguration dient als Beispiel, der euch den Einstieg in den sicheren und datenschutzfreundlichen Betrieb eines ejabberd-Servers erleichtern soll. Folgende Besonderheiten gelten für diese Konfiguration:

  • Es werden ausschließlich XMPP-Clients wie Conversations oder Gajim unterstützt. Web-Clients (basierend auf JavaScript) bzw. XMPP-over-HTTP werden nicht unterstützt.
  • Eine Registrierung von einem neuen Konto per Weboberfläche ist nicht vorgesehen. Neue Accounts können einfach per In-Band-Registration (also direkt über den XMPP-Client) eröffnet werden.
  • Grundsätzlich ist es jedem gestattet ein XMPP-Konto auf dem Server anzulegen.
  • Aus- und eingehende Verbindungen zu bzw. von anderen XMPP-Servern sind ausschließlich über einen TLS-verschlüsselten Kanal vorgesehen. Kann dieser aus irgendwelchen Gründen (kein gültiges Zertifikat, keine unterstützten Cipher-Suiten) nicht aufgebaut werden, wird die Verbindung abgebrochen.
  • Die Auswahl der TLS-Cipher-Suiten ist sehr strikt. Unter Umständen kann dies zu Problemen bei der Föderation mit anderen Servern führen, die bspw. (noch) keine aktuellen OpenSSL-Bibliotheken verwenden.

Bei Bedarf könnt ihr die genannten Punkte natürlich jederzeit an eure Bedürfnisse anpassen. Mein Fokus lag eher auf einer sicheren und datenschutzfreundlichen Konfiguration, die insbesondere den XMPP Compliance Test besteht.

XMPP-Compliance

Hinweis

An dieser Stelle möchte ich mich bei Holger Weiß bedanken, der mir mit Rat und Tat bei der Inbetriebnahme eines ejabberd-Testservers zur Seite stand. Holger ist unter anderem als freier Entwickler bei ejabberd tätig.

2.4 Installation: Debian GNU/Linux

Als Systemgrundlage für ejabberd nutze ich für die vorliegende Anleitung ein Debian GNU/Linux (Stretch) in der Minimalinstallation.

In der aktuellen stabilen Version von Debian basiert ejabberd auf der Version 16.09-4. In Debian gilt: Die in der jeweils stabilen Version enthaltene Software wird grundsätzlich nicht auf neuere Versionen aktualisiert – nur Sicherheitsaktualisierungen aus neueren Versionen werden vom Debian-Security-Team in den Stable-Zweig portiert. Daher greifen wir auf die Debian-Backports zurück, um eine aktuelle Version von ejabberd zu bekommen. Es handelt sich bei den Backports um Rückportierungen von Paketen aus (hauptsächlich) Testing, die gegen die Stable Bibliotheken gebaut sind.

Zunächst fügen wir der sources.list die Backports für Debian (Stretch) hinzu:

nano /etc/apt/sources.list
# Stretch Backports
deb http://ftp.debian.org/debian stretch-backports main

Anschließend aktualisieren wir die Paketquellen und installieren das ejabberd-Backport-Paket mit der Version 18.06:

apt-get update
apt-get install -t stretch-backports ejabberd

Zur Darstellung der Captcha-Grafiken (später dazu mehr) benötigen wir noch Imagemagick:

apt-get install imagemagick gsfonts --no-install-recommends

3. Let’s Encrypt

Let’s Encrypt ist ein Vorzeigeprojekt, dem es gelungen ist, den komplexen Vorgang der Erstellung, Validierung, Signierung und Erneuerung von X.509-Zertifikaten zu automatisieren und diese Dienstleistung kostenlos anzubieten. Hunderttausende von kommerziellen und nichtkommerziellen Webseiten, Projekten etc. setzen auf Let’s-Encrypt-Zertifikate, die den Datenverkehr via TLS vor dem Abhören und der Manipulation schützen.

Für die Beantragung der benötigten Let’s-Encrypt-Zertifikate nutzen wir den acme.sh-Client – ein Shell-Skript für Unix- / Linux-Systeme. Es unterstützt ebenfalls den ACME v2 Standard. Alternativ dürft ihr gerne einen anderen mit ACME v2 kompatiblen Client nutzen.

3.1 Benötigte Pakete installieren

Auf dem ejabberd-Server kommt kein Webserver (nginx, Apache etc.) zum Einsatz, über den wir den Let’s-Encrypt-Prozess abbilden können. Daher nutzen wir den Standalone-Modus, der einen Webserver bereitstellt, um die Domainvalidierung durchzuführen – dafür sind die Programme bzw. Pakete socat und curl erforderlich:

apt-get install socat curl

3.2 Download & Installation von acme.sh

Die Installation von acme.sh ist mit einem Befehl erledigt:

wget -O - https://get.acme.sh | sh

Bei Bedarf lässt sich die Installation einfach aktualisieren:

bash /root/.acme.sh/acme.sh --upgrade

3.3 Zertifikate beantragen

Anschließend müssen wir für die folgenden Domains bzw. Subdomains Let’s-Encrypt-Zertifikate beantragen. Insgesamt sind es fünf Stück:

  • kuketz-lab.de: Ein Zertifikat für unsere Hauptdomain
  • conference.kuketz-lab.de: Das Modul mod_muc nutzt standardmäßig die virtuelle Subdomain conference.@HOST@
  • upload.kuketz-lab.de: Das Modul mod_http_upload nutzt standardmäßig die virtuelle Subdomain upload.@HOST@
  • pubsub.kuketz-lab.de: Das Modul mod_pubsub nutzt standardmäßig die virtuelle Subdomain pubsub.@HOST@
  • proxy.kuketz-lab.de: Das Modul mod_proxy65 nutzt standardmäßig die virtuelle Subdomain proxy.@HOST@

Hinweis

Selbstverständlich solltet ihr den Domainnamen »kuketz-lab.de« mit eurem ersetzen.

Für den Praxisbetrieb nutzen wir RSA-basierte Zertifikate. Aktuell unterstützt ejabberd den Parallelbetrieb von RSA- und ECDSA-Zertifikaten leider noch nicht. Wir beantragen alle Domains bzw. Subdomains in einem Rutsch:

bash /root/.acme.sh/acme.sh --issue -d kuketz-lab.de -d conference.kuketz-lab.de -d upload.kuketz-lab.de -d pubsub.kuketz-lab.de -d proxy.kuketz-lab.de --keylength 4096 --standalone

Falls jemand ECDSA-Zertifikate bevorzugt, kann er sich diese ebenfalls ausstellen lassen. Allerdings unterstützen einige ältere OpenSSL-Bibliotheken ECDSA-Zertifikate noch nicht, weshalb diese für den Föderationsbetrieb aktuell noch nicht empfehlenswert sind:

bash /root/.acme.sh/acme.sh --issue -d kuketz-lab.de -d conference.kuketz-lab.de -d upload.kuketz-lab.de -d pubsub.kuketz-lab.de -d proxy.kuketz-lab.de --keylength ec-384 --standalone

3.4 ejabberd: Zertifikate ausrollen

Die Let’s-Encrypt-Zertifikate sind nun beglaubigt und können in ejabberd eingebunden werden. Dazu erstellen wir zunächst einen Unterordner, in dem wir die Zertifikatsdateien ablegen:

mkdir /etc/ejabberd/certs

cp /root/.acme.sh/kuketz-lab.de/fullchain.cer /etc/ejabberd/certs/kuketz-lab.pem
cp /root/.acme.sh/kuketz-lab.de/kuketz-lab.de.key /etc/ejabberd/certs/kuketz-lab.key

Anschließend schränken wir noch die Berechtigungen auf den Ordner und die darin befindlichen Zertifikatsdateien ein:

chown ejabberd:ejabberd /etc/ejabberd/certs/
chown ejabberd:ejabberd /etc/ejabberd/certs/*
chmod 600 /etc/ejabberd/certs/*

3.5 Diffie-Hellman-Parameter (optional)

Die Generierung von (neuen) Diffie-Hellman-Parametern ist optional. Dies wird benötigt, falls ihr TLS-Cipher-Suiten verwenden wollt, die auf dem DH-Schlüsselaustausch basieren:

openssl dhparam -out /etc/ejabberd/dh4096.pem 4096

4. DNS-Konfiguration

Über Service-Records (SRV) hinterlegen wir im Domain-Name-System (DNS), auf welchem Port bestimmte Dienste von unserem ejabberd für Clients und Server erreichbar sind. Im XMPP-Wiki werden einige Beispiele aufgezeigt. Für den Praxisbetrieb sind folgende SRVs sinnvoll:

  • Port 5222: Für Clients, die sich mit unserem Server verbinden wollen
    • Host: _xmpp-client._tcp.kuketz-lab.de.
    • Type: SRV
    • Destination: 5 0 5222 kuketz-lab.de.
  • Port 443: Für Clients, die sich direkt via TLS mit unserem Server verbinden wollen
    • Host: _xmpps-client._tcp.kuketz-lab.de.
    • Type: SRV
    • Destination: 4 0 443 kuketz-lab.de.
  • Port 5269: Für XMPP-Server, die sich mit unserem Server verbinden wollen
    • Host: _xmpp-server._tcp.kuketz-lab.de.
    • Type: SRV
    • Destination: 5 0 5269 kuketz-lab.de.
  • Port 5270: Für XMPP-Server, die sich direkt via TLS mit unserem Server verbinden wollen
    • Host: _xmpps-server._tcp.kuketz-lab.de.
    • Type: SRV
    • Destination: 4 0 5270 kuketz-lab.de.

Konferenzräume bzw. MUCs sind meist unter der Subdomain »conference.DOMAIN« erreichbar. Über einen entsprechenden DNS-Eintrag (CNAME) machen wir diese Information bekannt:

  • Host: conference
  • Type: CNAME
  • Destination: kuketz-lab.de

Auf einem Root-Server beim Hosting-Anbieter netcup würde die DNS-Konfiguration dann folgendermaßen aussehen:

DNS-Records

5. ejabberd-Konfiguration

Die nachfolgenden Anpassungen sind eine Abweichung von der Standardkonfiguration, die mit dem Debian-Package von ejabberd (18.09-1~bpo9+1) mitgeliefert wird. Alle Anpassungen sind kurz erklärt. Die komplette Konfiguration (ohne Kommentare) stelle ich unter der Ziffer 5.10 zur Verfügung. Bei der Anpassung lag mein Fokus auf einer sicheren und datenschutzfreundlichen Konfiguration – bei Bedarf solltet ihr die Vorschläge prüfen und in euer Setup überführen.

5.1 Logging

Das Log-Level legt die Ausführlichkeit fest, mit dem ejabberd Protokolldateien erzeugt. Wird der Parameter loglevel auf einen Wert von 3 eingestellt, werden nur Fehler und Warnungen in die Log-Datei geschrieben. Anmeldevorgänge von Clients oder das Versenden von Nachrichten werden nicht erfasst.

Wenn wir den Parameter hide_sensitive_log_data zusätzlich ergänzen, werden keine IP-Adressen oder sonstige sensitive Daten in den Log-Dateien aufgezeichnet.

## loglevel: Verbosity of log files generated by ejabberd.
## 0: No ejabberd log at all (not recommended)
## 1: Critical
## 2: Error
## 3: Warning
## 4: Info
## 5: Debug
##
loglevel: 3
hide_sensitive_log_data: true

5.2 Hostnamen [Served Hostnames]

Angabe des Host- bzw. Domainnamens, über den unsere ejabberd-Instanz erreichbar ist. Ein ejabberd-Server kann übrigens mehrere Domains bedienen.

## hosts: Domains served by ejabberd.
##
hosts:
  - "kuketz-lab.de"

5.3 Zertifikate [Certificates]

Die beantragten Let’s-Encrypt-Zertifikate haben wir bereits im Unterordner /etc/ejabberd/certs/ abgelegt. Diese müssen wir nun ejabberd bekannt machen. Wie bereits erwähnt nutzen wir für den Praxisbetrieb RSA-basierte Zertifikate, da ein Parallelbetrieb mit ECDSA-Zertifikaten aktuell noch nicht möglich ist.

## List all available PEM files containing certificates for your domains,
## chains of certificates or certificate keys. Full chains will be built
## automatically by ejabberd.
##
certfiles:
  - "/etc/ejabberd/certs/kuketz-lab.pem"
  - "/etc/ejabberd/certs/kuketz-lab.key"

5.4 TLS [TLS configuration]

Bei der TLS-Konfiguration müssen wir stets zwischen Abwärtskompatibilität und Sicherheit abwägen. Mit der Ergänzung des Parameters no_tlsv1_1 schließen wir alle TLS-Cipher-Suiten aus, die auf TLS 1.1 (oder niedriger) basieren und in bestimmten Kombinationen als anfällig bzw. schwach gelten. Wir setzen also ausschließlich auf TLS 1.2 oder höher. Doch damit nicht genug, wir schränken die von unserer ejabberd-Instanz angebotenen Cipher-Suiten über den Parameter TLS_CIPHERS auf eine Handvoll ein. Das mag auf den ersten Blick ein drastischer Schritt sein, da wir dadurch die Föderationskompatibilität einschränken – denn können sich zwei XMPP-Server beim TLS-Verbindungsaufbau nicht auf eine Cipher-Suite einigen, wird die Verbindung (im Normalfall) abgebrochen.

Ähnlich wie bei einem E-Mail-Service stehen wir also vor dem Dilemma: Sicherheit vs. Abwärtskompatibilität. Unter Umständen kann es also erforderlich sein, dass ihr weitere Cipher-Suiten ergänzt, um bestimmten XMPP-Servern oder Clients den TLS-Verbindungsaufbau zu ermöglichen. Das Mozilla-Wiki bietet eine Übersicht von unterschiedlichen TLS-Cipher-Konfigurationen an.

## Note that the following configuration is the default
## configuration of the TLS driver, so you don't need to
## uncomment it.
##
define_macro:
  'TLS_CIPHERS': "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
  'TLS_OPTIONS':
    - "no_sslv3"
    - "no_tlsv1" 
          -   "no_tlsv1_1"
    - "cipher_server_preference"
    - "no_compression"
    ## 'DH_FILE': "/etc/ejabberd/dh4096.pem" # generated with: openssl dhparam -out dhparams.pem 2048

Über CryptCheck (Auswahl XMPP) lassen sich alle Cipher-Suiten anzeigen, die euer ejabberd-Server anbietet. Dabei fällt der 256-Bit-Schlüssel auf, der zum Schlüsselaustausch verwendet wird und auf Elliptic-Curve-Cryptography (ECC) basiert. Aktuell lässt ejabberd leider keine Anpassung der ECC-Schlüsselgröße zu und wir müssen uns mit 256-Bit begnügen. Generell wäre hier mindestens eine Schlüssellänge von 384 oder sogar 521-Bit empfehlenswert.

TLS-Cipher

Über den folgenden Befehl könnt ihr eine TLS-verschlüsselte Verbindung zu eurem ejabberd-Server initiieren und die Let’s-Encrpyt-Zertifikate prüfen:

openssl s_client -starttls xmpp-server -xmpphost conference.kuketz-lab.de -connect kuketz-lab.de:5269 | openssl x509 -noout -text

5.5 Dienste [Listening Ports]

Um mit der Außenwelt zu kommunizieren bietet euer ejabberd-Server diverse Dienste bzw. Ports an, über die sich Clients als auch (XMPP-)Server verbinden und kommunizieren. Wir ergänzen die Standardkonfiguration um weitere Ports, die anschließend einen direkten Verbindungsaufbau via TLS (sozusagen TLS-on-Connect) ermöglichen, ohne zuvor den »Umweg« über STARTTLS nehmen zu müssen.

Der Port 5222 dient in der XMPP-Welt als Standard für Clients, die sich mit einem XMPP-Server verbinden möchten. Möchte sich ein Client mit unserem ejabberd-Server verbinden setzen wir STARTTLS voraus.

## listen: The ports ejabberd will listen on, which service each is handled
## by and what options to start it with.
##
-
  port: 5222
  ip: "::"
  module: ejabberd_c2s
  starttls_required: true
  protocol_options: 'TLS_OPTIONS'
  max_stanza_size: 65536
  shaper: c2s_shaper
  access: c2s

Den Port 5223 ergänzen wir in der Konfiguration und ermöglichen Clients damit den direkten TLS-Verbindungsaufbau.

-
  port: 5223
  ip: "::"
  module: ejabberd_c2s
  tls: true
  max_stanza_size: 65536
  shaper: c2s_shaper
  access: c2s

Der Port 5296 dient in der XMPP-Welt als Standard für alle Server, die sich mit einem anderen XMPP-Server verbinden möchten. Über den Parameter s2s_use_starttls: required (hier nicht sichtbar) erzwingen wir die Verwendung von STARTTLS.

-
  port: 5269
  ip: "::"
  module: ejabberd_s2s_in

Auch für die XMPP-Server ergänzen wir einen Port, der dann anschließend für den direkten TLS-Verbindungsaufbau genutzt werden kann.

-
  port: 5270
  ip: "::"
  module: ejabberd_s2s_in
  tls: true

Den Port 5280 entfernen wir aus der Standardkonfiguration und ergänzen dafür den Port 5443, worüber im Betrieb der Versand von Dateien geregelt wird.

-
  port: 5443
  ip: "::"
  module: ejabberd_http
  request_handlers:
    "/upload": mod_http_upload
  tls: true
  ciphers: 'TLS_CIPHERS'
  protocol_options: 'TLS_OPTIONS'

Damit sich ein Client gegenüber dem ejabberd-Server authentifizieren kann, werden ihm diverse SASL-Methoden angeboten. Zwei dieser Methoden schließen wir aus Sicherheitsgründen aus.

disable_sasl_mechanisms:
  - "digest-md5"
  - "x-oauth2"

5.6 Zugriffskontrolle [ACL]

Für unseren ejabberd-Server legen wir ein Administrationskonto an:

ejabberdctl register admin kuketz-lab.de [Passwort]

Diesem Konto gewähren wir anschließend über die Konfiguration Administrationsrechte.

acl:
  ##
  ## The 'admin' ACL grants administrative privileges to XMPP accounts.
  ## You can put here as many accounts as you want.
  ##
  admin:
     user:
       - "admin": "kuketz-lab.de"

5.7 Shaper-Rules

Mit den Shaper-Rules lassen sich unter anderem die maximale Anzahl an gleichzeitigen Verbindungen von einem Nutzer festlegen. Wir erhöhen die maximale Anzahl an Offline-Nachrichten, die der Server für einen Benutzer vorhält, bis dieser wieder online kommt und diese abholt.

max_user_offline_messages:
  - 5000: admin
  - 500

5.8 Captchas [Captcha]

Um die Registrierung von Accounts zu vermeiden, die anschließend von Bots zum Versand von Spam missbraucht werden, aktivieren wir die Captcha-Abfrage bzw. den Pfad zum Skript für die Generierung der Captchas. Dank dem XEP-0158 betten die meisten XMPP-Clients die Captcha-Abfrage direkt bei der Registrierung ein. Anschließend limitieren wir über den Parameter captcha_limit die Auslieferung von Captchas auf 5 pro Minute, um einen Denial-of-Service (DoS) möglichst zu vermeiden.

##
## Full path to a script that generates the image.
##
captcha_cmd: "/usr/share/ejabberd/captcha.sh"
captcha_limit: 5

5.9 Module [Modules]

Ejabberd basiert auf einer modularen Architektur, die es über Module erlaubt, die Funktionalität beliebig zu erweitern. In der Standardkonfiguration sind einige dieser Module bereits vorkonfiguriert bzw. werden (unnötigerweise) eingebunden. Einen Teil dieser Modul werden wir im Folgenden anpassen bzw. deaktivieren.

Damit Spam oder Missbrauch gemeldet werden kann, solltet ihr Kontaktinformationen über das Modul mod_disco in der Konfiguration hinterlegen:

mod_disco:
  server_info:
    -
      modules: all
      name: "abuse-addresses"
      urls:
        - "mailto:admin@kuketz-lab.de"
    -
      modules: all
      name: "support-addresses"
      urls:
        - "mailto:admin@kuketz-lab.de"
    -
      modules: all
      name: "admin-addresses"
      urls:
        - "mailto:admin@kuketz-lab.de"

Da wir XMPP-over-HTTP nicht anbieten, können wir das Modul mod_bosh deaktivieren:

## mod_bosh: {}

Für Debugging-Zwecke mag das Modul mod_echo sinnvoll sein – für den Praxisbetrieb eher nicht, weshalb wir es deaktivieren:

## mod_echo: {}

Das Modul mod_http_upload ermöglicht den Dateitransfer zwischen verschiedenen Teilnehmern per HTTP-Upload. Über den Parameter secret_length legen wir die Länge des Random-Strings fest, die an hochgeladene Dateien angehängt wird. Dadurch erschweren wir das »Erraten« von Dateinamen (bspw. per Brute-Force):

mod_http_upload:
  put_url: "https://@HOST@:5443/upload"
    docroot: "@HOME@/upload"
    secret_length: 40

Über das Modul mod_http_upload_quota lässt sich unter anderem die Speicherdauer von hochgeladenen Dateien festlegen. Mit dem Parameter max_days legen wir die Dauer auf 30 Tage fest:

mod_http_upload_quota:
  max_days: 30

Das Modul mod_last protokolliert den Zeitpunkt von An- und Abmeldevorgängen der Clients. Im Sinne einer datenschutzfreundlichen Konfiguration deaktivieren wir das Modul:

## mod_last {}

Die Nachrichtenarchivierung (MAM) lässt sich über das Modul mod_mam konfigurieren. Wir aktivieren MAM standardmäßig, überlassen es mit dem Parameter request_activates_archiving allerdings dem Client bzw. dem Nutzer, ob er Nachrichten archivieren möchte:

mod_mam: 
  assume_mam_usage: true
    default: always
    request_activates_archiving: true

Die Konferenzräume für den Austausch mit mehreren XMPP-Nutzern ist eine Kernkomponente von XMPP. Über das Modul mod_muc bzw. den Parameter default_room_options nehmen wir Anpassungen vor, mit welcher Anfangskonfiguration neu erstellte MUCs starten:

mod_muc:
    access:
      - allow
    access_admin:
      - allow: admin
    access_create: muc_create
    access_persistent: muc_create
    default_room_options:
              mam: true
              persistent: true
              public: false
              public_list: false

Das XEP-0065 definiert einen Bytestream-Proxy, über den sich bei Bedarf große Binärdaten austauschen lassen – vereinfacht: Dateitransfers. Über den Parameter max_connections begrenzen wir die Anzahl auf 5 (aktive) Verbindungen pro Dateitransfer:

mod_proxy65:
  max_connections: 5

Das Modul mod_register ermöglicht XMPP-Clients die direkte Erstellung eines Kontos (In-Band-Registration) auf eurem ejabberd-Server. Aus Sicherheitsgründen aktivieren wir den Parameter captcha_protected – anschließend muss ein Nutzer bei der Registrierung zunächst ein Captcha lösen. Über den Parameter password_strength erzwingen wir eine Passwort-Entropie von mindestens 64 Bit – die Verwendung von »einfachen« Passwörtern ist damit ausgeschlossen:

mod_register:
  captcha_protected: true
    password_strength: 64
    ip_access: all
    access: register

Über das Modul mod_roster bzw. den Parameter versioning (XEP-0237) können wir vermeiden, dass beim Login der komplette Roster (Kontaktliste eines Nutzers) vollständig wieder heruntergeladen wird. Der Roster wird nur dann neu geladen, wenn sich seit der letzten Online-Session etwas geändert hat:

mod_roster:
  versioning: true

Auf Anfrage gibt der ejabberd-Server die verwendete Betriebssystem-Version heraus. Das können wir mit einer Anpassung von mod_version verhindern:

mod_version: 
  show_os: false

Das Modul mod_http_api erlaubt die Steuerung bzw. Administration von ejabberd via HTTP-Befehle. Aus Sicherheitsgründen deaktivieren wir dieses Modul. Unser ejabberd-Server lässt sich ausschließlich über die Kommandozeile via ejabberdctl administrieren.

## mod_http_api: {}

5.10 Vollständige ejabberd-Konfiguration

Anbei die vollständige Konfiguration, bereinigt von den Kommentaren:

###
###'              ejabberd configuration file
###
###

### The parameters used in this configuration file are explained in more detail
### in the ejabberd Installation and Operation Guide.
### Please consult the Guide in case of doubts, it is included with
### your copy of ejabberd, and is also available online at
### https://docs.ejabberd.im/
---
###.  =======
###'  LOGGING

loglevel: 3
hide_sensitive_log_data: true

log_rotate_size: 0
log_rotate_date: ""

log_rate_limit: 100

###.  ================
###'  SERVED HOSTNAMES

hosts:
  - "kuketz-lab.de"

###.  ============
###'  Certificates

certfiles:
  - "/etc/ejabberd/certs/kuketz-lab.pem"
  - "/etc/ejabberd/certs/kuketz-lab.key"

###.  =================
###'  TLS configuration

define_macro:
  'TLS_CIPHERS': "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
  'TLS_OPTIONS':
    - "no_sslv3"
    - "no_tlsv1"
    - "no_tlsv1_1"
    - "cipher_server_preference"
    - "no_compression"

c2s_ciphers: 'TLS_CIPHERS'
s2s_ciphers: 'TLS_CIPHERS'
c2s_protocol_options: 'TLS_OPTIONS'
s2s_protocol_options: 'TLS_OPTIONS'

###.  ===============
###'  LISTENING PORTS

listen:
  -
    port: 5222
    ip: "::"
    module: ejabberd_c2s
    starttls_required: true
    max_stanza_size: 65536
    shaper: c2s_shaper
    access: c2s
  -
    port: 5223
    ip: "::"
    module: ejabberd_c2s
    tls: true
    max_stanza_size: 65536
    shaper: c2s_shaper
    access: c2s
  -
    port: 5269
    ip: "::"
    module: ejabberd_s2s_in
  -
    port: 5270
    ip: "::"
    module: ejabberd_s2s_in
    tls: true
  -
    port: 5443
    ip: "::"
    module: ejabberd_http
    request_handlers:
      "/upload": mod_http_upload
    tls: true
    ciphers: 'TLS_CIPHERS'
    protocol_options: 'TLS_OPTIONS'

disable_sasl_mechanisms:
  - "digest-md5"
  - "x-oauth2"

###.  ==================
###'  S2S GLOBAL OPTIONS

s2s_use_starttls: required

###.  ==============
###'  AUTHENTICATION

auth_method: internal
auth_password_format: scram

###.  ==============
###'  DATABASE SETUP

###.  ===============
###'  TRAFFIC SHAPERS

shaper:
  normal: 1000
  fast: 50000

max_fsm_queue: 10000

###.   ====================
###'   ACCESS CONTROL LISTS

acl:
  admin:
     user:
       - "admin": "kuketz-lab.de"

  local:
    user_regexp: ""

  loopback:
    ip:
      - "127.0.0.0/8"
      - "::1/128"
      - "::FFFF:127.0.0.1/128"

###.  ============
###'  SHAPER RULES

shaper_rules:
  max_user_sessions: 10
  max_user_offline_messages:
    - 5000: admin
    - 500
  c2s_shaper:
    - none: admin
    - normal
  s2s_shaper: fast

###.  ============
###'  ACCESS RULES

access_rules:
  local:
    - allow: local
  c2s:
    - deny: blocked
    - allow
  announce:
    - allow: admin
  configure:
    - allow: admin
  muc_create:
    - allow: local
  pubsub_createnode:
    - allow: local
  register:
    - allow
  trusted_network:
    - allow: local

## ===============
## API PERMISSIONS
## ===============

api_permissions:
  "console commands":
    from:
      - ejabberd_ctl
    who: all
    what: "*"
  "admin access":
    who:
      - access:
        - allow:
          - acl: loopback
          - acl: admin
      - oauth:
        - scope: "ejabberd:admin"
        - access:
          - allow:
            - acl: loopback
            - acl: admin
    what:
      - "*"
      - "!stop"
      - "!start"
  "public commands":
    who:
      - ip: "127.0.0.1/8"
    what:
      - "status"
      - "connected_users_number"

###.  ================
###'  DEFAULT LANGUAGE

language: "en"

###.  =======
###'  CAPTCHA

captcha_cmd: "/usr/share/ejabberd/captcha.sh"
captcha_limit: 5

###.  ====
###'  ACME

acme:
  contact: "mailto:example-admin@example.com"
  ca_url: "https://acme-v01.api.letsencrypt.org"

###.  =======
###'  MODULES

modules:
  mod_adhoc: {}
  mod_admin_extra: {}
  mod_announce:   
    access: announce
  mod_block_strangers: {}
  mod_blocking: {}   
  mod_caps: {}
  mod_carboncopy: {}
  mod_client_state: {}
  mod_configure: {}   
  ## mod_delegation: {}  
  mod_disco:
    server_info:
      -
        modules: all
        name: "abuse-addresses"
        urls:
          - "mailto:admin@kuketz-lab.de"
      -
        modules: all
        name: "support-addresses"
        urls:
          - "mailto:admin@kuketz-lab.de"
      -
         modules: all
         name: "admin-addresses"
         urls:
           - "mailto:admin@kuketz-lab.de"
  ## mod_echo: {}
  ## mod_bosh: {}
  ## mod_http_fileserver:
  mod_http_upload:
    put_url: "https://@HOST@:5443/upload"
    docroot: "@HOME@/upload"
    secret_length: 40
  mod_http_upload_quota:
    max_days: 30
  ## mod_last: {}
  mod_mam:
    assume_mam_usage: true
    default: always
    request_activates_archiving: true
  mod_muc:
    access:
      - allow
    access_admin:
      - allow: admin
    access_create: muc_create
    access_persistent: muc_create
    default_room_options:
      mam: true
      persistent: true
      public: false
      public_list: false
  mod_muc_admin: {}
  ## mod_muc_log: {}
  ## mod_multicast: {}
  mod_offline:
    access_max_user_messages: max_user_offline_messages
  mod_ping: {}
  mod_pres_counter:
    count: 16
    interval: 60
  mod_privacy: {}
  mod_private: {}
  mod_proxy65:
    max_connections: 5
  mod_pubsub:
    access_createnode: pubsub_createnode
    ignore_pep_from_offline: true
    last_item_cache: false
    plugins:
      - "flat"
      - "pep"
    force_node_config:
      "eu.siacs.conversations.axolotl.*":
        access_model: open
      "storage:bookmarks":
        access_model: whitelist
  mod_push: {}
  mod_push_keepalive: {}
  mod_register:
    captcha_protected: true
    password_strength: 64
    ip_access: all
    access: register
  mod_roster:
    versioning: true
  mod_shared_roster: {}
  mod_sic: {}
  mod_stats: {}
  mod_time: {}
  mod_vcard:
    search: false
  mod_vcard_xupdate: {}
  mod_avatar: {}
  mod_version:
    show_os: false
  mod_stream_mgmt:
    resend_on_timeout: if_offline
  mod_s2s_dialback: {}
  ## mod_http_api: {}
  mod_fail2ban: {}

allow_contrib_modules: true

6. Weitere Anpassungen

6.1 XMPP over TLS: iptables

Damit wir beim XMPP Compliance Tester ein grünes Häkchen beim Prüfpunkt »XEP-0368: SRV records for XMPP over TLS« erreichen, genügt es nicht, die entsprechenden SRV-Einträge im DNS zu hinterlegen. Wir müssen Client-Anfragen auf den Port 443 (HTTPS) auch entsprechend an den Port 5223 weiterleiten, auf dem ejabberd regulär lauscht. Wir können uns hierbei mit einer iptables-NAT-Regel behelfen. Anschließend können auch Clients, die von restriktiven (Unternehmens-)Firewalls abgeschottet werden, den ejabberd-Server via Port 443 erreichen – nicht jeder Administrator wird damit glücklich sein.

Unter Debian legen wir dafür ein Systemd-Service-Unit an:

nano /etc/systemd/system/xmpp-port-redirection.service

Das Interface -i ens3 müsst ihr an eure Umgebung anpassen:

[Unit]
Description=Port redirection rules for XMPP
After=network.target

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/sbin/iptables -t nat -A PREROUTING -i ens3 -p tcp --dport 443 -j REDIRECT --to-port 5223
ExecStop=/sbin/iptables -t nat -D PREROUTING -i ens3 -p tcp --dport 443 -j REDIRECT --to-port 5223

Anschließend aktivieren wir das Service-Unit:

systemctl enable xmpp-port-redirection.service

Nach einem Neustart des Servers können wir kontrollieren, ob die iptabes-Regel erfolgreich angewendet wurde:

iptables -t nat -L

Ausgabe:

iptables

Hinweis

Idealerweise kombiniert ihr die NAT-Regel mit eurer iptables-Konfiguration.

6.2 Erlang-Ports: Nur auf Localhost

Der Erlang Port Mapper Daemon (epmd) ist ein Nameserver, den ejabberd benötigt, um ejabberdctl zu verwenden und kommt ebenfalls beim Clustering von mehreren ejabberd-Servern zum Einsatz. Da wir allerdings kein Cluster betreiben, sollte der epmd aus Sicherheitsgründen nur auf der lokalen Netzwerkschnittstelle lauschen und seine Dienste nicht der Außenwelt anbieten. Dazu legen wir einen Systemd-Socket an:

mkdir /etc/systemd/system/epmd.socket.d
nano /etc/systemd/system/epmd.socket.d/listen-on-localhost.conf

Inhalt der Konfigurationsdatei:

[Socket]
ListenStream=
ListenStream=127.0.0.1:4369

Aber nicht nur der epmd ist standardmäßig für entfernte Systeme erreichbar, sondern auch die Erlang-VM. Auch dies werden wir über eine entsprechende Konfigurationsanpassung ändern:

nano /etc/ejabberd/ejabberdctl.cfg

Dort entfernen wir den Kommentar vor der folgenden Zeile:

INET_DIST_INTERFACE=127.0.0.1

Anschließend starten wir den epmd-Service nochmal durch:

systemctl daemon-reload
systemctl stop epmd.service
systemctl start epmd.service

Und auch der ejabberd-Service muss danach neu gestartet werden:

/etc/init.d/ejabberd start

Anschließend kontrollieren wir alle Ports / Dienste, die unser Server anbietet:

netstat -tlpen

Ports

Das sieht prima aus. Alle ejabberd-Dienste, die für einen XMPP-Betrieb notwendig sind, können von außen erreicht werden. Die Erlang-VM (Port 42087 – wechselt) und der epmd (Port 4369) sind hingegen nur für lokale Programme / Dienste erreichbar.

6.3 Datenbankanbindung

In der vorliegenden Konfiguration / Beitrag ist die Anbindung an eine Datenbank nicht beschrieben. Insbesondere wenn ihr MAM (XEP-0313) bzw. die Nachrichtenarchivierung aktiviert, wird die ejabberd-interne Mnesia-Datenbank schnell an ihre Grenzen stoßen. Ejabberd bietet daher die Unterstützung für die Anbindung unterschiedlicher Datenbanken wie MySQL / MariaDB, PostgreSQL oder SQLite.

Persönlich nutze ich ausschließlich MariaDB-Datenbanken. Die Datenbankanbindung ist allerdings reine Geschmackssache. Die Installation und der Betrieb einer MySQL- / MariaDB-Datenbank im Zusammenspiel mit ejabberd ist im Beitrag »Using ejabberd with MySQL« beschrieben.

6.4 ejabberdctl

Mit dem Kommandozeilenwerkzeug ejabberdctl könnt ihr eure ejabberd-Instanz administrieren bzw. diverse Informationen abfragen. Anbei ein Auszug von Befehlen.

Anzahl der aktuell verbundenen Nutzer:

ejabberdctl connected-users-number

Anzahl der eingehenden s2s-Verbindungen zum Server:

ejabberdctl incoming_s2s_number

Ausgabe des aktuellen Log-Levels:

ejabberdctl get_loglevel

Für bestimmte Aufgaben ist es sinnvoll einen cronjob anzulegen. So können bspw. alte MAM-Nachrichten nach einer festgelegten Zeit (30 Tage) entfernt werden:

ejabberdctl delete-old-mam-messages all 30

7. Datenschutzerklärung

In einer Datenschutzerklärung solltet ihr eure Nutzer transparent und verständlich darüber informieren, welche Daten gesammelt und für den ejabberd-Betrieb verarbeitet werden. Darüber hinaus kann es sinnvoll sein aufzuzeigen, welche technischen und organisatorischen Maßnahmen ihr ergriffen habt, um die Sicherheit und Privatsphäre eurer Nutzer zu schützen.

Anbei ein paar Hinweise, die euch bei der Ausarbeitung einer Datenschutzerklärung für euren ejabberd-Server behilflich sein können.

  • [1] Welche Daten speichert ihr von euren Nutzern bei der Registrierung?
    • Den Anmelde- bzw. Benutzernamen, den sog. Jabber-Identifier (JID)
    • Das Passwort als SCRAM-SHA1 Hash
    • […]
  • [2] Welche Daten werden von ejabberd verarbeitet bzw. entstehen bei der Nutzung eures XMPP-Dienstes?
    • Alle Kontakte zu einem Konto werden in einer Liste gespeichert
    • Das Nachrichtenarchiv (MAM) wird für eine gewisse Dauer auf dem Server vorgehalten
    • Dateien, die ein Nutzer mit anderen Kontakten oder Gruppen getauscht hat, liegen für einen gewissen Zeitraum (bspw. 30 Tage) auf dem Server
    • Eine gewisse Anzahl an (Offline-)Nachrichten (bspw. 500) werden zwischengespeichert, bis der Nutzer wieder online ist
    • […]
  • [3] Welche Maßnahmen habt ihr getroffen, um die Privatsphäre eurer Nutzer zu schützen?
    • Keine Speicherung der IP-Adresse bei der Registrierung, Anmeldung oder Nutzung
    • Verzicht auf die Speicherung der Anmeldezeit bzw. wann das Konto aktiv genutzt wird
    • […]
  • [4] Was passiert beim Löschen eines Kontos?
    • Alle gespeicherten Daten inkl. dem Konto (JID, Passwort) werden unverzüglich gelöscht
    • Dateien werden automatisch nach 30 Tagen entfernt

Darüber hinaus ist es sinnvoll, wenn ihr eure Nutzer auf die Verwendung von OMEMO hinweist. Nur eine (funktionierende) Ende-zu-Ende-Verschlüsselung kann letztendlich sicherstellen, dass niemand außer den Teilnehmern die Nachrichteninhalte mitlesen kann.

8. Fazit

Wie bereits im Beitrag »Messenger: XMPP ist nicht der Heilsbringer – aber eine Lösung« aufgezeigt ist XMPP nicht der Heilsbringer für die Messenger-Welt. XMPP ist aber eine Lösung, die es Menschen gestattet, miteinander in den Austausch zu treten bzw. ein Kommunikationsnetzwerk zu betreiben, ohne von zentralen Anbietern in irgendeiner Form abhängig zu sein. Insbesondere für Personen oder Institutionen mit hohem Autonomiebedürfnis kommt nach meiner Auffassung nur XMPP oder Matrix in Betracht.

Mit dem vorliegenden Beitrag wollte ich meinen Anteil zu XMPP beisteuern, der es engagierten ejabberd-Administratoren gestattet, ihre bestehende Konfiguration um sicherheits- und datenschutzrelevante Parameter zu ergänzen. Die vorstehende Konfiguration kann natürlich auch als Basis für neue ejabberd-Server dienen, mit dem Ziel, das XMPP-Netzwerk weiter zu vergrößern.

Über den Autor | Kuketz

Mike Kuketz

In meiner freiberuflichen Tätigkeit als Pentester / Sicherheitsforscher (Kuketz IT-Security) schlüpfe ich in die Rolle eines »Hackers« und suche nach Schwachstellen in IT-Systemen, Webanwendungen und Apps (Android, iOS). Des Weiteren bin ich Lehrbeauftragter für IT-Sicherheit an der Dualen Hochschule Karlsruhe, sensibilisiere Menschen in Workshops und Schulungen für Sicherheit und Datenschutz und bin unter anderem auch als Autor für die Computerzeitschrift c’t tätig.

Der Kuketz-Blog bzw. meine Person ist regelmäßig in den Medien (heise online, Spiegel Online, Süddeutsche Zeitung etc.) präsent.

Mehr Erfahren ➡

SpendeUnterstützen

Die Arbeit von kuketz-blog.de wird zu 100% durch Spenden unserer Leserinnen und Leser finanziert. Werde Teil dieser Community und unterstütze auch du unsere Arbeit mit deiner Spende.

Folge dem Blog

Wenn du über aktuelle Beiträge informiert werden möchtest, hast du verschiedene Möglichkeiten, dem Blog zu folgen:

Bleib aktuell ➡


Diskussion

21 Ergänzungen zu “ejabberd: Installation und Betrieb eines XMPP-Servers”

  1. Comment Avatar waterjail sagt:

    Wieso ist denn jetzt die wahl auf ejabberd und nicht auf prosody gefallen?

    • Comment Avatar Daniel sagt:

      Wenn Mike dieses Frage zu heikel ist gebe ich mal meinen Senf zu der Frage Prosody + ejabberd.
      Aber erst einmal vorweg; Nutze einfach dass, was deine Anforderungen erfüllt. Wenn du also irgendeinen speziellen Grund hast das eine dem anderen vor zu ziehen dann mach das einfach.
      Das Problem in jüngerer Zeit mit Prosody war, dass es für viele relativ essentielle Dinge sog. community modules gebraucht hat die unabhängig von Prosody teilweise von Prosody Entwicklern teilweise von third parties entwickelt wurden. Ohne diese community modules konntest du Prosody 0.9 und Prosody 0.10 nicht vernünftig benutzen. Die Qualität diese community modules schwankt sehr stark – manche davon können eventuell den Server unnötig verlangsamen weil sie blocking i/o machen. Teilweise gibt es mehrere module die den gleichen Job machen. (Siehe csi) Bei ejabberd auf der anderen Seite kommt eigentlich alles von Haus aus schon mit. Ein Howto für ejabberd kann man im Grunde auch einfach als ‚lad dir die default config runter; be done‘ zusammen fassen.
      Mittlerweile holt Prosody allerdings auch stark auf. Das gestern veröffentlichte Prosody 0.11 verschiebt viele community module in core und löst damit ein Teil der eben angesprochenen Probleme. (Aber als Mike diesen Artikel geschrieben hat gab es Prosody 0.11 natürlich noch nicht.) Überhaupt ist die XMPP Welt immer in Bewegung. Eine Empfehlung für das eine muss morgen nicht mehr gültig sein. Ich kann mich noch an Zeiten erinnern wo ejabberd quasi unbrauchbar war und eine erlang (nicht yaml) config datei hatte die extrem schwer zu schreiben war. Damals war Prosody der klare Favorit.
      Auf der anderen Seite ist Prosody mit den community modules und der freundlichen Sprache Lua natürlich leichter zu modifizieren wenn man selber gerne neue XMPP features prototypen möchte. Macht natürlich nicht jeder. Deshalb nochmal das was ich am Anfang gesagt hab; Jeder hat andere Anforderungen; Nutz was du für richtig hälst.
      Für ‚professionelle‘ setups habe ich lange zeit ejabberd benutzt weil mir hier die DB Anbindung zB auch besser gefällt. Dennoch habe ich für private Zwecke und zum Hacken ein Prosody auf der lokalen Maschine.
      Was Prosody gerade mit Version 0.11 macht darf man nicht verachten und das bewegt sich in die richtige Richtung.

  2. Comment Avatar Chris sagt:

    Klasse Artikel. Sowas wünsch ich mir mehr. Vielen Dank.

  3. Comment Avatar Anonymous sagt:

    Ist das regelmäßige Löschen von alten Nachrichten notwendig wenn diese bereits in der Konfiguration begrenzt werden? Würden ältere Nachrichten nicht schon von ejabberd gelöscht wenn die Zahl der offline Messages überschritten wird?

  4. Comment Avatar michael sagt:

    Welcher Client wäre der tollste für google Android?

  5. Comment Avatar Björn sagt:

    Super Beitrag Mike!! Das sind die Dinge die XMPP wirklich weiter bringen. :)

    Wie realisierst du in diesem Fall die Erneuerung der LE-Zertifikate?
    Es reicht ja nicht mittels Cronjob neue Zertifikate zu beantragen, diese müssen dann auch wieder kopiert und in ihren Rechten angepasst werden?
    Gibt es dafür eine elegante Lösung? Könntest du diese ggf. noch ergänzen?

    • Comment Avatar Mike Kuketz sagt:

      Da könntest du dir ein Script basteln. Bspw. so:

      ## Renew certs
      bash /root/.acme.sh/acme.sh --renew -d kuketz-lab.de -d conference.kuketz-lab.de -d upload.kuketz-lab.de -d pubsub.kuketz-lab.de -d proxy.kuketz-lab.de --keylength 4096 --standalone --force
      
      ## Copy certs
      cp /root/.acme.sh/kuketz-lab.de/fullchain.cer /etc/ejabberd/certs/kuketz-lab.pem
      cp /root/.acme.sh/kuketz-lab.de/kuketz-lab.de.key /etc/ejabberd/certs/kuketz-lab.key
      chmod 600 /etc/ejabberd/certs/*
      
      ## Restart ejabberd
      /etc/init.d/ejabberd restart
    • Comment Avatar Izzy sagt:

      Um das Erneuern kümmert sich acme.sh selbstständig. Der Cron-Job läuft einmal täglich und prüft, welche Zertifikate innerhalb der nächsten 30 Tage ablaufen würden. Für die führt er ein „renew“ aus. Und wenn Du einmal „acme.sh –installcert …“ ausgeführt hast, weiß acme auch wohin die Zertifikate kopiert werden sollen – was dann im Anschluss des „renew“ ebenfalls automatisch erfolgt, einschließlich des angegebenen „–reloadcmd“. Also kein extra Cron Job nötig.

      • Comment Avatar Mike Kuketz sagt:

        Da hat Izzy recht, ich kümmere mich allerdings lieber selbst darum.

        Aus einem Mastodon-Toot von Izzy:

        Um Renew, Copy & Restart kümmert sich acme.sh selbst. Das Snippet dafür, damit Du es in den Artikel einpflegen kannst:

        acme.sh --installcert -d kuketz-lab.de --certpath /etc/ejabberd/certs/kuketz-lab.pem --keypath /etc/ejabberd/certs/kuketz-lab.key --fullchainpath /etc/ejabberd/certs/kuketz-lab.chain --reloadcmd  "/etc/init.d/ejabberd restart"
  6. Comment Avatar Roland Hummel sagt:

    „Und in der nächsten Folge: »Synapse: Installation und Betrieb eines Matrix-Servers«“? ;)

  7. Comment Avatar Tobi sagt:

    Hallo Mike,
    ich konnte mit folgenden Cipern 100% erreichen, ist dies aus irgendwelchen Gründen (Kompatibilität/Sicherheit) nicht zu empfehlen:

    EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SEED:!AES128:!CAMELLIA128

    Mir ist aufgefallen dass in deiner Config kein RSA4096 bei DH auftaucht, hat das spezielle Gründe?

    https://malte-kiefer.de/blog/prosody-lets-encrypt/

    • Comment Avatar Tobi sagt:

      Genau, dort. Jetzt stellt sich mir die Frage ob diese Chiper evtl. Nachteile haben, bzw. ob mir die 100% dort, mehr Sicherheit bringen.
      Du erwähntest das optionale Erstellen der DH Parameter, allerdings werden laut Cryptcheck bei dir keine angezeigt, mit dem Snippet von Malte schon.

      • Comment Avatar Mike Kuketz sagt:

        Anders als CryptCheck würde ich dir für die gewählten Cipher keine 100% vergeben. CryptCheck eignet sich nach meiner Auffassung insbesondere dafür, um zu sehen, welche Cipher-Suiten ein Dienst bzw. Server anbietet. Die Bewertung (aufgrund der angebotenen Cipher-Suiten) finde ich eher supoptimal. ;-)

        ECDH(E) ist eine Variante des Diffie-Hellman-Protokolls, das elliptische Kurven verwendet, um den Rechen-, Speicher- und Speicherbedarf zu senken.

        In der Praxis solltest du DHE oder ECDHE als Schlüsselaustauschprotokoll verwenden.

  8. Comment Avatar Anonymous sagt:

    Super, danke für den Beitrag. Warum hast du dich für netcup für den Server, die Domains und die Nameserver als Hoster entschieden? Ist netcup vertrauenswürdig, datenschutzfreundlich und sicher?

    • Comment Avatar Mike Kuketz sagt:

      Ich betreibe meine Root-Server seit Jahren über netcup. Persönlich halte ich netcup für vertrauenswürdig. Wie »sicher« und datenschutzfreundlich netcup ist, ist allerdings nur schwer messbar. Da musst du dir selbst ein Bild davon machen, die Webseite besuchen, Forum besuchen und vielleicht die Datenschutzerklärung bzw. AGBs lesen.

  9. Comment Avatar Trollinger sagt:

    Moin moin!
    Ja, schöner umfassender Bericht, aber ist das mit dem Server für 10000 Nutzer nicht ein wenig oversized?;-)
    Es geht auch etwas einfacher mit FREEDOMBOX. Ich hatte mit einer 17 Jahre alten PC-Büchse erste Versuche mit dem in Freedombox (unter Debian9) enthaltenen ejabberd gemacht, die auch funktionierten. In freedombox ist auch ein dyndns-Client enthalten der die benötigte eigene Domain generiert. Client auf dem PC ist Gajim und auf dem Android-Tablett Conversations. Da die 20Gb HD in der alte Büchse leider den Geist aufgegeben hat, erfolgt ein neuer Versuch mit einem Raspberry Pi Zerro W mit 16Gb SD, der fast die selbe Leistung hat wie die alte Kiste. Für diejenigen die auf wirkliche Autonomie setzen, sehe ich freedombox als interessante Alternative an.

  10. Comment Avatar thomas1020 sagt:

    Hallo,
    danke für die ausführliche Anleitung! Der Betrieb eines solchen Servers ist natürlich für Profis interessant – für Hobby Admins die einen Chat für die Familie, kleine Firma oder einen Verein bereitstellen möchten aber wenig praktikabel.
    Daher möchte ich eine einfachere Möglichkeit erwähnen: Nextcloud Talk. Einen Nextcloud Server aufsetzen (sehr einfach), die „Talk“ App aktivieren (ein Klick) und schon hat man sein eigenes privates Skype/Hangouts am Laufen, inkl. Video Telefonie, Chat etc. zwischen allen Nutzern die am eigenen Nextcloud Server registriert sind (und mit Gast Nutzern denen man einen Link geschickt hat). Und: Es gibt auch Apps dafür, bei der man nur die Adresse seines Servers und die Zugangsdaten angeben muss.
    Für 10.000 Nutzer wird das natürlich auch komplizierter, aber für 10 Nutzer ist es ein Kinderspiel.
    lg Thomas

  11. Comment Avatar Beadspriter sagt:

    Hallo,

    es gibt evtl. einen Fehler:

    bei DNS soll man Port 443 beschreiben, dabei kann man unter ejabberd aus debian-repos keinen kleineren Port als 1024 verwenden. Und in der weiteren Anleitung wird Port 443 auch nicht verwendet.

    Warum dann überhaupt Port 443 bei DNS beschreiben?

    Vielen Dank

HilfeWenn du konkrete Fragen hast oder Hilfe benötigst, sind das offizielle Forum oder der Chat geeignete Anlaufstellen, um dein Anliegen zu diskutieren. Per E-Mail beantworte ich grundsätzlich keine (Support-)Anfragen – dazu fehlt mir einfach die Zeit. Kuketz-Forum

Abschließender Hinweis

Blog-Beiträge erheben nicht den Anspruch auf ständige Aktualität und Richtigkeit wie Lexikoneinträge (z.B. Wikipedia), sondern beziehen sich wie Zeitungsartikel auf den Informationsstand zum Zeitpunkt des Redaktionsschlusses.

Kritik, Anregungen oder Korrekturvorschläge zu den Beiträgen nehme ich gerne per E-Mail entgegen.