Communityコーディング&開発github.com

eageric/cursor-cloud-eag

Cloudflare SSH トンネル経由で EAG Proxmox VE サーバー上に使い捨てテスト VM を作成、接続、クリーンアップします。

cursor-cloud-eag とは?

このスキルは、AI エージェント(Claude Code、Codex、Cursor など)が Cloudflare 接続された Proxmox VE サーバー上でテスト VM を管理できるようにします。事前設定された Cloudflare Access SSH トンネルを使用して、Windows Server 2025 テンプレート(vmbr0 上の ws2025-template、VMID 101)または Ubuntu 24.04 テンプレート(VMID 100)のクローンを作成します。このスキルは、テンプレート確認、クローン作成、VM 設定(VM 名、タグ付け、クラウド初期化)、QEMU ゲストエージェントからの IP アドレス取得、各 OS の初回起動完了待機、テスト実行、最後にユーザーによる確認後の VM 破棄またはシャットダウンを含む完全なライフサイクルワークフローをカバーします。これは、SSH キー `~/.ssh/pve_ssh` を使用した強力なセキュリティ慣行を実施し、プロキシ経由でゲストに接続するためのジャンプホストパターンを提供し、PowerShell リモーティング(`pwsh` から `Enter-PSSession` を使用)をサポートします。このスキルは、テンプレート VM(100/101)の変更、クローン上での sysprep またはクラウド初期化準備スクリプトの再実行、および明示的なユーザー許可なしの VM 破棄を防止するハードルールを課します。

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

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Cloudflare SSH トンネル経由の EAG Proxmox

Proxmox VE 9.2 サーバーは、使い捨てテスト VM をホストします。この環境から、ホストは eric-pve-ssh.eag.tools です。エージェントはテンプレートのクローンを作成し、テストを実行してから、削除する前にユーザーに確認します。

テンプレート、クローン手順、およびゲストログインは LAN 環境と同じです。変更点はパスです。クラウドエージェントは Cloudflare Access を経由してホストに到達し、そのホストを経由してすべてのゲストに到達します。

アクセス

環境開始スクリプトは、PVE_SSH_PRIVATE_B64 と PVE_SSH_PUBLIC_KEY からキーペアを書き込みます。

ファイルモード用途
~/.ssh/pve_ssh600秘密鍵。Proxmox ホスト、Windows Administrator、Ubuntu erolleman。
~/.ssh/pve_ssh.pub644対応する公開鍵。

/etc/ssh/ssh_config.d/eric-pve-ssh.conf は、eric-pve-ssh.eag.tools に対して、User root、IdentityFile ~/.ssh/pve_ssh、IdentitiesOnly yes、および ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h を既に設定しています。そのホストエイリアスを使用してください。システムファイルはそのままにしておきます。

KEY="$HOME/.ssh/pve_ssh"
test -r "$KEY" || { echo "missing $KEY; the start script creates it from PVE_SSH_PRIVATE_B64" >&2; exit 1; }
PVE="ssh -o StrictHostKeyChecking=accept-new eric-pve-ssh.eag.tools"
$PVE 'qm list'

