在 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 代理拨号。