Skip to content

Instantly share code, notes, and snippets.

@Martin91
Last active April 18, 2023 06:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Martin91/067aba6eaa443457fbe6e72383204eed to your computer and use it in GitHub Desktop.
Save Martin91/067aba6eaa443457fbe6e72383204eed to your computer and use it in GitHub Desktop.
Connect to a database via SSH tunnel
// Package internal ...
package internal
import (
"fmt"
"github.com/go-sql-driver/mysql"
"golang.org/x/crypto/ssh"
"net"
)
type ViaSSHDialer struct {
client *ssh.Client
}
func (self *ViaSSHDialer) Dial(addr string) (net.Conn, error) {
return self.client.Dial("tcp", addr)
}
type SSHTunnelConfig struct {
Host string
User string
Password string
Port uint
}
// SetupSSHTunnel Register a custom network named "mysql+tcp"
func SetupSSHTunnel(tunnelConf *SSHTunnelConfig) error {
sshConfig := &ssh.ClientConfig{
User: tunnelConf.User,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Auth: []ssh.AuthMethod{
ssh.PasswordCallback(func() (string, error) {
return tunnelConf.Password, nil
}),
},
}
sshcon, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", tunnelConf.Host, tunnelConf.Port), sshConfig)
if err != nil {
return err
}
mysql.RegisterDial("mysql+tcp", (&ViaSSHDialer{sshcon}).Dial)
return nil
}
package main
import (
// ...
)
type MySqlConfig struct {
Dsn string
MaxIdleConns int
MaxOpenConns int
ConnMaxLifetime int
SSHTunnel *internal.SSHTunnelConfig
}
mysqlConf := new(MySqlConfig)
// ... set configurations
if mysqlConf.SSHTunnel != nil {
if err = internal.SetupSSHTunnel(mysqlConf.SSHTunnel); err != nil {
log.Fatal(err)
}
}
// for traditional and direct connection, Dsn is like: user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
// for connection connected through SSH tunnel, Dsn is like: user:pass@mysql+tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
conn, err := gorm.Open(gormMySQL.Open(mysqlConf.Dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
})
@hendra-jti
Copy link

this doesnt work

@Martin91
Copy link
Author

this doesnt work

could you provide detailed error message?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment