Mon serveur relai privé pour Syncthing sous Docker

Je vous propose une image Docker pour avoir votre propre serveur relais pour Syncthing ! Je vous donne toutes les infos dans cette article !

Qu’est-ce que Syncthing ?

Syncthing est un outils que vous pouvez héberger vous même sur un PC, voir une Raspberry Pi, pour synchroniser des fichiers entre différents périphériques. Il s’appuie sur le protocole BEP (Block Exchange Protocol), vous choisissez pour chaque partage avec quels périphériques synchroniser et seulement les vôtres. Les communications sont chiffrés avec TLS et les périphériques s’authentifie avec un certificat et un identifiant unique, généré à partir de ce certificat.

Il est disponible pour Windows, macOS, Linux, OpenBSD, NetBSD, FreeBSD et Android.

Pourquoi ce logiciel ?

Tout d’abord, un peu d’information. Avant, comme tout utilisateur lambda, j’utilisais soit OneDrive ou Google Drive pour synchroniser des données entre mes différents périphériques. Et plus particulièrement mes notes sous Obsidian.

Mais j’avais un problème quand j’ai commencé à vouloir l’utiliser sur mon smartphone. Obsidian oblige à utiliser un répertoire local sur téléphone et me demandait de payer un abonnement à leur service Sync. Même si c’est quelques choses que j’utilise au quotidien, autant professionnellement que personnellement, je n’ai pas spécialement les moyens financier.

Et un jour, au détour d’un post sur Reddit dans /r/selfhosted, je vois plusieurs utilisateurs parler de Syncthing. Après un rapide coup d’œil, je pense que cette solution peut m’aider !

Première chose qui m’a plu : l’utilisation d’une interface web ! Pas de CLI1 ou de client GUI2 lourd ! L’autre point qui en plus de m’avoir plu, m’a positivement surpris, c’est sa capacité à synchroniser en temps réel dès qu’une modification est détecté !

De plus, il permet de gérer les différentes versions des fichiers qu’il synchronise avec une durée de conservation. Ca ne fait pas office de sauvegarde, mais c’est une première protection à une suppression accidentelle.

Enfin, tout n’est pas tout beau tout rose, il y a un point que je trouve complexe, c’est la gestion des ID ! Pourquoi donc générer des ID aussi long ? Surtout quand pour les trouver ce n’est pas intuitif ! Mais bon, il faut aussi des points négatifs, si c’était parfait, on s’ennuierait !

Mais alors, pourquoi un serveur relais ?

C’est là où ce serveur rentre en jeu ! De base, Syncthing met à disposition des serveurs relais qui seront utilisé si les communications TCP3 ou QUIC4 directe ne sont pas possible entre vos périphériques. Mais, le problème de Syncthing, c’est que :

  • Il utilise des ports non standards pour la découverte (22000, 22067, etc.)
  • Il est étiqueté comme un logiciel de Peer-to-Peer (ce qui n’est pas totalement faux)

Et donc, sur mon ordinateur de travail pro, impossible de l’utiliser. J’avais donc mis en place RClone sur ma Raspberry Pi, pour faire des synchronisation bidirectionnelle entre le répertoire local et mon OneDrive.

Les ennuis ne firent que commencer… Entre les planifications toutes les 15 minutes qui peuvent retarder jusqu’à une heure pour que j’ai mes notes prisent en réunion sur téléphone, vers mon ordinateur et, sans compter les erreurs de synchronisations (fichiers corrompus) voir même des arrêt de synchronisation pour aucune raison. Qui plus est, cela demande une intervention manuelle pour forcer la synchronisation d’un un seul sens pour restaurer tout ça !

Il fallait donc que je trouve une solution ! Le relais ! Mais ce n’était pas gagner d’avance !

La solution de contournement !

Comme je l’ai dis plus haut, je ne pouvais pas utiliser le port standard de Syncthing, mon entreprise n’autorise en sortie que le 80, 443 et 8080.

