Files
go-ssh-app/ssh/connect.go
2024-12-28 16:27:20 +01:00

76 lines
2.1 KiB
Go

package ssh
import (
"fmt"
"io/ioutil"
"log"
"golang.org/x/crypto/ssh"
)
type SSHConfig struct {
User string
Host string
Port string
Password string
PrivateKey string
}
// ConnectSSH handles both key-based and password authentication dynamically.
func ConnectSSH(config SSHConfig) error {
log.Printf("Attempting SSH connection to %s@%s:%s", config.User, config.Host, config.Port)
// Build SSH authentication methods
var authMethods []ssh.AuthMethod
// Add key-based authentication if a private key is provided
if config.PrivateKey != "" {
log.Println("Attempting key-based authentication...")
key, err := ioutil.ReadFile(config.PrivateKey)
if err != nil {
log.Printf("Error reading private key: %v", err)
return fmt.Errorf("failed to read private key: %w", err)
}
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
log.Printf("Error parsing private key: %v", err)
return fmt.Errorf("failed to parse private key: %w", err)
}
authMethods = append(authMethods, ssh.PublicKeys(signer))
}
// Add password-based authentication if a password is provided
if config.Password != "" {
log.Println("Attempting password-based authentication...")
authMethods = append(authMethods, ssh.Password(config.Password))
}
// Ensure at least one authentication method is configured
if len(authMethods) == 0 {
return fmt.Errorf("no authentication method provided (password or private key)")
}
// Configure SSH client
clientConfig := &ssh.ClientConfig{
User: config.User,
Auth: authMethods,
HostKeyCallback: ssh.InsecureIgnoreHostKey(), // Use a proper host key callback for production!
}
// Dial the SSH server
address := fmt.Sprintf("%s:%s", config.Host, config.Port)
log.Printf("Connecting to SSH server at %s...", address)
client, err := ssh.Dial("tcp", address, clientConfig)
if err != nil {
log.Printf("Failed to connect to SSH server: %v", err)
return fmt.Errorf("failed to connect to SSH server: %w", err)
}
defer client.Close()
log.Printf("Successfully connected to %s@%s:%s", config.User, config.Host, config.Port)
return nil
}