安全保障基于软件全生命周期-Istio的认证机制

在介绍Istio的认证机制前,先了解一些安全领域的理论知识。传统网络安全架构是基于边界的安全架构,企业构建网络安全体系时,先寻找安全边界,把网络划分为外网、内网、DMZ(DeMilitarized Zone)等不同的区域,然后在边界上部署防火墙、入侵检测等产品。传统的认证是以网络为中心,采用内网信任、边界防护、静态访问控制的机制。


随着云计算、大数据、物联网等新技术与业务的融合,在安全方面提出了新的概念零信任架构(ZTA Zero Trust Architecture),零信任的核心原则是:从不信任、始终验证。安全架构的核心有如下几点

  • 以身份为中心
  • 以识别、持续认证、动态访问控制、授权、审计以及监测为链条
  • 以最小化实时授权为核心
  • 以多维信任算法为基础
  • 认证达末端

 零信任架构三大技术SIM包括
软件定义边界(SDP,Software Defined Perimeter)
SDP旨在使应用程序能在需要时部署安全边界,以便将服务于不安全的网络隔离开。
身份识别与访问管理(IAM,Identity and Access Management)
微隔离(MSG,Micro Segmentation)
微隔离本质上是一种网络安全隔离技术,相比较传统的网络安全隔离,微隔离的区别在于将网络边界分割到尽可能小,这样能缓解传统边界安全理念下的边界过度信任带来的安全风险。