ゲスト SSH(10.115.64.x(vmbr0)と 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"

VMSSH を展開する前に、USER を Administrator または erolleman に、IP をゲストアドレスに設定します。

  • Windows VM ログイン: Administrator / Change_me、または ~/.ssh/pve_ssh。
  • Ubuntu VM ログイン: ~/.ssh/pve_ssh を使用する erolleman。sudo はパスワード不要です。docker は sudo が必要です。
  • Proxmox Web UI は LAN 上の https://10.115.64.44:8006 で待機しています。このトンネルは SSH のみです。$PVE を介して qm および pvesh でホストを管理します。
  • キー素材は上記のファイルに保持してください。~/.ssh/pve_ssh も PVE_SSH_PRIVATE_B64 もコマンド、ログ、返信に読み込まないでください。交換キーを生成しないでください。

SSH 経由の PowerShell リモーティングは同じジャンプを使用します。~/.ssh/config にこれを追加します(ゲスト Host ブロックのみ。システムファイルはトンネルホストを既にカバーしています)。

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"

ハードルール

  • VM 100(ubuntu-2404)または VM 101(ws2025-template)を開始、変更、上書きクローン、または削除しないでください。両方ともテンプレートです。
  • ユーザーが明示的に要求しない限り、ホスト設定(ストレージ、ネットワーク、SDN、パッケージ)を変更しないでください。
  • クローン上で sysprep、windows-template/Copy-SysprepFiles.ps1、または ubuntu-template/cloud-init-prepare.sh を再実行しないでください。これらのスクリプトはテンプレートを準備し、ワークステーション上に残ります。この環境にはありません。
  • 作成するすべての VM に ai-test のタグを付けます。
  • テストが終了したら、作成した VM を破棄するかどうかをユーザーに確認してください。ユーザーの回答なしに VM を破棄しないでください。
  • 10.115.64.44、10.115.64.x、または 10.20.0.x への直接 SSH セッションを開かないでください。これらのネットワークはクラウドエージェントにルーティングされていません。ホストコマンドは eric-pve-ssh.eag.tools を経由します。ゲストコマンドは上記の ProxyCommand ジャンプを使用します。

ホスト情報

ホストは Hyper-V 仮想マシンです。ネストされた VT-x が公開されています。LAN 上では、そのアドレスは 10.115.64.44 です。

項目値
ハードウェアIntel Xeon Gold 6234(8 コア / 16 スレッド)、94 GB RAM。VM はそれに応じて割り当てます。
vmbr0LAN ブリッジ、DHCP。ホストアドレス 10.115.64.44/24、ゲートウェイと DNS 10.115.64.1、検索ドメイン eag.lan。両方のテンプレートの NIC はこのブリッジ上にあります。ゲストアドレスは 10.115.64.x です。この環境から、それらへの SSH は eric-pve-ssh.eag.tools を経由してジャンプします。
nat0SDN VNet(シンプルゾーン nat)、10.20.0.0/24。ゲートウェイ 10.20.0.1。DHCP 10.20.0.100–10.20.0.200(12 時間)ホスト上の dnsmasq から、DNS 10.20.0.1。SNAT は vmbr0 を経由して 10.115.64.44 として出力。Proxmox ホストはこのサブネットに到達できます。この環境から、10.20.0.x への SSH は同じジャンプを使用します。
local-dataVG vmdata 上の LVM-thin、約 671 GB。VM ディスク、EFI、TPM、および cloud-init ドライブ。
local-lvm小さな PVE システム VG 上の LVM-thin、約 23 GB、空。未使用のままにします。
localルートファイルシステム上のディレクトリ。バックアップ、コンテナテンプレート、インポート。
isosディレクトリ /mnt/isos。インストール ISO のみ。

どのテンプレート

ニーズクローン
Windows、RDP、または Windows PowerShell101 ws2025-template
Linux、Docker、pwsh、または Nushell100 ubuntu-2404

ユーザーが OS を指定しない場合は、クローンを作成する前に確認します。

Windows クローンは、ゲスト内で RDP を有効にします。Cloudflare トンネルは SSH を伝送します。SSH または PowerShell リモーティングを使用してゲストに接続します。

テンプレート: ws2025-template(VMID 101)

Windows Server 2025 Datacenter Evaluation。4 vCPU(host)、4 GB RAM、UEFI + セキュアブート + TPM 2.0、local-data 上の 64 GB VirtIO SCSI ディスク、vmbr0 上の VirtIO NIC(4 キュー)、VirtIO ドライバーと QEMU ゲストエージェントがインストール済み。

初回起動時に、すべてのクローンは自動的に:

  • ランダムなコンピューター名、太平洋時間帯、en-US ロケール、および Administrator パスワード Change_me を取得します。
  • 自動ログオンを 1 回実行し、Initialize-WindowsServer.ps1 を実行します。このスクリプトは、GitHub から最新の PowerShell 7 をインストールし、powershell サブシステム(SSH 経由の PS リモーティング)を使用して OpenSSH サーバーを有効にし、SSH キーを administrators_authorized_keys に追加し、RDP を有効にし、パブリックネットワークをプライベートに設定し、Ctrl+Alt+Del 要件を削除します。
  • 自動ログオンパスワードと応答ファイルを削除し、C:\ProgramData\TemplateSetup\setup-complete を作成してから、再起動します。

初回起動には数分かかり、インターネットアクセス(PowerShell 7 ダウンロード)が必要です。ログ: C:\ProgramData\TemplateSetup\Initialize-WindowsServer.log。

テンプレート: ubuntu-2404(VMID 100)

Ubuntu 24.04.5 LTS。2 vCPU(x86-64-v2-AES)、4 GB RAM、UEFI(セキュアブートキー未登録)、TPM なし、local-data 上の 32 GB VirtIO SCSI ディスク、vmbr0 上の VirtIO NIC。QEMU ゲストエージェント、OpenSSH、PowerShell 7(pwsh)、Nushell(/usr/local/bin 上の nu)、および Docker がインストールされています。Podman はインストールされていません。タイムゾーンは UTC です。

Cloud-init はクリーンアップされ、NoCloud および ConfigDrive データソースに制限されています。ディスクには netplan がないため、Proxmox cloud-init が実行されるまで、クローンにはネットワークがありません。アカウント erolleman は既に sudo グループに属し、プロジェクトの公開鍵を持っています。SSH はソケットアクティベーションされています。ゲストエージェントは、virtio ポートが表示されたときに udev から起動します。

Proxmox によって生成された user-data は、ロックされた ubuntu アカウントを SSH キーなしで作成します。erolleman としてログインします。

ワークフロー: テスト VM を作成する

- [ ] 1. ソース VM がテンプレートであることを確認する
- [ ] 2. クローンを作成し、設定し、タグを付け、起動する
- [ ] 3. ゲストエージェントから IP を取得する
- [ ] 4. 初回起動が完了するまで待機する
- [ ] 5. テストを実行する
- [ ] 6. ユーザーに VM を破棄するかどうかを確認する

1. テンプレートを確認する。 何も出力されない場合は、停止してユーザーに伝えます。テンプレートではない VM をクローンしないでください。

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

2. クローンを作成し、設定し、タグを付け、起動する。 リンククローンがデフォルトです。VM がテンプレートよりも長く存続する必要がある場合のみ、--full --storage local-data を追加します。

クローンは 4 vCPU / 4 GB(Windows)または 2 vCPU / 4 GB(Ubuntu)を継承します。テストでより多くのリソースが必要な場合は、起動する前に qm set でクローンを設定します。テンプレートは変更しないでください。

Windows:

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

Ubuntu: 初回起動前に cloud-init ドライブを接続します。テンプレートの ide2 は空の CD です。それを置き換えます。--ciupgrade 0 はデフォルトの完全なパッケージアップグレードをスキップします。--ipconfig0 ip=dhcp がないと、クローンはアドレスを取得できません。

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

分離ネットワーク、どちらの OS でも: 起動前に NIC を nat0 に配置します。これは、ユーザーが VM を LAN からオフにしたい場合のみ保持します。ゲストアドレスは 10.20.0.x になります。この環境からの SSH は、アクセスのジャンプを引き続き使用します。Proxmox ホストは nat0 に到達できるホストです。

$PVE "qm set $ID --net0 virtio,bridge=nat0"
# Ubuntu のみ。Windows は独自に DHCP を取得します。Ubuntu DNS を NAT ゲートウェイ上の dnsmasq にポイントします。
$PVE "qm set $ID --ipconfig0 ip=dhcp --nameserver 10.20.0.1"

3. IP を取得する。 ゲストエージェントは、OS が起動すると応答します。約 15 秒ごとに再試行します。vmbr0 NIC の場合は 10.115.64.x アドレスを、nat0 の場合は 10.20.0.x アドレスを使用します。

$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. 初回起動を待機する。 クローンは新しいホストキーを取得し、アドレスは再利用されるため、ゲスト SSH はホストキーチェックをスキップします。ジャンプホストキーは accept-new で保存されています。

Windows: SSH はセットアップ中に起動し、スクリプトは終了時に VM を再起動します。setup-complete が存在し、それが書き込まれてから Windows が再度起動すると、VM の準備は完了です。

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) はネストされた bash/cmd/PowerShell 引用を回避します。
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 は、セットアップが完了し、VM が再起動したことを意味します。READY failed が出力された場合は、ログを読み取って報告します:

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