Mais mon choix était limité ! Le 80 et 443 sont utilisé par mon Nginx Proxy Manager5 en reverse proxy6 ! Je n’avais donc que le port 8080 de disponible. Me suffisait donc de l’exploiter.

J’utilise beaucoup (seulement) Docker comme solution d’hébergement, cela permet une grande flexibilité et, surtout peut fonctionner n’importe où, tant que l’architecture processeur est supporté par l’application containerisé.

Je trouve que Syncthing eux-mêmes fournissent une image Docker sur GitHub ! Parfait, sauf que…

Par défaut, un relai Syncthing est publique, cela signifie qu’il se présente au pool par défaut et que n’importe qui peut être amener à l’utiliser. Voulant l’héberger localement, en terme de sécurité je ne suis pas très ouvert à ça. Et leur image ne permet pas d’exclure au pool ou d’ajouter une passphrase (qu’ils appellent token) pour verrouiller. Je cherche désespérément une autre image, mais même chez LinuxServer.io ils n’en n’ont pas… Il ne me reste qu’une solution : construire mon image Docker !

Ma propre image Docker !

C’est donc avec grand plaisir que je vous propose une image Docker si vous souhaitez l’utiliser aussi ! Le code source est disponible sur GitHub et l’image sur le Docker Hub officiel !

Petite parenthèse sur la construction

Tout d’abord, je me suis basé à la fois sur l’image officiel de Syncthing pour le relai7 et sur la manière de LinuxServer.io de le faire. De là, j’ai aussi appris à utiliser s6-overlay8 qui permet d’exécuter plusieurs actions ou services dans un container.

Les labels dans l’image font à référence à Syncthing, c’est leurs applications, même Opensource, je me dois de les citer !

Détails de l’image

Architectures supportés

Faites un simple pull de chucky2401/syncrelay:tagversion pour récupérer l’image qui correspond à votre architecture.

Utilisation

Vous pouvez utiliser docker compose (recommandé) ou la ligne de commande docker cli.

docker compose (recommandé)

Le code ci-dessous vous permet de lancer un serveur Syncthing relai par défaut (donc publique !)

services:
  syncrelay:
    image: chucky2401/syncrelay:1.0.0
    container_name: syncrelay
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - ./strelaysrv:/var/strelaysrv
    ports:
      - 22067:22067
      - 22070:22070
    restart: unless-stopped
docker cli
docker run -d \
  --name=syncrelay \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Etc/UTC \
  -p 22067:22067 \
  -p 22070:22070 \
  -v /path/to/syncthing/strelaysrv:/var/strelaysrv
  --restart unless-stopped \
  chucky2401/syncrelay:1.0.0

Paramètres

