Elastic Stack的組件是不安全的,因為它沒有內置的固有安全性。 這意味着任何人都可以訪問它。 在生產環境中運行Elastic Stack時,這會帶來安全風險。 為了防止生產中未經授權的訪問,采用了不同的機制來施加安全性,例如在防火牆后運行Elastic Stack並通過反向代理(例如nginx,HAProxy等)進行保護。 Elastic提供商業產品來保護Elastic Stack。 此產品是X-Pack的一部分,模塊稱為安全性。
在今天的文章中,我們來講述如何為我們的Elastics索引設置字段級的安全。這樣有的字段對有些用戶是可見的,而對另外一些用戶是不可見的。我們也可以通過對用戶安全的設置,使得不同的用戶有不同的權限。
User authentication
在X-Pack安全性中,安全資源是基於用戶的安全性的基礎。 安全資源是需要訪問以執行Elasticsearch集群操作的資源,例如索引,文檔或字段。 X-Pack安全性通過分配給用戶的角色的權限來實現。 權限是針對受保護資源的一項或多項特權。 特權是一個命名的組,代表用戶可以針對安全資源執行的一個或多個操作。 用戶可以具有一個或多個角色,並且用戶擁有的總權限集定義為其所有角色的權限的並集,如下圖所示:
從上面的圖上可以看出來:一個用戶可以用多個role,而每個role可以對應多個permission(權限)。在接下來的練習中,我們來展示如何創建用戶,role(角色)以及把permission分配到每個role。通過這樣的組合,我們可以實現對字段級的安全控制。
為Elastic設置安全及創建用戶
當我們設置完我們的安全賬戶后,最開始我們使用最原始的elastic的賬號進行登錄。請注意這里的密碼是我們設置elastic賬號的密碼:
等登錄進去之后,現在我們去Manage/Sercurity/Users頁面:
我們來創建一個新的賬號。針對我的情況,我想創建一個叫做liuxg的用戶名。點擊當前頁面的Create User按鈕:
然后填入我們所需要的信息:
點擊Create User按鈕,這樣我們就創建了我們的用戶。
按照同樣的步驟,我們來創建另外一個叫做user1的用戶。
准備實驗數據
在我們還沒退出elastic用戶的情況下,我們使用bulk API來把如下的文檔輸入到Elasticsearch中。
POST employee/_bulk
{"index":{"_index":"employee"}}
{"name":"user1","email":"user1@packt.com","salary":5000,"gender":"M","address1":"312 Main St","address2":"Walthill","state":"NE"}
{"index":{"_index":"employee"}}
{"name":"user2","email":"user2@packt.com","salary":10000,"gender":"F","address1":"5658 N Denver Ave","address2":"Portland","state":"OR"}
{"index":{"_index":"employee"}}
{"name":"user3","email":"user3@packt.com","salary":7000,"gender":"F","address1":"300 Quinterra Ln","address2":"Danville","state":"CA"}
這樣我們把三個文檔存入到employee的索引之中。
創建新的role
請注意:如下的操作是在elastic用戶登錄的情況下進行操作的。要創建新用戶,請導航到管理UI並在“Security”部分中選擇“role”,或者如果您當前在“Users”屏幕上,請單擊“Roles”選項。 角色屏幕顯示所有已定義/可用的角色:
當我們點擊roles后:
我們點擊Create role按鈕。
在這里,我們定義了一個叫做monitor_role,它具有monitor的權限。
把role賦予給用戶
我們打開我們的用戶列表。針對我的情況,我們打開liuxg用戶:
我們修改liuxg賬號的Roles。把剛才創建的monitor_role賦予給liuxg用戶。點擊Update User按鈕。這樣我們的設定就好了。設定好的賬號是這樣的:
從上面,我們可以看出來liuxg賬號是有monitor_role的,而user1賬號是沒有的。
下面我們來做一些基本的測試。我們在一個terminal中打入如下的命令:
curl -u liuxg:123456 "http://localhost:9200/_cluster/health?pretty"
注意這里的123456是liuxg的賬號密碼。執行上面的顯示結果是:
我們顯然看到了結果。那么我們同樣地對use1賬號來進行實驗:
curl -u user1:123456 "http://localhost:9200/_cluster/health?pretty"
顯示的結果是:
顯然,user1賬號沒有得到任何結果。這個根本的原因是因為這個賬號沒有相應的權限。
文檔級或字段級安全
現在,我們知道了如何創建新用戶,創建新角色以及將角色分配給用戶,讓我們探討如何針對給定的索引/文檔對文檔和字段施加安全性。接下來,我們使用我之前給大家輸入進的employee索引來展示。
案例1
當用戶搜索員工詳細信息時,該用戶不允許包含在屬於員工索引的文檔中的薪水/地址詳細信息。這就是我們所說的字段級安全。首先,讓我們來創建一個叫做employee_read的role。這個role只具有employ索引的read權限。為了限制字段,我們可以在設置里做相應的配置:
我們只允許這個employee_read role訪問gender,state及email字段,而且只有read權限。
運用我們剛才設置的employee_read role,我們賦予給我們的user1用戶:
設置好的用戶界面為:
上面顯示我們的user1具有employ_read的role。
在我們的一個terminal里打入如下的命令:
curl -u user1:123456 "http://localhost:9200/employee/_search?pretty"
請注意:這里的123456是user1用戶的密碼。上面命令顯示的結果為:
顯然,user1只能訪問在employee_read中的三個字段。
案例2
我們想定義一個role。這個role具有read的權限,並且只能訪問state為OR的那些文檔。我們做一下的設置:
我們創建了一個叫做OR_state的role。它通過一個query:
{"match": {"state.keyword":"OR"}}
來匹配項對應的文檔。我們接着把這個role賦予給liuxg用戶:
在我們設置完后,我們接着在一個terminal中打入如下的命令:
curl -u liuxg:123456 "http://localhost:9200/employee/_search?pretty"
顯示的結果:
我們可以看出來這次的顯示的結果只有一個,而且這個文檔的state是OR。