# SOCKS5-туннель для Cursor (обход PING timeout из РФ). # Использование: .\cursor-socks-tunnel.ps1 [start|stop|status] # См. docs/cursor/README.md и docs/connectivity/WINDOWS_CURSOR_TUNNEL.md param( [Parameter(Position = 0)] [ValidateSet("start", "stop", "status")] [string]$Command = "start" ) $CURSOR_SOCKS_PORT = if ($env:CURSOR_SOCKS_PORT) { $env:CURSOR_SOCKS_PORT } else { "10809" } $SSH_HOST = if ($env:CURSOR_TUNNEL_HOST) { $env:CURSOR_TUNNEL_HOST } else { "ahau@149.154.64.19" } $CursorViaDo = ($env:CURSOR_SOCKS_VIA_DO -ne "0") function Test-PortListening { $conn = Get-NetTCPConnection -LocalPort $CURSOR_SOCKS_PORT -State Listen -ErrorAction SilentlyContinue return $null -ne $conn } function Get-SshTunnelPids { # Найти процессы ssh.exe, у которых в командной строке есть -D и наш порт Get-CimInstance Win32_Process -Filter "Name = 'ssh.exe'" -ErrorAction SilentlyContinue | Where-Object { $_.CommandLine -match "-D\s+$CURSOR_SOCKS_PORT" } | ForEach-Object { $_.ProcessId } } function Start-Tunnel { if (Test-PortListening) { Write-Host "SOCKS already listening on 127.0.0.1:$CURSOR_SOCKS_PORT" return } $targetHost = $SSH_HOST $stableOpts = @( "-o", "TCPKeepAlive=yes", "-o", "IPQoS=throughput", "-o", "ServerAliveInterval=60", "-o", "ServerAliveCountMax=4" ) $ruOpts = @( "-o", "ServerAliveInterval=30", "-o", "ServerAliveCountMax=6" ) if ($CursorViaDo) { & ssh -o BatchMode=yes -o ConnectTimeout=6 -o ConnectionAttempts=1 hsites-ahau "exit 0" 2>$null if ($LASTEXITCODE -ne 0) { Write-Error "hsites-ahau недоступен: SOCKS только по цепочке Mac→RU→DO (без прямого Mac→DO). Восстановите SSH до RU или задайте CURSOR_SOCKS_VIA_DO=0." exit 1 } $targetHost = "telegram-socks-via-do" } $sshArgs = @( "-D", $CURSOR_SOCKS_PORT, "-f", "-N" ) if ($CursorViaDo) { $sshArgs += $stableOpts } else { $sshArgs += $ruOpts } $sshArgs += $targetHost & ssh @sshArgs if ($LASTEXITCODE -eq 0) { if ($CursorViaDo) { Write-Host "SOCKS tunnel started: 127.0.0.1:$CURSOR_SOCKS_PORT -> $targetHost (DO exit)" } else { Write-Host "SOCKS tunnel started: 127.0.0.1:$CURSOR_SOCKS_PORT -> $targetHost (RU exit, CURSOR_SOCKS_VIA_DO=0)" } } else { Write-Error "Failed to start tunnel (exit code $LASTEXITCODE). Check SSH config (telegram-socks-via-do) or host: $targetHost" exit $LASTEXITCODE } } function Stop-Tunnel { $pids = Get-SshTunnelPids if ($pids) { foreach ($pid in $pids) { Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue } Write-Host "Tunnel stopped (killed SSH process(es): $($pids -join ', '))." } else { # Fallback: убить процесс, занимающий порт 10809 $conn = Get-NetTCPConnection -LocalPort $CURSOR_SOCKS_PORT -State Listen -ErrorAction SilentlyContinue if ($conn) { $conn | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue } Write-Host "Tunnel stopped (killed process on port $CURSOR_SOCKS_PORT)." } else { Write-Host "No SOCKS tunnel found on port $CURSOR_SOCKS_PORT." } } } function Get-Status { if (Test-PortListening) { Write-Host "SOCKS listening on 127.0.0.1:$CURSOR_SOCKS_PORT" Get-NetTCPConnection -LocalPort $CURSOR_SOCKS_PORT -State Listen -ErrorAction SilentlyContinue | Format-Table LocalAddress, LocalPort, State, OwningProcess -AutoSize } else { Write-Host "No SOCKS listener on port $CURSOR_SOCKS_PORT" } } switch ($Command) { "start" { Start-Tunnel } "stop" { Stop-Tunnel } "status" { Get-Status } }