commit af5fe5074c7686037526b5f983131ba5794e030e Author: Mateusz GruszczyƄski Date: Thu Jan 15 14:10:13 2026 +0100 first commit diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..41ca75a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +FROM debian:trixie-slim + +RUN apt update \ + && apt -y upgrade \ + && apt install --no-install-recommends -y supervisor iproute2 iputils-ping openssh-server procps corosync-qnetd \ + && apt -y autoremove \ + && apt clean all + +RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config +RUN sed -i 's/^#Port 22/Port 22/' /etc/ssh/sshd_config && \ + grep -qE '^Port 22$' /etc/ssh/sshd_config || echo 'Port 22' >> /etc/ssh/sshd_config && \ + grep -qE '^Port 11922$' /etc/ssh/sshd_config || echo 'Port 11922' >> /etc/ssh/sshd_config + +RUN grep -q '^UsePAM' /etc/ssh/sshd_config && \ + sed -i 's/^UsePAM.*/UsePAM yes/' /etc/ssh/sshd_config || \ + echo 'UsePAM yes' >> /etc/ssh/sshd_config + +COPY set_root_password.sh /usr/local/bin/set_root_password.sh +RUN chown root.root /usr/local/bin/set_root_password.sh \ + && chmod 755 /usr/local/bin/set_root_password.sh + +RUN mkdir -p /run/sshd +RUN mkdir -p /etc/update-motd.d +COPY motd-qdevice.sh /etc/update-motd.d/20-qdevice +RUN chmod 755 /etc/update-motd.d/20-qdevice +RUN : > /etc/motd + +COPY supervisord.conf /etc/supervisord.conf + +EXPOSE 22 +EXPOSE 11922 +EXPOSE 5403 + +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..6aaad5e --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# Proxmox Qdevice + +This repository will allow you build and deploy a docker container for use with a proxmox cluster as an external qdevice. Properly configured proxmox clusters require an odd number servers in the cluster. In the event that you have an even number of proxmox servers (like 2, such as I have), you need an another device to vote. Proxmox supports this by allow you to configure a qdevice for an external vote. + +Normally running an even number of servers in a cluster isn't a problem, but I've had situations where I've booted both promox servers at the same time. In that case, the first server to come online doesn't have a quarum (1 of 2) so the images won't start. The 2nd server will (2 of 2). With an external qdevice thats already up, the first device to come up has quarom (2 of 3). + +For more information on proxmmox clusters, external qdevices, and how to configure/use them, go [here](https://pve.proxmox.com/wiki/Cluster_Manager#_corosync_external_vote_support). + +Run this container on a device that is *NOT* a virtual instance on one of your proxmox servers. + +# Build and upload to RouterOS device (x86): + +1. Build +``` +docker build -t proxmox-qdevice . +``` +2. Save +``` +docker save proxmox-qdevice:latest -o proxmox-qdevice.tar +``` +3. Upload to RouteOS device +``` +scp -P 22 proxmox-qdevice.tar admin@10.0.0.1: +``` + +# Run on RouterOS +1. Prepare network, vlans, veth (name: veth-qdevice), etc. + +2. Add ENV +``` +ssh +/container envs +add comment=env-qdevice key=NEW_ROOT_PASSWORD list=env-qdevice value=SSH_PASSWD_FOR_CONTAINER +``` +3. Create container + +``` +/container +add dns=DNS_ADDRESS envlists=env-qdevice file=proxmox-qdevice.tar hostname=qdevice interface=veth-qdevice layer-dir="" logging=yes name=proxmox-qdevice \ + root-dir=/containers/proxmox-qdevice/root start-on-boot=yes +``` + +4. Start + +``` +/container/start proxmox-qdevice +``` + +5. Test +``` +/system ssh CONTAINER-IP user=root port=22 +``` \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1cc57d0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,30 @@ +services: + qnetd: + container_name: proxmox-qdevice + build: . + ports: + - "22:22" + - "11922:11922" + - "5403:5403" + environment: + - VAR=example + volumes: + - /run/sshd + - :/etc/corosync + restart: unless-stopped + hostname: + networks: + vlan: + ipv4_address: + +networks: + vlan: + driver: macvlan + driver_opts: + parent: + ipam: + driver: default + config: + - subnet: "/32" + gateway: "" diff --git a/motd-qdevice.sh b/motd-qdevice.sh new file mode 100644 index 0000000..a1d7cc7 --- /dev/null +++ b/motd-qdevice.sh @@ -0,0 +1,25 @@ +#!/bin/sh +set -eu + +echo "=== Proxmox qdevice (corosync-qnetd) ===" + +echo +echo "IPs:" +ip -br addr show scope global 2>/dev/null | awk '{print " - " $1 " " $3}' + +echo +echo "sshd_config Ports:" +grep -E '^[[:space:]]*Port[[:space:]]+[0-9]+' /etc/ssh/sshd_config 2>/dev/null \ + | awk '{print " - TCP " $2}' || true + +echo +echo "Listening sockets (ss):" +ss -H -lntup 2>/dev/null | awk '{print " - " $1 " " $5 " " $7}' || true + +echo +echo "qnetd process:" +ps -ef 2>/dev/null | grep -E '[c]orosync-qnetd' || echo " - corosync-qnetd: not running" + +echo +echo "Notes:" +echo " - corosync-qnetd typically uses TCP/5403 (unless started with -p)." diff --git a/proxmox-qdevice.tar b/proxmox-qdevice.tar new file mode 100644 index 0000000..fa5e982 Binary files /dev/null and b/proxmox-qdevice.tar differ diff --git a/routeros_start.txt b/routeros_start.txt new file mode 100644 index 0000000..00fe274 --- /dev/null +++ b/routeros_start.txt @@ -0,0 +1,2 @@ +/container envs +add comment=env-qdevice key=NEW_ROOT_PASSWORD list=env-qdevice value=SSH_PASSWD_FOR_CONTAINER \ No newline at end of file diff --git a/set_root_password.sh b/set_root_password.sh new file mode 100644 index 0000000..e05b14b --- /dev/null +++ b/set_root_password.sh @@ -0,0 +1,6 @@ +#!/bin/sh -x + +if [ ! -z ${NEW_ROOT_PASSWORD+x} ] +then + echo "root:${NEW_ROOT_PASSWORD}" | chpasswd +fi diff --git a/supervisord.conf b/supervisord.conf new file mode 100644 index 0000000..ad21b19 --- /dev/null +++ b/supervisord.conf @@ -0,0 +1,19 @@ +[supervisord] +nodaemon=true +user=root + +[program:set_root_password] +command=/usr/local/bin/set_root_password.sh +priority=100 +autorestart=false +exitcodes=0 +startsecs=0 +startretries=0 + +[program:sshd] +command=/usr/sbin/sshd -D +priority=200 + +[program:corosync-qnetd] +command=/usr/bin/corosync-qnetd -f +priority=200