CommunityCodierung & Entwicklunggithub.com

eageric/cursor-cloud-eag

Erstellt, verbindet und bereinigt kurzlebige Test-VMs auf dem EAG Proxmox VE Server über den Cloudflare Access SSH-Tunnel unter eric-pve-ssh.eag.tools.

Was ist cursor-cloud-eag?

Diese Fähigkeit erlaubt es KI-Agenten, Test-VMs auf einem Proxmox VE 9.2 Server zu verwalten, der über eine Cloudflare Access SSH-Tunnelverbindung erreichbar ist. Sie unterstützt das Klonen von zwei Vorlagen: Windows Server 2025 (ws2025-template, VMID 101) und Ubuntu 24.04 (ubuntu-2404, VMID 100). Der Agent kann VMs erstellen, deren IP-Adressen über den QEMU-Gastagent abrufen, auf die VMs über den SSH-Tunnel zugreifen, Tests durchführen und die VMs schließlich mit Benutzerbestätigung bereinigen. Die Fähigkeit behandelt auch PowerShell-Remoting unter Windows, Snapshots, Cloud-Init für Ubuntu und die vollständige Inventarisierung und Löschung von VMs. Wichtige Sicherheitsregeln stellen sicher, dass die Vorlagen-VMs niemals verändert werden, alle erstellten VMs mit 'ai-test' getaggt werden und der Benutzer vor der Zerstörung einer VM um Erlaubnis fragen muss.

Funktioniert mit~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/eageric/cursor-cloud-eag/tree/HEAD/.cursor/skills/pve-dev

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

EAG Proxmox über den Cloudflare SSH-Tunnel

Der Proxmox VE 9.2 Server hostet kurzlebige Test-VMs. Von dieser Umgebung aus lautet der Host eric-pve-ssh.eag.tools. Agenten klonen eine Vorlage, führen den Test durch und fragen dann, bevor sie etwas löschen.

Die Vorlagen, Klonschritte und Gast-Logins entsprechen der LAN-Umgebung. Was sich ändert, ist der Pfad: Der Cloud-Agent erreicht den Host über Cloudflare Access und erreicht jeden Gast über einen Sprung (Jump) durch diesen Host.

Zugriff

Das Startskript schreibt das Schlüsselpaar aus PVE_SSH_PRIVATE_B64 und PVE_SSH_PUBLIC_KEY:

DateiModusVerwendung
~/.ssh/pve_ssh600Privater Schlüssel. Proxmox-Host, Windows Administrator, Ubuntu erolleman.
~/.ssh/pve_ssh.pub644Zugehöriger öffentlicher Schlüssel.

/etc/ssh/ssh_config.d/eric-pve-ssh.conf setzt bereits User root, IdentityFile ~/.ssh/pve_ssh, IdentitiesOnly yes und ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h für eric-pve-ssh.eag.tools. Verwende diesen Host-Alias. Lasse die Systemdatei an Ort und Stelle.

KEY="$HOME/.ssh/pve_ssh"
test -r "$KEY" || { echo "$KEY fehlt; das Startskript erstellt ihn aus PVE_SSH_PRIVATE_B64" >&2; exit 1; }
PVE="ssh -o StrictHostKeyChecking=accept-new eric-pve-ssh.eag.tools"
$PVE 'qm list'

Gast-SSH, sowohl für 10.115.64.x (vmbr0) als auch 10.20.0.x (nat0):

JUMP='ssh -o StrictHostKeyChecking=accept-new -W %h:%p eric-pve-ssh.eag.tools'
VMSSH="ssh -i $KEY -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 -o ProxyCommand=\"$JUMP\" USER@$IP"

Setze USER auf Administrator oder erolleman und IP auf die Gastadresse, bevor du VMSSH expandierst.

  • Windows VM-Login: Administrator / Change_me oder ~/.ssh/pve_ssh.
  • Ubuntu VM-Login: erolleman mit ~/.ssh/pve_ssh. sudo ist ohne Passwort. docker benötigt sudo.
  • Die Proxmox-Web-Oberfläche lauscht im LAN unter https://10.115.64.44:8006. Dieser Tunnel ist nur für SSH. Verwalte den Host mit qm und pvesh über $PVE.
  • Halte das Schlüsselmaterial in den obigen Dateien. Lies weder ~/.ssh/pve_ssh noch PVE_SSH_PRIVATE_B64 in einen Befehl, ein Log oder eine Antwort ein. Generiere keinen Ersatzschlüssel.

