安全方面的常见问题

安装 Istio 之后如何启用或者禁用双向 TLS?

可以利用认证策略目标规则随时为服务设置双向 TLS 认证。请阅读认证策略任务以获取更多相关细节。

如何检查服务是否启动了双向 TLS?

istioctl 工具为此提供了一个选项,你可以像下面那样做:

$ istioctl authn tls-check $CLIENT_POD httpbin.default.svc.cluster.local
HOST:PORT                                  STATUS     SERVER     CLIENT     AUTHN POLICY        DESTINATION RULE
httpbin.default.svc.cluster.local:8000     OK         mTLS       mTLS       default/            default/istio-system

其中 $CLIENT_POD 是作为客户端服务运行的 Pods 中任意一个的 ID。

更多详细信息,请参见检查双向 TLS 配置

同一集群中是否可以仅对部分服务启用双向 TLS ?

认证策略可以是网格范围的(对网格中的所有服务都有效)、命名空间范围的(对同一命名空间中的所有服务都有效)或者是针对特定服务的。在集群中可以用任何需要的方式来为服务设置双向 TLS 策略。

如果全局启用了双向 TLS,非 Istio 服务可以访问 Istio 服务吗?

非 Istio 服务无法与 Istio 服务进行通信,除非它们可以提供有效证书,而这种证书也很难提供。这正是双向 TLS 功能的目的。但是,你可以覆盖特定命名空间或服务的全局标志 (global flag)。有关详细信息,请参阅任务

如何使用 Istio 的服务访问非 Istio 服务?

当全局启用双向 TLS 时,全局目标规则 (global destination rule) 匹配群集中的所有服务,无论这些服务是否具有 Istio sidecar。 这包括 Kubernetes API 服务器,以及集群中的任何非 Istio 服务。 要让这些非 Istio 服务与有 Istio sidecar 的服务进行通信,你需要设置目标规则以免除服务。 例如:

$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: "api-server"
spec:
 host: "kubernetes.default.svc.cluster.local"
 trafficPolicy:
   tls:
     mode: DISABLE
EOF

同样,您可以为其他非 Istio 服务添加目标规则。 有关更多示例,请参阅任务

当启用双向 TLS 认证时应该如何使用 Kubernetes liveness 和 readiness 对服务进行健康检查?

如果启用了双向 TLS 认证,则来自 kubelet 的 http 和 tcp 健康检查将不能正常工作,因为 kubelet 没有 Istio 颁发的证书。

从 Istio 1.0 开始,针对服务新增了 PERMISSIVE 模式 ,因此当这个模式打开时他们可以接受 http 和双向 TLS 流量。这可以解决健康检查问题。 请记住,双向 TLS 没有强制执行,因为其他服务可以使用 http 流量与该服务进行通信。

您可以使用单独的端口进行健康检查,并只在常规服务端口上启用双向 TLS。请参阅 Istio 服务的健康检查了解更多信息。

由于存在新功能的风险,我们默认情况下不会启用上述功能。未来的推出计划将在 GitHub 问题上进行跟踪。

为了降低风险,另一种解决方法是对健康检查使用 liveness 命令,例如,可以在服务 Pod 中安装 curl 并在 Pod 内对自身执行 curl 操作。

一个 readiness 探针的例子:

livenessProbe:
exec:
  command:
  - curl
  - -f
  - http://localhost:8080/healthz # Replace port and URI by your actual health check
initialDelaySeconds: 10
periodSeconds: 5
如何配置 Istio 证书的有效期?

对于在 Kubernetes 上运行的工作负载来说,它们的 Istio 证书有效期是受到 Citadel 的 workload-cert-ttl 标志控制的。缺省值是 90 天。这个值不能大于 Citadel 的 max-workload-cert-ttl

Citadel 使用标志 max-workload-cert-ttl 对 Istio 签发给工作负载的证书的有效期进行控制。缺省值是 90 天。如果 Citadel 或者 Node agent 中的 workload-cert-ttl 大于 max-workload-cert-ttl,Citadel 的证书签发就会失败。

可以对文件 istio-demo-auth.yaml 进行修改,从而对 Citadel 配置进行定制。下面的修改过程,让 Istio 为 Kubernetes 工作负载签发有效期为一小时的证书。并且 Istio 签发证书的最长有效期被设置为 48 小时。

