mtls-configuration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

mTLS Configuration

mTLS 配置

Comprehensive guide to implementing mutual TLS for zero-trust service mesh communication.
为零信任服务网格通信实施双向TLS的综合指南。

When to Use This Skill

何时使用此技能

  • Implementing zero-trust networking
  • Securing service-to-service communication
  • Certificate rotation and management
  • Debugging TLS handshake issues
  • Compliance requirements (PCI-DSS, HIPAA)
  • Multi-cluster secure communication
  • 实施零信任网络
  • 保护服务间通信
  • 证书轮换与管理
  • 排查TLS握手问题
  • 合规要求(PCI-DSS、HIPAA)
  • 多集群安全通信

Core Concepts

核心概念

1. mTLS Flow

1. mTLS 流程

┌─────────┐                              ┌─────────┐
│ Service │                              │ Service │
│    A    │                              │    B    │
└────┬────┘                              └────┬────┘
     │                                        │
┌────┴────┐      TLS Handshake          ┌────┴────┐
│  Proxy  │◄───────────────────────────►│  Proxy  │
│(Sidecar)│  1. ClientHello             │(Sidecar)│
│         │  2. ServerHello + Cert      │         │
│         │  3. Client Cert             │         │
│         │  4. Verify Both Certs       │         │
│         │  5. Encrypted Channel       │         │
└─────────┘                              └─────────┘
┌─────────┐                              ┌─────────┐
│ Service │                              │ Service │
│    A    │                              │    B    │
└────┬────┘                              └────┬────┘
     │                                        │
┌────┴────┐      TLS Handshake          ┌────┴────┐
│  Proxy  │◄───────────────────────────►│  Proxy  │
│(Sidecar)│  1. ClientHello             │(Sidecar)│
│         │  2. ServerHello + Cert      │         │
│         │  3. Client Cert             │         │
│         │  4. Verify Both Certs       │         │
│         │  5. Encrypted Channel       │         │
└─────────┘                              └─────────┘

2. Certificate Hierarchy

2. 证书层级结构

Root CA (Self-signed, long-lived)
    ├── Intermediate CA (Cluster-level)
    │       │
    │       ├── Workload Cert (Service A)
    │       └── Workload Cert (Service B)
    └── Intermediate CA (Multi-cluster)
            └── Cross-cluster certs
Root CA (Self-signed, long-lived)
    ├── Intermediate CA (Cluster-level)
    │       │
    │       ├── Workload Cert (Service A)
    │       └── Workload Cert (Service B)
    └── Intermediate CA (Multi-cluster)
            └── Cross-cluster certs

Templates

配置模板

Template 1: Istio mTLS (Strict Mode)

模板1:Istio mTLS(严格模式)

yaml
undefined
yaml
undefined

Enable strict mTLS mesh-wide

Enable strict mTLS mesh-wide

apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: istio-system spec: mtls: mode: STRICT

apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: istio-system spec: mtls: mode: STRICT

Namespace-level override (permissive for migration)

Namespace-level override (permissive for migration)

apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: legacy-namespace spec: mtls: mode: PERMISSIVE

apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: legacy-namespace spec: mtls: mode: PERMISSIVE

Workload-specific policy

Workload-specific policy

apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: payment-service namespace: production spec: selector: matchLabels: app: payment-service mtls: mode: STRICT portLevelMtls: 8080: mode: STRICT 9090: mode: DISABLE # Metrics port, no mTLS
undefined
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: payment-service namespace: production spec: selector: matchLabels: app: payment-service mtls: mode: STRICT portLevelMtls: 8080: mode: STRICT 9090: mode: DISABLE # Metrics port, no mTLS
undefined

Template 2: Istio Destination Rule for mTLS

模板2:Istio 目标规则(用于mTLS)

yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: default
  namespace: istio-system
spec:
  host: "*.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
---
yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: default
  namespace: istio-system
spec:
  host: "*.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
---

TLS to external service

TLS to external service

apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: external-api spec: host: api.external.com trafficPolicy: tls: mode: SIMPLE caCertificates: /etc/certs/external-ca.pem

apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: external-api spec: host: api.external.com trafficPolicy: tls: mode: SIMPLE caCertificates: /etc/certs/external-ca.pem

Mutual TLS to external service

Mutual TLS to external service

apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: partner-api spec: host: api.partner.com trafficPolicy: tls: mode: MUTUAL clientCertificate: /etc/certs/client.pem privateKey: /etc/certs/client-key.pem caCertificates: /etc/certs/partner-ca.pem
undefined
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: partner-api spec: host: api.partner.com trafficPolicy: tls: mode: MUTUAL clientCertificate: /etc/certs/client.pem privateKey: /etc/certs/client-key.pem caCertificates: /etc/certs/partner-ca.pem
undefined

