IP地址为'xxx.xx.xxx.xxx'的主机无法连接到此MySQL服务器。

863

这应该很简单,但是我死活弄不好。
我只是想远程连接到我的MySQL服务器。

  • 连接身份:

mysql -u root -h localhost -p  
正常运行,但尝试:
mysql -u root -h 'any ip address here' -p
  • 出现以下错误:

    ERROR 1130 (00000):主机“xxx.xx.xxx.xxx”不被允许连接到此MySQL服务器

  • mysql.user表中,有一个与本地主机的用户'root'完全相同的条目,另一个条目的主机为“%”。

    我已经陷入了困境,不知道该怎么办。欢迎任何想法。


    1
    由于安全预防措施,在大多数情况下无法使用root登录。 - AO_
    30个回答

    1064

    可能是出于安全考虑。您可以尝试添加一个新的管理员帐户:

    mysql> CREATE USER 'monty'@'localhost' IDENTIFIED BY 'some_pass';
    mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'
        ->     WITH GRANT OPTION;
    mysql> CREATE USER 'monty'@'%' IDENTIFIED BY 'some_pass';
    mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'
        ->     WITH GRANT OPTION;
    

    尽管 Pascal 和其他人指出,让拥有此类访问权限的用户对任何 IP 开放并不是一个好主意。如果你需要管理员用户,请使用 root 用户,并将其保留在本地。对于任何其他操作,请明确指定所需的特权,并像 Pascal 建议的那样限制用户的可访问性。
    编辑:
    来自 MySQL FAQ:
    "如果您无法弄清为什么会收到“拒绝访问”的错误,请从用户表中删除所有包含通配符(包含“%”或“_”字符)的 Host 值的条目。一个非常常见的错误是插入一个 Host='%',User='some_user' 的新条目,认为这允许您指定 localhost 以从同一台机器连接。之所以不起作用的原因是默认特权包括一个 Host='localhost',User='' 的条目。由于该条目具有比“%”更具体的 Host 值 'localhost',因此在从 localhost 连接时优先使用该条目!正确的过程是插入第二个条目 Host='localhost',User='some_user',或者删除 Host='localhost',User='' 条目。删除条目后,请记得发出 FLUSH PRIVILEGES 语句以重新加载授权表。另请参见第5.4.4节“访问控制,阶段1:连接验证”。"

    25
    不错的发现,Yannick。然而,我不建议他将所有权限授予非 root 用户。也许可以减少一部分权限? - Corey Ballou
    4
    这确实不是一个好主意,但允许“root”从所有主机连接到服务器时,由于拥有相同的权限级别,效果是一样的。 - Yannick Motton
    3
    我认为你没有理解我的观点,Pascal。关键是“root”用户已经拥有这些权限,他想让任何IP都能作为该用户进行身份验证。因此,如果这确实是他想要的,创建一个新的管理员用户(具有完全相同的权限)的默认示例是他尝试的另一种选择。 - Yannick Motton
    3
    没错,Yannick。我读得太快了,将删除我的评论。然而,据我所知,MySQL中的权限正常工作,因此:1.也许OP手动修改了授权表,然后需要刷新权限。2.也许他没有使用正确的root授权语法。添加另一个管理用户可能是一种解决方法,但在我看来,这并不能解决真正的问题。 - Pascal Thivent
    3
    我认为允许所有主机访问root不是一个合适的解决方案。相反,我创建了一个新用户并授予了一组较少的权限,这个权限集在MySQL Workbench上被描述为“DBManager”。我还只允许来自本地网络中特定组的主机访问,特别是192.168.0.%。 - Gustavo Guevara
    显示剩余5条评论

    374

    需要在phpMyAdmin或命令提示符中通过以下方式创建一个新的MySQL用户并分配权限:

    CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
    
    GRANT ALL PRIVILEGES ON *.* TO 'username'@'localhost' WITH GRANT OPTION;
    
    CREATE USER 'username'@'%' IDENTIFIED BY 'password';
    
    GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' WITH GRANT OPTION;
    
    FLUSH PRIVILEGES;
    

    完成这四个查询之后,它应该连接到 用户名 / 密码

    9
    完成上述步骤后,我不得不重新启动mysql才能使其正常运行。 - tollbooth
    1
    是的,如果权限有所不同,创建一个@localhost可能是有意义的,但在这里它们是相同的,这可能会更加混乱(例如更改密码时没有意识到另一个存在并且您的登录可能会命中该密码)。 - Bratchley
    1
    作为一个初学者,这确实帮助了我。 - Muhammad Nayab
    1
    感谢它解决了我在Windows容器化的Laravel应用程序中遇到的“SQLSTATE [HY000] [1130] Host 'DESKTOP-xxx.xx'无法连接到此MariaDB服务器”的问题。 - Zulqarnain
    如果我甚至无法使用命令mysql -u root -p或者phpmyadmin(使用xampp)进入mysql,我该怎么办? - Gabriel Augusto
    显示剩余4条评论

    138

    我的错误消息类似,并且显示“主机XXX无法连接到此MySQL服务器”,尽管我使用的是root。以下是确保root具有正确权限的方法。

    我的设置

    • Ubuntu 14.04 LTS
    • MySQL v5.5.37

    解决方案

    1. 打开etc/mysql/my.cnf文件

    2. 检查以下内容:

      • port(默认为port = 3306
      • bind-address(默认为bind-address = 127.0.0.1;如果要对所有人开放,则只需注释掉此行。例如,如果实际服务器位于10.1.1.7上,则可以将其更改为该地址)
    3. 现在访问您的实际服务器上的MySQL数据库(假设您的远程地址为123.123.123.123,端口为3306,用户名为root,我想更改数据库"dataentry"的权限。请记得根据您的设置更改IP地址、端口和数据库名称)

    mysql -u root -p
    Enter password: <enter password>
    mysql>GRANT ALL ON *.* to root@'123.123.123.123' IDENTIFIED BY 'put-your-password';
    mysql>FLUSH PRIVILEGES;
    mysql>exit
    
  • 现在您应该能够远程连接到数据库。例如,我使用MySQL Workbench,并输入“主机名:10.1.1.7”,“端口:3306”,“用户名:root”

  • sudo服务mysqld重启


  • 1
    你可以跳过 use dataentry 这一行(因为大多数人不会创建该数据库)。 - Jedidja
    3
    最终我能够做到这一点而无需重新启动mysql服务。 - ryantuck
    13
    "FLUSH PRIVILEGES" 应该可以让您无需重新启动。 - Adam B
    这对我在Windows 10上的MySQL 5.5版本使用FLUSH PRIVILEGES命令生效,而无需重启服务。在Windows上,服务的属性应该标识用于配置的my.ini文件(属性|常规|可执行文件路径)。 - FreeText
    我曾经认为通过指定bind-address="0.0.0.0",它会监听所有接口并且远程连接也能够工作,但是我错了。是的,netstat显示mysql正在监听0.0.0.0(所有接口),但我仍然遇到了标题中的错误。一旦我完全删除了bind-address行,它就开始工作了。很奇怪。 - Henno
    每次执行"grant all"命令时,它都引用创建用户,而不是我只是更新用户列主机为"localhost"的"%"或指定我的IP地址然后刷新权限并重启MySQL,这样就可以工作。 - Yogi Arif Widodo

    98
    只需按照以下步骤操作:
    1. 连接到MySQL(通过localhost)

      mysql -uroot -p
      
      • 如果MySQL服务器在Kubernetes(K8s)中运行,并通过NodePort访问

      kubectl exec -it [pod-name] -- /bin/bash
      mysql -uroot -p
      
    1. 创建用户

    CREATE USER 'user'@'%' IDENTIFIED BY 'password';
    
  • 授权权限

  • GRANT ALL PRIVILEGES ON *.* TO 'user'@'%' WITH GRANT OPTION;
    
  • 刷新权限

    FLUSH PRIVILEGES;
    

  • 5
    错误1045(28000):用户'root'@'localhost'被拒绝访问(使用密码YES)。 - Gank
    12
    应该将 \.\ 替换为 *.* 吗? - sgarg
    这个方法能用在类似docker的问题上吗?https://devops.stackexchange.com/q/12449/23443 - Nicholas Saunders
    1
    如何处理mysql docker容器? - A l w a y s S u n n y
    CREATE USER 'sammy'@'localhost' IDENTIFIED BY 'password';CREATE USER 'user'@'%' IDENTIFIED BY 'password'; 是不同的,% 可以让它完美运行。 - Yogi Arif Widodo
    我只是想澄清 @YogiArifWidodo 的评论:百分号(%)使其“像魔术一样”起作用,因为百分号告诉mysql允许任何主机连接。这是在mysql中使用通配符匹配主机的方法,如文档所述。 - Jeff R

    84

    您需要授予用户从任何主机名访问的权限。

    以下是通过phpmyadmin添加新特权的步骤:

    进入“Privileges” > “添加新用户”

    输入图像描述

    为所需的用户名选择 任意主机

    输入图像描述


    这需要添加到 MAMP for Mac 帮助文件中,我认为。在 2021 年仍然有效。 - vr_driver

    33

    简单的方法:

    Grant All Privileges ON *.* to 'USER_NAME'@'%' Identified By 'YOUR_PASSWORD'; 
    

    然后

    FLUSH PRIVILEGES;
    

    完成了!


    %符号代表什么? - dataviews
    1
    就像一切一样。你可以像这样思考:WHERE CustomerName LIKE 'a%' - 找到以"a"开头的任何值。 - devugur
    给出了 SQL 语法错误。 - Sushil
    @Sushil,请写下详细信息。 - devugur

    30

    这条信息 *Host ''xxx.xx.xxx.xxx'' is not allowed to connect to this MySQL server 是MySQL服务器发给MySQL客户端的回复。请注意它返回的是IP地址而不是主机名。

    如果您尝试使用mysql -h<hostname> -u<somebody> -p连接,但是收到带有IP地址的此消息,则MySQL服务器无法对客户端进行反向查找。这很关键,因为这就是它如何将MySQL客户端映射到授权中的方式。

    确保您可以在MySQL服务器上从nslookup <mysqlclient>进行查找。如果不行,则DNS服务器中没有该条目。或者,您可以在MySQL服务器的HOSTS文件中放置一个条目(<ipaddress> <fullyqualifiedhostname> <hostname> <- 这里的顺序可能很重要)。

    我的服务器中HOSTS文件中的条目解决了这个问题。


    1
    这是MySQL服务器对MySQL客户端的回复。谢谢,我一直在想错误是来自我的机器还是服务器。我遇到了错误“ERROR 1130 (HY000):”等等。 - PJ Brunet

    26

    这将适用于任何未来的远程MySQL连接!

        sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
    

    导航到以bind-address指令开头的那一行。它应该是这个样子:

    Navigate to the line that begins with the bind-address directive. It should look like this:

        bind-address            = 0.0.0.0
    

    以root权限登录到你的mysql终端

        mysql -u root -p
        -- root password
    
        CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
    
        GRANT ALL PRIVILEGES ON *.* TO 'username'@'localhost' WITH GRANT OPTION;
    
        CREATE USER 'username'@'%' IDENTIFIED BY 'password';
    
        GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' WITH GRANT OPTION;
    
        FLUSH PRIVILEGES;
    
        EXIT;
    

    最后,使用以下命令授予该机器独占的权限远程连接到数据库。

        sudo ufw allow from remote_IP_address to any port 3306
    

    添加'username'@'%'修复了我的问题,因为'username'@'localhost'不够用,非常感谢。 - Mina

    18
    如果您手动修改授权表(使用INSERT,UPDATE等),则应执行FLUSH PRIVILEGES语句以告诉服务器重新加载授权表。
    注意:我不建议允许任何主机连接到任何用户(特别是root用户)。如果您正在使用MySQL进行客户端/服务器应用程序,请选择子网地址。如果您正在使用MySQL与Web服务器或应用程序服务器一起使用,请使用特定的IP地址。

    7
    如果您正在使用MySQL WorkBench,您可以轻松地完成以下操作:
    1. 从菜单中选择Server -> Users And Privileges enter image description here

    2. 在左下角,点击"Add account" enter image description here

    3. 填写表格,包括用户名、主机匹配(%表示每个主机)和密码 enter image description here

    4. 点击右下角的"Apply" enter image description here

    然后您就可以开始使用了。如果您想进一步调整配置,可以使用"Administrative Roles"选项卡设置用户可以使用的命令(如SELECT、ALTER等),并使用"Schema privileges"选项卡将用户的交互限制在特定模式下。

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