...
kind: Deployment
...
metadata:
  name: istio-citadel
  namespace: istio-system
spec:
  ...
  template:
    ...
    spec:
      ...
      containers:
      - name: citadel
        ...
        args:
          - --workload-cert-ttl=1h # 签发给 Kubernetes 工作负载的证书的有效期。
          - --max-workload-cert-ttl=48h # Citadel 签发给 Kubernetes 工作负载的证书的最大有效期。

对于运行于物理机或者虚拟机上的工作负载来说,他们的 Istio 证书有效期是由每个 Node agent 的 workload-cert-ttl 决定的。其缺省值同样也是 90 天,这个值也不允许超出 Citadel 的 max-workload-cert-ttl 选项的值。

要定制这一配置,要在完成设置虚拟机步骤之后,对 Node agent 服务(/lib/systemd/system/istio-auth-node-agent.service)的参数进行修改。

...
[Service]
ExecStart=/usr/local/bin/node_agent --workload-cert-ttl=24h # 设置本机的证书有效时间。
Restart=always
StartLimitInterval=0
RestartSec=10
...

上面的配置中要求 Istio 为虚拟机或物理机上运行的工作负载签发 24 小时有效期的证书。完成服务配置之后,需要重新启动 Node agent 服务。

MySQL 连接错误的排查

在安装 Istio 之后,你可能会遇到 MySQL 无法连接的问题。这是因为 istio-demo.yaml 中缺省启用了 PERMISSIVE,这一模式会影响 MySQL 的连接。

有两种方法可以解决这一问题。

  1. 禁用双向 TLS

    如果不需要 Istio 的双向 TLS 支持的话,就可以选择这一方法。可以在 MySQL 服务上显式的禁用双向 TLS。

    $ kubectl apply -f <<EOF
    apiVersion: "authentication.istio.io/v1alpha1"
    kind: "Policy"
    metadata:
      name: mysql-nomtls-authn
    spec:
      targets:
      - name: mysql-service
    EOF
    
  2. 用 STRICT 模式启用双向 TLS

    如果希望使用双向 TLS 保护 MySQL,可以用 DestinationRule 结合认证策略来启用双向 TLS。

    $ kubectl apply -f <<EOF
    apiVersion: "authentication.istio.io/v1alpha1"
    kind: "Policy"
    metadata:
      name: mysql-mtls-authn
    spec:
      targets:
      - name: mysql-service
      peers:
      - mtls:
          mode: STRICT
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: mysql-mtls-dr
    spec:
      host: "mysql-service"
      trafficPolicy:
        tls:
          mode: ISTIO_MUTUAL
    EOF
    
Istio 是否支持授权和鉴权?

是的。 Istio 为网格中的 HTTP 和普通 TCP 服务提供授权功能。 了解更多

Istio 权限认证是否使用了 Kubernetes secrets?

是的。Istio 权限认证中密钥和证书的分发是基于 Kubernetes secrets

Secrets 有已知的 安全风险。Kubernetes 团队正在开发 几个功能特性 来提高 Kubernetes secret 的安全性,从 secret 的加密到节点级别的访问控制。并且 Kubernetes 从 1.6 版本引入了 RBAC authorization ,提供了细力度的 secrets 管理。

工作负载中的密钥和证书是加密存储的么?

缺省情况下,这些数据会进行 Base64 编码,但是并没有加密。然而 Kubernetes 中的 Secret 资源加密功能是可以用来进行加密的。

注意 Google 容器引擎(GKE)中这一功能还未启用。因此 Master 节点上运行 ETCD 中的数据可能未被加密,而 Master 节点自身是加密的,请阅读 GKE 相关文档了解更多相关细节。

Istio 中如何配置 Ingress 令其仅接受 TLS 连接?

依照用 HTTPS 加密 Gateway 任务中的陈述进行配置,能够让 Istio Ingress 只接受 TLS 流量。

我可以为 HTTPS 服务安装 Istio sidecar 吗?

是的,你可以这么做。它可以在启用和禁用双向 TLS 的情况下工作。更多详细信息,请参阅双向 TLS 如何与 HTTPS 服务配合使用