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.
- 🔒 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.
During pvecm qdevice setup, Proxmox connects to the QDevice host over SSH to bootstrap certificates/keys.
After the setup is detected, this container:
- Creates a persistent lock file:
./persistent_data/SSH_DISABLED - Stops the SSH daemon (port 22 becomes closed/refused)
- Keeps only QNetd running (port 5403)
If you ever need to redo the setup:
rm -f persistent_data/SSH_DISABLED
docker restart proxmox-qdeviceIf you want to disable SSH immediately:
touch persistent_data/SSH_DISABLED
docker restart proxmox-qdevicePassword 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 32Security & 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:22so Proxmox tools can use SSH without extra port tricks.
Also ensure:
- Port
5403/TCPis reachable from all Proxmox nodes to the Synology NAS. - Time is synced (NTP) on all Proxmox nodes (recommended for stable clusters).
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- Create the data folder (required):
mkdir -p persistent_data- Create
.envfile (from.env.example):
cp .env.example .env- Edit
.envand set a strong password:
# Generate a strong password
openssl rand -base64 32
# Then edit .env and replace ROOT_PASSWORD value
nano .envOptional: 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)
docker-compose up -d --build(If you use the newer plugin: docker compose up -d --build)
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
yesto accept the SSH fingerprint. - Enter the password you set in
ROOT_PASSWORD(from your.envfile).
After the setup, wait up to ~2 minutes:
- SSH will be stopped automatically.
- The file
persistent_data/SSH_DISABLEDwill appear.
Check the status on any Proxmox node:
pvecm statusYou 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
# 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# 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># On the Proxmox node, remove old fingerprint
ssh-keygen -R <NAS_IP>
# Retry the setup
pvecm qdevice setup <NAS_IP>- 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# 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- 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.
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-qdeviceFor integration with monitoring systems (Prometheus/Grafana), you'll need a custom exporter as QNetd doesn't expose native metrics.
Expected files in the repo:
docker-compose.ymlDockerfileentrypoint.shauto_lock.sh(auto-disables SSH after successful setup)healthcheck.shsupervisord.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
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.
- 🔒 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.
Pendant pvecm qdevice setup, Proxmox se connecte au QDevice en SSH pour initialiser les certificats/clefs.
Une fois le setup détecté, le conteneur :
- Crée un fichier témoin persistant :
./persistent_data/SSH_DISABLED - Coupe le démon SSH (le port 22 ne répond plus)
- Laisse uniquement QNetd actif (port 5403)
Si vous devez refaire le setup :
rm -f persistent_data/SSH_DISABLED
docker restart proxmox-qdevicePour couper SSH immédiatement :
touch persistent_data/SSH_DISABLED
docker restart proxmox-qdeviceSé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:22pour que les outils Proxmox fonctionnent simplement.
Vérifiez aussi :
- Le port
5403/TCPdoit être joignable depuis tous les nœuds Proxmox vers le NAS. - Synchronisation de l'heure (NTP) sur les nœuds Proxmox (recommandé).
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- Créer le dossier de données :
mkdir -p persistent_data- Créer le fichier
.env(depuis.env.example) :
cp .env.example .env- Éditer
.envet 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 .envOptionnel : 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)
docker-compose up -d --build(ou docker compose up -d --build selon votre installation)
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
yespour 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_DISABLEDapparaît.
Sur n'importe quel nœud Proxmox :
pvecm statusVous 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
# 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# 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># Sur le nœud Proxmox, supprimer l'ancienne empreinte
ssh-keygen -R <IP_NAS>
# Réessayer le setup
pvecm qdevice setup <IP_NAS>- 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# 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 --buildPour 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-qdeviceFichiers attendus dans le dépôt :
docker-compose.ymlDockerfileentrypoint.shauto_lock.sh(désactive SSH automatiquement après setup)healthcheck.shsupervisord.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