Oracle有关skip_name_resolve参数的总计

作为MySQL调优的一某个,很几人都推荐开启skip_name_resolve。这几个参数是禁止域名解析的(当然,也席卷主机名)。很多童鞋会好奇,那背后的原理是怎么着,什么动静下打开那一个参数比较适合。

 

基于以下原因,MySQL服务端会在内部存款和储蓄器中爱护着一份host消息,
包罗三有些:IP,主机名和错误音讯。首要用以非本地TCP连接。

  1. 透过在率先次建立连接时缓存IP和host
    name的照射关系,同一主机的继续连接将一贯查看host
    cache,而不用再行展开DNS解析。

  2. host
    cache中相同会蕴含IP登录战败的错误音信。可依照那几个信息,对那一个IP举办相应的限定。前边将会实际涉及。

host cache的消息可通过performance_schema中host_cache表查看。

 

那么,IP和host name的映照关系是怎么样树立的啊?

  1. 当有一个新的客户端连接进来时,MySQL Server会为那些IP在host
    cache中创造1个新的笔录,包含IP,主机名和client lookup validation
    flag,分别对应host_cache表中的IP,HOST和HOST_VALIDATED那三列。第三遍建立连接因为唯有IP,没有主机名,所以HOST将安装为NULL,HOST_VALIDATED将设置为FALSE。

  2. MySQL
    Server检测HOST_VALIDATED的值,假诺为FALSE,它会试图拓展DNS解析,假若条分缕析成功,它将更新HOST的值为主机名,并将HOST_VALIDATED值设为TRUE。固然没有解析成功,判断战败的案由是永恒的依旧权且的,倘使是永久的,则HOST的值仍然为NULL,且将HOST_VALIDATED的值设置为TRUE,后续连接不再进行辨析,要是该原因是方今的,则HOST_VALIDATED还是为FALSE,后续连接会再一次展开DNS解析。

 

另,解析成功的标志并不只是透过IP,获取到主机名即可,那只是内部一步,还有一步是通过分析后的主机名来反向解析为IP,判断该IP是还是不是与原IP相同,借使一致,才看清为分析成功,才能创新host
cache中的音讯。

 

传说下面的下结论,上边谈谈 host cache的利弊:

症结:当有二个新的客户端连接进来时,MySQL
Server都要树立三个新的记录,假如DNS解析不快,无疑会潜移默化属性。借使被允许访问的主机很多,也会潜移默化属性,那些与host_cache_size有关,那些参数是5.6.5引入的。5.6.8以前暗中认可是128,5.6.8过后私下认可是-1,基于max_connections的值动态调整。所以假设被允许访问的主机很多,基于LRU算法,先前创立的总是可能会被挤掉,这几个主机重新进入时,会再度开始展览DNS查询。

可取:经常状态下,主机名是不变的,而IP是形成的。即使三个客户端的IP平时转移,那基于IP的授权将是叁个累赘的长河。因为你很难分明IP哪天变化。而依照主机名,只需三回授权。而且,基于host
cache中的战败新闻,可在自然水准上拦截外界的暴力破解攻击。

 

至于阻止外界的暴力破解攻击,涉及到max_connect_errors参数,暗中同意为100,官方的解释如下:

If more than this many successive connection requests from a host are interrupted without a successful connection, the server blocks that host from further connections.

假诺有些客户端的连日达到了max_connect_errors的限量,将被取缔访问,并提示以下错误:

Host 'host_name' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'

 

下边来效仿一下

首先,设置max_connect_errors的值

mysql> show variables like 'max_connect_errors';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| max_connect_errors | 100   |
+--------------------+-------+
1 row in set (0.00 sec)

mysql> set global max_connect_errors=2;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'max_connect_errors';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| max_connect_errors | 2     |
+--------------------+-------+
1 row in set (0.00 sec)

通过telnet模拟interrupted without a successful connection。

[root@mysql-slave1 ~]# telnet 192.168.244.145 3306
Trying 192.168.244.145...
Connected to 192.168.244.145.
Escape character is '^]'.
N
5.6.26-log
          K]qA1nYT!w|+ZhxF1c#|kmysql_native_password
^]
!#08S01Got packets out of orderConnection closed by foreign host.
[root@mysql-slave1 ~]# telnet 192.168.244.145 3306
Trying 192.168.244.145...
Connected to 192.168.244.145.
Escape character is '^]'.
N
Y#>PVB(>!Bl}NKnjIj]sMmysql_native_password
^]
!#08S01Got packets out of orderConnection closed by foreign host.
[root@mysql-slave1 ~]# mysql -h192.168.244.145 -uroot -p123456
Warning: Using a password on the command line interface can be insecure.
ERROR 1129 (HY000): Host '192.168.244.144' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'

