better-argo-tunnels/internal/client/ssh.go

57 lines
1.2 KiB
Go

package client
import (
"fmt"
"os"
"strings"
"golang.org/x/crypto/ssh"
)
// LoadPrivateKey loads an SSH private key from a file path or raw PEM content.
func LoadPrivateKey(keyOrPath string) (ssh.Signer, error) {
var keyBytes []byte
if isFilePath(keyOrPath) {
data, err := os.ReadFile(keyOrPath)
if err != nil {
return nil, fmt.Errorf("read key file %s: %w", keyOrPath, err)
}
keyBytes = data
} else {
keyBytes = []byte(keyOrPath)
}
signer, err := ssh.ParsePrivateKey(keyBytes)
if err != nil {
return nil, fmt.Errorf("parse private key: %w", err)
}
return signer, nil
}
func isFilePath(v string) bool {
if strings.HasPrefix(v, "/") || strings.HasPrefix(v, "./") || strings.HasPrefix(v, "~") {
return true
}
return !strings.Contains(v, "-----BEGIN")
}
// Connect establishes an SSH connection to the tunnel server.
func Connect(addr string, signer ssh.Signer) (*ssh.Client, error) {
config := &ssh.ClientConfig{
User: "tunnel",
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
client, err := ssh.Dial("tcp", addr, config)
if err != nil {
return nil, fmt.Errorf("SSH dial %s: %w", addr, err)
}
return client, nil
}