57 lines
1.2 KiB
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
|
|
}
|