Istio 中的安全性涉及多个组件:
用于密钥和证书管理的证书颁发机构(CA
配置 API 服务器分发给代理:认证策略/授权策略
安全命名信息
Sidecar和边缘代理作为Policy Enforcement Points(PEPs) 以保护客户端和服务器间的通信安全。
一组Envoy代理扩展,用于管理遥测和审计。Istio PKI 使用 X.509 证书为每个工作负载都提供强大的身份标识。伴随着每个 Envoy 代理的 istio-agent(istio-agent是指sidecar容器中的pilot-agent进程)和 istiod 一起协作来大规模进行自动化密钥和证书轮换。如下图所示完成完成身份的供应。

  • istiod 提供 gRPC 服务以接受证书签名请求(CSRs)。当工作负载启动时,Envoy通过秘密发现服务(SDS)API向同容器内的istio-agent发送证书和密钥请求。
  • 在收到SDS请求后,istio-agent 创建私钥和CSR,然后将CSR及其凭据发送到istiod CA签名
  • istiod CA 验证 CSR 中携带的凭据,成功验证后签署 CSR 以生成证书。
  • Istio-agent 通过 Envoy SDS API 将私钥和从 Istio CA 收到的证书发送给 Envoy。
  • Istio-agent会监工作负载证书的有效期。上述CSR过程会周期性地重复以处理证书和密钥轮换

Istio提供两种类型的认证:
Peer authentication:用于服务到服务的认证,以验证进行连接的客户端。Istio提供双向TLS 作为传输认证的全栈解决方案,无需更改服务代码就可以启用它。
Request authentication:用于最终用户认证,以验证附加到请求的凭据。 Istio使用JSON Web Token(JWT)验证启用请求级认证,并使用自定义认证实现或任何 OpenID Connect 的认证实现来简化的开发人员体验。

安全命名:服务器身份(Server identities)被编码在证书里,但服务名称(service names)通过服务发现或 DNS 被检索。安全命名信息将服务器身份映射到服务名称。身份 A 到服务名称 B 的映射表示“授权 A 运行服务 B“。控制平面监视 apiserver,生成安全命名映射,并将其安全地分发到 PEPs。

上面介绍了概念,接下来通过实际例子演示Istio如何完成认证的。创建三个namespace foo,bar,lagacy,其中foo,bar注入Istio sidecar,且三个namespace下都部署httpbin和sleep服务,这两个服务都来自Istio官网的sample目录下。创建对象完成后,查看bar下面的应用,可以看到是2/2,说明已经注入了Sidecar。接着尝试通过命令让bar namespace下的sleep应用通过curl命令访问httpbin应用,可以看到成功返回了200.

接着在三个namespace下让sleep服务访问httpbin服务。访问命令如下,也全部访问成功

for from in "foo" "bar" "legacy"; do for to in "foo" "bar" "legacy"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl -s "http://httpbin.${to}:8000/ip" -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done

 接着查看是否存在peerauthentication对象和destinationRules,都不存在。查看httpbin/headers,可以看到header里面有Client-Cert信息。

接着直接在主机上通过httpbin pod的IP地址访问headers信息,可以看到无Cert信息。

 

通过上面的例子可以看到对于注入了Istio sidecard的应用来说,自动启动了mTLS的双向认证机制。接下来创建一个PeerAuthentication对象,模式是STRICT模式,PeerAuthentication的模式有三种,三种模式的区别如下所示:

PERMISSIVE:工作负载接受双向 TLS 和纯文本流量。此模式在迁移因为没有 sidecar 而无法使用双向 TLS 的工作负载的过程中非常有用。一旦工作负载完成 sidecar 注入的迁移,应将模式切换为 STRICT。
STRICT: 工作负载仅接收双向 TLS 流量。
DISABLE:禁用双向 TLS。 从安全角度来看,除非您提供自己的安全解决方案,否则请勿使用此模式。

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "default"
  namespace: "istio-system"
spec:
  mtls:
    mode: STRICT
EOF

因为上述PeerAuthentication对象是创建在istio-system namespaces下面,即Istio的根namespace下,所以是全局生效。生效后再次用三个namespace下的sleep应用访问httpbin服务。可以看到legacy下的sleep服务访问foo,bar下的httpbin服务都失败了,因为legacy没有注入Istio sidecar,所以是纯文本流量,现在采用STRICT模式,所以会失败。Istio默认是采用PERMISSIVE。

接着在foo namespace下创建新的PeerAuthentication,对于访问httpbin的流量DISABLE,即禁用双向TLS。

cat <<EOF | kubectl apply -n foo -f -
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "overwrite-example"
  namespace: "foo"
spec:
  selector:
    matchLabels:
      app: httpbin
  mtls:
    mode: DISABLE
EOF

再次查看服务之间相互访问情况,可以看到Legacy下面的sleep应用访问foo下面的httpbin应用重新通了,只有bar下面的不同。因为上面的PA是创建在foo namespace。

通过上面的例子演示,可以看到可以通过配置PeerAuthentication来精细化控制服务间的隔离,即实现微隔离,也符合SDP原则,即应用自身来确定部署的安全边界。

上面介绍了PeerAuthentication(主要用户客户端和服务端都受Istio管理的场景),接着来看看Request Authentication(用户客户端不受Istio管理,无法使用mTLS的场景).。

Request 认证策略指定验证 JSON Web Token(JWT)所需的值。 这些值包括:
token 在请求中的位置
请求的 issuer
公共 JSON Web Key Set(JWKS)

Istio会根据request认证策略中的规则检查提供的令牌(如果已提供),并拒绝令牌无效的请求。当请求不带有令牌时,默认情况下将接受它们。接着通过实际例子来看看Request Authentication如何工作。首先通过gateway把httpbin的服务暴露出来。

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
  namespace: foo
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
EOF
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
  namespace: foo
spec:
  hosts:
  - "*"
  gateways:
  - httpbin-gateway
  http:
  - route:
    - destination:
        port:
          number: 8000
        host: httpbin.foo.svc.cluster.local
EOF

接着创建RequestAuthentication对象。

 kubectl apply -f - <<EOF
apiVersion: "security.istio.io/v1beta1"
kind: "RequestAuthentication"
metadata:
  name: "jwt-example"
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  jwtRules:
  - issuer: "testing@secure.istio.io"
    jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.14/security/tools/jwt/samples/jwks.json"
EOF

 在Istio的官网上提供了生成token的python代码,可以通过这个脚本生成有效的token。通过ingress svc的IP地址访问服务,如果不带token,默认是接收请求。

可以看到不带token的情况下,访问成功。

通过Istio官网提供的脚本生成有效的token,生成有效token官网提供了两种方式。

方式一
TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/master/security/tools/jwt/samples/demo.jwt -s)
curl --header "Authorization: Bearer $TOKEN" $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n"

方式二
pip install jwcrypto
TOKEN=$(./gen-jwt.py key.pem --expire=300 --iss "new-issuer@secure.istio.io")

带着有效token访问ingress可以看到返回了200.如果把token替换成任意的字符串,返回了401,说明认证不通过。

 上面的例子中如果访问服务不带token则默认接受,这里通过生成AuthoriztionPolicy对象来控制如果不带token则拒绝请求。

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "frontend-ingress"
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  action: DENY
  rules:
  - from:
    - source:
        notRequestPrincipals: ["*"]
EOF

AuthorizationPolicy对象生效后,不带token访问则refused,带上有效token访问,仍然能成功访问成功。关于AuthorizationPolicy的使用会在下一篇博客中详细介绍。

通过上面的例子演示 AuthenticationRequest的工作过程。可以看到如果不受Istio管控的服务,通过AuthenticationRequest可以完成认证管控,保证应用安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

taoli-qiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值