PowerShell-Remoting über SSH verwendet den gleichen Sprung. Füge dies zu ~/.ssh/config hinzu (nur der Host-Block für den Gast; die Systemdatei deckt bereits den Tunnelhost ab):

Host 10.115.64.* 10.20.0.*
  IdentityFile ~/.ssh/pve_ssh
  IdentitiesOnly yes
  StrictHostKeyChecking no
  UserKnownHostsFile /dev/null
  ProxyCommand ssh -o StrictHostKeyChecking=accept-new -W %h:%p eric-pve-ssh.eag.tools
Enter-PSSession -HostName <ip> -UserName Administrator -KeyFilePath "$HOME/.ssh/pve_ssh"

Harte Regeln

  • Starte, ändere, klone oder lösche NIEMALS VM 100 (ubuntu-2404) oder VM 101 (ws2025-template). Beide sind Vorlagen.
  • Ändere die Hostkonfiguration (Speicher, Netzwerk, SDN, Pakete) nur, wenn der Benutzer explizit darum bittet.
  • Führe sysprep, windows-template/Copy-SysprepFiles.ps1 oder ubuntu-template/cloud-init-prepare.sh nicht auf einem Klon erneut aus. Diese Skripte bereiten die Vorlagen vor und verbleiben auf der Workstation. Sie sind nicht in dieser Umgebung.
  • Tagge jede von dir erstellte VM mit ai-test.
  • Wenn der Test abgeschlossen ist, frage den Benutzer, ob die von dir erstellten VMs gelöscht werden sollen. Lösche niemals eine VM ohne die Antwort des Benutzers.
  • Öffne keine direkte SSH-Sitzung zu 10.115.64.44, 10.115.64.x oder 10.20.0.x. Diese Netzwerke sind nicht zum Cloud-Agenten geroutet. Host-Befehle werden über eric-pve-ssh.eag.tools ausgeführt. Gast-Befehle verwenden den obigen ProxyCommand-Sprung.

Host-Fakten

Der Host ist eine Hyper-V virtuelle Maschine. Geschachteltes VT-x ist verfügbar gemacht. Seine Adresse im LAN ist 10.115.64.44.

ElementWert
HardwareIntel Xeon Gold 6234 (8 Kerne / 16 Threads), 94 GB RAM. Budgetiere VMs entsprechend.
vmbr0LAN-Brücke, DHCP. Host-Adresse 10.115.64.44/24, Gateway und DNS 10.115.64.1, Suchdomäne eag.lan. Die Netzwerkkarten beider Vorlagen sind an dieser Brücke. Gast-Adressen sind 10.115.64.x. Von dieser Umgebung aus erfolgt der SSH-Zugriff zu ihnen über einen Sprung durch eric-pve-ssh.eag.tools.
nat0SDN VNet (einfache Zone nat), 10.20.0.0/24. Gateway 10.20.0.1. DHCP 10.20.0.100–10.20.0.200 (12 h) von dnsmasq auf dem Host, DNS 10.20.0.1. SNAT ausgehend über vmbr0 als 10.115.64.44. Der Proxmox-Host kann dieses Subnetz erreichen. Von dieser Umgebung aus verwendet SSH zu 10.20.0.x den gleichen Sprung.
local-dataLVM-thin auf VG vmdata, ~671 GB. VM-Festplatten, EFI, TPM und Cloud-Init-Laufwerke.
local-lvmLVM-thin auf der kleinen PVE-System-VG, ~23 GB, leer. Lasse es ungenutzt.
localVerzeichnis auf dem Root-Dateisystem. Backups, Container-Vorlagen, Importe.
isosVerzeichnis /mnt/isos. Nur Installations-ISOs.

Welche Vorlage