Template 3: Cert-Manager with Istio

模板3:Cert-Manager 与 Istio 集成

yaml
undefined
yaml
undefined

Install cert-manager issuer for Istio

Install cert-manager issuer for Istio

apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: istio-ca spec: ca: secretName: istio-ca-secret

apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: istio-ca spec: ca: secretName: istio-ca-secret

Create Istio CA secret

Create Istio CA secret

apiVersion: v1 kind: Secret metadata: name: istio-ca-secret namespace: cert-manager type: kubernetes.io/tls data: tls.crt: <base64-encoded-ca-cert> tls.key: <base64-encoded-ca-key>

apiVersion: v1 kind: Secret metadata: name: istio-ca-secret namespace: cert-manager type: kubernetes.io/tls data: tls.crt: <base64-encoded-ca-cert> tls.key: <base64-encoded-ca-key>

Certificate for workload

Certificate for workload

apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: my-service-cert namespace: my-namespace spec: secretName: my-service-tls duration: 24h renewBefore: 8h issuerRef: name: istio-ca kind: ClusterIssuer commonName: my-service.my-namespace.svc.cluster.local dnsNames: - my-service - my-service.my-namespace - my-service.my-namespace.svc - my-service.my-namespace.svc.cluster.local usages: - server auth - client auth
undefined
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: my-service-cert namespace: my-namespace spec: secretName: my-service-tls duration: 24h renewBefore: 8h issuerRef: name: istio-ca kind: ClusterIssuer commonName: my-service.my-namespace.svc.cluster.local dnsNames: - my-service - my-service.my-namespace - my-service.my-namespace.svc - my-service.my-namespace.svc.cluster.local usages: - server auth - client auth
undefined

Template 4: SPIFFE/SPIRE Integration

模板4:SPIFFE/SPIRE 集成

yaml
undefined
yaml
undefined

SPIRE Server configuration

SPIRE Server configuration

apiVersion: v1 kind: ConfigMap metadata: name: spire-server namespace: spire data: server.conf: | server { bind_address = "0.0.0.0" bind_port = "8081" trust_domain = "example.org" data_dir = "/run/spire/data" log_level = "INFO" ca_ttl = "168h" default_x509_svid_ttl = "1h" }
plugins {
  DataStore "sql" {
    plugin_data {
      database_type = "sqlite3"
      connection_string = "/run/spire/data/datastore.sqlite3"
    }
  }

  NodeAttestor "k8s_psat" {
    plugin_data {
      clusters = {
        "demo-cluster" = {
          service_account_allow_list = ["spire:spire-agent"]
        }
      }
    }
  }

  KeyManager "memory" {
    plugin_data {}
  }

  UpstreamAuthority "disk" {
    plugin_data {
      key_file_path = "/run/spire/secrets/bootstrap.key"
      cert_file_path = "/run/spire/secrets/bootstrap.crt"
    }
  }
}

apiVersion: v1 kind: ConfigMap metadata: name: spire-server namespace: spire data: server.conf: | server { bind_address = "0.0.0.0" bind_port = "8081" trust_domain = "example.org" data_dir = "/run/spire/data" log_level = "INFO" ca_ttl = "168h" default_x509_svid_ttl = "1h" }
plugins {
  DataStore "sql" {
    plugin_data {
      database_type = "sqlite3"
      connection_string = "/run/spire/data/datastore.sqlite3"
    }
  }

  NodeAttestor "k8s_psat" {
    plugin_data {
      clusters = {
        "demo-cluster" = {
          service_account_allow_list = ["spire:spire-agent"]
        }
      }
    }
  }

  KeyManager "memory" {
    plugin_data {}
  }

  UpstreamAuthority "disk" {
    plugin_data {
      key_file_path = "/run/spire/secrets/bootstrap.key"
      cert_file_path = "/run/spire/secrets/bootstrap.crt"
    }
  }
}

SPIRE Agent DaemonSet (abbreviated)

SPIRE Agent DaemonSet (abbreviated)

apiVersion: apps/v1 kind: DaemonSet metadata: name: spire-agent namespace: spire spec: selector: matchLabels: app: spire-agent template: spec: containers: - name: spire-agent image: ghcr.io/spiffe/spire-agent:1.8.0 volumeMounts: - name: spire-agent-socket mountPath: /run/spire/sockets volumes: - name: spire-agent-socket hostPath: path: /run/spire/sockets type: DirectoryOrCreate
undefined
apiVersion: apps/v1 kind: DaemonSet metadata: name: spire-agent namespace: spire spec: selector: matchLabels: app: spire-agent template: spec: containers: - name: spire-agent image: ghcr.io/spiffe/spire-agent:1.8.0 volumeMounts: - name: spire-agent-socket mountPath: /run/spire/sockets volumes: - name: spire-agent-socket hostPath: path: /run/spire/sockets type: DirectoryOrCreate
undefined

