mysql之許可權驗證

myownstars發表於2012-12-20

帳戶許可權資訊存放在mysql資料庫中的user/db/host/tables_priv/columns_priv/procs_priv表中,在伺服器啟動時將其讀入記憶體以供使用;

oracle不同,mysql的帳戶由使用者名稱和主機名兩部分組成,如不顯示指定主機名則等同於’username’@’%’

一個資料庫會話從發起連線到執行sql,經歷兩個階段的許可權驗證:資料庫連線驗證和sql請求驗證

資料庫連線驗證

一個資料庫連線由user表裡的Host/user/password三個列進行驗證,但user/password列都可能為空;

Mysql在伺服器啟動時將user表記錄排序讀入記憶體,當user表裡有多條記錄都匹配資料庫連線時,則選擇第一條;

排序規則:先排序host列,空值排在最後,%次之;然後是user列,空值排在最後

1

--user表原始記錄

+-----------+----------+-

| Host      | User     | ...

+-----------+----------+-

| %         | root     | ...

| %         | jeffrey  | ...

| localhost | root     | ...

| localhost |          | ...

+-----------+----------+-

讀入記憶體排序後的記錄

+-----------+----------+-

| Host      | User     | ...

+-----------+----------+-

| localhost | root     | ...

| localhost |          | ...

| %         | jeffrey  | ...

| %         | root     | ...

+-----------+----------+-

這種規則可能會產生問題,即使客戶端連線時顯示指定了user名,也有可能最終以其他使用者登陸進入mysql

2

假定mysql伺服器的localhostthomas.loc.gov,從localhostjeffrey為使用者名稱嘗試連線mysql

--user表記錄

+----------------+----------+-

| Host           | User     | ...

+----------------+----------+-

| %              | jeffrey  | ...

| thomas.loc.gov |          | ...

+----------------+----------+-

--記憶體排序後

+----------------+----------+-

| Host           | User     | ...

+----------------+----------+-

| thomas.loc.gov |          | ...

| %              | jeffrey  | ...

+----------------+----------+-

則該連線會以anonymous匿名使用者登入進入mysql

mysql> SELECT CURRENT_USER();

+----------------+

| CURRENT_USER() |

+----------------+

| @localhost     |

+----------------+

 

Sql請求驗證

連線進入mysql伺服器後,執行的每個sql都需要經過許可權檢查,相關表為user/db/host/tables_priv/columns_priv/procs_priv

user表是全域性性的,比如user表賦給一個使用者delete許可權,則該使用者可以刪除任何表的記錄;所以最好只賦給管理員使用者;

db/host則是資料庫級別的,兩表的host/db列均可使用萬用字元;對於db表,其host列若為%則表示所有主機,為空則需聯絡host表進一步檢視;對於host表,%或空值代表所有主機;對兩表而言,db列為%或空值代表所有資料庫;

db/host表同user表一起在伺服器啟動時讀入記憶體並排序,db表基於host/db/user列,而host表則基於host/db列;當有多行匹配時以第一行為準;

另外三個表從其名稱即可看出其適用範圍,只有host列可以使用萬用字元%_

每當伺服器接受到請求時,便查詢這7個表以驗證其許可權;

當收到管理員命令諸如shutdown/reload時,只查詢user表;

當收到資料庫相關請求insert/update時,首先檢查user表,沒有相應global許可權時再去檢查db/host表;檢查db表的host/user/db列,如無返回行則請求被拒絕,若返回行的host列為空,則需進一步查詢host表驗證,若host表有返回行則交集匹配,即兩個表的許可權列都須為Y(此功能允許將資料庫操作許可權只賦給特定host發起的使用者連線)

使用者許可權計算規則類似下面的表示式

global privileges

OR (database privileges AND host privileges)

OR table privileges

OR column privileges

OR routine privileges

 

注:

Grant/revoke操作不會對host表產生影響,但可以用來維護特定的安全server列表,反之亦然;

比如,假定公共網路的public.your.domain不完全,可透過如下設定來自禁止該域名的機器訪問

+--------------------+----+-

| Host               | Db | ...

+--------------------+----+-

| public.your.domain | %  | ... (all privileges set to 'N')

| %.your.domain      | %  | ... (all privileges set to 'Y')

+--------------------+----+-

                                                                                                 

如何使修改的許可權生效

如果透過呼叫grant/revoke/set password/rename user等命令修改許可權,則伺服器會立即重新整理並將grant表重新載入記憶體;

若透過insert/update/delete直接修改grant表,則需要手工過載這些表(flush privileges/mysqladmin flush-privileges/mysqladmin reload),否則只有在伺服器重啟後才能生效;

修改許可權並過載grant表,會對現有的連線產生如下影響:

/列許可權改動會在客戶端下一次請求時生效;資料庫許可權改動在客戶端下次執行use db_name時生效;global許可權和密碼只對新發起的連線生效;

當伺服器使用—skip-grant-tables啟動時,則不會讀取grant表,任何使用者都可以登入並進行任何操作

 

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

相關文章