刪除MySQL中的匿名用戶

今天使用MySQL的時候遇到一個問題,建了一個登錄地點任意的用戶卻無法在本地登錄。後來才發現是受系統初始化數據時生成的匿名用戶的影響。這個匿名用戶的存在不但有安全風險,還影響正常使用,建議儘快刪除。

問題出現的具體過程是這樣的:

創建一個新用戶,不限制登錄地點:

CREATE USER 'xindong' IDENTIFIED BY 'xindong';

向這個用戶授權,可以無限制使用數據庫:

GRANT ALL ON `nhcloud`.* TO 'xindong';

然後試圖用這個用戶登錄數據庫:

mysql -u xindong -p nhcloud

但總是返回錯誤:

Enter password: *******
ERROR 1045 (28000): Access denied for user 'xindong'@'localhost' (using password: YES)

以爲是密碼輸錯了。但輸了好幾次錯誤依舊。

查看mysql.user表,發現瞭如下用戶:

mysql> select host,user from mysql.user;
+-----------+---------+
| host      | user    |
+-----------+---------+
| %         | xindong |
| 127.0.0.1 | root    |
| ::1       | root    |
| localhost |         |
| localhost | root    |
+-----------+---------+
5 rows in set (0.00 sec)

除了root用戶和我剛建的用戶'xindong'@'%'外,還有個匿名用戶''@'localhost'。這個用戶的存在允許不提供用戶名就可以在本地登錄。

查閱mysql的文檔發現,就是這個用戶影響了'xingdong'@'%'在本地的登錄。當我使用xingdong在本地登錄時,會被認爲是這樣的一個用戶:
    host='localhost', user='xindong'
這樣一個用戶不但和mysql.user表中的我剛建的'xingdong'@'%'匹配,也和那個匿名用戶''@'localhost'匹配。不幸的是,mysql認爲那個匿名用戶和它更加匹配(因爲mysql在處理時認爲host比user更優先),所以認爲是''@'localhost'正在登錄,結果就是mysql會用''@'localhost'的信息來認證我輸入的密碼,就出現了前述錯誤。

MySQL的文檔裏對這種產品行爲有所描述(但它並沒有特別提醒用戶注意這種不尋常的情況):
http://dev.mysql.com/doc/refman/5.6/en/adding-users.html

從裏面可以看出,在確定待認證用戶的身份時,mysql會對匹配用戶登錄host和user的所有mysql.user表項進行排序。兩者都相同的排序最靠前,host相同但user不同卻匹配的排序其次,user相同但host不同卻匹配的排序再次,兩者都不同但都匹配的排序最後。

至於匿名用戶,是在數據庫初始化數據目錄的過程中創建的。本意是方便用戶快速使用,不創建特定名稱的用戶就可以訪問數據庫。但這個設計非常業餘,它的存在不但帶來了安全問題,還影響了其它用戶的正常訪問。我認爲這樣的功能不該放在產品發佈中。

這個問題的解決方法有二:

一是另外建一個用戶'xindong'@'localhost'。這樣使用xindong在本地登錄時,mysql會認爲是這個用戶在登錄,會使用正確的信息認證用戶。這個方法能解決問題我不喜歡,因爲是在爲一個畫蛇添足的功能再打一個多餘的補丁。

二是徹底刪除那個匿名用戶,一舉解決它帶來的安全問題和對正常使用的影響問題。使用如下SQL即可刪除匿名用戶:

DELETE FROM mysql.user WHERE User='';
FLUSH PRIVILEGES;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章