不怕后来利用了未可厚非的账号和密码登录,还是会被拦住。

再来看看host_cache表中的音讯,sum_connect_errors为2了。

mysql> select ip,host,host_validated,sum_connect_errors,count_authentication_errors from performance_schema.host_cache;
+-----------------+------+----------------+--------------------+-----------------------------+
| ip              | host | host_validated | sum_connect_errors | count_authentication_errors |
+-----------------+------+----------------+--------------------+-----------------------------+
| 192.168.244.144 | NULL | YES            |                  2 |                           0 |
+-----------------+------+----------------+--------------------+-----------------------------+
1 row in set (0.00 sec)

 

该拦截会直接生效,直到采用以下操作:

1. mysql> flush hosts;

2. # mysqladmin flush-hosts

3. truncate table performance_schema.host_cache;

  1. 抑或等待该记录从host cache中被挤掉。

 

只要要禁止DNS解析,可安装skip_name_resolve参数,那样,mysql.user表中基于主机名的授权将不大概运用,且错误日志中会提醒:

[Warning] 'user' entry 'root@mysql-slave1' ignored in --skip-name-resolve mode.

此处,通过mysql-slave1访问,将会拒绝访问

[root@mysql-slave1 ~]# mysql -h192.168.244.145 -uroot -p123
Warning: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'192.168.244.144' (using password: YES)

 

host
cache是暗中同意开启的,借使要禁掉,可将host_cache_size设置为0,该参数是个动态参数,可在线修改。

 

即使要统统禁掉TCP/IP连接,可在MySQL运转时,设置skip-networking参数。

 

总结:

1.
从规律上看,DNS解析一般只针对客户端的率先次一连,客户端数据量比较小的事态下,成本其实相当小,完全不用禁掉skip_name_resolve参数,带来的裨益就是,为客户端和形成的IP直接解耦,只需对主机名进行3次授权。

可通过\s查看当前一连使用的是socket如故TCP。

  1. 奇怪的是,对于skip_name_resolve参数,即便合法文书档案说的是布尔值,

但就算在配置文件中钦定了,无论是skip_name_resolve=off或者skip_name_resolve=0。

最后,通过show variables like
‘%skip_name_resolve%’查看均展现ON。将该参数设置为OFF的唯一格局是不写该参数(因为它暗中认可值即为OFF)。

  1. 在skip_name_resolve=ON的景观下,在地面通过-h127.0.0.1从未难点。

    [root@localhost ~]# mysql -uroot -h127.0.0.1 -p123456
    Warning: Using a password on the command line interface can be insecure.
    Welcome to the MySQL monitor. Commands end with ; or \g.
    Your MySQL connection id is 4
    Server version: 5.6.31-log MySQL Community Server (GPL)

    Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.

    Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

    root@(none) 09:02:15> \s

    mysql Ver 14.14 Distrib 5.6.31, for Linux (x86_64) using EditLine wrapper

    Oracle, Connection id: 4
    Current database:
    Current user: root@127.0.0.1
    SSL: Not in use
    Current pager: stdout
    Using outfile: ”
    Using delimiter: ;
    Server version: 5.6.31-log MySQL Community Server (GPL)
    Protocol version: 10
    Connection: 127.0.0.1 via TCP/IP
    Server characterset: utf8
    Db characterset: utf8
    Client characterset: utf8
    Conn. characterset: utf8
    TCP port: 3306
    Uptime: 11 min 10 sec

    Threads: 1 Questions: 20 Slow queries: 0 Opens: 70 Flush tables: 1 Open tables: 63 Queries per second avg: 0.029

    root@(none) 09:02:18> show variables like ‘%skip_name_resolve%’;
    +——————-+——-+
    | Variable_name | Value |
    +——————-+——-+
    | skip_name_resolve | ON |
    +——————-+——-+
    1 row in set (0.06 sec)

 

固然该参数设置为OFF,则上述格局就会报错,通过报错音讯方可观察,它一向将127.0.0.1转载为localhost了。

[root@localhost ~]# mysql -uroot -h127.0.0.1 -p123456 -P3306
Warning: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

只顾:
‘t1’@’%’中包蕴’t1’@’127.0.0.1’,固然开启skip_name_resolve参数,则’t1’@’%’中定义的密码可用于’t1’@’127.0.0.1’的记名,尽管没有开启该参数,则’t1’@’127.0.0.1’会转化为’t1’@’localhost’登录,此时’t1’@’%’定义的密码并不适用。

 

参考:

  1. http://www.tuicool.com/articles/7R7BRb

2. http://dev.mysql.com/doc/refman/5.7/en/host-cache.html

3. http://dev.mysql.com/doc/refman/5.7/en/blocked-host.html

 

相关文章