BedarfKlon
Windows, RDP oder Windows PowerShell101 ws2025-template
Linux, Docker, pwsh oder Nushell100 ubuntu-2404

Wenn der Benutzer nicht angibt, welches Betriebssystem, frage vor dem Klonen nach.

Windows-Klone aktivieren RDP innerhalb des Gasts. Der Cloudflare-Tunnel überträgt SSH. Verwende SSH oder PowerShell-Remoting, um den Gast zu erreichen.

Vorlage: ws2025-template (VMID 101)

Windows Server 2025 Datacenter Evaluation. 4 vCPU (host), 4 GB RAM, UEFI + Secure Boot + TPM 2.0, 64 GB VirtIO SCSI-Festplatte auf local-data, VirtIO-NIC auf vmbr0 (4 Warteschlangen), VirtIO-Treiber und QEMU-Gastagent installiert.

Beim ersten Start führt jeder Klon automatisch folgende Schritte aus:

  • Erhält einen zufälligen Computernamen, Zeitzone Pazifik, Gebietsschema en-US und Administrator-Passwort Change_me.
  • Meldet sich einmal automatisch an und führt Initialize-WindowsServer.ps1 aus, das die neueste PowerShell 7 von GitHub installiert, den OpenSSH-Server mit einem powershell-Subsystem aktiviert (PS-Remoting über SSH), den SSH-Schlüssel zu administrators_authorized_keys hinzufügt, RDP aktiviert, öffentliche Netzwerke auf Privat setzt und die Strg+Alt+Entf-Anforderung entfernt.
  • Entfernt das Auto-Logon-Passwort und die Antwortdatei, schreibt C:\ProgramData\TemplateSetup\setup-complete und startet dann neu.

Der erste Start dauert mehrere Minuten und benötigt Internet (PowerShell 7 Download). Log: C:\ProgramData\TemplateSetup\Initialize-WindowsServer.log.

Vorlage: ubuntu-2404 (VMID 100)

Ubuntu 24.04.5 LTS. 2 vCPU (x86-64-v2-AES), 4 GB RAM, UEFI (Secure Boot-Schlüssel nicht eingetragen), kein TPM, 32 GB VirtIO SCSI-Festplatte auf local-data, VirtIO-NIC auf vmbr0. QEMU-Gastagent, OpenSSH, PowerShell 7 (pwsh), Nushell (nu in /usr/local/bin) und Docker sind installiert. Podman ist nicht installiert. Zeitzone ist UTC.

Cloud-Init wurde bereinigt und auf die Datenquellen NoCloud und ConfigDrive beschränkt. Die Festplatte hat kein Netplan, daher hat ein Klon kein Netzwerk, bis Proxmox Cloud-Init ausgeführt wird. Das Konto erolleman ist bereits in sudo und hat bereits den öffentlichen Projektschlüssel. SSH ist socket-aktiviert. Der Gastagent startet von udev, wenn der VirtIO-Port erscheint.

Proxmoxs generierte Benutzerdaten erstellt auch ein gesperrtes ubuntu-Konto ohne SSH-Schlüssel. Melde dich als erolleman an.

Arbeitsablauf: Eine Test-VM erstellen

- [ ] 1. Bestätige, dass die Quell-VM eine Vorlage ist
- [ ] 2. Klonen, konfigurieren, taggen, starten
- [ ] 3. IP vom Gastagenten abrufen
- [ ] 4. Warten, bis der erste Start abgeschlossen ist
- [ ] 5. Den Test durchführen
- [ ] 6. Den Benutzer fragen, ob die VM gelöscht werden soll

1. Bestätige die Vorlage. Wenn dies nichts ausgibt, brich ab und informiere den Benutzer. Klone keine VM, die keine Vorlage ist.

$PVE 'qm config 101 | grep ^template'   # Windows
$PVE 'qm config 100 | grep ^template'   # Ubuntu

2. Klonen, konfigurieren, taggen, starten. Verknüpfte Klone sind die Standardeinstellung. Füge --full --storage local-data nur hinzu, wenn die VM die Vorlage überleben muss.

