dqg95034 2019-05-29 07:52
浏览 34
已采纳

新连接失败时,使用数据库/ SQL库并从保管库获取密码

I have a long running daemon written in Go, that listens to a port and spins up multiple go routines for every new connection to handle the data. There is a global variable db that is assigned connection context returned by database/sql library's open() function in the func main() of my script.

We store the db password in a vault which rotates it every couple of days for security reasons. I can fetch the password from the vault the first time it creates the connection context and the same context is used in all go routines for creating new db connections. However, when the password is rotated by the vault, all new db connections fail. I would like to know what is the best way of handling this so that it fetches the password from the vault on failure and reconnects. If it was an oop language, I could extend the db library and override the connection function to catch the error and fetch password from the vault on connection failure. Is there a similar approach that can be used in Go or are there any other way of handling this? I am very new to Go, and apologies if I have not framed the question right.

package main

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "net"
)

var db *sql.DB
const port = "port number"

func main() {

    db, err = sql.Open("mysql","<Connection string that contains the password fetched from vault>")

    db.SetMaxOpenConns(100)

    listener, err := net.Listen("tcp", ":"+port)

    for {
        conn, err := listener.Accept() 

        go handleConnection(conn)
    }
}

func handleConnection(conn net.Conn) {
    // Uses db variable to connect to db.
}

  • 写回答

2条回答 默认 最新

  • dougu1896 2019-06-12 04:35
    关注

    I have solved this problem by creating a custom driver that imports github.com/go-sql-driver/mysql and get registered in the sql package, so that when ever a new connection is required the custome driver can fetch password from vault and pass it down to mysql driver to open the connection. Refer the code sample below.

    package vault-mysql-driver
    
    import (
        "database/sql"
        "github.com/go-sql-driver/mysql"
    )
    
    type VaultMysqlDriver struct {
        *mysql.MySQLDriver
    }
    
    func updateDsn(dsn string) (string, err) {
        // logic to fetch password from vault and update dsn with the password
    }
    
    func (d VaultMysqlDriver) Open(dsn string) (driver.Conn, error) {
    
        updateddsn, err := updateDsn(dsn)
    
        // Pass down the dsn with password to mysql driver's open function
        return d.MySQLDriver.Open(updateddsn)
    
    }
    
    // When initialised will register the driver in sql package
    func init() {
        sql.Register(vault-driver, &CyberarkMysqlDriver{&mysql.MySQLDriver{}})
    }
    
    

    This package is now imported in the daemon as below,

    import (
        "database/sql"
        _ "vault-mysql-driver"// init is invoked and it will get registered in sql package
        "net"
    )
    
    var db *sql.DB
    const port = "port number"
    
    func main() {
        // vault-driver is used instead of mysql so that the sql package knows to use the custom driver for new connections.
        db, err = sql.Open("vault-driver","<Connection string that contains the password fetched from vault>")
    
        db.SetMaxOpenConns(100)
    
        listener, err := net.Listen("tcp", ":"+port)
    
        for {
            conn, err := listener.Accept() 
    
            go handleConnection(conn)
        }
    }
    
    func handleConnection(conn net.Conn) {
        // Uses db variable to connect to db.
    }
    

    This way whenever the vault rotates the password there won't be any connection failure since the vault driver will always fetch password from vault for every new connections.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图点聚合中Marker的位置无法实时更新
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程