對mysql來講,其訪問受權相關模塊主要是由兩部分組成。html
(1)一個是基本的用戶管理模塊;另外一個是訪問受權控制模塊。 (2)用戶管理模塊相對簡單,主要是負責用戶登錄鏈接相關的基本權限控制,但其在安全控制方面的做用沒必要任何環節小。 (3)他就像mysql的一個「大門門衛」同樣,經過校驗每一位敲門者所給的進門「暗號」(登入口令),決定是非給敲門者開門。 (4)而訪問控制模塊則是隨時隨地檢查已經進門的訪問者,校驗他們是否有訪問所發出請求須要訪問的數據的權限。 (5)經過校驗者能夠順利拿到數據,而未經過校驗的訪問者,只能收到「訪問越權」的相關反饋。
SQL語句相關安全因素:mysql
(1)「SQL注入攻擊」指的就是攻擊者根據數據庫的SQL語句解析器的原理,利用程序中對客戶端所提交數據的校驗漏洞,從而經過程序動態提交數據接口提交非法數據,達到攻擊者的入侵目的。 (2)「SQL注入攻擊「的破壞性很是大,輕者形成數據被竊取,重者數據遭到破壞,甚至可能丟失所有的數據。
程序代碼相關安全因素:sql
(1)程序代碼若是權限校驗不夠仔細而存在安全漏洞,則一樣可能會被入侵者利用,達到竊取數據等目的。 (2)好比一個存在安全漏洞的信息管理系統,很容易就可能竊取到其餘一些系統的登入口令。以後,就能冠冕堂皇的輕鬆登錄到其餘相關係統達到竊取相關數據的目的。 (3)甚至還可能經過應用系統中保存不善的數據庫系統鏈接登錄口令,從而帶來更大的損失。
Global Level:數據庫
(1)Global Level的權限控制也叫全局權限控制,全部權限信息都保存在mysql.user表中。 (2)Global Level的全部權限都是針對整個mysqld的,對全部的數據庫下的全部表及全部字段都有效。 (3)若是一個權限是以Global Level來授予的,則會覆蓋其餘全部級別的相同權限設置。 (4)好比咱們首先給abc用戶受權能夠update指定數據庫如test的t表,而後又在全局級別REVOKE掉了abc用戶對全部數據庫的全部表的UPDATE權限,那麼這時候的abc用戶將再也不擁有對test.t表的更新權限。 (5)要授予Global Level的權限,則只須要在執行GRANT命令的時候,用「*.*」來指定適用範圍是Global的便可,當有多個權限須要授予的時候,也並不須要屢次重複執行GRANT命令,只須要一次將全部須要的權限名稱經過逗號(「,」)隔開便可,如:GRANT SELECT,UPDATE,DELETE,INSERT ON *.* TO 'def'@'localhost';
Database Level:安全
(1)Database Level是在Global Level之下,其餘三個Level之上的權限級別,其做用域即爲所指定整個數據庫中的全部對象。 (2)與Global Level相比,Database Level主要少了如下幾個權限:CREATE USER、FILE、PROCESS、RELOAD、REPLICATION CLIENT、REPLICATION SLAVE、SHOW DATABASES、SHUTDOWN、SUPER和USAGE這幾個權限,沒有增長任何權限。 (3)以前咱們說Global Level的權限會覆蓋底下其餘四層的相同權限,Database Level也同樣,雖然他可能被Global Level的權限所覆蓋,但同時他也能覆蓋比他更下層的Table、Column和Routine這三層的權限。 (4)若是要授予Database Level的權限,則能夠有兩種實現方式: 【1】在執行GRANT命令的時候,經過「database.*」來限定權限做用域爲database整個數據庫:GRANT ALTER ON test.* TO 'def'@'localhost'; 【2】先經過USE命令選定須要受權的數據庫,而後經過「*」來限定做用域,這樣受權的做用域實際上就是當前選定的數據庫 (5)在授予權限的時候,若是有相同的權限須要授予多個用戶,咱們也能夠在受權語句中一次寫上多個用戶信息,用逗號分隔開就能夠了,如:grant create on perf.* to 'abc'@'localhost','def'@'localhost';
Table Level:網絡
(1)Database Level之下就是Table Level的權限了,Table Level的權限能夠被Global Level 和Database Level的權限所覆蓋,同時也能覆蓋Column Level 和Routine Level 的權限。 (2)Table Level 的權限做用範圍是受權語句中所指定數據庫的指定表。如能夠經過以下語句給test數據庫的t1表受權:GRANT INDEX ON test.t1 TO 'abc'@'%.jianzhaoyang.com'; (3)Table Level的權限因爲其做用域僅限於某個特定的表,因此權限種類也比較少,僅有ALTER、CREATE、DELETE、DROP、INDEX、INSERT、SELECT、UPDATE這八種權限。
Column Level:函數
(1)Column Level的權限做用範圍就更小了,僅僅是某個表的指定的某個列。 (2)因爲權限覆蓋的原則,Column Level的權限一樣能夠被Global、Database、Table這三個級別的權限中的相同級別所覆蓋,並且因爲Column Level所針對的權限和Routine Level的權限做用域沒有重合部分,因此不會有覆蓋與被覆蓋的關係。 (3)Column Level的權限只有INSERT、SELECT和UPDATE這三種。 (4)Column Level的權限受權語句語法基本和Table Level差很少,只是須要在權限名稱後面將須要受權的列名列表經過括號括起來:GRANT SELECT(id,value) ON test.t2 TO 'abc'@'%.jianzhaoyang.com'; (5)當某個用戶在向某個表插入數據的時候,若是該用戶在該表中某列上面沒有INSERT權限,則該列的數據將以默認值填充。這一點和不少其餘的數據庫有一些區別,是mysql本身在SQL上面的擴展。
Routine Level:工具
(1)Routine Level的權限主要只有EXECUTE和ALTER ROUTINE兩種,主要的針對的對象是procedure 和function這兩種對象。 (2)在授予Routine Level權限的時候,須要指定數據庫和相關對象,如:GRANT EXECUTE ON test.p1 to 'abc'@'localhost';
GRANT權限:性能
(1)除了上述幾類權限外,還有一個很是特殊的權限GRANT,擁有GRANT權限的用戶能夠將自身所擁有的任何權限所有授予其餘任何用戶,因此GRANT權限是一個很是特殊也很是重要的權限。 (2)GRANT權限的授予方式也和其餘任何權限都不太同樣。 (3)一般是經過在執行GRANT受權語句的時候在最後添加WITH GRANT OPTION子句達到授予GRANT權限的目的。 (4)另外,咱們還能夠經過GRANT ALL語句授予某個Level的全部可用權限給某個用戶,如: grant all on test.t5 to 'abc';
用戶管理:加密
(1)在mysql中,用戶訪問控制部分的實現比較簡單,全部受權用戶都存放在一個系統表中:mysql.user,固然這個表不只存放了受權用戶的基本信息,還存放有部分細化的權限信息。 (2)用戶管理模塊須要使用的信息不多,主要就是Host、User、Password這三項,都在mysql.user表中 (3)一個用戶想要訪問mysql,至少須要提供上面列出的三項數據,mysql才能判斷是否該讓它進門。 (4)這三項實際是由兩部分組成:來訪者來源的主機名(或主機IP地址信息)和訪問者的來訪「暗號」(登錄用戶名和登錄密碼),這兩部分中的任何一個沒有可以匹配上都沒法讓看守大門的用戶管理模塊乖乖開門。 (5)其中Host信息存放的是mysql容許所對應的User的信任主機,能夠是某個具體的主機名或域名,也能夠是用「%」來充當通配符的某個域名集合,也能夠是一個具體的IP地址,一樣也能夠是存在通配符的域名集合,還能夠用「%」來表明任何主機,就是不對訪問者的主機作任何限制。
訪問控制:
(1)當客戶端鏈接經過用戶管理模塊的驗證,可鏈接上mysql server以後,就會發送各類Query和Command給mysql server,以實現客戶端應用的各類功能。 (2)當mysql接收到客戶端的請求以後,訪問控制模塊是須要校驗該用戶是否知足提交的請求所須要的權限。 (3)權限校驗過程是從最大範圍往最小範圍的權限開始依次校驗所涉及到的每一個對象的每一個權限。 (4)在驗證所需權限的時候,mysql首先會查找存儲在內存結構中的權限數據,首先查找Global Level權限,若是所需權限在Global Level都有定義(GRANT或REVOKE),則完成權限校驗(經過或者拒絕); (5)若是沒有找到全部權限的定義,則會繼續查找Database Level的權限,進行Global Level未定義的所需權限的校驗,若是仍然沒有找到全部所需權限的定義,則會繼續往更小範圍的權限定義域查找,也就是Table Level、Column Level或者Routine Level。 (6)在前面咱們瞭解到mysql的grant tables有mysql.user、mysql.db、mysql.host、mysql.table_priv和mysql.column_priv這五個。 (7)我想除了mysql.host以外的四個都很是容易理解,每個表都針對mysql的一種邏輯對象,存放某一特定Leve的權限,惟獨mysql.host稍有區別。 (8)咱們來看看mysql.host權限表在mysql訪問控制中充當了什麼樣的角色? 【1】mysql.host在mysql訪問控制模塊中所實現的功能比較特殊,和其餘幾個grant tables不太同樣。 【2】首先mysql.host中的權限數據不是經過GRANT或REVOKE來授予或者去除,而是必須手工經過INSESRT、UPDATE和DELETE命令來修改其中的數據。 【3】其次是其中的權限數據沒法單獨生效,必須經過和mysql.db權限表的數據一塊兒才能生效。 【4】並且僅當mysql.db總存在不完整的時候,纔會促使訪問控制模塊再結合mysql.host中查找是否有相應的補充權限數據實現以達到權限校驗的目的。 【5】在mysql.db中沒法找到知足權限校驗的全部條件的數據,則說明在mysql.db中沒法完成權限校驗,因此也不會直接校驗db.select_priv的值是不是Y。 (9)mysql的權限授予至少須要用戶名和主機名兩者才能肯定一個訪問者的權限。 (10)mysql如何肯定權限信息?實際上,mysql永遠優先考慮更精確範圍的權限。 (11)在mysql內部會按照username和hostname作一個排序,對於相同username的權限,其host信息越接近訪問者的來源host,則排序位置越靠前,則越早被校驗使用到。 (12)並且mysql在權限校驗過程當中,只要找到匹配的權限以後,就不會再繼續日後查找是否還有匹配的權限信息,而直接完成校驗過程。
首先須要瞭解來訪主機:
(1)因爲mysql數據庫登錄驗證用戶的時候是除了用戶名和密碼以外,還要驗證來源主機,因此咱們還須要瞭解每一個用戶可能從哪些主機發起鏈接。 (2)固然,咱們也能夠經過受權的時候直接經過「%」通配符來給全部主機授予都有訪問的權限,可是這樣就違背了咱們安全策略的原則,帶來了潛在風險,因此並不可取。 (3)尤爲是在沒有局域網防火牆保護的狀況下,更是不能輕易容許能夠從任何主機登錄的用戶存在。 (4)能經過具體主機名和IP地址指定的儘可能經過使用具體的主機名和IP地址來限定來訪主機,不能用具體的主機名和IP地址限定的也須要用盡量小的通配範圍來限定。
其次,瞭解用戶需求:
(1)既然要作到僅授予必要的權限,那麼咱們必須瞭解每一個用戶所擔當的角色,也就是說,咱們充分了解每一個用戶須要鏈接到數據庫上完成什麼工做。 (2)瞭解用戶是一個只讀應用的用戶,仍是一個讀寫都有的用戶,是一個備份做業的用戶仍是一個平常管理的用戶,是隻須要訪問特定的數據庫,仍是須要訪問全部的數據庫。 (3)只有瞭解了須要作什麼,才能準確的瞭解須要授予什麼樣的權限。 (4)由於若是權限太低,會形成工做沒法正常完成,而權限太高,則存在潛在的安全風險。
再次,要爲工做分類:
(1)爲了作到各司其職,咱們須要將須要作的工做分門別類,不一樣類別的工做使用不一樣的用戶,作好用戶分離。 (2)雖然這樣可能會帶來管理成本方面的部分工做量增長,可是基於安全方面的考慮,這部分管理工做量的增長是很是值得的。 (3)並且咱們所要作的分離也只是適度的分離。好比將執行備份工做、複製工做、常規應用訪問、只讀應用訪問和平常管理工做分別分理出單獨的特定帳戶來授予各自所需權限。 (4)這樣,既可讓安全風險儘可能下降,也可讓同類同級別的類似權限合併在一塊兒,不互相交織在一塊兒。 (5)對於PROCESS、FILE和SUPER這樣的特殊權限,僅僅只有管理類帳號才須要,不該該授予其餘非管理帳號。
最後,確保只有絕對必要者擁有GRANT OPTION權限:
(1)以前在權限系統介紹的時候咱們已經瞭解到GRANT OPTION權限的特殊性,和擁有該權限以後的潛在風險,因此在這裏就不贅述了。 (2)總之,爲了安全考慮,擁有GRANT OTPION權限的用戶越少越好,儘量只讓擁有超級權限的用戶才擁有GRANT OPTION權限。