Skip to content

Repository files navigation

Proxmox QDevice for Synology (Docker)

A lightweight, secure, and persistent Corosync QNetd (QDevice) container designed to run on a Synology NAS via Docker.

This container acts as a third voter (tie-breaker) for your 2-node Proxmox VE cluster, helping maintain quorum if one node fails.

✨ Features

  • 🔒 Secure by default after setup: SSH is enabled only for the initial Proxmox setup, then automatically disabled.
  • 💾 Persistent: Keeps SSH host keys and Corosync QNetd NSS DB across reboots/rebuilds (stored in ./persistent_data).
  • 🚀 Lightweight: Based on Debian Slim, minimal footprint.
  • 🧰 Self-healing: Idempotent startup (safe restarts), auto-initializes QNetd cert DB if missing.
  • 🩺 Healthcheck: Docker healthcheck verifies QNetd responsiveness.

🔐 Security model (important)

During pvecm qdevice setup, Proxmox connects to the QDevice host over SSH to bootstrap certificates/keys. After the setup is detected, this container:

  1. Creates a persistent lock file: ./persistent_data/SSH_DISABLED
  2. Stops the SSH daemon (port 22 becomes closed/refused)
  3. Keeps only QNetd running (port 5403)

Re-enable SSH later (maintenance / re-setup)

If you ever need to redo the setup:

rm -f persistent_data/SSH_DISABLED
docker restart proxmox-qdevice

Force-disable SSH manually

If you want to disable SSH immediately:

touch persistent_data/SSH_DISABLED
docker restart proxmox-qdevice

Authentication Methods

Password Authentication (Default - Recommended for setup isolation)

This container uses password-based SSH authentication by default, which is acceptable because:

  • SSH is only active for ~2-5 minutes during initial setup
  • The container should be on an isolated management network (not public internet)
  • SSH auto-disables permanently after cluster connection
  • Password is only stored in your local docker-compose.yml

Generate a strong password:

openssl rand -base64 32

⚠️ Prerequisites (Synology)

Security & Port Conflict: Synology often uses port 22 for its own SSH service. This container also needs port 22 during the Proxmox setup phase.

Recommended approach:

  • Change Synology SSH port to a custom one (e.g. 2222) in DSM.
  • Keep this container mapped as 22:22 so Proxmox tools can use SSH without extra port tricks.

Also ensure:

  • Port 5403/TCP is reachable from all Proxmox nodes to the Synology NAS.
  • Time is synced (NTP) on all Proxmox nodes (recommended for stable clusters).

🛠️ Installation

1) Download the project

SSH into your Synology (or use a terminal) and clone the repository:

cd /volume1/docker/
git clone https://github.com/antibill51/synology-proxmox-qdevice.git
cd synology-proxmox-qdevice

2) Configuration

  1. Create the data folder (required):
mkdir -p persistent_data
  1. Create .env file (from .env.example):
cp .env.example .env
  1. Edit .env and set a strong password:
# Generate a strong password
openssl rand -base64 32

# Then edit .env and replace ROOT_PASSWORD value
nano .env

Optional: Adjust environment variables if needed:

  • ROOT_PASSWORD - SSH root password (used only during setup, ~2-5 minutes)
  • AUTO_LOCK_WAIT - Delay before locking (default: 120 seconds)
  • AUTO_LOCK_THRESHOLD - Cluster detection threshold (default: 3)
  • TZ - Timezone for logs (default: Europe/Paris)

3) Build & Run

docker-compose up -d --build

(If you use the newer plugin: docker compose up -d --build)

4) Connect Proxmox

On one of your Proxmox nodes, run:

# 1. Install qdevice support (if not already present)
apt update && apt install corosync-qdevice

# 2. Add the QDevice (replace with your NAS IP)
pvecm qdevice setup <YOUR_NAS_IP>
  • Type yes to accept the SSH fingerprint.
  • Enter the password you set in ROOT_PASSWORD (from your .env file).

After the setup, wait up to ~2 minutes:

  • SSH will be stopped automatically.
  • The file persistent_data/SSH_DISABLED will appear.

🔍 Verification

Check the status on any Proxmox node:

pvecm status

You should see the QDevice as online:

Votequorum information
----------------------
Expected votes:   3
Highest expected: 3
Total votes:      3
Quorum:           2
Flags:            Quorate Qdevice

Membership information
----------------------
    Nodeid      Votes    Qdevice Name
         1          1    A,V,NMW node1
         2          1    A,V,NMW node2
         0          1            Qdevice

🔧 Troubleshooting

SSH doesn't auto-disable after setup

# Check autolock logs
docker logs proxmox-qdevice -f | grep AUTOLOCK

# Verify cluster connection
docker exec proxmox-qdevice corosync-qnetd-tool -l

# Manually trigger lock (if cluster is connected)
docker exec proxmox-qdevice touch /data/SSH_DISABLED
docker restart proxmox-qdevice

"Connection refused" during pvecm qdevice setup