Template 5: Linkerd mTLS (Automatic)

模板5:Linkerd mTLS(自动模式)

yaml
undefined
yaml
undefined

Linkerd enables mTLS automatically

Linkerd enables mTLS automatically

Verify with:

Verify with:

linkerd viz edges deployment -n my-namespace

linkerd viz edges deployment -n my-namespace

For external services without mTLS

For external services without mTLS

apiVersion: policy.linkerd.io/v1beta1 kind: Server metadata: name: external-api namespace: my-namespace spec: podSelector: matchLabels: app: my-app port: external-api proxyProtocol: HTTP/1 # or TLS for passthrough

apiVersion: policy.linkerd.io/v1beta1 kind: Server metadata: name: external-api namespace: my-namespace spec: podSelector: matchLabels: app: my-app port: external-api proxyProtocol: HTTP/1 # or TLS for passthrough

Skip TLS for specific port

Skip TLS for specific port

apiVersion: v1 kind: Service metadata: name: my-service annotations: config.linkerd.io/skip-outbound-ports: "3306" # MySQL
undefined
apiVersion: v1 kind: Service metadata: name: my-service annotations: config.linkerd.io/skip-outbound-ports: "3306" # MySQL
undefined

Certificate Rotation

证书轮换

bash
undefined
bash
undefined

Istio - Check certificate expiry

Istio - Check certificate expiry

istioctl proxy-config secret deploy/my-app -o json |
jq '.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes' |
tr -d '"' | base64 -d | openssl x509 -text -noout
istioctl proxy-config secret deploy/my-app -o json |
jq '.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes' |
tr -d '"' | base64 -d | openssl x509 -text -noout

Force certificate rotation

Force certificate rotation

kubectl rollout restart deployment/my-app
kubectl rollout restart deployment/my-app

Check Linkerd identity

Check Linkerd identity

linkerd identity -n my-namespace
undefined
linkerd identity -n my-namespace
undefined

Debugging mTLS Issues

mTLS 问题排查

bash
undefined
bash
undefined

Istio - Check if mTLS is enabled

Istio - Check if mTLS is enabled

istioctl authn tls-check my-service.my-namespace.svc.cluster.local
istioctl authn tls-check my-service.my-namespace.svc.cluster.local

Verify peer authentication

Verify peer authentication

kubectl get peerauthentication --all-namespaces
kubectl get peerauthentication --all-namespaces

Check destination rules

Check destination rules

kubectl get destinationrule --all-namespaces
kubectl get destinationrule --all-namespaces

Debug TLS handshake

Debug TLS handshake

istioctl proxy-config log deploy/my-app --level debug kubectl logs deploy/my-app -c istio-proxy | grep -i tls
istioctl proxy-config log deploy/my-app --level debug kubectl logs deploy/my-app -c istio-proxy | grep -i tls

Linkerd - Check mTLS status

Linkerd - Check mTLS status

linkerd viz edges deployment -n my-namespace linkerd viz tap deploy/my-app --to deploy/my-backend
undefined
linkerd viz edges deployment -n my-namespace linkerd viz tap deploy/my-app --to deploy/my-backend
undefined

Best Practices

最佳实践

Do's

建议做法

  • Start with PERMISSIVE - Migrate gradually to STRICT
  • Monitor certificate expiry - Set up alerts
  • Use short-lived certs - 24h or less for workloads
  • Rotate CA periodically - Plan for CA rotation
  • Log TLS errors - For debugging and audit
  • 从PERMISSIVE模式开始 - 逐步迁移到STRICT模式
  • 监控证书过期时间 - 设置告警
  • 使用短期证书 - 工作负载证书有效期设为24小时或更短
  • 定期轮换CA证书 - 规划CA证书轮换流程
  • 记录TLS错误 - 用于问题排查和审计

Don'ts

避免事项

  • Don't disable mTLS - For convenience in production
  • Don't ignore cert expiry - Automate rotation
  • Don't use self-signed certs - Use proper CA hierarchy
  • Don't skip verification - Verify the full chain
  • 不要在生产环境中禁用mTLS - 不要为了方便而关闭
  • 不要忽略证书过期 - 自动化证书轮换
  • 不要使用自签名证书 - 使用正规的证书层级结构
  • 不要跳过证书验证 - 验证完整的证书链

Resources

参考资源