Private Cloud mit Seafile und Radicale auf einem Raspberry Pi (Teil 2)

Im ersten Teil der Artikelserie „Private Cloud mit Seafile und Baïkal Radicale auf einem Raspberry Pi“ ging es darum, den Raspberry Pi zum Laufen zu bekommen und vorzubereiten. In diesem 2. Teil soll es nun um die Inbetriebnahme des Kalender- und Kontakte-Servers gehen. Bei diesem setzte ich seit Jahren auf den Baïkal-Server, welcher wenig Ressourcen beansprucht und stabil läuft. Eigentlich sollte diese Anleitung auch für diesen geschrieben werden. Während der Recherche stellte sich aber heraus, dass Baïkal nicht mehr weiterentwickelt wird. Anleitungen für Software, welche nicht mehr weiterentwickelt werden und damit schnell veraltet sind, machen keinen Sinn und so werde ich die Anleitung für eine ebenso schlanke Open-Source-Alternative schreiben: Radicale. Bis man den Server installieren kann, sind aber noch ein paar Vorarbeiten zu leisten. Es werden folgende Schritte notwendig sein:

  1. Den Raspberry Pi vom Internet erreichbar machen
  2. Erstellen eines SSL-Zertifikats
  3. Aufsetzen eines Nginx-Webservers
  4. Das PiDrive mounten
  5. Radicale installieren und einrichten

 

Schritt 1: Den Raspberry Pi vom Internet erreichbar machen

Bisher war der RasPi gut versteckt im eigenen Heimnetzwerk und man konnte nur über die interne IP-Adresse auf ihn zugreifen. Für die Nutzung als Wolke ist natürlich eine Zugriff aus dem Internet unerlässlich.

Schritt 1a: DynDNS-Adresse erzeugen
Da die Meisten einen Internetanschluss mit dynamischer IP-Adresse haben, wird sich die IP-Adresse spätestens alle 24 h ändern. Um nicht permanent die Internetadresse anpassen zu müssen, bedient man sich eines DynDNS-Dienstes. Mit Hilfe eines solchen Dienstes, kann man einem Internetanschluss eine feste Internetadresse zuweisen, ohne jeden Tag die IP-Adresse ändern zu müssen. Ich persönlich nutze dafür den Dynamic-DNS-Service spDYN von Securepoint, einem kostenlosen Angebot, mit dem ich bis jetzt durchweg gute Erfahrungen gemacht habe.

Meldet man sich bei diesem Dienst an, kann man eine Adresse in der Form meineAdresse.spdns.de erhalten (oder eine der anderen Domains, die angeboten werden). Am Beispiel für den o.g. Dienst gibt man einfach einen Host-Namen an, welcher dann die Subdomain zu der Hauptdomain bildet, welche man ebenfalls in dem Dialog auswählen kann (s. Abbildung). In der Bedienoberfläche des Routers kann man die aktuelle IP-Adresse ablesen und gibt diese im Feld IP an. Damit wäre der Dienst (zumindest) bei spDYN bereits eingerichtet.

Einen neuen Host hinzufügen

Schritt 1b: DynDNS-Dienst im Router aktivieren
Damit der DynDNS-Dienst aber auch weiß, wie bei einer IP-Adressenänderung die neue IP-Adresse lautet, muss man im Router dies auch einrichten, damit dieser die neue IP-Adresse weitergibt. Am Beispiel der Fritz!Box sieht das folgendermaßen aus (s. Abbildung):

Einstellungen für einen DynDNS-Dienst in der Fritz!Box