# Check if SSH is running in the container
docker exec proxmox-qdevice supervisorctl status sshd

# Verify port mapping
docker port proxmox-qdevice

# Test SSH connection from Proxmox node
ssh -v root@<NAS_IP>

"Host key verification failed" error

# On the Proxmox node, remove old fingerprint
ssh-keygen -R <NAS_IP>

# Retry the setup
pvecm qdevice setup <NAS_IP>

QDevice shows as "Not alive" in pvecm status

  • Verify port 5403/TCP is reachable from all Proxmox nodes:
# From each Proxmox node
nc -zv <NAS_IP> 5403
  • Check firewall rules on Synology NAS (DSM Control Panel → Security → Firewall)
  • Verify container is healthy:
docker ps  # Should show "healthy" status
docker logs proxmox-qdevice

Complete reset (clean slate)

# On Proxmox cluster (all nodes)
pvecm qdevice remove

# On Synology
cd /volume1/docker/synology-proxmox-qdevice
docker-compose down
sudo rm -rf persistent_data/*
docker-compose up -d --build

⚠️ Known Limitations

  • No TLS client certificate verification: By default, QNetd accepts connections without client cert validation. For maximum security in production, consider configuring corosync-qnetd -c required (requires additional manual setup).
  • Temporary SSH exposure: Port 22 is exposed during setup (~2-5 minutes). Ensure this window is protected by network isolation or firewall rules.
  • Single cluster support: This implementation is designed for one Proxmox cluster. Multiple clusters require separate QDevice instances.
  • No automatic log rotation: Container logs are sent to Docker's logging driver. Configure Docker log rotation if needed.

📊 Monitoring

To monitor QDevice health in your infrastructure:

# Quick status check
docker exec proxmox-qdevice corosync-qnetd-tool -s

# List connected clusters
docker exec proxmox-qdevice corosync-qnetd-tool -l

# View live logs
docker logs -f proxmox-qdevice

For integration with monitoring systems (Prometheus/Grafana), you'll need a custom exporter as QNetd doesn't expose native metrics.

📁 Project files

Expected files in the repo:

  • docker-compose.yml
  • Dockerfile
  • entrypoint.sh
  • auto_lock.sh (auto-disables SSH after successful setup)
  • healthcheck.sh
  • supervisord.conf (base supervisor config with include)
  • qnetd.sv.conf (supervisor program: corosync-qnetd)
  • sshd.sv.conf (supervisor program: sshd, enabled only during setup)
  • autolock.sv.conf (supervisor program: autolock, enabled only during setup)
  • ARCHITECTURE.md (internal architecture documentation)
  • LICENSE

🇫🇷 Version Française

Un conteneur Corosync QNetd (QDevice) léger, sécurisé et persistant conçu pour fonctionner sur NAS Synology via Docker.

Ce conteneur agit comme un troisième votant (arbitre) pour votre cluster Proxmox VE à 2 nœuds, afin de préserver le quorum si un nœud tombe.

✨ Fonctionnalités

  • 🔒 Sécurisé après setup : SSH est actif uniquement pour le paramétrage initial Proxmox, puis désactivé automatiquement.
  • 💾 Persistant : Conserve les clés d'hôte SSH et la base NSS de QNetd après redémarrage/rebuild (dans ./persistent_data).
  • 🚀 Léger : Basé sur Debian Slim.
  • 🧰 Fiable : Démarrage idempotent (redémarrages sans casse), init automatique de la DB certs si absente.
  • 🩺 Healthcheck : Healthcheck Docker qui vérifie que QNetd répond.

🔐 Modèle de sécurité (important)

Pendant pvecm qdevice setup, Proxmox se connecte au QDevice en SSH pour initialiser les certificats/clefs. Une fois le setup détecté, le conteneur :

  1. Crée un fichier témoin persistant : ./persistent_data/SSH_DISABLED
  2. Coupe le démon SSH (le port 22 ne répond plus)
  3. Laisse uniquement QNetd actif (port 5403)

Réactiver SSH plus tard (maintenance / refaire un setup)

Si vous devez refaire le setup :

rm -f persistent_data/SSH_DISABLED
docker restart proxmox-qdevice

Désactiver SSH manuellement

Pour couper SSH immédiatement :

touch persistent_data/SSH_DISABLED
docker restart proxmox-qdevice

⚠️ Prérequis (Synology)

Sécurité et conflit de port : Synology utilise souvent le port 22 pour son SSH. Le conteneur a aussi besoin du port 22 pendant la phase de setup.

Approche recommandée :

  • Changer le port SSH du Synology (ex : 2222) dans DSM.
  • Garder le conteneur mappé en 22:22 pour que les outils Proxmox fonctionnent simplement.

Vérifiez aussi :

  • Le port 5403/TCP doit être joignable depuis tous les nœuds Proxmox vers le NAS.
  • Synchronisation de l'heure (NTP) sur les nœuds Proxmox (recommandé).

🛠️ Installation

1) Télécharger le projet

Connectez-vous en SSH à votre Synology et clonez le dépôt :

cd /volume1/docker/
git clone https://github.com/antibill51/synology-proxmox-qdevice.git
cd synology-proxmox-qdevice

2) Configuration

  1. Créer le dossier de données :
mkdir -p persistent_data
  1. Créer le fichier .env (depuis .env.example) :
cp .env.example .env
  1. Éditer .env et définir un mot de passe fort :
# Générer un mot de passe fort
openssl rand -base64 32

# Puis éditer .env et remplacer la valeur ROOT_PASSWORD
nano .env

Optionnel : Ajuster les variables d'environnement si nécessaire :

  • ROOT_PASSWORD - Mot de passe root SSH (utilisé uniquement pendant le setup, ~2-5 minutes)
  • AUTO_LOCK_WAIT - Délai avant verrouillage (défaut : 120 secondes)
  • AUTO_LOCK_THRESHOLD - Seuil de détection du cluster (défaut : 3)
  • TZ - Fuseau horaire des logs (défaut : Europe/Paris)

3) Lancer le conteneur

docker-compose up -d --build

(ou docker compose up -d --build selon votre installation)

4) Connecter Proxmox

Sur un nœud Proxmox :

# 1. Installer le support qdevice (si nécessaire)
apt update && apt install corosync-qdevice

# 2. Ajouter le QDevice
pvecm qdevice setup <VOTRE_IP_NAS>
  • Tapez yes pour accepter l'empreinte SSH.
  • Entrez le mot de passe défini dans ROOT_PASSWORD (depuis votre fichier .env).

Après le setup, patientez jusqu'à ~2 minutes :

  • SSH est coupé automatiquement.
  • Le fichier persistent_data/SSH_DISABLED apparaît.

🔍 Vérification

Sur n'importe quel nœud Proxmox :

pvecm status

Vous devriez voir :

Votequorum information
----------------------
Expected votes:   3
Highest expected: 3
Total votes:      3
Quorum:           2
Flags:            Quorate Qdevice

Membership information
----------------------
    Nodeid      Votes    Qdevice Name
         1          1    A,V,NMW node1
         2          1    A,V,NMW node2
         0          1            Qdevice

🔧 Dépannage

SSH ne se désactive pas automatiquement

# Vérifier les logs autolock
docker logs proxmox-qdevice -f | grep AUTOLOCK

# Vérifier la connexion du cluster
docker exec proxmox-qdevice corosync-qnetd-tool -l

# Forcer le verrouillage manuellement (si cluster connecté)
docker exec proxmox-qdevice touch /data/SSH_DISABLED
docker restart proxmox-qdevice

"Connection refused" pendant pvecm qdevice setup

# Vérifier si SSH tourne dans le conteneur
docker exec proxmox-qdevice supervisorctl status sshd

# Vérifier le mapping de ports
docker port proxmox-qdevice

# Tester la connexion SSH depuis le nœud Proxmox
ssh -v root@<IP_NAS>

Erreur "Host key verification failed"

# Sur le nœud Proxmox, supprimer l'ancienne empreinte
ssh-keygen -R <IP_NAS>

# Réessayer le setup
pvecm qdevice setup <IP_NAS>

QDevice affiché comme "Not alive" dans pvecm status

  • Vérifier que le port 5403/TCP est joignable depuis tous les nœuds Proxmox :
# Depuis chaque nœud Proxmox
nc -zv <IP_NAS> 5403
  • Vérifier les règles de pare-feu sur le NAS Synology (Panneau DSM → Sécurité → Pare-feu)
  • Vérifier l'état du conteneur :
docker ps  # Doit afficher "healthy"
docker logs proxmox-qdevice

Réinitialisation complète

# Sur le cluster Proxmox (tous les nœuds)
pvecm qdevice remove

# Sur le Synology
cd /volume1/docker/synology-proxmox-qdevice
docker-compose down
sudo rm -rf persistent_data/*
docker-compose up -d --build

📊 Surveillance

Pour surveiller la santé du QDevice :

# Vérification rapide du statut
docker exec proxmox-qdevice corosync-qnetd-tool -s

# Lister les clusters connectés
docker exec proxmox-qdevice corosync-qnetd-tool -l

# Voir les logs en direct
docker logs -f proxmox-qdevice

📁 Fichiers du projet

Fichiers attendus dans le dépôt :

  • docker-compose.yml
  • Dockerfile
  • entrypoint.sh
  • auto_lock.sh (désactive SSH automatiquement après setup)
  • healthcheck.sh
  • supervisord.conf (configuration de base supervisor)
  • qnetd.sv.conf (programme supervisor : corosync-qnetd)
  • sshd.sv.conf (programme supervisor : sshd, actif uniquement pendant setup)
  • autolock.sv.conf (programme supervisor : autolock, actif uniquement pendant setup)
  • ARCHITECTURE.md (documentation de l'architecture interne)
  • LICENSE

About

Proxmox QDevice for Synology (Docker)

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages