天天看點

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

作者:手辨

實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

第一節 什麼是 max_connect_errors

一開始接觸這個參數的時候,感覺他和max_connections的含義差不多,字面意思簡單明了,這個參數的含義是最大連接配接錯誤數,翻翻mysql的文檔中的解釋是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,大意是:如果mysql伺服器連續接收到了來自于同一個主機的請求,且這些連續的請求全部都沒有成功的建立連接配接就被斷開了,當這些連續的請求的累計值大于 max_connect_errors的設定值時,mysql伺服器就會阻止這台主機後續的所有請求。”without a successful connection”那太好辦了,故意輸錯密碼不就行了,并且網上搜尋了下該參數的說明,大量的文章充斥着” 防止暴力破解密碼”的内容,于是興高采烈的去做了測試。以下測試基于自建的mysql(非rds for mysql),由于rds for mysql無法直接設定set global,設定時需要在"rds控制台-參數這裡"裡進行設定:

https://help.aliyun.com/document_detail/26179.html?spm=5176.11065259.1996646101.searchclickresult.44156de7pLffcV

第二節 測試

1,建立賬号:

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

2,設定max_connect_errors為3:

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

3,故意輸錯密碼3次,第四次使用正确密碼登入進行驗證:

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

4,結論是第四次依然可以登入,即密碼不對(認證失敗)不屬于” ”without a successful connection””的範疇,網上的” 防止暴力破解密碼”也不成立了。

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

第三節 繼續分析

再繼續看文檔,發現還有以下說明:

You can unblock blocked hosts by flushing the host cache. To do so, issue a

FLUSH HOSTS

statement or execute a

mysqladmin flush-hosts

command.

大意是:

當你遇到主機被阻止的時候,你可以清空host cache來解決,具體的清空方法是執行flush hosts或者在mysql伺服器的shell裡執行

操作

既然清空host cache可以解決主機被阻止通路的問題,那應該與host cache有些關系,看看host cache的介紹可能會有些眉目,關于host cache,文檔解釋如下:

The MySQL server maintains a host cache in memory that contains information about clients: IP address, host name, and error information. The server uses this cache for nonlocal TCP connections. It does not use the cache for TCP connections established using a loopback interface address (127.0.0.1 or ::1), or for connections established using a Unix socket file, named pipe, or shared memory.

Mysql伺服器會在記憶體裡管理一個host cache,host cache裡儲存了一些用戶端的ip位址,主機名,以及這個用戶端在與server建立連接配接時遇到的一些錯誤資訊,host cache對不是本地的TCP連接配接才有效,是以host cache對127.0.0.1 或者::1是無效的,并且對于Unix socket file、named pipe以及 shared memory方式建立的連接配接也是無效的。并且通過了解,host cache的内容可以通過performance_schema.host_cache來檢視,通過performance_schema.host_cache表裡的幾個列的描述資訊,對之前的測試不成立的原因有些了解了,部分相關列如下:

  • IP

    The IP address of the client that connected to the server, expressed as a string.

連接配接到mysql server的主機的連接配接位址

  • HOST

    The resolved DNS host name for that client IP, or NULL if the name is unknown.

通過dns解析IP位址擷取到的該IP位址對應的mysql client的主機名

  • SUM_CONNECT_ERRORS

    The number of connection errors that are deemed “blocking” (assessed against the max_connect_errors system variable). Only protocol handshake errors are counted, and only for hosts that passed validation (HOST_VALIDATED = YES).

  • COUNT_HANDSHAKE_ERRORS

    The number of errors detected at the wire protocol level.

通過SUM_CONNECT_ERRORS(連接配接錯誤計數)描述,重點是紅色部分:隻計算協定握手過程的錯誤(Only protocol handshake errors are counted),也就是說max_connect_errors 可能記錄的是協定(不确定是tcp協定還是應用協定,通過抓包以及COUNT_HANDSHAKE_ERRORS的” the wire protocol level”說明可能是指應用協定)的握手過程中出現的錯誤 ,也就是可以說網絡不好(無法順利握手)會導緻該問題。

第四節 繼續測試

通過之前的說明,需要模拟應用協定握手失敗的情況,最後考慮使用telnet一些來做測試

1,建立賬号

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉
被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

3,先使用telnet 10.26.254.217 3306連接配接3次,第四次使用正确的賬号密碼嘗試登陸:

telnet前檢視performance_schema.host_cache的記錄為空

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

第一次telnet 10.26.254.217 3306

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉
被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

第二次 telnet 10.26.254.217 3306

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉
被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

第三次telnet 10.26.254.217 3306

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉
被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

第四次執行mysql -h10.26.254.217 -utestcon -p123 -P3306

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉
被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

問題複現了,出現了錯誤提示ERROR 1129 (HY000): Host '10.24.236.231' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'

第五節 ERROR 1129 (HY000)問題延伸

解決ERROR 1129 (HY000)的方法是執行flush host或者

,其目的是為了清空host cache裡的資訊,那是不是說不使用host cache就可以了?使host cache不生效的方式有如下兩種:

1,設定

host_cache_size

為0/ 打開

skip-host-cache

2,打開

skip-name-resolve

需要通過測試看下推測是否生效

5.1 設定

host_cache_size 為0

/ 打開

為0

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

2,再次查詢performance_schema.host_cache

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

3,繼續之前的測試:先使用telnet 10.26.254.217 3306連接配接3次,第四次使用正确的賬号密碼嘗試登陸

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

更改已經生效,

的作用無效了

5.2 打開

1,在cnf配置檔案裡設定

以此打開

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

2,繼續之前的測試:先使用telnet 10.26.254.217 3306連接配接3次,第四次使用正确的賬号密碼嘗試登陸

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

3,查詢performance_schema.host_cache

被我誤解的max_connect_errors實為吾之愚見,望諸君酌之!聞過則喜,與君共勉

的作用無效了,RDS for mysql 的skip_name_resolve是on的狀态,

是以很少會出現ERROR 1129 (HY000)的錯誤