Ubuntu: cloud-init が status: done を報告するまで待機します。status: error は、停止して /var/log/cloud-init-output.log を読み取ることを意味します。

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. テストを実行する。

Windows: デフォルトの SSH シェルは cmd.exe です。

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

SSH 経由の PowerShell リモーティング(クラウドエージェント上の pwsh から)は、アクセスの ~/.ssh/config ゲストブロックを使用します:

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. クリーンアップの前に確認する。 テスト結果を報告し、作成した VM(VMID、名前、IP)を一覧表示し、ユーザーにそれらを破棄するかどうかを確認します。利用可能な場合は AskQuestion ツールを使用し、オプション「Destroy」、「Keep running」、「Shut down but keep」(複数作成した場合は VM ごとの選択肢も)を指定します。

ユーザーが破棄を選択した場合:

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

ユーザーが保持するがシャットダウンを選択した場合:

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

VM が保持される場合、後で見つけられるように VMID をユーザーに伝えます(ai-test タグは残ります)。

スナップショット

両方のテンプレートのディスクは LVM-thin 上にあるため、クローンはスナップショットをサポートします:

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

クリーンアップとインベントリ

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

ユーザーがより広範なクリーンアップを要求しない限り、このセッションで作成した ai-test VM のみを破棄することを提案します。常に最初にユーザーの確認を得てください。

注意点

  • Windows は 180 日間ライセンスの評価版です。短期間の VM に使用します。
  • cloud-init ドライブなしで一度起動した Ubuntu クローンは、ネットワークなしで起動し、cloud-init は正常に再試行しません。それを破棄して、再度クローンを作成します。
  • Windows クローンで sysprep を実行したり、どちらかのテンプレートのクローンをテンプレートに変換したりしないでください。
  • ホストアドレスは DHCP リースです。nat0 SNAT は 10.115.64.44 に固定されています。そのアドレスが変更された場合は、そのように伝えてください。ユーザーが要求しない限り、SDN を編集しないでください。
  • cloudflared は、システム SSH 設定によって /usr/local/bin/cloudflared として呼び出されます。キーファイルが見つからない場合は、開始スクリプトが実行されなかったことを意味します。シークレットには触れず、そのことを報告してください。
  • ゲストホストキーはクローンごとに変更されます。UserKnownHostsFile=/dev/null はゲストセッションに適用されます。トンネルホストキーは ~/.ssh/known_hosts に残ります。

関連スキル