在 Go 中使用 Socks 代理连接 MySQL

一般情况下,连接 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 代理拨号。

posted @ 2022-09-10 10:13  liuxianshen  阅读(602)  评论(0编辑  收藏  举报