用Sidecar安全代理保護(hù)Jaeger用戶界面
譯文【51CTO.com快譯】您將學(xué)習(xí)到如何使用Sidecar安全代理來(lái)提高應(yīng)用程序的安全性能,并能防止諸如暴力破解等類型的攻擊。
在Jaeger的產(chǎn)品部署中,我們限制訪問(wèn)Jaeger的查詢服務(wù),包括用戶界面(UI),是非常有益的。例如,您可能有各種內(nèi)部安全的要求,只允許某些群組能夠訪問(wèn)跟蹤數(shù)據(jù),或者您可能將Jaeger部署到了公有云之上。在真正的微服務(wù)(microservices)方式里,一種可能的方法是給Jaeger查詢服務(wù)添加一個(gè)Sidecar作為安全代理。各種入向請(qǐng)求都被傳遞到我們的Sidecar,而非直接到達(dá)Jaeger的查詢服務(wù)上。而Sidecar將負(fù)責(zé)執(zhí)行各種身份驗(yàn)證和授權(quán)的限制。
如上圖所示:傳入的HTTP請(qǐng)求到達(dá)路徑(route)①,它使用內(nèi)部服務(wù)②來(lái)進(jìn)行解析,并與安全代理③進(jìn)行通信。一旦請(qǐng)求通過(guò)驗(yàn)證,且所有安全的限制得到了滿足,則該請(qǐng)求就到達(dá)Jaeger④。
出于演示的目的,我們將使用Keycloak(譯者注:Keycloak是一個(gè)為瀏覽器和RESTful Web服務(wù)提供SSO的集成)作為自己的安全解決方案,當(dāng)然其他任何安全代理也都適用于這個(gè)理念。當(dāng)然如果您并不修改Red Hat的SSO(Single Sign-On),這個(gè)演示也能夠運(yùn)作。因此對(duì)于本次操作練習(xí),我們需要如下:
- 一臺(tái)Keycloak(或是Red Hat的SSO)服務(wù)器的運(yùn)行實(shí)例。我們定義它的位置為$ { REDHAT_SSO_URL }
- 一個(gè)OpenShift的集群,我們將用來(lái)運(yùn)行Jaeger的后端組件。它就像oc cluster up一樣容易
- 一份Jaeger OpenShift產(chǎn)品模板的本地克隆
注意:我們并不會(huì)試圖對(duì)組件之間(比如說(shuō)從代理到收集器)的通信進(jìn)行安全加固。而對(duì)于此類場(chǎng)景,我們完全可以使用其他技術(shù)來(lái)實(shí)現(xiàn),例如相互間使用證書來(lái)進(jìn)行認(rèn)證,采用istio(譯者注:istio是一個(gè)開源項(xiàng)目,提供統(tǒng)一的連接、安全、管理和監(jiān)控微服務(wù)),或其他類似的工具。
準(zhǔn)備Keycloak
對(duì)于該演示,我們將直接在主機(jī)上通過(guò)Docker來(lái)運(yùn)行Keycloak。這是為了強(qiáng)調(diào)Keycloak并不需要像我們的Jaeger后端那樣運(yùn)行在同一個(gè)OpenShift集群之上。
下面的命令用來(lái)在主機(jī)上啟動(dòng)一個(gè)合適的Keycloak服務(wù)器。如果你已經(jīng)有了自己的Keycloak或Red Hat的SSO服務(wù)器的話,則完全跳過(guò)這一步驟。
- docker run --rm --name keycloak-server -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=password -p 8080:8080 jboss/keycloak
一旦Keycloak服務(wù)器啟動(dòng)并運(yùn)行,我們就可以創(chuàng)建一個(gè)Jaeger的域(realm)了:
1. 請(qǐng)使用用戶名:admin和密碼:password,登錄到Keycloak(http://<YOUR_IP>:8080/auth/admin/master/console)。
2. 在左上角Select realm中用鼠標(biāo)點(diǎn)擊Add realm。將其命名為jaeger,然后點(diǎn)擊Create。
3. 在Clients上,點(diǎn)擊Create,將proxy-jaeger設(shè)置為名稱并保存它。
4. 設(shè)置Access Type為confidential,并用*代表Valid Redirect URIs,并保存之。您可能需要在生產(chǎn)環(huán)境中進(jìn)行微調(diào),否則可能會(huì)暴露出已知的“未驗(yàn)證的重定向和轉(zhuǎn)發(fā)”(Unvalidated Redirects and Forwards,譯者注:源自O(shè)WASP TOP10 2010的A10)攻擊。
5. 打開Installation選項(xiàng)卡并選擇Keycloak OIDC JSON,然后復(fù)制其顯示的JSON。如下所示,不過(guò)auth-server-url和secret的值會(huì)有所不同。
- {
- "realm": "jaeger",
- "auth-server-url": "http://192.168.2.111:8080/auth",
- "ssl-required": "external",
- "resource": "proxy-jaeger",
- "credentials": {
- "secret": "7f201319-1dfd-43cc-9838-057dac439046"
- }
- }
最后,讓我們創(chuàng)建一個(gè)角色和用戶,使得我們能夠登錄Jaeger的查詢服務(wù):
1. 在左下側(cè)菜單-Configure的下面,請(qǐng)打開Roles頁(yè)面,然后單擊Add role。
2. 將角色的名稱設(shè)置為user,并點(diǎn)擊Save。
3. 在左下側(cè)菜單-Manage的下面,請(qǐng)打開Users頁(yè)面,然后單擊Add user。
4. 按照您的設(shè)想去填寫該表格,并將Email verified設(shè)置為ON,在并點(diǎn)擊Save。
5. 為該用戶打開Credentials選項(xiàng)卡,并設(shè)置一個(gè)(臨時(shí)的或非臨時(shí)的)密碼。
6. 打開該用戶的Role mappings選項(xiàng)卡,從Available Roles列表中選擇角色為user,再點(diǎn)擊Add。
準(zhǔn)備OpenShift
對(duì)于該演示,我們假設(shè)您已經(jīng)有一個(gè)OpenShift集群正在運(yùn)行了。如果還沒(méi)有的話,那么您可能需要參考minishift之類的工具了(譯者注:minishift是一個(gè)通過(guò)虛擬機(jī)來(lái)模擬OpenShift集群的工具)。如果您正在運(yùn)行最新版本的Fedora、CentOS或Red Hat Enterprise Linux,您可能需要安裝包origin-clients,并運(yùn)行oc cluster up --version=latest。這樣您就能有一個(gè)基本的、運(yùn)行在本地的OpenShift集群。
為了方便演示,我們將添加cluster-admin的權(quán)限給developer用戶。同時(shí)我們創(chuàng)建如下的Jaeger命名空間:
- oc login -u system:admin
- oc new-project jaeger
- oc adm policy add-cluster-role-to-user cluster-admin developer -n jaeger
- oc login -u developer
準(zhǔn)備Jaeger OpenShift模板
我們將使用Jaeger OpenShift產(chǎn)品模板(https://github.com/jaegertracing/jaeger-openshift/blob/master/production/jaeger-production-template.yml)作為開始:克隆整個(gè)存儲(chǔ)庫(kù),或者得到本地版本的模板。
第一步是添加sidecar容器到query-deployment對(duì)象里。在containers列表下,我們指定了jaeger-query之后,就可以添加如下的sidecar代碼:
- - image: jboss/keycloak-proxy
- name: ${JAEGER_SERVICE_NAME}-query-security-proxy
- volumeMounts:
- - mountPath: /opt/jboss/conf
- name: security-proxy-configuration-volume
- ports:
- - containerPort: 8080
- protocol: TCP
- readinessProbe:
- httpGet:
- path: "/"
- port: 8080
注意:該容器將volumeMount的名稱指定為security-proxy-configuration-volume,我們將使用它來(lái)存儲(chǔ)代理的配置文件。您可以在spec/template/spec節(jié)點(diǎn)下為query-deployment指定容量,并同樣設(shè)定dnsPolicy的屬性(它應(yīng)該是在前續(xù)的代碼片段中):
- volumes:
- - configMap:
- name: ${JAEGER_SERVICE_NAME}-configuration
- items:
- - key: proxy
- path: proxy.json
- name: security-proxy-configuration-volume
現(xiàn)在,我們需要來(lái)指定具有代理配置條目的ConfigMap。要做到這一點(diǎn),我們應(yīng)當(dāng)給該模板添加一個(gè)新的頂層項(xiàng)目。在這里,我們建議您將其放置得越接近于其被使用之處越好。例如,就放在query-deployment的前面:
- - apiVersion: v1
- kind: ConfigMap
- metadata:
- name: ${JAEGER_SERVICE_NAME}-configuration
- labels:
- app: jaeger
- jaeger-infra: security-proxy-configuration
- data:
- proxy: |
- {
- "target-url": "http://localhost:16686",
- "bind-address": "0.0.0.0",
- "http-port": "8080",
- "applications": [
- {
- "base-path": "/",
- "adapter-config": {
- "realm": "jaeger",
- "auth-server-url": "${REDHAT_SSO_URL}",
- "ssl-required": "external",
- "resource": "proxy-jaeger",
- "credentials": {
- "secret": "THE-SECRET-FROM-INSTALLATION-FILE"
- }
- }
- ,
- "constraints": [
- {
- "pattern": "/*",
- "roles-allowed": [
- "user"
- ]
- }
- ]
- }
- ]
- }
請(qǐng)注意:我們只允許具有user角色的用戶登錄我們的Jaeger用戶界面。在真實(shí)的場(chǎng)景中,您可能想要調(diào)整之,以適應(yīng)您自己的設(shè)置。例如,您的用戶數(shù)據(jù)可能來(lái)自LDAP,而您只想允許來(lái)自特定LDAP組的用戶去訪問(wèn)Jaeger的用戶界面。
各個(gè)credentials中的secret應(yīng)當(dāng)與我們從本練習(xí)最開始的Keycloak中所獲得的secret相匹配。頗具好奇心的讀者您也許會(huì)注意到,我們?cè)赼uth-server-url屬性下所提到了模板參數(shù)REDHAT_SSO_URL。改變您的Keycloak服務(wù)器,或是我們指定一個(gè)模板參數(shù),都能允許我們?cè)诓渴饡r(shí)對(duì)它進(jìn)行設(shè)置。在該模板的parameters部分,我們可以添加以下屬性:
- - description: The URL to the Red Hat SSO / Keycloak server
- displayName: Red Hat SSO URL
- name: REDHAT_SSO_URL
- required: true
- value: http://THE-URL-FROM-THE-INSTALLATION-FILE:8080/auth
可見這個(gè)值應(yīng)該是一個(gè)您的瀏覽器和sidecar都能訪問(wèn)到的位置,就像您主機(jī)的局域網(wǎng)IP地址(192.x.10.x)一樣。顯然,使用Localhost/127.x是無(wú)法工作的。
作為最后一步,我們需要更改服務(wù)引導(dǎo)請(qǐng)求到端口8080(即為代理)上,而不是16686。你可以更改服務(wù)名為query-service的屬性targetPort,將其設(shè)置到8080:
- - apiVersion: v1
- kind: Service
- metadata:
- name: ${JAEGER_SERVICE_NAME}-query
- labels:
- app: jaeger
- jaeger-infra: query-service
- spec:
- ports:
- - name: jaeger-query
- port: 80
- protocol: TCP
- targetPort: 8080
- selector:
- jaeger-infra: query-pod
- type: LoadBalancer
作為參考,您可以在博客鏈接--https://github.com/jaegertracing/jaeger-openshift/blob/KeycloakSecuringUI/production/jaeger-production-template.yml里看到完整的模板文件。
部署
現(xiàn)在我們已經(jīng)一切準(zhǔn)備就緒了,那么就開始部署Jaeger到我們的OpenShift集群上吧。請(qǐng)您在前續(xù)步驟里存儲(chǔ)了YAML文件的相同目錄中,運(yùn)行以下的命令。我們?cè)诖艘玫降拿Q是jaeger-production-template.yml:
- oc process -f jaeger-production-template.yml | oc create -n jaeger -f -
在開始運(yùn)行的頭幾分鐘內(nèi),如果pod的jaeger-query和jaeger-collector出現(xiàn)失敗的話并無(wú)大礙,Cassandra(譯者注:Cassandra是一套開源分布式數(shù)據(jù)庫(kù)管理系統(tǒng),用于儲(chǔ)存特別大的數(shù)據(jù))仍將會(huì)完成啟動(dòng)。最終,該服務(wù)也會(huì)啟動(dòng)并運(yùn)行,如下圖所示。
一旦準(zhǔn)備好了接收服務(wù),請(qǐng)點(diǎn)擊路徑(route)的URL(https://jaeger-query-jaeger.127.0.0.1.nip.io)。一個(gè)由Keycloak服務(wù)器所提供的登錄界面就會(huì)呈現(xiàn)在您眼前。請(qǐng)使用您在前續(xù)步驟中設(shè)置好的憑證進(jìn)行登錄,之后您就可以順利到達(dá)Jaeger的用戶界面了。
結(jié)論
在這個(gè)練習(xí)中,我們了解到了如何為Jaeger的查詢pod添加一個(gè)sidecar作為安全代理。它讓所有的入向請(qǐng)求都傳遞到該sidecar,而Keycloak的所有特性,例如:雙因素認(rèn)證、服務(wù)帳戶、單點(diǎn)登錄、暴力攻擊保護(hù)、LDAP支持、等都仍然是透明可用的。
原文標(biāo)題:Protecting Jaeger UI With a Sidecar Security Proxy,作者:Juraci Paixao Kroehling
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】