塗抹MySQL--第5章 MySQL資料庫中的許可權體系 - 5.4帳戶安全管理

dawn009發表於2015-06-26

5.4 帳戶安全管理

提到帳戶安全,我想即使是從沒有接觸過MySQL庫軟體的朋友,只要使用過計算機,暢遊過網際網路就都會有自己的理解,甚至對於那些從沒接觸過計算機的人也有自己的心得,畢竟當下就是資訊時代,不管是做為普通人到銀行辦理業務,或者極客在網上購物消費,都少不得要管理一系列的帳戶和口令,因此可以說人人都對此早有接觸,並且積累下深厚的帳戶管理經驗。

因為關於帳戶安全的一般性原則是通用的,因此這裡三思並不想再去強調什麼密碼設定原則、口令保護指南等等陳詞濫調,本章著重談到的幾方面內容更多可以視為一些小技巧,希望能夠真正幫助大家在運維MySQL資料庫的過程中,提供一些參考,減少一些隱患。

5.4.1 使用者與許可權設定原則

看完前面的內容,我想大家已經對如何建立使用者,如何管理使用者的許可權有了認識。不過,要知道想炒出一盤可口的佳餚,只有原料可還不行,廚藝的高低更加重要。

建立出一個資料庫帳戶,許可權是給大還是給小;前端的應用服務很多,是共用同一個帳戶,還是分開獨立操作;每一種選擇都有它的優點,相應也會有它的弊端,究竟怎麼設定才對,有時候我覺著這就像問大廚師炒菜時放多少鹽合適,它的回答可能是:適量就好。這個答案聽起來很虛,但實際上有時候就是這麼微妙,它確實不是一個定量,需要大家根據實際情況調整。

本節的內容並不一定都對,更多是三思個人的理解,不過,我可以負責任的告訴大家,我所管理的資料庫的帳戶,也正是按照這些原則在維護。

總體規劃目標:

l 考慮實際情況及使用習慣,許可權的設定應該是儘可能不增加應用端開發工作量的前提下,儘可能縮小許可權分配的粒度;

l 做到業務級的帳戶分享,不同應用(專案)分別使用不同的帳戶執行操作;

l 使操作者執行SQL時所使用的帳戶,與其能夠執行的操作相對應;

l 降低誤操作的機率,保障資料庫系統安全。

許可權按照可控程度分級設定。如何定義級別就請根據實際業務規模,我們目前的環境綜合考慮了團隊規模和業務資料規模,最終確定以庫為單位建立帳戶,在達到安全設定目標的前提下,儘可能簡化流程,將許可權級別設為三級:

l {user}_oper:定義為操作使用者,擁有指定庫下所有物件的操作許可權,授予增加(insert)、刪除(delete)、修改(update)、查詢(select)記錄的許可權,主要用於前端應用程式,連線資料庫讀寫資料;

l {user}_read:定義為只讀使用者,擁有指定庫下物件的讀取許可權,授予查詢(SELECT)記錄的許可權,可用於資料查詢、SQL除錯,資料驗證,資料匯出等操作,對於做了讀寫分離的應用,只讀訪問也使用本帳戶;

l {user}_mgr:定義為管理帳戶,擁有多個庫下物件操作許可權,用於各專案負責人實時操作物件資料;

上述的三類使用者主要用於應用端的業務,對於DB層維護的帳戶,首先按功能區分,其次在授予許可權時也是按照最小粒度許可權的原則授予,除此之外,所有系統維護的帳戶還會遵循下列兩個原則:

l MySQL資料庫的管理員帳戶改名,不允許出現"root"名稱的使用者;

l 使用者訪問域設定為伺服器所在IP段;

5.4.2 小心歷史檔案洩密

對特性掌握的越全面,對系統瞭解的越深入,在執行具體的運維工作就越能夠得心應手,做到有備無患。但是要達到這項要求難度極高極大,因為向上提升永無極限,我們總能夠做的更好。這就要求我們態度上謙虛審慎,同時還要時刻抓緊學習,不忘補充新的知識點。

就以MySQL資料庫來說,即使當前的密碼設定的極為規範,口令保護措施也很到位,但是,如果對mysql的某些特性不瞭解,就還是有可能存在巨大的系統漏洞。

你們信不信,我反正是信了,執行下列命令看一看吧:

$ tail -20 ~/.mysql_history 

...............

...............

grant select (phoneno) on jssdb.users to jss_col;

select * from mysql.columns_priv;

select * from mysql.tables_priv where user='jss_cols';

...............

驚訝了吧,前面所做的操作居然都儲存在這裡,如果一頁頁去翻開這個檔案的內容,你會發現我們執行過的所有操作,包括最初重新命名root使用者和修改system系統帳戶的口令均在其中,黑黑,小夥伴兒們當場就震驚了吧

在Linux/Unix系統下,使用mysql命令列工具執行的所有操作,都會被記錄到一個名為".mysql_history"的檔案中,該檔案預設儲存在當前使用者的根目錄下(也可以透過MYSQL_HISTFILE環境變數修改儲存路徑)

這個設定本意是為了提升mysql命令列工具操作體驗的,有了它,我們在mysql命令列介面,就能夠方便的使用方向鍵,上下翻看執行過的命令,但是,又因為它記錄了所有所執行過的操作,某些情況下又會成為巨大的安全隱患。

