如何为用户授予MySQL服务器的远程访问权限?

136

如果我在MySQL数据库中执行SHOW GRANTS,我会得到:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' 
    IDENTIFIED BY PASSWORD 'some_characters' 
    WITH GRANT OPTION

如果我没记错的话,root@localhost 表示用户 root 只能从 localhost 访问该服务器。我该如何告诉 MySQL 授予 root 用户从同一网络中的其他机器访问这个 MySQL 服务器的权限?


6
将“localhost”更改为“%”将授予公共网络root访问权限。不要忘记执行“flush privileges;”。 - user972946
8
添加root@%会带来很多风险,不应该这样做。我知道这是一篇旧文章,但警告应该在这里。攻击者首先会瞄准root账户,而root@'%'意味着root用户可以从任何地方连接到你的MySQL账户。评论中无法覆盖的内容太多,但你应该尽量删除尽可能多的users@'%',并且任何声明为此的用户都应该有非常有限的权限。无论如何,你绝对不应该添加root@'%',你的应用程序也不应该期望该账户存在。 - Damon
嘿伙计们,应该从这个命令中删除PASSWORD字符串...它会导致错误...只需以IDENTIFIED BY和密码本身结尾即可。 - Mário de Sá Vera
11个回答

153

这将授予使用相同密码的root访问权限,可以在*.example.com的任何机器上访问:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%.example.com' 
    IDENTIFIED BY 'some_characters' 
    WITH GRANT OPTION;
FLUSH PRIVILEGES;
如果名称解析无法生效,您也可以通过IP或子网授予访问权限。
GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.%'
    IDENTIFIED BY 'some_characters'  
    WITH GRANT OPTION;
FLUSH PRIVILEGES;

MySQL GRANT 语法文档。


17
我假设 ...TO 'root'@'%' IDENTIFIED... 可以从任何地方授予权限? - Aufwind
5
我在MySQL中执行了命令,但SHOW GRANTS仍然显示与我的问题中相同的内容。我甚至执行了FLUSH PRIVILEGES。我错过了什么吗? - Aufwind
10
请注意,IDENTIFIED BY PASSWORD 附带一个由41位十六进制数字组成的哈希值。如果您想直接包含密码,请使用 IDENTIFIED BY 'password' - Rainulf
@Aufwind @MichaelBerkowski - SHOW GRANTS; 只显示已登录用户(例如:root@localhost)的授权。如果您以 root@example.com 登录并从那里执行 SHOW GRANTS;,它不会显示 root@localhost,但会显示 root@%.example.com。要列出用户,您需要使用类似于 select user,host,grant_priv from mysql.user; 的语句。 - bobpaul
我更倾向于@moshe-beeri在下面提供的快速且不太准确的答案,但是这个答案显然更适合在生产中使用。 - einnocent
显示剩余4条评论

100

尝试:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'Pa55w0rd' WITH GRANT OPTION;

1
“Pa55w0rd”是什么意思?听起来很愚蠢,不要告诉我这就是你想设置的密码。你希望每个尝试登录你的MySQL的人都使用这个密码吗? - SSpoke
26
通常用于占位密码,表示“在这里输入你的强密码”。 - moshe beeri
3
这个命令需要注明一点,你只应该在安全无需考虑的应用程序中使用它,比如开发或测试。 - einnocent
如果在 Mac 上无法正常工作,请尝试将“root”@“%”更改为“root”@“localhost”或您正在授予权限的计算机的 /etc/hosts 名称。 - moshe beeri
2
不要忘记在此之后运行:FLUSH PRIVILEGES; - dane
在某些情况下,"IDENTIFIED BY 'Pa55w0rd'" 部分可能不是必需的。 - undefined

49