ParameterDefaultFunction
-p 22067N/APort pour que le relai s’annonce
-p 22070N/APort pour les statistiques d’utilisation
-e PUID=1000N/AID utilisateur utilisé pour les fichiers sur l’hôte des volumes
-e PGID=1000N/AID du groupe utilisé pour les fichiers sur l’hôte des volumes
-e TZ=Etc/UTCN/ASpécifier un fuseau horaire, voir la liste.
-e TOKEN=MyTokenEmptyAjouter un token à votre relais pour le sécuriser. Désactive la jointure aux pools de serveurs.
-e PRIVATE=TrueEmptyDéfinir le relai privé. Ne s’annoncera pas auprès du pool de serveur. Si non définis, il s’annoncera au pool par défaut (https://relays.syncthing.net/endpoint)
-e PORT=22067Si vous définissez un port différent du côté de l’hôte Docker pour les annonces du relai – Voir plus bas pour plus d’information
-e EXTERNAL_ADDRESS=EmptySi vous voulez fixer l’adresse externe de communication
-v /var/strelaysrvN/AFichiers de configuration. Important pour que l’ID du serveur ne change pas

Variable d’environnement depuis les secrets (Docker secrets)

Vous pouvez définir une variable d’environnement depuis un fichier en utilisant le préfix SECRET__.

Example:

-e SECRET__TOKEN=/run/secrets/mysupertoken

Définira la variable TOKEN sur le contenu du fichier /run/secrets/mysupertoken.

Note: Je vous recommande d’utiliser ce format pour passer votre token

Example:

services:
  syncrelay:
    image: chucky2401/syncrelay:1.0.0
    container_name: syncrelay
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - SECRET_TOKEN=/run/secrets/mysupertoken
    secrets:
      - mysupertoken
    volumes:
      - ./strelaysrv:/var/strelaysrv
    ports:
      - 22067:22067
      - 22070:22070
    restart: unless-stopped
secrets:
  mysupertoken:
    file: ./secrets/token_file

Vous pouvez ne pas définir la variable d’environnement et juste utiliser le secret.

ATTENTION: soyez informé que le container attend la variable TOKEN, pas écrit autrement.

services:
  syncrelay:
    image: chucky2401/syncrelay:1.0.0
    container_name: syncrelay
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    secrets:
      - TOKEN
    volumes:
      - ./strelaysrv:/var/strelaysrv
    ports:
      - 22067:22067
      - 22070:22070
    restart: unless-stopped
secrets:
  TOKEN:
    file: ./secrets/token_file

Utiliser la variable port

Je ne vais pas redire ce que j’ai dis plus haut sur les ports autorisés dans ma société. Donc j’utilise ce fichier compose.yml

services:
  syncrelay:
    image: chucky2401/syncrelay:1.0.0
    container_name: syncrelay
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - SECRET_TOKEN=/run/secrets/mysupertoken
      - PORT=8080
    secrets:
      - mysupertoken
    volumes:
      - ./strelaysrv:/var/strelaysrv
    ports:
      - 22067:22067
      - 22070:22070
    restart: unless-stopped
secrets:
  mysupertoken:
    file: ./secrets/token_file

Dans ce cas, strelaysrv est démarré avec l’argument -ext-address=:8080, parce que le serveur doit savoir sur quel port le client essaiera de le contacter.

Note: Dans mon cas j’utilise NGinX Proxy Manager pour stream le port 8080 vers le port 22067 de mon hôte Docker.

Si vous n’utilisez pas de reverse proxy, vous devrez mettre votre port dans le compose.yml:

ports:
      - 8080:22067

Conclusion

Maintenant je peux me passer de RClone pour synchroniser mes notes Obsidian et le faire directement avec Syncthing. L’avantage aussi, c’est que ma Raspberry sert de serveur, donc ça passe forcément par elle avant d’aller sur les autres périphériques. Donc je suis sûr d’avoir une copie avant de mettre à jour un client et donc de faire une version différente du fichier.

Je voulais aussi partager ça avec d’autres qui pourrait en avoir besoin ou qui souhaite aussi apprendre de ce que j’ai fait. Je ne suis pas rentré dans les détails techniques, surtout sur s6-overlay, mais vous pouvez venir sur Discord ou sur tous autres moyen de communications pour venir en discuter avec moi !

N’hésitez pas à passer sur le GitHub mettre une étoile 😋 ou voire mes autres dépôts !

Je vous invite à faire un tour sur les autres articles de mon blog


  1. CLI : Command Line Interface (Interface en ligne de commande) ↩︎
  2. GUI : Graphical User Interface (Interface utilisateur graphique) ↩︎
  3. https://www.ionos.fr/digitalguide/serveur/know-how/presentation-de-tcp/#c219607 ↩︎
  4. https://www.ionos.fr/digitalguide/hebergement/aspects-techniques/quic/#c151493 ↩︎
  5. https://github.com/NginxProxyManager/nginx-proxy-manager ↩︎
  6. https://www.ionos.fr/digitalguide/serveur/know-how/quest-ce-quun-reverse-proxy-le-serveur-reverse-proxy/ ↩︎
  7. Fichier Dockerfile ↩︎
  8. https://github.com/just-containers/s6-overlay ↩︎

Leave a Reply

Your email address will not be published.Required fields are marked *

Facebook Twitter Instagram YouTube