基於安全性方面的考慮,服務端的.mysql_history檔案有必要進行保護,以避免操作被外洩,特別是對於像建立使用者/修改密碼[這類管理操作,如果沒有防護,那資料庫對某些有心人士來說就是不設防的狀態。

如何消除這種隱患呢(也相當於禁用),兩種方案:

l 一種方式是徹底清除,修改作業系統層的MYSQL_HISTFILE環境變數,將其值改為/dev/null,這樣所有操作都會被輸出到空,操作的歷史自然不會被保留;

l 另一個是仍然保留.mysql_history檔案,但是該檔案實際上為/dev/null的軟連結,這樣所有操作也是會被輸出到空,操作的歷史不會被保留;

兩種方式功能基本相同,原理也一樣,只不過一種是在MySQLDB層操作,另外一種則是在OS層實施,究竟選擇哪種方式,完全可以由DBA自行決定。

這裡以第二種方式為例,操作最為簡單,在作業系統的命令列介面執行下列命令:

$ ln -f -s /dev/null ~/.mysql_history

之後再透過mysql命令列登入到資料庫時,方向鍵上下翻則僅針對當前會話有效,不過退出會話後再次登入,就看不到上次執行過的操作了。

 

5.4.3 管理員口令丟失怎麼辦

使用者的口令很重要,大家對其重視程度都不低,讀過前面小節中的內容後,想必在設定密碼時也會花些心思,設定一個不那麼有規律的口令。這種設定有時候真是挺矛盾,設定的太簡單吧不安全,設定的太複雜又真不容易記,更何況忘記口令這種事兒並不稀奇,看看各大網站的使用者登入頁面吧,顯著位置都留有"找回密碼"的連結,就知道這類需求實在太過稀鬆平常了,這位仁兄,今天,你密碼忘了沒?

對於資料庫軟體來說,要是普通使用者的口令忘記了倒還好處理,拿系統帳戶登入進去後簡單的一條命令就改了,但是如果系統管理員帳戶的口令也忘了(這事兒也不稀奇),別擔心,照樣有方法處理,儘管方法用的非常規,但是:正能量,無所畏。

在操作前必須要首先強調,非常規方式重置系統管理員帳戶的密碼,對MySQL服務的正常執行是有影響的,因為操作過程中必須多次重啟MySQL服務。

MySQL官方給出的非常規方式重置系統管理員帳戶有兩種方法:

l 啟動MySQL服務時附加引數(--init-file),使其執行含有密碼重置的指令碼,達到修改帳戶密碼的目地;

l 啟動MySQL服務時透過附加特殊的引數,使其跳過許可權驗證,而後登入資料庫中重置密碼後,再按照正常的方式重啟MySQL服務;

前一種方式安全性更強,操作的步驟稍多一些,而且不同平臺執行的命令也稍有差異,後一種方法通用性強,適用範圍廣(Windows/Linux/Unix平臺均適用),因此這裡我們重點介紹第二種方式,具體步驟如下。

首先,停止當前的MySQL服務,因為沒有管理帳戶密碼,常規關停方法無法使用,只好直接殺程式了,對於Windows平臺可以在"服務"中停止MySQL服務,Linux/Unix平臺則查詢到mysqld主程式後殺掉該程式:

[mysql@mysqldb01 ~]$ kill `cat /data/mysqldata/3306/mysql.pid` 

接下來又重新啟動mysqld服務,啟動時在啟動命令後附加--skip-grant-tables選項。該選項的功能,正是當有使用者連線時,跳過檢查授權表,直接授予所有登入使用者最大許可權(相當於所有登入的使用者都是系統管理員),執行mysqld_safe命令啟動資料庫,操作如下(Windows平臺沒有mysqld_safe指令碼,直接執行mysqld命令即可)

$ mysqld_safe --defaults-file=/data/mysqldata/3306/my.cnf --skip-grant-tables --skip-networking&

大家注意到三思這裡還另外指定了--skip-networking選項,這主要是考慮到附加--skip-grant-tables選項啟動後,連線資料庫時不再有許可權驗證,在此期間如果有其它使用者建立連線的話可能存在安全隱患,那麼我們可以在啟動伺服器同時附加--skip-networking選項,這樣該MySQL服務不會監聽來自TCP/IP的連線,相當於禁用了網路上其它主機發出的登入請求,只允許MySQL服務本地建立連線,安全性方面更加可靠。

而後就可以無須使用者驗證,即可直接登入到MySQL資料庫服務裡:

[mysql@mysqldb01 ~]$ mysql

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 1

........

........

(root@localhost) [(none)]>  

所有連線進來的使用者現在都是系統使用者,預設就是root想做啥都可以,對於我們來說,接下來就執行update語句,修改系統管理員帳戶的密碼:

(root@localhost) [(none)]> update mysql.user set password=password('5ienet.com') where user='system';

Query OK, 0 rows affected (0.00 sec)

Rows matched: 1  Changed: 0  Warnings: 0

關閉MySQL服務,這次不用殺程式了,就用常規的mysqladmin命令關閉吧:

[mysql@mysqldb01 ~]$ mysqladmin shutdown

然後按照正常的方式重新啟動MySQL服務:

$ mysqld_safe --defaults-file=/data/mysqldata/3306/my.cnf &

系統管理員帳戶的密碼重置完畢,接下來就可以用剛剛設定的新密碼來管理你的MySQL資料庫了。

 

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29119536/viewspace-1712835/,如需轉載,請註明出處,否則將追究法律責任。

相關文章