Go语言使用仅限本地访问的非root用户连接MySQL失败如何解决?
问题描述
我为Go语言项目创建了MySQL用户gou,执行的SQL语句如下:
create user 'gou'@'localhost' identified by 'gop'; grant select, insert, update, delete, create, drop, alter on gdb.* to 'gou'@'localhost';
我的Go语言数据库连接代码片段:
... _ "github.com/go-sql-driver/mysql" ... db, err := sql.Open("mysql", "gou:gop@tcp(localhost:3306)/gdb?parseTime=true")
运行代码时触发权限错误:
Error 1045 (28000): Access denied for user 'gou'@'my.very.own.ip' (using password: YES) exit status 1
已知两种可行但不符合需求的方案:
- 使用root用户连接,但不想用高权限账号
- 创建
gou@'%'用户,但仅希望该账号限制本地访问
问题原因
MySQL里'gou'@'localhost'账号仅允许通过**Unix套接字(Linux/macOS)或命名管道(Windows)**连接,不支持TCP/IP方式的本地IP访问。而你在Go连接字符串里用了tcp(localhost:3306),驱动会把localhost解析成你的本机网卡IP,而非使用本地套接字,导致权限校验不通过。
另外要注意:MySQL中'user'@'localhost'和'user'@'127.0.0.1'是两个独立账号,前者对应本地套接字连接,后者对应TCP/IP回环连接。
解决方法
有两种针对性的解决方式:
方法1:强制使用本地套接字连接
修改Go连接字符串,把TCP连接替换为Unix套接字路径,示例:
db, err := sql.Open("mysql", "gou:gop@unix(/var/run/mysqld/mysqld.sock)/gdb?parseTime=true")
不同系统的套接字路径有区别:Linux通常是
/var/run/mysqld/mysqld.sock,Homebrew安装的MySQL(macOS)一般是/tmp/mysql.sock,Windows系统建议用方法2。
方法2:新增支持本地TCP/IP连接的账号
创建一个允许从127.0.0.1访问的gou账号,保留原localhost账号的套接字访问权限:
create user 'gou'@'127.0.0.1' identified by 'gop'; grant select, insert, update, delete, create, drop, alter on gdb.* to 'gou'@'127.0.0.1'; flush privileges;
这样既可以通过tcp(localhost:3306)正常连接,又能确保账号仅本地可访问,不会开放给外部IP。
内容的提问来源于stack exchange,提问作者Sergio Valdez
相关产品推荐
相关产品推荐