您需要采取一些步骤来确保可以从外部访问首先是mysql,然后是root用户:

  1. my.cnf文件(例如:/etc/mysql/my.cnf)中禁用skip-networking

  2. 检查my.cnfbind-address的值是否设置为127.0.0.1,如果是,则可以将其更改为0.0.0.0以允许从所有IP访问或从您要连接的任何IP。

  3. 授权远程访问根用户(或指定您的IP而不是%

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'
    IDENTIFIED BY 'your_root_password'
    WITH GRANT OPTION;
FLUSH PRIVILEGES;
  • 重新启动mysql服务:

    sudo service mysql restart
    

  • 你还需要从防火墙打开mysql端口3306,否则远程客户端将无法连接。 - David Okwii
    仅就@Khashayar的第二点快速通知一下:0.0.0.0表示任何IPv4地址。*表示任何地址,无论是IPv4还是IPv6。 - Gustavo Pinsard
    现在的位置是 /etc/mysql/mysql.conf.d/mysql.conf - Eoop Xoeno

    38
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' 
        IDENTIFIED BY 'YOUR_PASS' 
        WITH GRANT OPTION;
    FLUSH PRIVILEGES;  
    

    *.* = DB.TABLE 可以限制用户访问特定的数据库和表。

    'root'@'%' 您可以将root更改为您创建的任何用户,而%允许所有IP地址。您还可以通过更改为%.168.1.1等来限制它。


    如果这样无法解决问题,则还需修改my.cnf或my.ini文件,并注释掉以下行:

    bind-address = 127.0.0.1 更改为 #bind-address = 127.0.0.1

    skip-networking 更改为 #skip-networking

    • 重新启动MySQL并重复以上步骤。

    在Raspberry Pi上,我发现bind-address配置位于\etc\mysql\mariadb.conf.d\50-server.cnf中。


    2
    只回答解释 *.*'user'@'address' 部分的答案。谢谢! :) - Philipp
    授予 . 的 ALL 权限容易引来黑客。 - Rick James
    这就是为什么我解释了 *.* - Wasim A.

    13

    从mysql 8及更高版本开始,您无法通过授予权限来添加用户。也就是说,使用以下查询:

    GRANT ALL PRIVILEGES ON *.* TO 'user'@'localhost' IDENTIFIED BY 'password';

    必须改为以下两个查询:

    CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';

    GRANT ALL PRIVILEGES ON *.* TO 'user'@'localhost';

    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' 
        IDENTIFIED BY 'type-root-password-here' 
        WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    

    mysql会返回此错误:

    ERROR 1064 (42000): 在第1行附近有一个语法错误,检查对应于你的MySQL服务器版本的手册以获取正确的语法使用方式 'IDENTIFIED BY 'written password'

    这意味着你没有%域的root用户。因此,你需要首先插入用户,然后像这样授予权限:

    mysql> CREATE USER 'root'@'%' IDENTIFIED BY 'your password';
    Query OK, 0 rows affected (0.11 sec)
    
    mysql> GRANT ALL ON *.* TO 'root'@'%';
    Query OK, 0 rows affected (0.15 sec)
    
    mysql> FLUSH PRIVILEGES;
    

    不要忘记用您自己的特定密码替换密码。


    它抛出了一个错误:ERROR 1396 (HY000):'root'@'%'的操作CREATE USER失败。 - Package.JSON
    我们能为已创建的用户做这个吗?因为它会出现访问被拒绝的错误。 - Heemanshu Bhalla

    8

    那些被其他人分享的SQL授权确实有效。如果您仍然无法访问数据库,有可能是因为端口受到防火墙限制。这取决于您的服务器类型(以及中间的任何路由器)如何打开连接。打开TCP端口3306的入站流量,并为外部机器(所有/子网/单个IP等)设置类似的访问规则。


    5

    两个步骤:

    1. 使用通配符设置用户:
    create user 'root'@'%' identified by 'some_characters'; 
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' 
        IDENTIFIED BY PASSWORD 'some_characters' 
        WITH GRANT OPTION
    
    vim /etc/my.cnf
    

    添加以下内容:

    bind-address=0.0.0.0
    

    重新启动服务器,您连接时不应该遇到任何问题。


    跟着操作,收到了“ERROR 1827 (HY000): The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function.”的错误信息。你能解释一下我在这里做错了什么吗? - lampShadesDrifter

    4

    打开 /etc/mysql/mysql.conf.d/mysqld.cnf 文件,并注释掉以下行:

    #bind-address = 127.0.0.1
    

    在 Ubuntu 19.4 上工作。 - Ngô Văn Thao

    3
    在我的情况下,我尝试连接到一台运行CentOS的远程MySQL服务器。经过尝试了很多解决方案(授权所有权限、删除IP绑定、启用网络),问题仍未得到解决。
    后来,在研究各种解决方案时,我发现了iptables,这让我意识到MySQL端口3306不接受连接。
    以下是我如何检查和解决此问题的简要说明:
    • 检查端口是否接受连接:
    telnet (mysql服务器IP) [端口号]

    -添加ip表规则以允许在端口上进行连接:

    iptables -A INPUT -i eth0 -p tcp -m tcp --dport 3306 -j ACCEPT

    -不建议在生产环境中使用此方法,但如果您的iptables配置不正确,则添加规则可能仍无法解决问题。在这种情况下,应执行以下操作:

    service iptables stop
    希望这可以帮到您。

    1

    Ubuntu 18.04

    安装并确保mysqld正在运行...

    进入数据库并设置root用户:

    sudo mysql -u root
    SELECT User,Host FROM mysql.user;
    DROP USER 'root'@'localhost';
    CREATE USER 'root'@'%' IDENTIFIED BY 'obamathelongleggedmacdaddy';
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    exit;
    

    编辑mysqld权限并重新启动:

    sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
    
    # edit the line to be this:
    bind-address=0.0.0.0
    
    sudo systemctl stop mysql
    sudo systemctl start mysql
    

    从另一台机器进行测试..显然,mysqld机器上的端口(3306)必须允许来自测试机器的连接。

    mysql -u root -p -h 123.456.789.666
    

    所有额外的MySql“安全”措施并没有提高安全性,只是让事情变得更加复杂和难以理解。现在实际上比过去更容易出错了,在过去你只需要使用一个非常长的密码就可以了。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接