In der Regel stellt der DynDNS-Anbieter eine Update-URL bereit (bei spDYN: https://update.spdyn.de/nic/update?hostname=<domain>&myip=<ipaddr>), die man der Fritz!Box mitteilen muss. Weiterhin müssen DynDNS-Domainname und Benutzername des Dienstes angegeben werden. Als Kennwort gibt man hier nicht das Kennwort für die Administrationsoberfläche des DynDNS-Dienst-Nutzerkontos an. Für den Domainnamen stellt der DynDNS-Anbieter einen Update-Token bereit, welchen man in der Fritz!Box als Kennwort eingibt. Nach dem Speichern in der Fritz!Box sollte auf diese nun über die Dyn-DNS-Adresse aus dem Internet zugegriffen werden können.

Schritt 1c (optional): Eigene Domain auf die DynDNS-Adresse aufschalten
Will man seine eigene Domain für die zukünftige Wolke verwenden, muss man ein wenig in den DNS-Einstellungen der Domain tätig werden (Dieser Schritt ist nicht zwingend notwendig, wenn man mit der DynDNS-Adresse zufrieden ist). Ich persönlich nutze für meine Domainverwaltung den Dienst INWX, der bisher tadellos funktioniert hat.

In der Domainverwaltung gibt man im Bereich DNS-Einträge (u.U. heißt der Punkt auch anders wie Nameserver etc., das ist von Anbieter zu Anbieter unterschiedlich) als Name die Subdomain an, unter der die Wolke aufgerufen werden soll (in diesem Beispiel cloud). Als Typ wählt man CNAME und als Wert die DynDNS-Adresse (s. Abbildung). Nach dem Abspeichern wird es einige Zeit dauern, bis die neue Domain aufrufbar ist, aber der Router sollte nun auch unter der eigenen Domain erreichbar sein (in diesem Beispiel http://cloud.hotzpotz.de)

DNS-Eintrag für Dyn-DNS-Adresse bei INWX

Um zu prüfen, ob die unternommenen Schritte von Erfolg gekrönt waren, kann man die beiden Adressen mal anpingen. Es sollte bei beiden das gleiche Ergebnis herauskommen und die eigene IP-Adresse auftauchen.

ping hotzpotz.spdns.eu
ping cloud.hotzpotz.de

 

Schritt 1d: Ports 80 und 443 im Router freigeben
In der Fritz!Box-eigenen Firewall müssen für den RasPi zunächst die Ports 80 und 443 für die SSL-Übertragung freigegeben werden. Dafür geht man in der Admin-Oberfläche auf Internet >> Freigaben. Im Reiter Port-Freigaben muss man zunächst seinen RasPi hinzufügen.

In dem Fenster, in dem man das Gerät hinzufügt, kann man auch gleich Ports freigeben. Dort wählt man die Option Portfreigabe, als Anwendung HTTPS-Server und als Port 443 (s. Abbildung) sowie HTTP-Server und den Port 80. Bestätigt man dies mit OK und fügt danach das Gerät hinzu, ist der Port gleich freigegeben.

SSL-Port-Freigabe in der Fritz!Box

Schritt 2: Erstellen eines SSL-Zertifikats

Schritt 2a: Erstellen des Zertifikats
Zum Erstellen eines SSL-Zertifikats bedient man sich am besten der kostenlosen Zertifizierungsstelle Let’s Encrypt. Zunächst installiert man certbot:

sudo apt-get install certbot

Im Anschluss kann man sofort mit der Zertifikaterstellung beginnen:

sudo certbot certonly --standalone -d cloud.hotzpotz.de

Hinter der Option -d muss die Domain folgen, für die das Zertifikat ausgestellt werden soll (in diesem Beispiel cloud.hotzpotz.de). Das Zertifikat wird dann im Verzeichnis /etc/letsencrypt/live/cloud.hotzpotz.de/ abgelegt als fullchain.pem.

Schritt 2b: Erstellen eines Cronjobs zur regelmäßigen Erneuerung des Zertifikats
Da ein Zertifikat von Let’s Encrypt nur 90 Tage gültig ist, muss es regelmäßig erneuert werden. Das lässt sich am besten durch einen Cronjob automatisieren:

sudo crontab -e

Mit obigem Befehl kann man die crontab editieren. Dabei wird man, falls man es das erste mal macht, nach dem zu nutzenden Editor gefragt. Wer keine besondere Vorlieben hat, macht mit nano nicht viel falsch. In der crontab setzt man am Ende folgende Zeile:

0 3 * * * certbot renew --standalone --pre-hook "service nginx stop" --post-hook "service nginx start" -q

Zur Erklärung:

  • 0 3 * * *: der Cronjob wird jeden Tag um 3 Uhr früh ausgeführt
  • certbot renew: der Befehl zum aktualisieren des Zertifikats
  • –standalone: Authentifizierungs-Plugin; nur mit dem standalone-Plugin ist eine Authentifizierung über den Port 443 mit (dem noch zu installierenden) Nginx möglich
  • –pre-hook: vor dem Aktualisieren soll der Nginx-Server gestoppt werden
  • –post-hook „service nginx start“: nach dem Aktualisieren soll der Nginx-Server wieder gestartet werden
  • -q: da das Zertifikat nur innerhalb etwa eines Monats vor Ablauf aktualisiert werden kann, würden Versuche vorher zu Fehlermeldungen führen, welche mit der Option -q (für quiet) unterdrückt werden

Update 21.01.2019: Let’s Encrypt verkündete vor einigen Tagen, dass zum 13.02.2019 die Unterstützung für die Validierungsmethode TLS-SNI-01 aufgrund einer Sicherheitslücke ausläuft. Unter Raspbian ist allerdings noch die Version 0.10.1 installiert, welche nur diese Validierungsmethode unterstützt. Die Folge wäre, dass man die Lets-Encrypt-Zertifikate nicht mehr erneuern kann und diese früher oder später auslaufen. Bis sich auch in den offiziellen Raspbian-Quellen eine aktuelle certbot-Version befindet, muss man auf die Debian-Backports zurückgreifen, damit man eine aktuelle Version von certbot installieren kann (aktuell 0.28), welche auch andere Validierungsmethoden unterstützt. Wie man dies erreicht habe ich in einem eigenen Artikel zusammengefasst: Let’s-Encrypt-Zertifikate mit aktueller Certbot-Version auf einem Raspbian Stretch erneuern


 

Schritt 3: Aufsetzen eines Nginx-Webservers

Schritt 3a: Installation von Nginx
Zunächst installiert man das Paket nginx:

sudo apt-get install nginx

Um den RasPi nicht zu überlasten, müssen die maximalen Prozesse angepasst werden:

sudo sed -i "s/worker_processes 4;/worker_processes 1;/g" /etc/nginx/nginx.conf
sudo sed -i "s/worker_connections 768;/worker_connections 128;/g" /etc/nginx/nginx.conf

Nun muss der Webserver nur noch gestartet werden und dann war es das auch schon:

sudo /etc/init.d/nginx start

Zum Testen kann man mal schnell die lokale IP-Adresse des RasPi in den Browser eingeben. Dann sollte eine Willkommens-Seite des Nginx-Servers zu sehen sein.

Schritt 3b: SSL-Zertifikat in Nginx einbinden
Zum Einbinden des in Schritt 2 erstellten SSL-Zertifikats ruft man mit nano die Webserver-Konfiguration auf:

sudo nano /etc/nginx/sites-available/default

Dort sucht man folgenden Abschnitt:

listen 80 default_server;
listen [::]:80 default_server;

und fügt danach folgenden Abschnitt ein (statt cloud.hotzplotz.de sollte man seine eigene Domain einsetzen):

listen 443 ssl default_server; 
server_name cloud.hotzpotz.de;
ssl_certificate /etc/letsencrypt/live/cloud.hotzpotz.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.hotzpotz.de/privkey.pem;

Danach kann man die Konfiguration mit Strg+X, Y und Enter speichern. Mit einem Restart von Nginx lädt man die neue Konfiguration:

sudo /etc/init.d/nginx restart

Zum Test kann man die eigene Domain (also im Beispiel wäre dies dann https://cloud.hotzpotz.de) im Browser eingeben und sollte die gleiche Nginx-Willkommensseite angezeigt bekommen wie schon in Schritt 3a.

 

Schritt 4: Das PiDrive mounten

Als Datenträger für die Wolke habe ich mich für ein PiDrive von Western Digital entschieden, welches extra für den Betrieb mit einem Raspberry Pi konzipiert ist (Update 30.7.2018: Mit der Schließung der WDLabs wurde auch der Vertrieb der PiDrives eingestellt). Zur Einführung des PiDrive hat WD u.a. eine Größe von 314 GB angeboten (in Anlehnung an die Zahl Pi), welche ich auch verwende. Mittlerweile gibt es diese Größe nicht mehr, dafür andere. Um das PiDrive als Datenlaufwerk zu nutzen, sind folgende vorbereitende Schritte notwendig:

Schritt 4a: PiDrive finden, formatieren und mounten
Mit folgendem Befehl kann man erstmal schauen, wo das PiDrive liegt:

sudo fdisk -l

Es folgt die Ausgabe von einigen Partitionen. U.a. sollte dann auch ein Eintrag in folgender Form zu finden sein:

Disk /dev/sda: 292.5 GiB, 314038026240 bytes, 613355520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Die Größe deutet schon an, dass es sich hier um das PiDrive handeln muss. Es liegt also auf /dev/sda. Zunächst formatiert man das Laufwerk im Ext4-Format. In diesem Beispiel wird die Festplatte als eine 314-GB-große Partition formatiert:

sudo mkfs.ext4 /dev/sda1 -L "PiDrive"

Um das Laufwerk zu mounten, erstellt man zunächst einen Mountpunkt (im Beispiel /mnt/data) und mountet dann das PiDrive auf dieses Verzeichnis:

sudo mkdir /mnt/data
sudo mount -t ext4 -o "noatime" /dev/sda /mnt/data

Im Teil 1 beim Einrichten des RasPi wurde ja der Benutzername geändert. Mit dem Befehl id prüft man, welche UID und GID dieser Nutzer hat. Dabei kommt in etwa folgendes Ergebnis raus:

uid=1000(hotzenplotz) gid=1000(hotzenplotz) groups=1000(hotzenplotz),4(adm),20(dialout),24(cdrom) ...

Wahrscheinlich wird die UID und GID wie bei den meisten und im obigen Beispiel auch 1000 sein. Diese Angaben braucht man, um die Zugriffsrechte für das PiDrive zu setzen:

sudo chown -R 1000:1000 /mnt/data
sudo chmod -R 775 /mnt/data

Damit ist das PiDrive fertig eingerichtet!

Schritt 4b: Das PiDrive dauerhaft mounten
Mit jedem Neustart des RasPi müsste man allerdings jedesmal das PiDrive manuell neu mounten. Um dies zu umgehen, muss man den Mountpunkt in die fstab eintragen, aus welcher beim Start des RasPi jedesmal die einzuhängenden Partitionen gelesen werden. Dazu muss man erst einmal die UUID der Partition wissen:

sudo blkid

In der erscheinenden Ausgabe sollte dann u.a. ein Abschnitt in folgender Form auftauchen:

/dev/sda: LABEL="PiDrive" UUID="0562789e-d965-4a85-9a6d-e5c363ddcb4e" TYPE="ext4"

Die hier angezeigte UUID des PiDrive schreibt man dann in die fstab.

sudo nano /etc/fstab

/dev/disk/by-uuid/0562789e-d965-4a85-9a6d-e5c363ddcb4e /mnt/data ext4 defaults,noatime,nofail 0 0

Die fstab sollte dann in etwa folgendermaßen aussehen:

proc                  /proc           proc    defaults          0       0
PARTUUID=557b7d14-01  /boot           vfat    defaults          0       2
PARTUUID=557b7d14-02  /               ext4    defaults,noatime  0       1
/dev/disk/by-uuid/0562789e-d965-4a85-9a6d-e5c363ddcb4e /mnt/data ext4 defaults,noatime,nofail 0 0

Damit wäre auch das PiDrive dauerhaft eingehängt und man kann (endlich) zum eigentlichen Teil übergehen: der Installation von Radicale.

 

Schritt 5: Radicale installieren und einrichten

Schritt 5a: Python und Radicale installieren
Radicale ist in Python geschrieben, sodass zunächst Python installiert werden muss. Anschließend kann dann Radicale mittels pip installiert werden.

sudo apt-get install python3 python3-pip
sudo python3 -m pip install --upgrade radicale

Vom Prinzip her wäre Radicale jetzt bereits lauffähig, aber man muss noch ein wenig Arbeit in die Konfiguration und die Absicherung stecken, damit es auch von außen nutzbar wird.

Schritt 5b: Radicale konfigurieren
Radicale ist standardmäßig so konfiguriert, dass es nur über localhost aufrufbar ist. Zum Konfigurieren legt man zunächst ein Radicale-Verzeichnis unter etc an (Zeile 1). Die Kalender- und Kontaktedaten sollen auf dem PiDrive gespeichert werden, wofür man dort vorbereitend ein Verzeichnis erstellt (Zeile 2). Im Anschluss kann die Konfigurationsdatei erstellt werden (Zeile 3):

sudo mkdir /etc/radicale
mkdir -p /mnt/data/radicale/collections
sudo nano /etc/radicale/config

In die config-Datei schreibt man folgende Zeilen:

[server]
hosts = 0.0.0.0:5232

[storage]
filesystem_folder = /mnt/data/radicale/collections

Mit der [server]-Zeile kann der Radicale-Server auch im lokalen Netzwerk über die IP-Adresse des RasPis und den Port 5232 aufgerufen werden (je nach im Router vergebener IP-Adresse z.B. http://192.168.2.86:5232). Mit der [storage]-Zeile legt man den Speicherort der Daten fest.

Mit folgender Zeile kann man den Radicale-Server zum ersten Mal testweise starten:

python3 -m radicale

Gibt man zur Kontrolle die IP-Adresse des RasPi mit dem Port in den Webbrowser ein (s.o.), sollte ein Anmeldefenster erscheinen. Damit Radicale auch mit jedem Neustart des RasPi mitgestartet wird, richtet man Radicale als Dienst ein.

Schritt 5c: Radicale als Dienst einrichten
Um den Radicale-Dienst einzurichten, erzeugt man mit nano die Datei radicale.service:

sudo nano /etc/systemd/system/radicale.service

und fügt die folgenden Abschnitte ein:

[Unit]
Description=A simple CalDAV (calendar) and CardDAV (contact) server

[Service]
ExecStart=/usr/bin/env python3 -m radicale
Restart=on-failure

[Install]
WantedBy=default.target

Mit Strg+X, Y und Enter speichert man die Datei. Mit folgenden Befehlen aktiviert und startet man den Dienst und kontrolliert, ob er ohne Fehler läuft:

# Dienst aktivieren
sudo systemctl enable radicale
# Dienst starten
sudo systemctl start radicale
# Status des Dienstes kontrollieren
sudo systemctl status radicale

 

Schritt 5d: Radicale absichern
Zur Absicherung der Authentifizierung nutzt man bcrypt, wofür einige Abhängigkeiten nachinstalliert werden müssen:

sudo python3 -m pip install --upgrade passlib bcrypt

Diese Methode muss auch in der Konfiguration hinterlegt werden. Dazu öffnet man die Config-Datei mit einem Editor und fügt den Abschnit [auth] ein:

sudo nano /etc/radicale/config

[auth]
type = htpasswd
htpasswd_filename = /etc/radicale/users
htpasswd_encryption = bcrypt

Da nur nginx installiert ist, wird das System den Befehl htpasswd nicht kennen, sodass man ihm diesen erst beibringen muss. Dafür wird ein Paket nachinstalliert:

sudo apt-get install apache2-utils

Nun kann man mit htpasswd eine Benutzerdatei erzeugen, wobei der zweite Befehl optional genutzt werden kann, falls man mehr als einen Benutzer anlegen möchte. Dabei werden auch gleich die Passwörter mit erzeugt:

#Neue htpasswd-Datei anlegen mit dem Benutzer "hotzenplotz"
sudo htpasswd -B -c /etc/radicale/users hotzenplotz

#Einen weiteren Benutzer "hotzenblitz" hinzufügen
sudo htpasswd -B /etc/radicale/users hotzenblitz

Da die gesamte Kommunikation mit Radicale per SSL abgesichert werden soll, muss man dies in der Config-Datei noch hinterlegen. Man öffnet also mit nano wieder diese Datei und fügt die unterhalb von [server] stehenden Zeilen dem bereits bestehenden Abschnitt [server] hinzu (als Pfad für die Zertifikate/Schlüssel nutzt man jene aus Schritt 3b):

sudo nano /etc/radicale/config

[server]
ssl = True
certificate = /etc/letsencrypt/live/cloud.hotzpotz.de/fullchain.pem
key = /etc/letsencrypt/live/cloud.hotzpotz.de/privkey.pem

In Schritt 2b wurde ein Cronjob eingerichtet, welcher in regelmäßigen Abständen das Let’s-Encrypt-Zertifikat erneuern soll. Die Erneuerung des Zertifikats wirkt sich allerdings nicht auf die Radicale-Instanz aus, da dafür der Radicale-Dienst erst neu gestartet werden muss. Spätestens mit Ablauf des Zertifikats wird folglich eine Synchronisierung mit dem Radicale-Server mit einem Fehler abbrechen. Daher muss in den Cronjob noch ein post-hook eingefügt werden, mit dem der Radicale-Dienst neu gestartet wird. Man editiert also die crontab mit Root-Rechten:

sudo crontab -e

Dort setzt man hinter den bestehenden –post-hook „service nginx start“ einfach einen zusätzlichen post-hook „systemctl restart radicale“ zum Neustart des Radicale-Dienstes, sodass der Cronjob dann folgendermaßen aussehen sollte:

0 3 * * * certbot renew --standalone --pre-hook "service nginx stop" --post-hook "service nginx start" --post-hook "systemctl restart radicale" -q

 

Schritt 5e: Radicale für den Zugriff aus dem Internet einrichten
Bisher kann auf den Radicale-Server nur aus dem lokalem Netzwerk zugegriffen werden. Als letzten Schritt richtet man das Ganze so ein, dass man auch von außerhalb des Netzwerkes (also dem Internet) darauf zugreifen kann.

Dazu ruft man die Standard-Webserver-Konfiguration mit nano auf:

sudo nano /etc/nginx/sites-available/default

sucht folgenden Abschnitt heraus:

location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
}

und fügt dahinter folgenden Inhalt ein (statt cloud.hotzpotz.de wie immer die eigene Domain einfügen):

  location /radicale/ { #Der / am Ende ist wichtig!
    proxy_pass        http://localhost:5232/; #Der / am Ende ist wichtig!
    include proxy_params;
    proxy_set_header  X-Script-Name /radicale;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass_header Authorization;
    proxy_ssl_certificate         /etc/letsencrypt/live/cloud.hotzpotz.de/fullchain.pem;
    proxy_ssl_certificate_key     /etc/letsencrypt/live/cloud.hotzpotz.de/privkey.pem;
}

Die Datei speichert man mit Strg+X, Y und Enter. Um die neue Konfiguration zu aktivieren, muss der nginx-Webserver neu gestartet werden (1. Zeile). Zusätzlich muss auch der Radicale-Server neu gestartet werden, da man ja im Schritt 5d die Konfiguration geändert hat (2. Zeile):

sudo /etc/init.d/nginx restart
sudo systemctl restart radicale

Nun ist der Radicale-Server theoretisch über das Internet erreichbar. Theoretisch deshalb, weil man im Router noch den Port für Radicale freigeben muss, damit die Anfragen vom Router auch an Radicale weitergeleitet werden. Wie man das macht, ist von Router zu Router unterschiedlich. Am Beispiel der Fritz!Box wurde das bereits in Schritt 1d erklärt, nur dass man statt des Ports 443 den Port 5232 freigibt.

Ist der Port freigegeben, kann man in einem Webbrowser die Adresse seiner Domain mit dem freigegebenen Port eingeben (in meinem Beispiel wäre es https://cloud.hotzpotz.de:5232). Es erscheint dann die Anmeldemaske des Radicale-Servers. Dort kann man sich mit einem der unter Schritt 5d angelegten Benutzer anmelden und Kalender oder Adressbücher erstellen. Ist ein Kalender oder Adressbuch angelegt worden, wird eine (kryptische) URL angezeigt, welche z.B. in Thunderbird zur Verwendung im Kalender genutzt werden kann.

Damit wäre der Radicale-Server vollständig und funktionstüchtig eingerichtet. Viel Spaß damit.

Private Cloud mit Seafile und Radicale auf einem Raspberry Pi (Teil 2)

72 Gedanken zu „Private Cloud mit Seafile und Radicale auf einem Raspberry Pi (Teil 2)

  1. Christoph schreibt:

    Hallo!

    Erstmal danke für den guide, sehr übersichtlich und gut aufgebaut! Ich habe gerade exakt laut deiner Beschreibung nachgebaut, komme aber leider nicht über einen 403 Forbidden mit nginx heraus… ich komme leider nicht mal bis zum auth-Teil und ich finde den Fehler leider nicht… :-/ Muss ich noch was Besonderes beachten?

    1. Ein 403-Fehler deutet auf ein Problem mit den Zugriffsrechten hin. Wann kommt denn der Fehler: schon beim Aufsetzen des Nginx-Servers (Schritt 3a) oder erst beim Testen von Radicale (Schritt 5b)?

      1. Christoph schreibt:

        Der 403 ist weg (hatte keine Benachrichtigung über deine Antwort bekommen, sorry :-/ ), aber der Teil mit dem reverse proxy funktioniert leider nicht.

        Ich komme über Port 5232 direkt auf radicale, aber der Sinn des Ganzen wäre es ja, https über nginx terminieren zu lassen, aber deine proxy config zeigt bei mir leider nur einen 500er error an und ich komm nicht drauf, was das Problem ist…

        1. Ist jetzt schwer, aus der Ferne die Ursache zu finden. Mir fallen da spontan 2 Möglichkeiten ein:
          1. Du hast die beiden abschließenden Schrägstriche in der Nginx-Konfig vergessen: es muss zwingend „location /radicale/“ sowie „http://localhost:5232/“ heißen
          2. Deine SSL-Konfiguration ist fehlerhaft: Funktioniert der Zugriff auf deine Domain ohne die Portangabe über https? Es müsste dann die Nginx-Standardseite kommen, falls du neben Radicale nichts anderes installiert hast.

          1. Christoph schreibt:

            Ich weiß, Ferndiagnose ist nicht leicht… :-/

            ad 1) habe das von dir übernommen, genauso hab ich es in der config stehen.

            ad 2) habe mehrere vhosts parallel, alle anderern funktionieren perfekt, haben aber auch keinen reverse proxy drin.

            Könntest du vielleicht deine komplette nginx conf posten oder ist das eh nicht mehr drin als der Teil da oben?

          2. Mmm … hab jetzt mal bei mir nachgeschaut. Ich habe zwar hier in der Anleitung im Schritt 3b stehen, dass man den Block mit der SSL-Konfiguration einfügen soll (also die 4 Zeilen mit „listen 443“ …), finde diese Zeilen aber nicht in meiner nginx-default-Konfiguration. Da ich bei mir Radicale zusammen mit Seafile nutze und für Seafile einen eigenen vhost angelegt habe (siehe Teil 3 der Artikelreihe), wird dort die SSL-Konfiguration hinterlegt. Ich vermute mal, dass ich es deshalb hier wieder entfernt habe. Versuche mal, ob es was bringt, die 4 Zeilen wieder zu entfernen, sodass nur noch

            listen 80 default_server;
            listen [::]:80 default_server;

            listen 443 ssl default_server;
            server_name cloud.hotzpotz.de;
            ssl_certificate /etc/letsencrypt/live/cloud.hotzpotz.de/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/cloud.hotzpotz.de/privkey.pem;

            steht.

  2. Christoph schreibt:

    Aber das ist es ja gerade: den SSL-Teil will ich ja über nginx abwickeln, weil ich da mehr Einstellungsmöglichkeiten in der config habe. Wie greifst du denn auf deine radicale Instanz zu? Nur per cloud.hotzpotz.de oder mit gesamter URL inklusive Port 5232?

      1. Christoph schreibt:

        Alles klar, so funktioniert es bei mir auch, aber das bedeutet, dass dein nginx proxy nicht greift und du sowieso nur auf deine radicale Instanz direkt zugreifst, genau das wollte ich ja verhindern. 🙂

        1. Christoph schreibt:

          Okay, ich habe es jetzt hinbekommen mit folgendem Proxy-Teil:

          location / {
          proxy_pass http://127.0.0.1:5232/;
          include proxy_params;
          #proxy_set_header X-Script-Name /;
          #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          #proxy_pass_header Authorization;
          proxy_ssl_certificate /etc/letsencrypt/live/DOMAIN/fullchain.pem;
          proxy_ssl_certificate_key /etc/letsencrypt/live/DOMAIN/privkey.pem;
          }

          Danke nochmal für deine Unterstützung!

          1. Ich habe jetzt (ich weiß, es ist lang her, Asche auf mein Haupt) nachvollziehen können, was du meintest. Musste es erst selbst zu spüren bekommen 😉
            Mit einem iPhone hatte die Synchronisierung nicht mehr funktioniert. Auf der Spurensuche stellte ich fest, dass beim Aufruf der Radicale-Seite ein Fehler kam, weil das SSL-Zertifikat angeblich abgelaufen war. Beim Aufruf der normalen Domain ohne Portangabe war das Zertifikat aber gültig. Ich habe nun in der nginx-Konfiguration die eine Zeile von dir include proxy_params; eingefügt und siehe da es ging.

            Vielen Dank für den Hinweis! Ich habe den Artikel entsprechend angepasst.

  3. Frederic schreibt:

    Danke für die gute Anleitung. Hat super funktioniert und ich habe viel bei der Einrichtung gelernt.
    Hast du auch noch eine Möglichkeit parat, die CardDAV- und CalDAV-Daten (automatisch) zu sichern?

    1. Christoph schreibt:

      Hallo!

      Nachdem das nur Files in einem Verzeichnis sind, kannst du es leicht mit einem script sichern, hier ist meines:

      ===Skript Beginn===

      #!/bin/bash
      set -x

      mkcdir ()
      {
      mkdir -p — „$1“ &&
      cd -P — „$1“
      }

      cd /data/backups/radicale
      mkcdir „radicale_backup_$(date ‚+%F‘)“

      cp -a /opt/radicale/collection-root .

      exit 0

      ===Skript Ende===

      Das Ganze per cronjob einrichten und das Backup läuft. 🙂

      1. Frederic schreibt:

        Danke für die schnelle Antwort!
        Kannst du die Einrichtung des Backups in den Blog als „Schritt 6“ hinzufügen?
        Das würde das Tutorial komplettieren und User wie ich (Raspbian- bzw. Raspberry-Neulinge) machen bei dem sehr wichtigen Thema Backup & Restore keinen bösen Fehler 🙂

        Vielen Dank!

  4. Christoph schreibt:

    Mir ist noch was eingefallen, was ich bei meiner radicale Installation konfiguriert habe, das sehr wichtig ist: ein rights file, das den Zugriff auf die files regelt.

    Meine /etc/radicale/rights:

    # Authenticated users can read and write their own collections.
    [owner-write]
    user = .+
    collection = %(login)s(/.*)?
    permission = rw

    [admin]
    user = admin
    collection = .*
    permission = rw

    Wenn das nicht eingestellt ist, kannst du jederzeit ohne Authentifizierung mittels URL auf deine Kalender/Adressbücher zugreifen, was security-technisch eine Katastrophe ist natürlich. 🙂

    1. Mmm, das musst du mir jetzt erklären. Die Absicherung erfolgt eigentlich unter Schritt 5d. In der config-Datei gibst du als auth-type htpasswd an. Wenn du die Benutzer mit htpasswd anlegst, kann man auch nur mit Benutzername und Passwort auf den jeweiligen Kalender oder Adressbuch zugreifen.

      Zumindest kommt bei mir eine Benutzername- und Passwortabfrage, wenn ich direkt auf den Kalender im Webbrowser zugreifen möchte. Von daher sehe ich gerade nicht den Sinn deiner Konfiguration mit einer rights-Datei. Zumal diese offensichtlich für die Radicale-Version 1.1 ist. In der Doku von Radicale 2.0 finde ich keinen Hinweis auf die Notwendigkeit einer rights-Datei. Die Option einer rights-Datei ist in der aktuellen Dokumentation gar nicht vorgesehen: http://radicale.org/configuration/ … zumindest nicht für die Authentifizierung. Für das Rechte-Management schon, aber da als default-Wert in Radicale owner_only vorgesehen ist, muss man dies nicht extra in der config angeben.

      1. Christoph schreibt:

        Interessant… bei mir konnte man direkt mit der URL ohne Passwort-Abfrage zugreifen. 🙂

        Wenn das bei dir eh funktioniert, dann passt das, ich werde am Abend mal checken, welche radicale-Version ich da installiert habe bei mir.

        1. Da musst du mal darauf achten, ob du im Browser in Radicale angemeldet bist. Dann hat der Browser natürlich deine Logindaten im Cache und der Abruf funktioniert ohne Abfrage der Logindaten. Um sicher zu gehen, kannst du die URL mal in einem Browserfenster mit Privat- bzw. Inkognito-Modus ausprobieren. Da sollten deine Logindaten nicht gespeichert sein 😉

          1. Christoph schreibt:

            Keine Sorge, ich habe das Ganze mit anderen Browsern (in denen ich noch nie angemeldet war), anderen Computern (auch VMs) getestet, ich habe alles probiert, was mir eingefallen ist dazu. 😉

  5. Doni schreibt:

    Hallo und danke für die Anleitung erstmal.
    Ich habe Probleme mit Schritt 2a
    er findet die Domain nicht
    obwohl sie anpingbar ist.
    Kannst du mir weiterhelfen?

    1. Björn schreibt:

      Hallo zusammen. Bei Schritt 2a hänge ich leider auch. Folgender Fehler tritt auf:
      – The following errors were reported by the server:

      Domain: rahma.dyndns.org
      Type: connection
      Detail: Fetching
      http:///.well-known/acme-challenge/glRoScTSYCTLDnyar9lHVR5US7vrTC8lay8GPhPJ_PA:
      Timeout during connect (likely firewall problem)

      To fix these errors, please make sure that your domain name was
      entered correctly and the DNS A/AAAA record(s) for that domain
      contain(s) the right IP address. Additionally, please check that
      your computer has a publicly routable IP address and that no
      firewalls are preventing the server from communicating with the
      client. If you’re using the webroot plugin, you should also verify
      that you are serving files from the webroot path you provided.

      Hat jemand eine Idee? Beste Grüße

      1. Wenn ich es richtig sehe, möchtest du ein Zertifikat für eine Subdomain von dyndns.org einrichten. Ich bin mir nicht sicher, ob du das so einfach machen kannst, da du ja nicht der Inhaber der Domain bist. Das geht nicht bei jedem DynDNS-Anbieter. Eventuell kannst du das bei den Einstellungen zu der DynDNS-Domain einrichten.

      2. Björn schreibt:

        Ach mist, ich kam gerade nicht auf meinen PI daher hab ich eine analoge Fehlermeldung rausgesucht, aber vergessen alle Daten zu ersetzen. Hier nochmal die Originalmeldung:
        IMPORTANT NOTES:
        – The following errors were reported by the server:

        Domain: bjornscal2.firewall-gateway.com
        Type: connection
        Detail: Fetching
        http://bjornscal2.firewall-gateway.com/.well-known/acme-challenge/aY_T49oSh2FfQo7Zv4PMwVQwoQFvZlDaXjuiI6gnSFY:
        Timeout during connect (likely firewall problem)

        To fix these errors, please make sure that your domain name was
        entered correctly and the DNS A/AAAA record(s) for that domain
        contain(s) the right IP address. Additionally, please check that
        your computer has a publicly routable IP address and that no
        firewalls are preventing the server from communicating with the
        client. If you’re using the webroot plugin, you should also verify
        that you are serving files from the webroot path you provided.

          1. Björn schreibt:

            Damit wir uns nicht falsch verstehen: http://bjornscal2.firewall-gateway.com ist die DynDNS Adresse, die ich mir bei spDyn eingerichtet hab. Ich glaube da liegt auch schon das erste Probleme, da meine IP anscheinend nicht geupdated wird. Kann (bzw. muss) ich DynDNS für Ipv6 einrichten?

          2. Björn schreibt:

            Ich musste gerade feststellen, dass ich nur über einen DS-Lite Anschluss verfüge. Dann wird es vermutlich schwer..

        1. Björn schreibt:

          Hallo nochmal,
          ich habe mein Problem mit der Zertifikaterstellung beheben können, nun hänge ich aber bei 3b (Zertifikat einbinden). Unter der lokalen IP kommt der Nginx Startbildschirm, und anpingen kann ich meine DynDNS Domain auch, der Zugriff über https:// funktioniert aber leider nicht. Hat jemand vielleicht eine Idee, woran das liegen könnte?

          Und noch eine Frage am Rande: im Router kann ich DMZ mit dem Raspberry als lokalen Host aktivieren, ist das notwendig? (obiges Problem besteht in beiden Fällen)

          Besten Dank!

          1. Was heißt denn „funktioniert nicht“? Kommt eine Fehlermeldung? Falls ja, welche? Hast du den Port 443 im Router für den Raspberry freigegeben? DMZ brauchst du normalerweise nicht. Die Portfreigabe im Router ist ausreichend.

          2. Björn schreibt:

            Oh sorry, das war in der tat etwas ungenau. Safari sagt: „Safari kann die Seite nicht öffnen, da der Server, auf dem sich die Seite befindet, nicht antwortet.“ Bei Firefox bekomme ich irgendwann nur einen Zeitüberschreitungsfehler.
            Gebe ich https://192.168.0.115/ ein, komme ich allerdings drauf. Die Portweiterleitung auf den Raspberry ist für 80,443 und 5232 eingerichtet.

          3. Hmmm, sieht für mich nach einem Problem mit der Portfreigabe im Router aus. Wenn du intern https aufrufen kannst (ich vermute mal dann aber mit einer Warnung wegen falschem SSL-Zertifikat?) und extern aber nicht, scheint ja die Nginx-Konfiguration richtig zu sein.

  6. piRAT schreibt:

    Gut gemacht! Der Ariadne-Faden durch das Labyrinth.
    Nur leider komme ich am Minothaurus nicht vorbei:
    Unter „Schritt 5d: Radicale absichern“ führt das Kommando „sudo python3 -m pip install –upgrade passlib bcrypt“ zu massiven Fehlermeldungen wie:
    1 c/_cffi_backend.c:2:20: fatal error: Python.h: Datei oder Verzeichnis nicht gefunden
    #include
    2 compilation terminated
    3 Failed building wheel for bcrypt
    4 Failed cleaning build dir for bcrypt
    5 Failed building wheel for cffi
    6 Failed building wheel for pycparser
    Das Ganze mit einem Haufen kryptischer Strings mittenmang.

    Zur Ergänzung:
    Die Fehlermeldung: „Command python setup.py egg_info“ failed with error code 1 in /tmp/pip-build-s3 h5uzgc/radicale/, welche aus Schritt 5a und dem Kommando „sudo python3 -m pip install –upgrade radicale“ resultierte, ließ sich für mich als rookie noch mit einer vergleichsweise einfach zu ergooglenden erhofften Kommandozeilenlösung beheben („sudo python3 -m pip install –upgrade setuptools“).
    Leider kamen dann auch hier wieder viele rote Textbausteien, wie „Failed building wheel for radicale/vobject“.
    Nach einem sudo apt-get udate/upgrade lief dann der Befehl „sudo python3 -m pip install –upgrade radicale“ flüssig durch und der radicale-Dienst zeigte sich als aktiv.

    Nur die oben beschriebenen Fehlermeldungen, welche aus Schritt 5d resultieren, treffen bei mir auf absolute Ahnungslosigkeit.
    Wenn hier irgendwas nicht kompiliert/gewheelt wird, ist es doch auch nicht für den Rechner ausführbar, oder?
    Hab auch schon einfach mal „sudo python3 -m pip install cffi“ ausprobiert, weil „cffi“ häufig in den Fehlermeldungen aufgetaucht ist, was leider zu zusätzlichen Fehlermeldungen führt.

    Jetzt die Frage:
    Warum ich?
    Nee, Spaß.
    Was ist das Problem? Und wie behebe ich es?

    Danke an den Spender.

    [PS: Ich nutze einen Banana Pi Pro und armbian als OS auf microSD.]
    [PPS: Wenn jetzt noch OpenVPN und PiHole in der Anleitung Platz fänden, eventuell noch TVHeadend…;)))]

  7. Pi.RAT schreibt:

    Braucht es weitere Abhängigkeiten, um bcrypt zu kompilieren?
    Auf der bcrypt-Seite ist das angeblich mit: „sudo apt-get install build-essential libffi-dev python-dev“ erledigt. Bei mir jedoch nicht.
    Auch dieser Befehl „python3 -m pip install –upgrade radicale[bcrypt]“ brachte nicht den gewünschten Erfolg.
    Kann es sein, dass bcrypt nicht mit Python 3.5 kompatibel ist?
    Kann man das Python z.B. auf 3.4 downgraden ohne das es beim Rest der Anleitung zu weiteren Problemen führt?
    Ist hier überhaupt noch jemand, der das liest?

    Gruß Pi.RAT

    1. Hallo Pi.RAT,
      ja, hier liest noch jemand mit. Aber auch ich brauche manchmal Urlaub 😉 … zu deinem Python-Problem kann ich dir leider wenig helfen. Ich kann dir leider nur soviel sagen, dass die ganze Anleitung mit Raspbian 9 getestet wurde. Ich habe gerade nachgeschaut: bei mir ist Python 3.5.3 installiert. Von daher sollte es kein Kompatibilitäts-Problem von bcrypt sein. Allerdings weiß ich nicht, ob die installierten Pakete von armbian mit denen von Raspbian identisch sind.

  8. Pi.RAT schreibt:

    Vielen Dank. Sören.
    Ich weiß Deine Hilfe über die tolle Anleitung hinaus wirklich zu schätzen.
    Jedenfalls kann ich durch das Rumprobieren Deine sehr nützliche Anleitung noch um ein paar Eigenwünsche erweitern (Public-Key Login, eigene CA statt certbot, TVHeadend, PiHole, OpenVPN, Telemetrie etc.).

    Um das bcrypt-Problem anzugehen, habe ich mit:
    „sudo apt-get install build-essential libffi-dev python-dev “
    „sudo apt-get install python3-dev “
    das Maschinchen soweit bekommen, dass nach:
    „sudo apt-get upgrade passlib bcryp“
    die Meldung: „passlib und bcrypt installiert“ erschien.
    Die wheels konnten aber immer noch gebuildet werden.
    Schade, da ich gerne den binärcode implementiert hätte, da dies wesentlich schneller läuft als das bcrypt Python-Skript.
    Egal, solange bcrypt wenigstens zuverlässig seinen Dienst tut.
    Da rasbpian, wie armbian, debian Derivate sind, sollte es eigentlich keinen Unterschied geben. Bis auf das kompilieren wahrscheinlich, da die Hardware unterschiedlich ist.
    Z.Zt. hänge ich noch in der Seafileinstallation fest, weil ich als user seafile keine Berechtigungen habe die Config-Datei am Ende des Installtionsvorgangs zu schreiben. Das Setup bricht dann ab.
    Werde seafile mal in die sudoers Liste eintragen und es dann versuchen.
    Hast du irgendeine Idee, wie mann fail2ban dazu bringt auch für einen Login per Public-Key Verfahren zu funktionieren?
    In der Standardinstallation ist es leider nur für Passwort-Login zu gebrauchen.

    Übrigens:
    Die Links der Wocher auf deiner Seite sind sehr geil. Viele interessante Dinge dabei. Besten Dank.

    1. Wenn du mit sudo su seafile in den Benutzer seafile wechselst, solltest du eigentlich genügend Rechte zum Installieren haben, sodass der Eintrag in die sudoers-Liste nicht nötig ist (s. Schritt 1a von Teil 3).

      Zu deiner fail2ban-Frage: Leider nein, keine Ahnung.

  9. Pi.RAT schreibt:

    Hallo. Zum bcrypt wheel-building Problem:
    Habe vor „sudo python3 -m pip install –upgrade passlib bcrypt“ folgendes gemacht:

    „sudo apt-get update“
    „sudo apt-get install python-pip“
    „sudo apt-get install python-all-dev python-setuptools python-wheel“
    „sudo apt-get install build-essential libffi-dev python-dev“
    „sudo apt-get install gcc build-essential libffi-dev python3-dev“
    „sudo apt-get install build-essential libssl-dev libffi-dev python3-dev“
    „sudo python3 -m pip install cffi“
    Jetzt können die wheels auch gebuildet werden.

    Für die seafile-Installation mit usr seafile musste ich diesen in die sudoers-Liste eintragen.
    „sudo gpasswd -a seafile sudo“
    Dann hatte ich auch die Schreibberechtigung für die config-File auf die HDD und die Installation läuft durch.
    Mal sehen, was passiert, wenn ich user seafile wieder austrage…:)

  10. Marc schreibt:

    Hallo Sören. Hallo alle.
    Ich habe gesehen, dass eine neue Version von Radicale auf Github erschienen ist (Version 2.1.11 mit nur einer Änderung laut Changelog) und wollte von 2.1.10 aktualisieren. Das ist in meinem Fall die erste Möglichkeit für ein Update und ich fragte mich nun, wie ich überhaupt ein Update durchführe!? Weiß das jemand? Ich habe leider keine Informationen im Radicale Wiki oder der Dokumentation gefunden, sowie auch keine externen Anleitungen.
    Ist es womöglich so simpel, dass einfach der ursprüngliche Befehl zur Installation (’sudo python3 -m pip install –upgrade radicale‘) verwendet wird?

    Grüße, Marc

    1. Hallo Marc,
      das muss ich tatsächlich noch ergänzen an der Anleitung: die Update-Geschichte 🙂 … ich habe es zwar noch nicht getestet, aber vom Grundsatz her würde ich es auch so machen. Aber: Vorher ein Backup machen. Zur Sicherheit würde ich auch den Radicale-Dienst stoppen: sudo systemctl stop radicale. Nach erfolgreichem Update kannst du ihn wieder mit sudo systemctl start radicale starten.

  11. David schreibt:

    Hi Sören,
    besten Dank für die tolle Anleitung. Hiermit habe ich nun auch endlich Radicale auf einem Pi laufen.
    Ich habe aber noch etwas Verständnisprobleme (bei Punkt Schritt 5d: Radicale absichern) bei meinem Vorhaben:

    Die Ausgangssituation ist eine etwas andere:
    Raspberry A (10.0.0.102): hier ist Radicale installiert
    Raspberry B (10.0.10.151): hier ist Ngnix und PiHole installiert

    Auf Pi B habe ich das letsencrypt Zertifikat erstellt (weil da auch nginx läuft). Muss ich nun auf dem Pi A auch ein Zertifikat erstellen und in der /etc/radicale/config dann den Pfad, wie bei dir oben angegeben, einfügen? Oder muss ich den Pfad zum Pi B angeben und dem dortigen Zertifikat?

    Und eine zweite Frage bzgl. der Ningx Config. Mein DDNS läuft über goip.de. dort habe nur eine Domain, also müsste doch in der default- config bei „location/radicale/“ nach Proxy_pass dann „http://:5232/;“ stehen.

    Und eine Verständnisfrage zu nginx vielleicht noch: lege ich für jeden Webservice (also Radicale, PiHole, usw.) separate available Dateien an oder schreibe ich alles in eine Datei und dort in eigene Location Blöcke?

    Leitet Ihr eigentlich Http Anfragen direkt an Https weiter? Habe irgendwo aufgeschnappt, dass dies notwendig ist um radicale mit iOS zu syncronisieren?!

    Genug der vielen und hoffentlich nicht zu verwirrenden Fragen.
    Vielen Dank nochmal für das tolle HowTo!!!

    David

    1. Hallo David,
      da hast du natürlich ein ziemlich spezielles Setup, welches für mich auf den ersten Blick ein paar Nachteile mit sich bringt (dazu weiter unten mehr). Allerdings muss ich dazu sagen, dass ich da auch kein Experte bin. Ich versuche mal, soweit ich es weiß, deine Fragen zu beantworten:

      Muss ich nun auf dem Pi A auch ein Zertifikat erstellen und in der /etc/radicale/config dann den Pfad, wie bei dir oben angegeben, einfügen? Oder muss ich den Pfad zum Pi B angeben und dem dortigen Zertifikat?

      Ich bin mir nicht sicher, inwiefern man bei einer Pfadangabe von einem Server auf einen anderen Server verweisen kann. Ohne es genau zu wissen, hätte ich jetzt gesagt, dass das gar nicht geht, sodass das Zertifikat schon auch auf dem Pi A liegen muss. Das Problem ist nun, dass das Zertifikat von Pi A nicht identisch mit dem von Pi B ist. Eine Lösung könnte hier sein, dass du z.B. per rsync-cronjob das regelmäßig synchronisierst.

      Mein DDNS läuft über goip.de. dort habe nur eine Domain, also müsste doch in der default- config bei „location/radicale/“ nach Proxy_pass dann „http://:5232/;“ stehen.

      Das verstehe ich jetzt leider nicht ganz. Unabhängig von der Domain, ist das localhost vor dem :5232/ schon wichtig, da es hier nur darum geht, dem Nginx-Server zu sagen, dass Radicale über den Port 5232 aufzurufen ist.

      lege ich für jeden Webservice (also Radicale, PiHole, usw.) separate available Dateien an oder schreibe ich alles in eine Datei und dort in eigene Location Blöcke?

      Leider habe ich es aus Zeitgründen noch nicht geschafft, mich intensiver mit Nginx auseinanderzusetzen. Das mit den einzelnen available-Dateien hatte ich irgendwann mal versucht. Das hatte aber nicht geklappt und ich hatte nicht herausfinden können, woran das lag.

      Leitet Ihr eigentlich Http Anfragen direkt an Https weiter? Habe irgendwo aufgeschnappt, dass dies notwendig ist um radicale mit iOS zu syncronisieren?!

      Naja, dadurch, dass ich im Router nur den Port 443 freigegeben habe, kann ich nur per https auf die Dienste des Raspi zugreifen. Ein http würde zu einem Verbindungsfehler führen, sodass man quasi gleich dazu gezwungen wird https als Adresse einzugeben 😉

      Den Nachteil den ich sehe, liegt in der Aktualisierung des Lets-Encrypt-Zertifikats. Damit das bei der automatischen Erneuerung auch für Radicale gültig ist, muss nämlich auch der Radicale-Dienst neu gestartet werden. Wenn dieser aber auf einem anderen Raspi liegt, kannst du das mit dem Cronjob für die Lets-Encrypt-Erneuerung nicht automatisieren. Du müsstest immer alle zwei-drei Monate per Hand den Radicale-Dienst neu starten. Warum installierst du nicht dein Radicale auf dem gleichen Raspi, wo auch der Nginx-Server liegt? Da würdest du dir einiges erleichtern.

  12. David schreibt:

    Hi Sören,

    besten Dank für die schnelle Rückmeldung.
    Leider ist wohl bei einem Teil meiner Frage etwas untergegangen. Es sollte heißen „also müsste doch in der default- config bei „location/radicale/“ nach Proxy_pass dann „http://IPdes Pi-A:5232/;“ stehen“.

    Hintergrund dieser Aufteilung war der Gedanke daran, Sachen, welche direkt zum Schutz des internen Netz dienen auf einen separaten Pi „auszulagern“, in diesem Fall den reverseProxy und PiHole.

    Für den Fall, dass das Zertifikat nur bei Neustart von Radicale, übernommen wird, könnte ich ja einen cronjob einrichten, welcher z.B. 15min nach der Erneuerung, Radicale neustartet (per: „systemctl restart radicale“).

    1. Ja, da hast du Recht. Wenn Radicale auf einer anderen Maschine läuft, wird localhost nicht funktionieren. Ob es mit der IP-Adresse stattdessen funktioniert, findet man am ehesten durch ausprobieren heraus 😉 … bzgl. des Setups war mir bis eben nicht klar, dass du nginx als Reverse Proxy konfiguriert hast.

  13. Susann schreibt:

    Hi Sören, vielen Dank für diese sehr gut nachvollziehbare Anleitung.
    Ich habe ein Problem mit bcrypt (Schritt 5d). Wenn ich Radicale mit bcrypt starten will, bekomme ich die Fehlermeldung:

    [76fe8000] ERROR: An exception occurred during server startup: bcrypt: no backends available — recommend you install one (e.g. ‚pip install bcrypt‘)

    Ich habe bcrypt natürlich installiert. Wenn ich erneut ‚pip install bcrypt‘ versuche, bekomme ich auch die Bestätigung, dass es da ist:

    Requirement already satisfied (use –upgrade to upgrade): bcrypt in /usr/local/lib/python2.7/dist-packages
    Requirement already satisfied (use –upgrade to upgrade): cffi>=1.1 in /usr/local/lib/python2.7/dist-packages (from bcrypt)
    Requirement already satisfied (use –upgrade to upgrade): six>=1.4.1 in /usr/local/lib/python2.7/dist-packages (from bcrypt)
    Requirement already satisfied (use –upgrade to upgrade): pycparser in /usr/local/lib/python2.7/dist-packages (from cffi>=1.1->bcrypt)
    Cleaning up…

    Warum findet Radicale es dann nicht? Hast du vielleicht eine Idee?

    Viele Grüße,
    Susann

    1. Hallo Susann,

      wie es aussieht, hast du Python 2.7 installiert. Ich weiß nicht, inwiefern diese Version mit Radicale funktioniert. In der Radicale-Dokumentation wird immer Python 3 verwendet. Vielleicht liegt es daran. Also einfach mal die Installation von bcrypt mit python3 probieren. Vielleicht reicht das schon.

      1. Anonymous schreibt:

        Vielen Dank für die schnelle Antwort und Bingo!

        Tatsächlich habe ich Python 2.7 und Python 3.4 installiert. Radicale läuft mit Python 3.4, bcrypt war aber nur für Python 2.7 installiert. Ich habe jetzt bcrypt mit „python3 -m pip install bcrypt“ auch für Python 3.4 installiert und jetzt läuft es.

        Viele Grüße,
        Susann

  14. Stefan schreibt:

    Hätte jemand für mich, eine sofort funktionierende Lösung? Ich bin selbst mit dieser simplen Anleitung überfordert. Ich habe einen RasPi 3B+ mit dem neuesten Raspbian. Und ich würde gerne CalDAV und CardDAV zum laufen bekommen. Aber ich bleibe bei Schritt 5 hängen. Vorher möchte ich Schritt 4 nicht machen, bevor ich mir nicht sicher bin, dass es auch funktioniert. Ich habe schon diverse Anleitungen durch, die bisher alle Schrott waren. Bei dieser hier funktioniert wenigstens schonmal nginx.

    Mit freundlichen Grüßen

    Stefan

    1. Da müsstest du uns schon ein bisschen mehr verraten. An welcher Stelle hängst du? Welche Fehlermeldung gibt es (falls es eine gibt)?

      Spätestens bei Schritt 5b musst du allerdings einen Pfad zu dem Ordner angeben, wo deine Daten liegen sollen. Wenn du also eine zusätzliche Festplatte hast, sollte der Schritt 4 dann schon abgearbeitet sein.

      1. Stefan schreibt:

        Ich besitze keine externe Festplatte, da ich das erstmal mit der großen Speicherkarte im RasPi testen wollte. Ich habe in die /etc/radicale/config bei

        [server]
        hosts = meine IP:5232

        und bei

        [storage]
        filesystem_folder = /radicale/collections

        eingetragen.

        Und als Fehlermeldung wirft er mir aus: [76f44640] ERROR: An exception occurred during server startup: Failed to parse address ‚MEINE-IP:5232/‘: invalid literal for int() with base 10: ‚5232/‘

        Mit freundlichen Grüßen

        Stefan

          1. Stefan schreibt:

            Ich habe es gerade mal abgeändert. Da wirft er mir leider den gleichen Fehler aus.

            Mit freundlichen Grüßen

            Stefan

          2. Ist der von dir zitierte Auszug aus deiner config-Datei die exakte Kopie? Hintergrund der Frage: Die Fehlermeldung „invalid literal for int() with base 10: ‚5232/‘“ ist eine Python-Fehlermeldung und weist darauf hin, dass der Server einen Ausdruck erwartet, der aus Dezimalzahlen besteht, es anscheinend aber nicht tut. In der Fehlermeldung steht hinter der 5232 ein Schrägstrich „/“. Steht der auch so in der config-Datei (also hosts = 0.0.0.0:5232/ )? Falls ja, probier mal, den wegzulassen.

  15. Stefan schreibt:

    Ja, der steht auch so in der config. Ich probiere es direkt mal aus.

    Jetzt wirft er mir einen anderen Fehler aus.

    [76f53640] ERROR: An exception occurred during server startup: [Errno 13] Permission denied: ‚/radicale‘

    Mit freundlichen Grüßen

    Stefan

    1. Das hatte ich schon befürchtet. Dein Datenverzeichnis liegt im Linux-Wurzelverzeichnis, worauf du nur mit Root-Rechten Zugriff hast. Lege mal das Radicale-Datenverzeichnis unter dem home-Verzeichnis deines Benutzers an (also z.B. /home/BENUTZERNAME/radicale/collections) und schreibe diesen Pfad dann in die config-Datei.

  16. Stefan schreibt:

    Wie kann ich den denn über das Terminal verschieben? Oder muss ich mit rm und in dem anderen Verzeichnis mit mkdir arbeiten?

  17. Stefan schreibt:

    Sobald ich alle Schritte von 5e durchgearbeitet habe und die Services neustarte, wirft er mir bei nginx einen Fehler aus.

    Restarting nginx (via systemctl) nginx.serviceJob for nginx.service failed because the control process exited with error code.
    See „systemctl status nginx.service“ and „journalctl -xe“ for details.
    failed!

  18. Stefan schreibt:

    Bei dem ersten Befehl sagt er mir: Failed to start A high performance web server and a reverse proxy server

    Und bei dem 2. wird mir gar kein Fehler angezeigt.

    1. Ja, das wäre der letzte Schritt. Ich vermute mal, dass dir bei der Bearbeitung der nginx-Konfiguration ein Syntaxfehler unterlaufen ist. Überprüfe noch einmal ganz genau, ob nicht doch irgendwo ein Semikolon oder eine schließende Klammer fehlt etc. Ist schwer, aus der Entfernung zu sagen, woran es liegen könnte.

  19. Stefan schreibt:

    Ich habe dann die Services auch neu gestartet, und auf meiner Box den Port 5232 freigegeben, aber wenn ich von einem anderen Gerät in meinem Netzwerk drauf zugreifen möchte, komme ich nicht drauf.

  20. Thomas schreibt:

    Hallo,

    danke für die Anleitung.
    Hat alles soweit gut funktioniert.

    Nun leider wird meine USB Festplatte später erkannt und der Dienst ist schoin gestartet.
    Wie kann ich den Dienst konfigurieren damit er später startet?

    1. Ohne es ausprobiert zu haben, versuche mal folgendes zu testen:

      Unter Schritt 5c füge in der Datei radicale.service im Abschnitt [Service] über der Zeile ExecStart=[…] folgende Zeile ein: ExecStartPre=/bin/sleep 30

      Dabei steht die 30 für die Zeitverzögerung (30 Sekunden hier). Danach müsstest du den Dienst wahrscheinlich nochmal neu starten: sudo systemctl restart radicale

  21. Jürgen schreibt:

    Hallo,

    beim Lesen hatte ich gedacht „endlich mal eine einfache Anleitung“ und versucht, das bei mir umzusetzen. Auf meinem Raspi läuft allerdings nicht Raspbian, sondern osmc.

    Da ich nicht von außerhalb meines Hausnetzes auf den Server zugreifen will, hatte ich die Punkte 1 und 2 übersprungen. Bei der Installation von nginx habe ich dann aber etliche Fehlermeldungen erhalten (s.u.). Ist evtl. osmc für die Installation von nginx nicht geeignet?

    Setting up nginx-full (1.14.2-2+deb10u3) …
    Job for nginx.service failed because the control process exited with error code.
    See „systemctl status nginx.service“ and „journalctl -xe“ for details.
    invoke-rc.d: initscript nginx, action „start“ failed.
    * nginx.service – A high performance web server and a reverse proxy server
    Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
    Active: failed (Result: exit-code) since Wed 2021-01-13 18:34:00 CET; 62ms ago
    Docs: man:nginx(8)
    Process: 1381 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 1382 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE)

    Jan 13 18:33:59 osmc nginx[1382]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    Jan 13 18:33:59 osmc nginx[1382]: nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
    Jan 13 18:33:59 osmc nginx[1382]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    Jan 13 18:33:59 osmc nginx[1382]: nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
    Jan 13 18:34:00 osmc nginx[1382]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    Jan 13 18:34:00 osmc nginx[1382]: nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
    Jan 13 18:34:00 osmc nginx[1382]: nginx: [emerg] still could not bind()
    Jan 13 18:34:00 osmc systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
    Jan 13 18:34:00 osmc systemd[1]: nginx.service: Failed with result ‚exit-code‘.
    Jan 13 18:34:00 osmc systemd[1]: Failed to start A high performance web server and a reverse proxy server.
    dpkg: error processing package nginx-full (–configure):
    installed nginx-full package post-installation script subprocess returned error exit status 1
    dpkg: dependency problems prevent configuration of nginx:
    nginx depends on nginx-full (<< 1.14.2-2+deb10u3.1~) | nginx-light (<< 1.14.2-2+deb10u3.1~) | nginx-extras (<= 1.14.2-2+deb10u3) | nginx-light (>= 1.14.2-2+deb10u3) | nginx-extras (>= 1.14.2-2+deb1 0u3); however:
    Package nginx-full is not configured yet.
    Package nginx-light is not installed.
    Package nginx-extras is not installed.

    dpkg: error processing package nginx (–configure):
    dependency problems – leaving unconfigured
    Processing triggers for systemd (241-7~deb10u5) …
    Processing triggers for libc-bin (2.28-10) …
    Errors were encountered while processing:
    nginx-full
    nginx
    E: Sub-process /usr/bin/dpkg returned an error code (1)

    1. Ich kenne mich mit OSMC nicht aus. Was ich spontan gefunden habe ist, dass OSMC auf dem Standard Debian basiert und daher nicht alle Raspbian-Pakete enthält. In einer Zeile heißt es ja auch „dependency problems prevent configuration of nginx“, es gibt also Abhängigkeitsprobleme mit fehlenden Paketen. Ohne es ganu zu wissen, müsste man ggf. hier ein zusätzliches Raspbian-Repository einbinden, damit die richtigen Pakete gefunden und installiert werden können.
      Vielleicht bringen dich auch die beiden Befehle in der 3. Zeile der Fehlermeldung weiter. Dort stehen vielleicht mehr Hinweise, was schief läuft. Ich bin leider nicht der Experte, was das angeht. Sorry.

  22. Markus schreibt:

    Hallo Sören,
    vielen Dank für die sehr gute Anleitung. Ich musste aus bekannten Gründen von Baikal auf Radicale umsteigen und mit deiner Anleitung hat es auf Anhieb funktioniert.
    Ich habe lediglich einen anderen Speicherort für die Daten gewählt.
    Vorher sind diverse Anläufe mit anderen Anleitungen, Baikal upzudaten bzw. Radicale zu installieren, kläglich gescheitert.

    Vielen Dank,
    Markus

Schreibe einen Kommentar zu Stefan Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert