用Sidecar安全代理保护Jaeger用户界面

译文
安全 应用安全
您将学习到如何使用Sidecar安全代理来提高应用程序的安全性能,并能防止诸如暴力破解等类型的攻击。

【51CTO.com快译】您将学习到如何使用Sidecar安全代理来提高应用程序的安全性能,并能防止诸如暴力破解等类型的攻击。

在Jaeger的产品部署中,我们限制访问Jaeger的查询服务,包括用户界面(UI),是非常有益的。例如,您可能有各种内部安全的要求,只允许某些群组能够访问跟踪数据,或者您可能将Jaeger部署到了公有云之上。在真正的微服务(microservices)方式里,一种可能的方法是给Jaeger查询服务添加一个Sidecar作为安全代理。各种入向请求都被传递到我们的Sidecar,而非直接到达Jaeger的查询服务上。而Sidecar将负责执行各种身份验证和授权的限制。

如上图所示:传入的HTTP请求到达路径(route)①,它使用内部服务②来进行解析,并与安全代理③进行通信。一旦请求通过验证,且所有安全的限制得到了满足,则该请求就到达Jaeger④。

出于演示的目的,我们将使用Keycloak(译者注:Keycloak是一个为浏览器和RESTful Web服务提供SSO的集成)作为自己的安全解决方案,当然其他任何安全代理也都适用于这个理念。当然如果您并不修改Red Hat的SSO(Single Sign-On),这个演示也能够运作。因此对于本次操作练习,我们需要如下:

  • 一台Keycloak(或是Red Hat的SSO)服务器的运行实例。我们定义它的位置为$ { REDHAT_SSO_URL }
  • 一个OpenShift的集群,我们将用来运行Jaeger的后端组件。它就像oc cluster up一样容易
  • 一份Jaeger OpenShift产品模板的本地克隆

注意:我们并不会试图对组件之间(比如说从代理到收集器)的通信进行安全加固。而对于此类场景,我们完全可以使用其他技术来实现,例如相互间使用证书来进行认证,采用istio(译者注:istio是一个开源项目,提供统一的连接、安全、管理和监控微服务),或其他类似的工具。

准备Keycloak

对于该演示,我们将直接在主机上通过Docker来运行Keycloak。这是为了强调Keycloak并不需要像我们的Jaeger后端那样运行在同一个OpenShift集群之上。

下面的命令用来在主机上启动一个合适的Keycloak服务器。如果你已经有了自己的Keycloak或Red Hat的SSO服务器的话,则完全跳过这一步骤。

  1. docker run --rm --name keycloak-server -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=password -p 8080:8080 jboss/keycloak 

一旦Keycloak服务器启动并运行,我们就可以创建一个Jaeger的域(realm)了:

