Vollständige Installations-Anleitung · Praxis-Version

NetWatch auf Proxmox + Debian 13

Schritt-für-Schritt: Proxmox-VM → Debian-Installation → Absicherung → NetWatch-Service auf Port 3579. Inkl. Workarounds für die häufigsten Fallstricke.

Diese Anleitung verwendet die Ziel-IP 192.168.178.101, Hostname netwatch, Benutzer steffen. Falls du andere Werte nutzt, in allen Befehlen ersetzen.
Wichtige Vorabinfo — Mac-Terminal-Falle: Die macOS Terminal.app bricht beim Einfügen lange Zeilen visuell um und fügt teilweise Leerzeichen ein. Das zerschießt klassische Heredoc-Blöcke (<<EOF) und lange scp/sed-Zeilen. Diese Anleitung verwendet deshalb durchweg das Zeile-für-Zeile-Muster: kurze Befehle < 80 Zeichen, Datei wird mit mehreren echo ... >> datei in einer Root-Shell aufgebaut. Robust und paste-fest.
Inhalt
  1. Proxmox: VM anlegen
  2. Debian-Installation Schritt für Schritt
  3. Erste Anmeldung & System aktualisieren
  4. Statische IP setzen (192.168.178.101)
  5. Absicherung Schritt für Schritt
  6. Quellcode auf die VM kopieren
  7. Installer ausführen
  8. Token sichern & Aufrufen
  9. Betrieb & Troubleshooting
  10. Hinweis: LXC statt VM

1 Proxmox: VM anlegen

1.1 ISO bereitstellen

1.2 VM erstellen

Button Create VM rechts oben — bewährte Werte:

TabEinstellung
GeneralName: Netwatch
OSISO = Debian-ISO, Type Linux, Version 6.x - 2.6 Kernel
SystemMachine q35, SCSI Controller VirtIO SCSI single, Qemu Agent ✓
Disks16–32 GB, Bus SCSI, Discard ✓, SSD emulation ✓, IO thread
CPU1 Sockel, 2 Cores, Type x86-64-v2-AES oder host
Memory1024 MB · Ballooning ✓ · KSM darf an
NetworkBridge vmbr0, Model VirtIO, Firewall ✓
Cache-Mode der Disk: bei ZFS-Storage unbedingt No cache (Default) lassen — ZFS hat seinen eigenen ARC, doppeltes Caching kostet RAM und kann fsync-Garantien aushebeln.

1.3 Harmlose Boot-Meldungen

Beim Start der VM siehst du oft Zeilen wie:

shpchp 0000:05:01.0: pci_hp_register failed with error -16
shpchp 0000:05:01.0: Slot initialization failed

Kein Fehler. Das ist der PCI-Hotplug-Treiber, der mit q35 mehr Slots zu registrieren versucht als nötig. Boot, Netzwerk und Storage sind nicht betroffen.

2 Debian-Installation Schritt für Schritt

VM starten und in der Proxmox-Konsole den Installer durchklicken:

2.1 Sprache & Tastatur

2.2 Netzwerk

Statische IP setzen wir nach der Installation in Schritt 4. Hier zunächst DHCP zulassen.

2.3 Benutzer & Passwörter

2.4 Festplatte

2.5 Paketquellen

2.6 Software-Auswahl

Mit Leertaste ab-/anwählen. Nur diese setzen:

2.7 GRUB & Abschluss

3 Erste Anmeldung & System aktualisieren

Auf der Proxmox-Konsole als root einloggen.

3.1 sudo nachinstallieren & User berechtigen

apt update
apt install -y sudo curl ca-certificates gnupg
usermod -aG sudo steffen
Die sudo-Mitgliedschaft greift erst nach neuer Login-Sitzung.

3.2 System aktualisieren

apt update && apt upgrade -y
apt autoremove -y

3.3 QEMU Guest Agent

apt install -y qemu-guest-agent

Der Service ist socket/udev-aktiviert — kein systemctl enable nötig. Er startet automatisch, weil die VM agent: 1 gesetzt hat.

Test vom Proxmox-Host:

qm agent <VMID> ping

Leerer Output = Erfolg. Mehr Info:

qm agent <VMID> network-get-interfaces
qm agent <VMID> get-osinfo

4 Statische IP setzen (192.168.178.101)

4.1 Aktuelle IP herausfinden & per SSH einloggen

Auf der VM-Konsole:

ip a

Aktuelle DHCP-IP merken, vom Mac aus verbinden:

ssh steffen@<aktuelle-ip>

Dann zum Root-User wechseln (Root-Passwort eingeben):

su -

4.2 /etc/network/interfaces überschreiben

Statt nano: Datei in einem Rutsch per Heredoc schreiben — die Zeile bleibt kurz genug, dass Terminal sie nicht zerlegt:

cat > /etc/network/interfaces <<'EOF'
source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

