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条)

报告相同问题?

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