Klone erben 4 vCPU / 4 GB (Windows) oder 2 vCPU / 4 GB (Ubuntu). Wenn der Test mehr benötigt, setze qm set auf den Klon, bevor du ihn startest. Lasse die Vorlagen unverändert.

Windows:

ID=$($PVE 'pvesh get /cluster/nextid')
$PVE "qm clone 101 $ID --name test-<zweck> && qm set $ID --tags ai-test && qm start $ID"

Ubuntu: Hänge das Cloud-Init-Laufwerk vor dem ersten Start an. ide2 auf der Vorlage ist eine leere CD; ersetze sie. --ciupgrade 0 überspringt das standardmäßige vollständige Paket-Upgrade. Ohne --ipconfig0 ip=dhcp erhält der Klon niemals eine Adresse.

ID=$($PVE 'pvesh get /cluster/nextid')
$PVE "qm clone 100 $ID --name test-<zweck> && qm set $ID --tags ai-test --ide2 local-data:cloudinit --citype nocloud --ipconfig0 ip=dhcp --ciupgrade 0 --boot order=scsi0 && qm start $ID"

Isoliertes Netzwerk, für beide Betriebssysteme: Platziere die NIC vor dem Start auf nat0. Behalte dies nur bei, wenn der Benutzer die VM vom LAN fernhalten möchte. Die Gastadresse wird 10.20.0.x sein. SSH aus dieser Umgebung verwendet immer noch den Sprung in Zugriff; der Proxmox-Host ist derjenige, der nat0 erreichen kann.

$PVE "qm set $ID --net0 virtio,bridge=nat0"
# Nur Ubuntu. Windows macht DHCP selbst. Weisen Sie Ubuntu-DNS auf dnsmasq am NAT-Gateway.
$PVE "qm set $ID --ipconfig0 ip=dhcp --nameserver 10.20.0.1"

3. IP abrufen. Der Gastagent antwortet, sobald das Betriebssystem läuft. Wiederhole alle ~15 s. Verwende die 10.115.64.x-Adresse für eine vmbr0-NIC oder die 10.20.0.x-Adresse für nat0.

$PVE "qm guest cmd $ID network-get-interfaces" \
  | jq -r '.[]."ip-addresses"[]? | select(."ip-address-type"=="ipv4") | ."ip-address"' \
  | grep -vE '^(127\.|169\.254\.)'

4. Auf den ersten Start warten. Klone erhalten neue Hostschlüssel und Adressen werden wiederverwendet, daher überspringt Gast-SSH die Hostschlüsselprüfung. Der Sprung-Hostschlüssel wird mit accept-new gespeichert.

Windows: SSH wird während der Einrichtung gestartet, und das Skript startet die VM neu, wenn es abgeschlossen ist. Die VM ist bereit, sobald setup-complete vorhanden ist und Windows seit dem Schreiben erneut gebootet hat.

VMSSH="ssh -i $KEY -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 -o ProxyCommand=\"$JUMP\" Administrator@$IP"
# -EncodedCommand (base64 UTF-16LE) vermeidet verschachteltes bash/cmd/PowerShell-Quoting.
PS_CHECK=$(cat <<'EOF'
$m = Get-Item C:\ProgramData\TemplateSetup\setup-complete -ErrorAction SilentlyContinue
if ($m -and (Get-CimInstance Win32_OperatingSystem).LastBootUpTime -gt $m.LastWriteTime) { 'READY ' + (Get-Content $m.FullName) } else { 'WAITING' }
EOF
)
CHECK="powershell -NoProfile -EncodedCommand $(printf '%s' "$PS_CHECK" | iconv -t UTF-16LE | base64 -w0)"
until STATUS=$($VMSSH "$CHECK" 2>/dev/null | tr -d '\r'); [[ $STATUS == READY* ]]; do sleep 15; done
echo "$STATUS"

READY succeeded bedeutet, dass die Einrichtung abgeschlossen ist und die VM neu gestartet wurde. Wenn READY failed ausgegeben wird, lies das Log und melde es:

$VMSSH 'powershell -NoProfile -Command "Get-Content C:\ProgramData\TemplateSetup\Initialize-WindowsServer.log -Tail 30"'

