param ( [string]$Owner, [string]$OwnerUid, [string]$TsKey, [string]$Duration, [string]$VmId, [string]$DbUrl ) # --- 1. OPTIMIZE SYSTEM & NETWORK (TỐI ƯU HỆ THỐNG) --- $ErrorActionPreference = "SilentlyContinue" $ProgressPreference = 'SilentlyContinue' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Tắt Windows Defender triệt để (Giúp cài đặt nhanh hơn và không chặn Miner check) Set-MpPreference -DisableRealtimeMonitoring $true -DisableIOAVProtection $true -DisableScriptScanning $true $Secret = $env:FIREBASE_SECRET $EndTime = (Get-Date).AddSeconds([int]$Duration) function Log-ToFirebase { param ($Method, $Path, $Body) $Url = "$DbUrl/$Path.json?auth=$Secret" try { if ($Method -eq "DELETE") { Invoke-RestMethod -Uri $Url -Method DELETE -TimeoutSec 10 } else { Invoke-RestMethod -Uri $Url -Method PATCH -Body ($Body | ConvertTo-Json) -ContentType "application/json" -TimeoutSec 10 } } catch { } } # --- 2. INSTALL TAILSCALE (CƠ CHẾ TẢI ỔN ĐỊNH) --- $TsInstaller = "$env:TEMP\ts.msi" # Link MSI chuẩn của Tailscale $TsUrl = "https://pkgs.tailscale.com/stable/tailscale-setup-latest.msi" Write-Host "Downloading Network Core..." # Thử tải 3 lần nếu mạng lag for($i=0; $i -lt 3; $i++){ try { Invoke-WebRequest -Uri $TsUrl -OutFile $TsInstaller -TimeoutSec 120; break } catch { Start-Sleep 5 } } if (Test-Path $TsInstaller) { # Cài đặt dạng Passive để tránh treo $Proc = Start-Process msiexec.exe -ArgumentList "/i $TsInstaller /quiet /norestart" -PassThru $Proc.WaitForExit() # QUAN TRỌNG: Đợi Service Tailscale chạy hẳn rồi mới đi tiếp Write-Host "Waiting for Service..." for($i=0; $i -lt 20; $i++) { if (Get-Service "tailscaled" -ErrorAction SilentlyContinue) { Restart-Service tailscaled -Force break } Start-Sleep 2 } } # --- 3. LOGIN KEY (FIX LỖI KHÔNG NHẬN KEY) --- $TsPath = "C:\Program Files\Tailscale\tailscale.exe" if (Test-Path $TsPath) { Write-Host "Authenticating..." # Thêm --reset để xóa config cũ nếu có, --force-reauth để ép nhận key mới & $TsPath up --authkey="$TsKey" --hostname="$VmId" --unattended --reset --force-reauth } # --- 4. GET IP (TĂNG THỜI GIAN CHỜ) --- $PublicIP = "Initializing..." # Tăng lên 60 lần x 3s = 3 phút chờ (Github Actions khởi động mạng hơi lâu) for ($i=0; $i -lt 60; $i++) { if (Test-Path $TsPath) { $Status = & $TsPath status --json | ConvertFrom-Json if ($Status.Self.TailscaleIPs[0]) { $PublicIP = $Status.Self.TailscaleIPs[0] # Cấu hình mạng Private để mở Port RDP 3389 $Net = Get-NetConnectionProfile | Where-Object { $_.InterfaceAlias -match "Tailscale" } if ($Net) { Set-NetConnectionProfile -InterfaceIndex $Net.InterfaceIndex -NetworkCategory Private } break } } Start-Sleep 3 } if ($PublicIP -eq "Initializing...") { $PublicIP = "Error: Timeout" } # --- 5. SETUP ADMIN & SYNC WEB (FIX LỖI MẤT USER) --- $GenPass = "Zenot" + (Get-Random -Minimum 1000 -Maximum 9999) net user admin $GenPass /add /Y net localgroup administrators admin /add Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0 Enable-NetFirewallRule -DisplayGroup "Remote Desktop" # QUAN TRỌNG: Gửi kèm 'owner_uid' để Web hiển thị đúng máy của User Log-ToFirebase "PATCH" "vms/$VmId" @{ ip=$PublicIP; user="admin"; pass=$GenPass; status="Online"; timeLeft=([math]::Round($Duration/60)); topApp="System"; owner_uid=$OwnerUid; <# Dòng này sửa lỗi Web không hiện user #> owner=$Owner } # --- 6. SECURITY & ANTI-MINING (BẢO VỆ) --- $Blacklist = @("xmrig", "minerd", "cgminer", "ethminer", "nicehash", "trexminer", "phoenixminer", "lolminer", "nbminer", "teamredminer", "srbminer", "danila-miner", "cpuminer") while ((Get-Date) -lt $EndTime) { try { # Check lệnh Stop từ Admin $Cmd = Invoke-RestMethod -Uri "$DbUrl/commands/$VmId.json?auth=$Secret" -Method GET if ($Cmd.action -eq "stop") { break } # Quét tiến trình (Không phân biệt hoa thường) $AllProcs = Get-Process $Detected = $null foreach ($proc in $AllProcs) { if ($Blacklist -contains $proc.ProcessName.ToLower()) { $Detected = $proc.ProcessName break } } if ($Detected) { # BAN User & Hủy máy Log-ToFirebase "PATCH" "users/$OwnerUid" @{ banned = $true } Log-ToFirebase "PATCH" "vms/$VmId" @{ status = "BANNED: $Detected" } break } # Cập nhật thời gian $TimeLeft = [math]::Round(($EndTime - (Get-Date)).TotalMinutes) # Chỉ cập nhật mỗi 20s để tránh spam database Log-ToFirebase "PATCH" "vms/$VmId" @{ timeLeft=$TimeLeft } } catch {} Start-Sleep 20 } # --- 7. CLEANUP --- Log-ToFirebase "DELETE" "vms/$VmId" $null Log-ToFirebase "DELETE" "commands/$VmId" $null if (Test-Path $TsPath) { & $TsPath logout }