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 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题
  • ¥15 Python时间序列如何拟合疏系数模型