Files
AetherForge/agent/deploy/tunnel_ssh_windows.go
AetherForge 5fc601b564 feat: fleet ops, KEV scan, tunnels, beacon fallback, persistence
Extend owned-fleet control with scheduled tasks, audit log, file browser,
HTTPS beacon when WS drops, protocol tunnels, registry/autostart forge
options, KEV exposure in full sys check with Telegram alerts, and UI/tests.
2026-06-04 09:34:33 -07:00

68 lines
1.8 KiB
Go

//go:build windows
package deploy
import (
"encoding/json"
"fmt"
"os"
"os/exec"
"strings"
)
// StartSSHForward opens a local port on the agent that forwards to remote_host:remote_port via SSH.
func StartSSHForward(meta SSHForwardMeta) (string, error) {
if meta.LocalPort <= 0 || meta.LocalPort > 65535 {
return "", fmt.Errorf("local_port required (1-65535)")
}
meta.RemoteHost = strings.TrimSpace(meta.RemoteHost)
if meta.RemoteHost == "" {
return "", fmt.Errorf("remote_host required")
}
if meta.RemotePort <= 0 || meta.RemotePort > 65535 {
return "", fmt.Errorf("remote_port required (1-65535)")
}
jump := strings.TrimSpace(meta.JumpHost)
if jump == "" {
jump = meta.RemoteHost
}
user := strings.TrimSpace(meta.SSHUser)
if user == "" {
user = os.Getenv("USERNAME")
if user == "" {
user = "Administrator"
}
}
bind := fmt.Sprintf("127.0.0.1:%d:%s:%d", meta.LocalPort, meta.RemoteHost, meta.RemotePort)
target := fmt.Sprintf("%s@%s", user, jump)
var cmd *exec.Cmd
if sshPath, err := exec.LookPath("ssh"); err == nil {
cmd = HiddenCommand(sshPath, "-N",
"-o", "StrictHostKeyChecking=no",
"-o", "BatchMode=yes",
"-o", "ExitOnForwardFailure=yes",
"-L", bind,
target,
)
} else if plinkPath, err := exec.LookPath("plink"); err == nil {
cmd = HiddenCommand(plinkPath, "-N",
"-batch",
"-L", bind,
target,
)
} else {
return "", fmt.Errorf("OpenSSH client (ssh) or PuTTY plink not found on PATH")
}
if err := cmd.Start(); err != nil {
return "", fmt.Errorf("failed to start ssh forward: %w", err)
}
metaBlob, _ := json.Marshal(meta)
RegisterTunnelPID(TunnelSSHForward, cmd.Process.Pid, string(metaBlob))
return fmt.Sprintf("ssh forward pid %d — 127.0.0.1:%d → %s:%d via %s",
cmd.Process.Pid, meta.LocalPort, meta.RemoteHost, meta.RemotePort, target), nil
}