auto ens18
iface ens18 inet static
    address 192.168.178.101/24
    gateway 192.168.178.1
    dns-nameservers 192.168.178.1 1.1.1.1

iface ens18 inet6 auto
EOF
Heredoc-Falle: Wenn du diesen Block aus dem Browser ins Terminal einfügst und dabei Einrückungen mitkommen, bricht der schließende EOF nicht ab (Prompt bleibt bei >). Notausgang: +C, dann den Block ohne führende Leerzeichen erneut einfügen.

4.3 DNS via resolvconf aktivieren

Die dns-nameservers-Zeile wird nur ausgewertet, wenn das Paket resolvconf installiert ist:

apt install -y resolvconf
systemctl restart networking
cat /etc/resolv.conf

In resolv.conf sollten nameserver 192.168.178.1 und nameserver 1.1.1.1 stehen.

4.4 Alten DHCP-Lease loswerden

Nach systemctl restart networking bleibt manchmal der alte DHCP-Lease aktiv neben der neuen statischen IP (z. B. zusätzliche 192.168.178.199/24). Sauberster Fix:

reboot

Danach vom Mac neu verbinden:

ssh steffen@192.168.178.101

4.5 Tests

ip a show ens18
ping -c 2 192.168.178.1
ping -c 2 deb.debian.org

5 Absicherung Schritt für Schritt

Vom Mac per SSH eingeloggt:

ssh steffen@192.168.178.101

5.1 SSH-Key vom Mac einrichten

Auf dem Mac:

ls ~/.ssh/id_ed25519.pub 2>/dev/null || ssh-keygen -t ed25519 -C "steffen@mac"
ssh-copy-id steffen@192.168.178.101

Test: nächster Login darf nicht mehr nach Passwort fragen.

5.2 SSH-Daemon härten

Sicherheitsnetz vorbereiten: Vor dem SSH-Restart einen zweiten Mac-Tab öffnen (+T) und dort ebenfalls ssh steffen@192.168.178.101 — diese Session offen lassen, nichts tippen. Falls die Konfig kaputt ist, hast du noch eine offene Verbindung, über die du retten kannst.

In der ersten Session als root die Hardening-Datei Zeile für Zeile schreiben:

sudo -i
cd /etc/ssh/sshd_config.d
echo 'PermitRootLogin no'              >  99-hardening.conf
echo 'PasswordAuthentication no'       >> 99-hardening.conf
echo 'KbdInteractiveAuthentication no' >> 99-hardening.conf
echo 'PubkeyAuthentication yes'        >> 99-hardening.conf
echo 'X11Forwarding no'                >> 99-hardening.conf
echo 'MaxAuthTries 3'                  >> 99-hardening.conf
echo 'LoginGraceTime 30s'              >> 99-hardening.conf
echo 'ClientAliveInterval 300'         >> 99-hardening.conf
echo 'ClientAliveCountMax 2'           >> 99-hardening.conf
echo 'AllowUsers steffen'              >> 99-hardening.conf
cat 99-hardening.conf
sshd -t
systemctl restart ssh
exit

Tests in einem dritten Tab (+T):

ssh steffen@192.168.178.101                                                # muss klappen
ssh root@192.168.178.101                                                   # muss scheitern
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password \
    steffen@192.168.178.101                                                # muss scheitern

Sind alle drei wie erwartet, ist die Sicherheitsnetz-Session entbehrlich.

5.3 UFW-Firewall

sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 3579/tcp
sudo ufw enable
sudo ufw status verbose

5.4 fail2ban gegen Brute-Force

sudo apt install -y fail2ban
sudo -i
cd /etc/fail2ban
echo '[DEFAULT]'                                  >  jail.local
echo 'bantime  = 1h'                              >> jail.local
echo 'findtime = 10m'                             >> jail.local
echo 'maxretry = 5'                               >> jail.local
echo 'ignoreip = 127.0.0.1/8 ::1 192.168.178.0/24' >> jail.local
echo ''                                           >> jail.local
echo '[sshd]'                                     >> jail.local
echo 'enabled = true'                             >> jail.local
echo 'port    = ssh'                              >> jail.local
echo 'backend = systemd'                          >> jail.local
cat jail.local
exit
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
backend = systemd liest aus journalctl — Debian 13 schreibt keine klassische auth.log mehr. ignoreip verhindert, dass du dich aus dem eigenen LAN selbst sperrst.

5.5 Automatische Sicherheitsupdates

sudo apt install -y unattended-upgrades apt-listchanges
sudo dpkg-reconfigure -plow unattended-upgrades

Dialogbox: mit Tab auf Ja, Enter.

Kontrolle:

sudo systemctl status unattended-upgrades --no-pager | head -5
sudo cat /etc/apt/apt.conf.d/20auto-upgrades

Datei muss enthalten:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

