跳到主要内容

Go 语言中使用 Socks 代理连接 MySQL

· 阅读需 1 分钟

一般情况下,连接 MySQL 是这样的:

type Option func(*sql.DB)

func InitDB(dsn string, opts ...Option) *sql.DB {

db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatalf("err: %v\n", err)
}

for _, opt := range opts {
opt(db)
}

err = db.Ping()
if err != nil {
log.Fatalf("err: %v\n", err)
}

return db
}

要想通过 Socks 代理连接 MySQL,只需新添加一个 Option 即可:

import (
"context"
"database/sql"
"net"

"github.com/go-sql-driver/mysql"
"golang.org/x/net/proxy"
)

func SocksProxy(dialer proxy.Dialer) Option {
return func(d *sql.DB) {
mysql.RegisterDialContext("tcp", func(ctx context.Context, addr string) (net.Conn, error) {
return dialer.Dial("tcp", addr)
})
}
}

func NewSocksDialer(addr, user, password string) (proxy.Dialer, error) {
return proxy.SOCKS5("tcp", addr, &proxy.Auth{User: user, Password: password}, proxy.Direct)
}

func main() {

dialer, err := NewSocksDialer("", "", "")
if err != nil {
log.Fatalf("err: %v\n", err)
}

db := InitDB("root:12345678@tcp(localhost:3306)/test?parseTime=True&loc=Local&charset=utf8mb4", SocksProxy(dialer))
defer db.Close()
}

NewSocksDialer 自定义一个 Socks 代理拨号,mysql.RegisterDialContext 注册 Socks 代理拨号。