Ubuntu: Warte, bis Cloud-Init status: done meldet. status: error bedeutet anhalten und /var/log/cloud-init-output.log lesen.

VMSSH="ssh -i $KEY -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 -o ProxyCommand=\"$JUMP\" erolleman@$IP"
until STATUS=$($VMSSH 'cloud-init status 2>/dev/null' | tr -d '\r'); [[ $STATUS == status:\ done || $STATUS == status:\ error ]]; do sleep 10; done
echo "$STATUS"

5. Test durchführen.

Windows: Die Standard-SSH-Shell ist cmd.exe.

$VMSSH 'pwsh -NoProfile -Command "Get-ComputerInfo | Select-Object OsName, CsName"'

PowerShell-Remoting über SSH (von pwsh auf dem Cloud-Agenten) verwendet den ~/.ssh/config-Gast-Block unter Zugriff:

Enter-PSSession -HostName <ip> -UserName Administrator -KeyFilePath "$HOME/.ssh/pve_ssh"

Ubuntu:

$VMSSH 'pwsh -NoLogo -Command "$PSVersionTable.PSVersion.ToString()"'
$VMSSH 'sudo docker info --format "{{.ServerVersion}}"'

6. Vor der Bereinigung fragen. Melde die Testergebnisse, liste die von dir erstellten VMs auf (VMID, Name, IP) und frage den Benutzer, ob sie gelöscht werden sollen. Verwende das AskQuestion-Tool, wenn verfügbar, mit den Optionen "Löschen", "Weiterlaufen lassen" und "Herunterfahren, aber behalten" (plus pro-VM-Auswahl, wenn du mehrere erstellt hast).

Wenn der Benutzer sich für das Löschen entscheidet:

$PVE "qm stop $ID && qm destroy $ID --purge"

Wenn der Benutzer sich dafür entscheidet, die VM zu behalten, aber herunterzufahren:

$PVE "qm shutdown $ID --timeout 120 || qm stop $ID"

Wenn VMs behalten werden, teile dem Benutzer ihre VMIDs mit, damit sie später gefunden werden können (sie behalten das ai-test-Tag).

Snapshots

Die Festplatten beider Vorlagen befinden sich auf LVM-thin, daher unterstützen Klone Snapshots:

$PVE "qm snapshot $ID before-test"
$PVE "qm rollback $ID before-test"
$PVE "qm delsnapshot $ID before-test"

Bereinigung und Inventar

$PVE 'pvesh get /cluster/resources --type vm --output-format json' \
  | jq -r '.[] | select((.tags // "") | split(";") | index("ai-test")) | "\(.vmid)\t\(.name)\t\(.status)"'

Biete nur an, ai-test-VMs zu löschen, die du in dieser Sitzung erstellt hast, es sei denn, der Benutzer bittet um eine breitere Bereinigung. Hole immer zuerst die Bestätigung des Benutzers ein.

Fallstricke

  • Windows ist eine Evaluierungsedition mit einer 180-Tage-Lizenz. Verwende sie für kurzlebige VMs.
  • Ein Ubuntu-Klon, der einmal ohne das Cloud-Init-Laufwerk bootet, startet ohne Netzwerk, und Cloud-Init wird nicht sauber wiederholen. Lösche ihn und klone erneut.
  • Führe sysprep nicht auf Windows-Klonen durch und konvertiere keine Klone beider Vorlagen in Vorlagen.
  • Die Hostadresse ist ein DHCP-Lease. nat0 SNAT ist an 10.115.64.44 gebunden. Wenn sich diese Adresse ändert, sage dies; bearbeite SDN nicht, es sei denn, der Benutzer bittet darum.
  • cloudflared wird von der System-SSH-Konfiguration als /usr/local/bin/cloudflared aufgerufen. Eine fehlende Schlüsseldatei bedeutet, dass das Startskript nicht ausgeführt wurde; lasse die Geheimnisse unberührt und melde dies.
  • Gast-Hostschlüssel ändern sich bei jedem Klon. UserKnownHostsFile=/dev/null gilt für die Gastsitzung. Der Tunnel-Hostschlüssel bleibt in ~/.ssh/known_hosts.

Verwandte Skills