安全常见问题

在 Istio 安装完成之后,我应该如何开启/关闭双向 TLS?

您可以随时使用认证策略目标规则来为您的服务设置双向 TLS 认证。请参阅任务以获取更多细节。

在同一集群中,我可以为部分服务开启 TLS 双向认证,并为其它服务关闭 TLS 双向认证吗?

认证策略可以配置为 mesh-wide(影响网络中的所有服务)、namespace-wide(namespace 中的所有服务)或某个特定服务。 您可以根据需要对集群中的服务配置一种或多种 TLS 双向认证策略。

如何验证流量是否使用双向 TLS 加密?

如果您使用 values.global.proxy.privileged=true 安装 Istio,您可以使用 tcpdump 来确定加密状态。有关说明,请参见 Istio 双向 TLS 迁移

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

非 Istio 服务无法与 Istio 服务通信。除非它能出示有效证书,但这基本不可能。 这是 双向 TLS 认证 的预期表现。 但是,您可以为特定的 namespace 或服务重写全局标志。详见:任务

如何让 Istio 服务访问非 Istio 服务?

当启用了全局双向 TLS,全局 目标规则会匹配集群中的所有服务,无论这些服务是否具有 Istio sidecar。 包括 Kubernetes API 服务器,以及群集中所有的非 Istio 服务。 想要通过具有 Istio sidecar 的服务访问这些非 Istio 服务,你需要设置目标规则,以豁免该服务。例如:

$ 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.1 开始,我们提供了多种解决方案。

  1. 使用 probe rewrite 将 liveness 和 readiness 的请求直接重定向到工作负载。有关更多信息,请参阅 Probe Rewrite

  2. 使用单独的端口进行健康检查,并且仅在常规服务端口上启用双向 TLS。有关更多信息,请参阅 Istio 服务的运行状况检查

  3. 如果对 Istio 服务使用 PERMISSIVE 模式,那么他们可以接受 HTTP 和双向 TLS 流量。请记住,由于其他人可以通过 HTTP 流量与该服务进行通信,因此不强制执行双向 TLS。

  4. 健康检查使用 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
How to configure the lifetime for Istio certificates?

For the workloads running in Kubernetes, the lifetime of their Istio certificates is controlled by the workload-cert-ttl flag on Citadel. The default value is 90 days. This value should be no greater than max-workload-cert-ttl of Citadel.

Citadel uses a flag max-workload-cert-ttl to control the maximum lifetime for Istio certificates issued to workloads. The default value is 90 days. If workload-cert-ttl on Citadel or node agent is greater than max-workload-cert-ttl, Citadel will fail issuing the certificate.

Modify the istio-demo.yaml file to customize the Citadel configuration. The following modification specifies that the Istio certificates for workloads running in Kubernetes has 1 hours lifetime. Besides that, the maximum allowed Istio certificate lifetime is 48 hours.

...
kind: Deployment
...
metadata:
  name: istio-citadel
  namespace: istio-system
spec:
  ...
  template:
    ...
    spec:
      ...
      containers:
      - name: citadel
        ...
        args:
          - --workload-cert-ttl=1h # Lifetime of certificates issued to workloads in Kubernetes.
          - --max-workload-cert-ttl=48h # Maximum lifetime of certificates issued to workloads by Citadel.

For the workloads running on VMs and bare metal hosts, the lifetime of their Istio certificates is specified by the workload-cert-ttl flag on each node agent. The default value is also 90 days. This value should be no greater than max-workload-cert-ttl of Citadel.

To customize this configuration, the argument for the node agent service should be modified. After setting up the machines for Istio mesh expansion, modify the file /lib/systemd/system/istio-auth-node-agent.service on the VMs or bare metal hosts:

...
[Service]
ExecStart=/usr/local/bin/node_agent --workload-cert-ttl=24h # Specify certificate lifetime for workloads on this machine.
Restart=always
StartLimitInterval=0
RestartSec=10
...

The above configuration specifies that the Istio certificates for workloads running on this VM or bare metal host will have 24 hours lifetime.

After configuring the service, restart the node agent by running systemctl daemon-reload.

MySQL 连接故障排除

安装 Istio 后您可能会发现 MySQL 无法连接。这是因为 istio-demo.yaml 中默认使用的 PERMISSIVE 模式不适用于 MySQL。您可能会看到类似于 “ERROR 2013 (HY000) : Lost connection to MySQL server at ‘reading initial communication packet’, system error: 0” 的错误。

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

  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: YOUR-MYSQL-SERVICE     # The name of *your* K8s Service
    EOF
    
  2. 在 STRICT 模式下启用双向 TLS。

    如果您需要为 MySQL 提供双向 TLS 保护,请使用目标规则和认证策略来启用双向 TLS。

    $ kubectl apply -f - <<EOF
    apiVersion: "authentication.istio.io/v1alpha1"
    kind: "Policy"
    metadata:
      name: mysql-mtls-authn
    spec:
      targets:
      - name: YOUR-MYSQL-SERVICE     # The name of *your* K8s Service
      peers:
      - mtls:
          mode: STRICT
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: mysql-mtls-dr
    spec:
      host: YOUR-MYSQL-SERVICE     # The name of *your* K8s Service
      trafficPolicy:
        tls:
          mode: ISTIO_MUTUAL
    EOF
    
Istio 是否支持授权?

支持。Istio 对网格中的 HTTP 服务和普通 TCP 服务提供授权特性支持了解更多

Istio 认证是使用的 Kubernetes secret 吗?

是的,Istio 认证的密钥和证书分发基于 Kubernetes secret 实现。

Secret 安全风险需知。 Kubernetes 团队正在研究多种特性,以从 secret 加密到节点级访问控制,全面增强 Kubernetes secret 的安全性。 从 1.6 版本开始,Kubernetes 引入了 RBAC 认证,可以提供细粒度的 secret 管理。

是否为工作负载中的密钥和证书进行了加密?

默认情况下,它们是 base64 编码的,但未加密。但是,您可以按照 Kubernetes 中支持的加密特性来进行操作。

请注意,在 Google Container Engine (GKE) 中尚未启用此功能。尽管可能不会在主节点上运行的 etcd 内部对数据进行加密,但主节点本身的内容将被加密,更多相关信息,请参照此处

Istio 中如何配置 Ingress 使其仅处理 TLS 连接?

依照安全的网关(基于文件挂载的方式) 任务中的描述进行配置,能够让 Istio Ingress 只处理 TLS 连接。

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

可以,并且启用或禁用双向 TLS 都可以。