文章目录
skip_name_resolve参数控制MySQL服务器是否解析主机名,合理配置skip_name_resolve可以提高连接速度,尤其是在DNS解析速度较慢或不稳定的情况下。
本文基于MySQL8.4.3版本。MySQL8.4官方参考手册:https://dev.mysql.com/doc/refman/8.4/en/server-system-variables.html
skip_name_resolve = ON {#title-0}
不解析主机名:MySQL不会将客户端的IP地址解析为主机名。这可以减少DNS解析的开销,从而提高连接速度。
用户权限:在用户权限表中,Host列必须使用IP地址来指定,而不能使用主机名。
安全性:减少了DNS解析的依赖,降低了DNS污染攻击的风险。
skip_name_resolve = OFF {#title-1}
解析主机名:默认值,MySQL将尝试将客户端的IP地址解析为主机名。这可能会增加连接时的延迟,特别是在DNS解析速度较慢的情况下。
用户权限:可以在用户权限表中使用主机名来指定Host,这在某些情况下可能更方便管理。
灵活性:允许使用主机名来管理用户权限,提供了更高的灵活性。
演示示例 {#title-2}
基于wlnmp源,安装MySQL8.4版本验证skip_name_resolve参数。
连接MySQL,确保skip_name_resolve值为ON
mysql> SHOW VARIABLES LIKE 'skip_name_resolve'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | skip_name_resolve | ON | +-------------------+-------+ 1 row in set (0.01 sec)
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 | mysql> SHOW VARIABLES LIKE 'skip_name_resolve'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | skip_name_resolve | ON | +-------------------+-------+ 1 row in set (0.01 sec) |
创建测试用户,并给予测试用户权限,我这里创建两个用户,一个使用主机名,另一个使用IP地址。
mysql> CREATE USER 'whsir1'@'localhost' IDENTIFIED BY 'password1'; mysql> CREATE USER 'whsir2'@'127.0.0.1' IDENTIFIED BY 'password2'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'whsir1'@'localhost'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'whsir2'@'127.0.0.1'; mysql> FLUSH PRIVILEGES;
|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 | mysql> CREATE USER 'whsir1'@'localhost' IDENTIFIED BY 'password1'; mysql> CREATE USER 'whsir2'@'127.0.0.1' IDENTIFIED BY 'password2'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'whsir1'@'localhost'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'whsir2'@'127.0.0.1'; mysql> FLUSH PRIVILEGES; |
使用whsir1用户测试连接
使用whsir1用户,指定127.0.0.1连接MySQL
mysql -u whsir1 -p -h 127.0.0.1
|---|---------------------------------| | 1 | mysql -u whsir1 -p -h 127.0.0.1 |
由于whsir1被创建为localhost用户,而skip_name_resolve=ON,此连接将失败,因为MySQL将不会解析主机名localhost,错误信息可能类似于
ERROR 1045 (28000): Access denied for user 'whsir1'@'127.0.0.1' (using password: YES)
使用whsir1用户,指定localhost连接MySQL
mysql -u whsir1 -p -h localhost
|---|---------------------------------| | 1 | mysql -u whsir1 -p -h localhost |
可以发现,虽然skip_name_resolve配置为ON,但是这样是可以连接的,这是因为当你使用localhost连接MySQL时,MySQL客户端实际上会尝试通过Unix套接字文件(如/tmp/mysql.sock)进行连接,而不是通过TCP/IP。这种连接方式不涉及网络通信,因此不需要主机名解析,
使用whsir1用户,指定localhost连接MySQL,强制指定使用TCP/IP
mysql -u whsir1 -p -h localhost --protocol=TCP
|---|------------------------------------------------| | 1 | mysql -u whsir1 -p -h localhost --protocol=TCP |
可以发现,此时无法连接数据库,错误信息可能类似于
ERROR 1130 (HY000): Host '::1' is not allowed to connect to this MySQL server
如果此时调整skip_name_resolve = OFF,重启数据库,再次尝试
mysql -u whsir1 -p -h localhost --protocol=TCP
|---|------------------------------------------------| | 1 | mysql -u whsir1 -p -h localhost --protocol=TCP |
连接成功
如果需要在skip_name_resolve=ON的情况下使用主机名连接,确保所有用户的权限都是基于IP地址而不是主机名。例如,将whsir1的权限改为基于IP地址
mysql> DROP USER 'whsir1'@'localhost'; mysql> CREATE USER 'whsir1'@'127.0.0.1' IDENTIFIED BY 'password1'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'whsir1'@'127.0.0.1'; mysql> FLUSH PRIVILEGES;
|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 | mysql> DROP USER 'whsir1'@'localhost'; mysql> CREATE USER 'whsir1'@'127.0.0.1' IDENTIFIED BY 'password1'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'whsir1'@'127.0.0.1'; mysql> FLUSH PRIVILEGES; |
现在,whsir1可以通过127.0.0.1连接MySQL
mysql -u whsir1 -p -h 127.0.0.1
|---|---------------------------------| | 1 | mysql -u whsir1 -p -h 127.0.0.1 |
使用whsir2用户测试连接
使用whsir2连接MySQL
mysql -u whsir2 -p -h 127.0.0.1
|---|---------------------------------| | 1 | mysql -u whsir2 -p -h 127.0.0.1 |
这次直接连接成功,因为whsir2的权限是基于IP地址127.0.0.1。
通过以上演示过程,可以更好的让大家了解skip_name_resolve参数的效果。
注意事项 {#title-3}
1、性能影响:如果你的数据库服务器需要处理大量的连接请求,并且DNS解析速度较慢,建议将skip_name_resolve设置为ON以提高性能。
2、用户权限管理:如果使用skip_name_resolve=ON,确保在用户权限表中使用的是IP地址而不是主机名,否则会导致用户连接异常。
3、安全性考虑:在某些环境下,DNS解析可能会被利用进行攻击。设置skip_name_resolve=ON可以降低这种风险。
总结 {#title-4}
skip_name_resolve参数在MySQL中控制是否解析主机名。将其设置为ON可以提高连接速度,尤其在DNS解析速度较慢或不稳定的情况下。这样做不仅减少了DNS解析的开销,还降低了DNS污染攻击的风险。然而,用户权限在这种情况下必须基于IP地址而非主机名,否则会导致连接失败。通过上面的验证,我们可以看到,当skip_name_resolve为ON时,对使用了主机名的用户会连接失败,而使用IP地址的用户连接则正常。因此,应结合实际情况,合理配置skip_name_resolve参数。
附,MySQL my.cnf配置文件生成器:https://dbcnf.wlnmp.com/