1. 请使用用户名:admin和密码:password,登录到Keycloak(http://<YOUR_IP>:8080/auth/admin/master/console)。

2. 在左上角Select realm中用鼠标点击Add realm。将其命名为jaeger,然后点击Create。

3. 在Clients上,点击Create,将proxy-jaeger设置为名称并保存它。

4. 设置Access Type为confidential,并用*代表Valid Redirect URIs,并保存之。您可能需要在生产环境中进行微调,否则可能会暴露出已知的“未验证的重定向和转发”(Unvalidated Redirects and Forwards,译者注:源自OWASP TOP10 2010的A10)攻击。

5. 打开Installation选项卡并选择Keycloak OIDC JSON,然后复制其显示的JSON。如下所示,不过auth-server-url和secret的值会有所不同。

  1.   "realm""jaeger", 
  2.   "auth-server-url""http://192.168.2.111:8080/auth", 
  3.   "ssl-required""external", 
  4.   "resource""proxy-jaeger", 
  5.   "credentials": { 
  6.     "secret""7f201319-1dfd-43cc-9838-057dac439046" 
  7.   } 

最后,让我们创建一个角色和用户,使得我们能够登录Jaeger的查询服务:

1. 在左下侧菜单-Configure的下面,请打开Roles页面,然后单击Add role。

2. 将角色的名称设置为user,并点击Save。

3. 在左下侧菜单-Manage的下面,请打开Users页面,然后单击Add user。

4. 按照您的设想去填写该表格,并将Email verified设置为ON,在并点击Save。

5. 为该用户打开Credentials选项卡,并设置一个(临时的或非临时的)密码。

6. 打开该用户的Role mappings选项卡,从Available Roles列表中选择角色为user,再点击Add。

准备OpenShift

对于该演示,我们假设您已经有一个OpenShift集群正在运行了。如果还没有的话,那么您可能需要参考minishift之类的工具了(译者注:minishift是一个通过虚拟机来模拟OpenShift集群的工具)。如果您正在运行最新版本的Fedora、CentOS或Red Hat Enterprise Linux,您可能需要安装包origin-clients,并运行oc cluster up --version=latest。这样您就能有一个基本的、运行在本地的OpenShift集群。

为了方便演示,我们将添加cluster-admin的权限给developer用户。同时我们创建如下的Jaeger命名空间:

  1. oc login -u system:admin 
  2. oc new-project jaeger 
  3. oc adm policy add-cluster-role-to-user cluster-admin developer -n jaeger 
  4. oc login -u developer 

准备Jaeger OpenShift模板

我们将使用Jaeger OpenShift产品模板(https://github.com/jaegertracing/jaeger-openshift/blob/master/production/jaeger-production-template.yml)作为开始:克隆整个存储库,或者得到本地版本的模板。

第一步是添加sidecar容器到query-deployment对象里。在containers列表下,我们指定了jaeger-query之后,就可以添加如下的sidecar代码:

  1. - image: jboss/keycloak-proxy 
  2.           name: ${JAEGER_SERVICE_NAME}-query-security-proxy 
  3.           volumeMounts: 
  4.           - mountPath: /opt/jboss/conf 
  5.             name: security-proxy-configuration-volume 
  6.           ports: 
  7.           - containerPort: 8080 
  8.             protocol: TCP 
  9.           readinessProbe: 
  10.             httpGet: 
  11.               path: "/" 
  12.               port: 8080 

注意:该容器将volumeMount的名称指定为security-proxy-configuration-volume,我们将使用它来存储代理的配置文件。您可以在spec/template/spec节点下为query-deployment指定容量,并同样设定dnsPolicy的属性(它应该是在前续的代码片段中):

  1. volumes: 
  2.           - configMap: 
  3.               name: ${JAEGER_SERVICE_NAME}-configuration 
  4.               items: 
  5.                 - key: proxy 
  6.                   path: proxy.json 
  7.             name: security-proxy-configuration-volume 

现在,我们需要来指定具有代理配置条目的ConfigMap。要做到这一点,我们应当给该模板添加一个新的顶层项目。在这里,我们建议您将其放置得越接近于其被使用之处越好。例如,就放在query-deployment的前面:

  1. - apiVersion: v1 
  2.   kind: ConfigMap 
  3.   metadata: 
  4.     name: ${JAEGER_SERVICE_NAME}-configuration 
  5.     labels: 
  6.       app: jaeger 
  7.       jaeger-infra: security-proxy-configuration 
  8.   data: 
  9.     proxy: | 
  10.       { 
  11.           "target-url""http://localhost:16686", 
  12.           "bind-address""0.0.0.0", 
  13.           "http-port""8080", 
  14.           "applications": [ 
  15.               { 
  16.                   "base-path""/", 
  17.                   "adapter-config": { 
  18.                     "realm""jaeger", 
  19.                     "auth-server-url""${REDHAT_SSO_URL}", 
  20.                     "ssl-required""external", 
  21.                     "resource""proxy-jaeger", 
  22.                     "credentials": { 
  23.                       "secret""THE-SECRET-FROM-INSTALLATION-FILE" 
  24.                     } 
  25.                   } 
  26.             , 
  27.             "constraints": [ 
  28.                       { 
  29.                           "pattern""/*", 
  30.                           "roles-allowed": [ 
  31.                               "user" 
  32.                           ] 
  33.                       } 
  34.                   ] 
  35.               } 
  36.           ] 
  37.       } 

请注意:我们只允许具有user角色的用户登录我们的Jaeger用户界面。在真实的场景中,您可能想要调整之,以适应您自己的设置。例如,您的用户数据可能来自LDAP,而您只想允许来自特定LDAP组的用户去访问Jaeger的用户界面。

各个credentials中的secret应当与我们从本练习最开始的Keycloak中所获得的secret相匹配。颇具好奇心的读者您也许会注意到,我们在auth-server-url属性下所提到了模板参数REDHAT_SSO_URL。改变您的Keycloak服务器,或是我们指定一个模板参数,都能允许我们在部署时对它进行设置。在该模板的parameters部分,我们可以添加以下属性:

  1. - description: The URL to the Red Hat SSO / Keycloak server 
  2.   displayName: Red Hat SSO URL 
  3.   name: REDHAT_SSO_URL 
  4.   required: true 
  5.   value: http://THE-URL-FROM-THE-INSTALLATION-FILE:8080/auth 

可见这个值应该是一个您的浏览器和sidecar都能访问到的位置,就像您主机的局域网IP地址(192.x.10.x)一样。显然,使用Localhost/127.x是无法工作的。

作为最后一步,我们需要更改服务引导请求到端口8080(即为代理)上,而不是16686。你可以更改服务名为query-service的属性targetPort,将其设置到8080:

  1. - apiVersion: v1 
  2.   kind: Service 
  3.   metadata: 
  4.     name: ${JAEGER_SERVICE_NAME}-query 
  5.     labels: 
  6.       app: jaeger 
  7.       jaeger-infra: query-service 
  8.   spec: 
  9.     ports: 
  10.     - name: jaeger-query 
  11.       port: 80 
  12.       protocol: TCP 
  13.       targetPort: 8080 
  14.     selector: 
  15.       jaeger-infra: query-pod 
  16.     type: LoadBalancer 

作为参考,您可以在博客链接--https://github.com/jaegertracing/jaeger-openshift/blob/KeycloakSecuringUI/production/jaeger-production-template.yml里看到完整的模板文件。

部署

现在我们已经一切准备就绪了,那么就开始部署Jaeger到我们的OpenShift集群上吧。请您在前续步骤里存储了YAML文件的相同目录中,运行以下的命令。我们在此引用到的名称是jaeger-production-template.yml:

  1. oc process -f jaeger-production-template.yml | oc create -n jaeger -f - 

在开始运行的头几分钟内,如果pod的jaeger-query和jaeger-collector出现失败的话并无大碍,Cassandra(译者注:Cassandra是一套开源分布式数据库管理系统,用于储存特别大的数据)仍将会完成启动。最终,该服务也会启动并运行,如下图所示。

一旦准备好了接收服务,请点击路径(route)的URL(https://jaeger-query-jaeger.127.0.0.1.nip.io)。一个由Keycloak服务器所提供的登录界面就会呈现在您眼前。请使用您在前续步骤中设置好的凭证进行登录,之后您就可以顺利到达Jaeger的用户界面了。

结论

在这个练习中,我们了解到了如何为Jaeger的查询pod添加一个sidecar作为安全代理。它让所有的入向请求都传递到该sidecar,而Keycloak的所有特性,例如:双因素认证、服务帐户、单点登录、暴力攻击保护、LDAP支持、等都仍然是透明可用的。

原文标题:Protecting Jaeger UI With a Sidecar Security Proxy,作者:Juraci Paixao Kroehling

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】

责任编辑:武晓燕 来源: 51CTO专栏
相关推荐

2015-03-18 10:36:33

2009-06-19 13:03:31

JavaFX

2012-08-01 10:47:59

2012-08-08 14:57:00

2014-02-20 15:00:48

MetroWindows用户

2011-03-01 16:37:29

2014-03-03 09:50:59

Windows XP

2022-09-15 10:44:42

SidecarIstioeBPFizer

2016-08-02 17:08:46

2010-10-26 16:11:18

虚拟桌面环境数据安全

2020-09-15 10:28:42

Kubernetes容器

2011-04-14 18:13:37

Imperva文件保护

2018-08-04 07:56:03

云安全网络安全信息安全

2009-03-09 09:39:00

2010-09-17 20:40:09

2022-07-13 13:34:30

微服务边车SideCar

2010-09-29 10:09:41

2021-04-16 10:31:56

数据数据安全个人信息安全

2012-04-23 13:43:06

用户体验用户界面

2009-02-28 14:23:02

点赞
收藏

51CTO技术栈公众号