我想使用Go程序连接到AWS托管在AWS上的MySQL数据库实例,使用隧道连接到localhost。 我们通过堡垒实例连接到AWS。这些是.ssh / config文件中的规则:
User user1
Host bastion
HostName {ipaddress}
User user1
ForwardAgent yes
....
Host *.amazonaws.com
ProxyCommand ssh -qax bastion nc %h %p
我使用以下命令进行端口转发,并且能够使用本地mysql客户端甚至使用Go中的程序连接到127.0.0.1:3307上的mysql实例。
ssh -f user1@aws-instance1.amazonaws.com -L 3307:127.0.0.1:3306 -N
但是,有可能实现使用Jumpserver然后在Go中连接到远程数据库实例的完整功能吗? 我找到了这个答案:https://stackoverflow.com/a/35924799/3442754 但是,我无法弄清楚如何转发到正在127.0.0.1:3306监听的aws节点上的mysql实例。我相信我能够连接到aws实例,因为所有连接和客户端对象都是在下面的程序中成功创建的,但是不确定如何转发到mysql服务器。
func main() {
config := &ssh.ClientConfig{
User: "user1", // replace this
Auth: []ssh.AuthMethod{
ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) ([]string, error) {
// Just send the password back for all questions
answers := make([]string, len(questions))
for n, q := range questions {
a, err := getAnswer(q)
if err != nil {
log.Fatal(err)
}
answers[n] = a
}
return answers, nil
}),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
bastionHost := "bastion-ip:22"
awsDBNode := "aws-instance1.amazonaws.com:22"
bClient, err := ssh.Dial("tcp", bastionHost, config)
if err != nil {
log.Fatal(err)
}
fmt.Printf("client: %v", bClient)
defer bClient.Close()
// Dial a connection to the service host, from the bastion
conn, err := bClient.Dial("tcp", awsDBNode)
if err != nil {
log.Fatal(err)
}
fmt.Printf("conn: %v", conn)
defer conn.Close()
}
func getAnswer(quest string) (string, error) {
fmt.Printf("please enter %s: ", quest)
reader := bufio.NewReader(os.Stdin)
name, err := reader.ReadString('\n')
if err != nil {
return name, err
}
return clean.ReplaceAllString(name, ""), nil
}
var clean = regexp.MustCompile("[\r\n,]")