Trockenlauf:

sudo unattended-upgrade --dry-run -d 2>&1 | tail -5
Optional: Auto-Reboot um 04:00 nachts in /etc/apt/apt.conf.d/50unattended-upgrades aktivieren. Geht nur sauber per Editor (nano/vim) — keine Eile, Sicherheitsupdates greifen auch ohne Reboot, nur Kernel-Updates erst beim nächsten manuellen Neustart.

5.6 Sysctl-Härtung

sudo -i
cd /etc/sysctl.d
echo 'net.ipv4.conf.all.rp_filter = 1'             >  90-hardening.conf
echo 'net.ipv4.conf.default.rp_filter = 1'         >> 90-hardening.conf
echo 'net.ipv4.icmp_echo_ignore_broadcasts = 1'    >> 90-hardening.conf
echo 'net.ipv4.conf.all.accept_redirects = 0'      >> 90-hardening.conf
echo 'net.ipv6.conf.all.accept_redirects = 0'      >> 90-hardening.conf
echo 'net.ipv4.conf.all.send_redirects = 0'        >> 90-hardening.conf
echo 'net.ipv4.conf.all.accept_source_route = 0'   >> 90-hardening.conf
echo 'net.ipv6.conf.all.accept_source_route = 0'   >> 90-hardening.conf
echo 'net.ipv4.tcp_syncookies = 1'                 >> 90-hardening.conf
echo 'kernel.kptr_restrict = 2'                    >> 90-hardening.conf
echo 'kernel.dmesg_restrict = 1'                   >> 90-hardening.conf
cat 90-hardening.conf
sysctl --system
exit

5.7 Zeitzone & Zeit-Sync

sudo timedatectl set-timezone Europe/Berlin
timedatectl

Erwartet: Time zone: Europe/Berlin (CEST, +0200), System clock synchronized: yes, NTP service: active.

Nach 5.1–5.7 ist die VM solide abgesichert: Key-only-SSH, Firewall, Brute-Force-Schutz, automatische Sicherheitsupdates, gehärteter Netzwerk-Stack, korrekte Zeit.

6 Quellcode auf die VM kopieren

Auf dem Mac, im Projektordner. Variable für das Ziel macht die Befehle paste-fest:

cd /Users/bigbrain/Projects/gereate_website_monitoring
ssh steffen@192.168.178.101 'mkdir -p ~/netwatch-src'
T=steffen@192.168.178.101:netwatch-src/
scp -r install.sh server.js package.json public $T

Kontrolle:

ssh steffen@192.168.178.101 'ls -la ~/netwatch-src'

Erwartet: install.sh, server.js, package.json, Verzeichnis public/.

7 Installer ausführen

Auf der VM:

ssh steffen@192.168.178.101
cd ~/netwatch-src
sudo bash install.sh

Was passiert:

Erfolgsausgabe:

✅ NetWatch installiert
Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Desktop: http://192.168.178.101:3579
Mobile : http://192.168.178.101:3579/mobile

8 Token sichern & Aufrufen

8.1 Token in den Passwortmanager

Der Token ist dein „Passwort" zum Dashboard. Aus der Installer-Ausgabe in den Passwortmanager kopieren.

Er ist nicht verloren, wenn du ihn vergisst — jederzeit wieder einsehbar:

sudo cat /opt/netwatch/data/token
FrageAntwort
Wann generiert?Beim ersten Start, einmalig (24 zufällige Bytes, base64url)
Bleibt stabil?Ja — auch nach Reboot/Update, solange die Datei existiert
Wie schützen?Wie ein Passwort behandeln — wer ihn hat, bedient das Dashboard
Im Browser?Beim ersten Aufruf eintippen, UI merkt ihn lokal

Token zurücksetzen (z. B. nach Leak):

sudo systemctl stop netwatch
sudo rm /opt/netwatch/data/token
sudo systemctl start netwatch
sudo cat /opt/netwatch/data/token

8.2 Aufrufen

GerätURL
Desktophttp://192.168.178.101:3579
Mobile (PWA)http://192.168.178.101:3579/mobile

9 Betrieb & Troubleshooting

AufgabeBefehl
Status prüfensudo systemctl status netwatch
Live-Logsudo journalctl -u netwatch -f
Neustartsudo systemctl restart netwatch
Backups (7 Tage)sudo ls /opt/netwatch/data/backup/
Health-Check (ohne Auth)curl http://localhost:3579/health
fail2ban-Statussudo fail2ban-client status sshd
UFW-Statussudo ufw status verbose
Updates manuellsudo apt update && sudo apt upgrade -y

Wenn ein Befehl wegen Zeilenumbruch zerfällt

10 Hinweis: LXC statt VM

Geht auch — deutlich ressourcensparender. Voraussetzungen:

Für „einfach läuft" → VM. LXC = separate Anleitung.