Fix module import path and installation instructions
This commit is contained in:
parent
ee9c0edf8a
commit
e136c30266
@ -10,7 +10,7 @@ A Go-based command-line tool to manage SSH tunnels. This tool allows you to:
|
||||
## Installation
|
||||
|
||||
```
|
||||
go install git.mvl.sh/vleeuwenmenno/sshtunnel/cmd@latest
|
||||
go install git.mvl.sh/vleeuwenmenno/sshtunnel@latest
|
||||
```
|
||||
|
||||
Or clone this repository and build it yourself:
|
||||
|
186
cmd/start.go
186
cmd/start.go
@ -8,8 +8,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.mvl.sh/vleeuwenmenno/sshtunnel/pkg/stats"
|
||||
"github.com/spf13/cobra"
|
||||
"sshtunnel/pkg/stats"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -28,106 +28,106 @@ var startCmd = &cobra.Command{
|
||||
The tunnel will run in the background and can be managed using the list and stop commands.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// Check required flags
|
||||
// Generate the SSH command with appropriate flags for reliable background operation
|
||||
sshArgs := []string{
|
||||
"-N", // Don't execute remote command
|
||||
"-f", // Run in background
|
||||
"-L", fmt.Sprintf("%d:%s:%d", localPort, remoteHost, remotePort),
|
||||
// Generate the SSH command with appropriate flags for reliable background operation
|
||||
sshArgs := []string{
|
||||
"-N", // Don't execute remote command
|
||||
"-f", // Run in background
|
||||
"-L", fmt.Sprintf("%d:%s:%d", localPort, remoteHost, remotePort),
|
||||
}
|
||||
|
||||
if identity != "" {
|
||||
sshArgs = append(sshArgs, "-i", identity)
|
||||
}
|
||||
|
||||
sshArgs = append(sshArgs, sshServer)
|
||||
sshCmd := exec.Command("ssh", sshArgs...)
|
||||
|
||||
// Capture output for debugging
|
||||
var outputBuffer strings.Builder
|
||||
sshCmd.Stdout = &outputBuffer
|
||||
sshCmd.Stderr = &outputBuffer
|
||||
|
||||
// Run the command (not just Start) - the -f flag means it will return immediately
|
||||
// after going to the background
|
||||
if err := sshCmd.Run(); err != nil {
|
||||
fmt.Printf("Error starting SSH tunnel: %v\n", err)
|
||||
fmt.Printf("SSH output: %s\n", outputBuffer.String())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// The PID from cmd.Process is no longer valid since ssh -f forks
|
||||
// We need to find the actual SSH process PID
|
||||
actualPID, err := findSSHTunnelPID(localPort)
|
||||
if err != nil {
|
||||
fmt.Printf("Warning: Could not determine tunnel PID: %v\n", err)
|
||||
}
|
||||
|
||||
// Store tunnel information
|
||||
id := generateTunnelID()
|
||||
pid := 0
|
||||
|
||||
if actualPID > 0 {
|
||||
pid = actualPID
|
||||
}
|
||||
|
||||
tunnel := Tunnel{
|
||||
ID: id,
|
||||
LocalPort: localPort,
|
||||
RemotePort: remotePort,
|
||||
RemoteHost: remoteHost,
|
||||
SSHServer: sshServer,
|
||||
PID: pid,
|
||||
}
|
||||
|
||||
if err := saveTunnel(tunnel); err != nil {
|
||||
fmt.Printf("Error saving tunnel information: %v\n", err)
|
||||
if pid > 0 {
|
||||
// Try to kill the process
|
||||
process, _ := os.FindProcess(pid)
|
||||
if process != nil {
|
||||
process.Kill()
|
||||
}
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if identity != "" {
|
||||
sshArgs = append(sshArgs, "-i", identity)
|
||||
}
|
||||
|
||||
sshArgs = append(sshArgs, sshServer)
|
||||
sshCmd := exec.Command("ssh", sshArgs...)
|
||||
|
||||
// Capture output for debugging
|
||||
var outputBuffer strings.Builder
|
||||
sshCmd.Stdout = &outputBuffer
|
||||
sshCmd.Stderr = &outputBuffer
|
||||
|
||||
// Run the command (not just Start) - the -f flag means it will return immediately
|
||||
// after going to the background
|
||||
if err := sshCmd.Run(); err != nil {
|
||||
fmt.Printf("Error starting SSH tunnel: %v\n", err)
|
||||
fmt.Printf("SSH output: %s\n", outputBuffer.String())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// The PID from cmd.Process is no longer valid since ssh -f forks
|
||||
// We need to find the actual SSH process PID
|
||||
actualPID, err := findSSHTunnelPID(localPort)
|
||||
// Initialize statistics for this tunnel
|
||||
statsManager, err := stats.NewStatsManager()
|
||||
if err == nil {
|
||||
err = statsManager.InitStats(id, localPort)
|
||||
if err != nil {
|
||||
fmt.Printf("Warning: Could not determine tunnel PID: %v\n", err)
|
||||
fmt.Printf("Warning: Failed to initialize statistics: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Store tunnel information
|
||||
id := generateTunnelID()
|
||||
pid := 0
|
||||
|
||||
if actualPID > 0 {
|
||||
pid = actualPID
|
||||
}
|
||||
|
||||
tunnel := Tunnel{
|
||||
ID: id,
|
||||
LocalPort: localPort,
|
||||
RemotePort: remotePort,
|
||||
RemoteHost: remoteHost,
|
||||
SSHServer: sshServer,
|
||||
PID: pid,
|
||||
}
|
||||
// Verify tunnel is actually working
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
active := verifyTunnelActive(localPort)
|
||||
status := "ACTIVE"
|
||||
if !active {
|
||||
status = "UNKNOWN"
|
||||
}
|
||||
|
||||
if err := saveTunnel(tunnel); err != nil {
|
||||
fmt.Printf("Error saving tunnel information: %v\n", err)
|
||||
if pid > 0 {
|
||||
// Try to kill the process
|
||||
process, _ := os.FindProcess(pid)
|
||||
if process != nil {
|
||||
process.Kill()
|
||||
}
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Initialize statistics for this tunnel
|
||||
statsManager, err := stats.NewStatsManager()
|
||||
if err == nil {
|
||||
err = statsManager.InitStats(id, localPort)
|
||||
if err != nil {
|
||||
fmt.Printf("Warning: Failed to initialize statistics: %v\n", err)
|
||||
}
|
||||
}
|
||||
fmt.Printf("Started SSH tunnel (ID: %d): localhost:%d -> %s:%d (%s) [PID: %d] [Status: %s]\n",
|
||||
id, localPort, remoteHost, remotePort, sshServer, pid, status)
|
||||
},
|
||||
}
|
||||
|
||||
// Verify tunnel is actually working
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
active := verifyTunnelActive(localPort)
|
||||
status := "ACTIVE"
|
||||
if !active {
|
||||
status = "UNKNOWN"
|
||||
}
|
||||
func init() {
|
||||
rootCmd.AddCommand(startCmd)
|
||||
|
||||
fmt.Printf("Started SSH tunnel (ID: %d): localhost:%d -> %s:%d (%s) [PID: %d] [Status: %s]\n",
|
||||
id, localPort, remoteHost, remotePort, sshServer, pid, status)
|
||||
},
|
||||
}
|
||||
// Add flags for the start command
|
||||
startCmd.Flags().IntVarP(&localPort, "local", "l", 0, "Local port to forward")
|
||||
startCmd.Flags().IntVarP(&remotePort, "remote", "r", 0, "Remote port to forward to")
|
||||
startCmd.Flags().StringVarP(&remoteHost, "host", "H", "localhost", "Remote host to forward to")
|
||||
startCmd.Flags().StringVarP(&sshServer, "server", "s", "", "SSH server address (user@host)")
|
||||
startCmd.Flags().StringVarP(&identity, "identity", "i", "", "Path to SSH identity file")
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(startCmd)
|
||||
|
||||
// Add flags for the start command
|
||||
startCmd.Flags().IntVarP(&localPort, "local", "l", 0, "Local port to forward")
|
||||
startCmd.Flags().IntVarP(&remotePort, "remote", "r", 0, "Remote port to forward to")
|
||||
startCmd.Flags().StringVarP(&remoteHost, "host", "H", "localhost", "Remote host to forward to")
|
||||
startCmd.Flags().StringVarP(&sshServer, "server", "s", "", "SSH server address (user@host)")
|
||||
startCmd.Flags().StringVarP(&identity, "identity", "i", "", "Path to SSH identity file")
|
||||
|
||||
// Mark required flags
|
||||
startCmd.MarkFlagRequired("local")
|
||||
startCmd.MarkFlagRequired("remote")
|
||||
startCmd.MarkFlagRequired("server")
|
||||
}
|
||||
// Mark required flags
|
||||
startCmd.MarkFlagRequired("local")
|
||||
startCmd.MarkFlagRequired("remote")
|
||||
startCmd.MarkFlagRequired("server")
|
||||
}
|
||||
|
||||
// verifyTunnelActive checks if the tunnel is actually working
|
||||
func verifyTunnelActive(port int) bool {
|
||||
@ -138,4 +138,4 @@ func verifyTunnelActive(port int) bool {
|
||||
}
|
||||
conn.Close()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
10
cmd/stats.go
10
cmd/stats.go
@ -5,8 +5,8 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"sshtunnel/pkg/monitor"
|
||||
"sshtunnel/pkg/stats"
|
||||
"git.mvl.sh/vleeuwenmenno/sshtunnel/pkg/monitor"
|
||||
"git.mvl.sh/vleeuwenmenno/sshtunnel/pkg/stats"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@ -181,7 +181,7 @@ func watchTunnelStats(tunnelID int, interval int) {
|
||||
if err != nil {
|
||||
fmt.Printf("Warning: Tunnel #%d may not be active: %v\n", tunnelID, err)
|
||||
fmt.Println("Attempting to monitor anyway...")
|
||||
|
||||
|
||||
// Try to get port from stats
|
||||
statsManager, _ := stats.NewStatsManager()
|
||||
s, err := statsManager.GetStats(tunnelID)
|
||||
@ -226,7 +226,7 @@ func watchTunnelStats(tunnelID int, interval int) {
|
||||
if err != nil {
|
||||
fmt.Printf("Warning: %v\n", err)
|
||||
fmt.Println("Displaying minimal statistics...")
|
||||
statsStr = fmt.Sprintf("Monitoring tunnel #%d on port %d...",
|
||||
statsStr = fmt.Sprintf("Monitoring tunnel #%d on port %d...",
|
||||
tunnelID, tunnel.LocalPort)
|
||||
}
|
||||
fmt.Println(statsStr)
|
||||
@ -241,7 +241,7 @@ func watchTunnelStats(tunnelID int, interval int) {
|
||||
|
||||
statsStr, err := mon.FormatStats()
|
||||
if err != nil {
|
||||
statsStr = fmt.Sprintf("Warning: %v\n\nStill monitoring tunnel #%d on port %d...",
|
||||
statsStr = fmt.Sprintf("Warning: %v\n\nStill monitoring tunnel #%d on port %d...",
|
||||
err, tunnelID, tunnel.LocalPort)
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"git.mvl.sh/vleeuwenmenno/sshtunnel/pkg/stats"
|
||||
"github.com/spf13/cobra"
|
||||
"sshtunnel/pkg/stats"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -86,7 +86,7 @@ func killTunnel(t Tunnel) {
|
||||
|
||||
removeFile(t.ID)
|
||||
cleanupStats(t.ID)
|
||||
fmt.Printf("Stopped SSH tunnel (ID: %d): localhost:%d -> %s:%d\n",
|
||||
fmt.Printf("Stopped SSH tunnel (ID: %d): localhost:%d -> %s:%d\n",
|
||||
t.ID, t.LocalPort, t.RemoteHost, t.RemotePort)
|
||||
}
|
||||
|
||||
@ -102,4 +102,4 @@ func cleanupStats(tunnelID int) {
|
||||
if err != nil {
|
||||
fmt.Printf("Warning: Failed to delete statistics for tunnel %d: %v\n", tunnelID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
go.mod
2
go.mod
@ -1,4 +1,4 @@
|
||||
module sshtunnel
|
||||
module git.mvl.sh/vleeuwenmenno/sshtunnel
|
||||
|
||||
go 1.22.2
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user