Golang SSH隧道连接到远程postgres DB

时间:2016-03-16 17:14:15

标签: postgresql go

我查看了各种资源。我不确定如何完成这项任务。我可以在本地连接没问题,但我无法轻松连接到遥控器。我需要传递一个RSA .pem密钥,我不太确定如何执行此操作而不强制连接不安全

package main

import (
    "database/sql"
    "fmt"
    "os"

    _ "github.com/lib/pq"
)

var (
    dbUser  = os.Getenv("DB_USER")
    dbPass  = os.Getenv("DB_PASS")
    dbName  = os.Getenv("DB_NAME")
    dbHost  = os.Getenv("DB_HOST")
    dbPort  = os.Getenv("DB_PORT")
    sslMode = os.Getenv("SSLMODE")
)

// ConnectDb is a short cut function that takes parameters through
// CLI that returns a pointer to a sql.DB connection.
// It takes no arguments.
func ConnectDb() (*sql.DB, error) {

    db, err := sql.Open("postgres", getDbInfo())
    CheckErr(err, "Unable to connecto tthe DB")

    if err := db.Ping(); err != nil {
        return nil, err
    }

    return db, nil
}

func getDbInfo() string {
    var dbInfo string

    if dbName != "" {
        dbInfo += fmt.Sprintf("dbname=%s ", dbName)
    } else {
        dbInfo += fmt.Sprintf("dbname=%s ", "development")
    }

    // checks for nil value
    if dbUser != "" {
        dbInfo += fmt.Sprintf("dbuser=%s ", "user")
    }

    // checks for nil value
    if dbPass != "" {
        dbInfo += fmt.Sprintf("dbpass=%s ", dbPass)
    }

    if sslMode != "" {
        dbInfo += fmt.Sprintf("sslmode=%s", sslMode)
    } else {
        dbInfo += fmt.Sprintf("sslmode=disable")
    }

    return dbInfo
}

1 个答案:

答案 0 :(得分:1)

据我了解,您需要打开与postgre数据库的连接。我不知道是否存在本机postgre ssh隧道支持。所以,这个关于SSH隧道到数据库机器的答案。

我没有以这种方式测试postgre,但是我已经在某些专有服务器连接中使用了这个模型。

过程就是这样:

  1. 打开与db machine的连接
  2. 从本地端口到远程数据库端口建立隧道
  3. 在本地端口上打开数据库连接
  4. 你可以使用像OpenSSH或putty这样的ssh客户端完成#1和#2。你可能应该这样做。如果外部客户端工作,那么您可以尝试将其全部放入go语言代码而无需外部SSH客户端。

    在go中你会使用

    “golang.org/x/crypto/ssh”

    包。

    有教程如何使用GO ssh隧道。以下不是没有错误检查的测试样本:

    var buffer []byte
    var err error
    buffer, err = ioutil.ReadFile(sshKeyFile)
    var key ssh.Signer
    key, err = ssh.ParsePrivateKey(buffer)
    var authMethod ssh.AuthMethod
    authMethod = ssh.PublicKeys(key)
    sshConfig = &ssh.ClientConfig{
        User: "user_id",
        Auth: []ssh.AuthMethod{authMethod},
    }
    conn, err := ssh.Dial("tcp", endpoint, sshConfig)
    // open connection on postgre:
    dbConn, err = conn.Dial("tcp", dbEndpoint)
    

    上面的最后一行并不完全是隧道,而是对数据库服务器开放的TCP连接。您可以将该连接传递到db库。如果没有,则必须设置隧道。