mtls-configuration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesemTLS 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 certsRoot CA (Self-signed, long-lived)
│
├── Intermediate CA (Cluster-level)
│ │
│ ├── Workload Cert (Service A)
│ └── Workload Cert (Service B)
│
└── Intermediate CA (Multi-cluster)
│
└── Cross-cluster certsTemplates
配置模板
Template 1: Istio mTLS (Strict Mode)
模板1:Istio mTLS(严格模式)
yaml
undefinedyaml
undefinedEnable 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
undefinedapiVersion: 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
undefinedTemplate 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
undefinedapiVersion: 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
undefinedTemplate 3: Cert-Manager with Istio
模板3:Cert-Manager 与 Istio 集成
yaml
undefinedyaml
undefinedInstall 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
undefinedapiVersion: 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
undefinedTemplate 4: SPIFFE/SPIRE Integration
模板4:SPIFFE/SPIRE 集成
yaml
undefinedyaml
undefinedSPIRE 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
undefinedapiVersion: 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
undefinedTemplate 5: Linkerd mTLS (Automatic)
模板5:Linkerd mTLS(自动模式)
yaml
undefinedyaml
undefinedLinkerd 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
undefinedapiVersion: v1
kind: Service
metadata:
name: my-service
annotations:
config.linkerd.io/skip-outbound-ports: "3306" # MySQL
undefinedCertificate Rotation
证书轮换
bash
undefinedbash
undefinedIstio - 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
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
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
undefinedlinkerd identity -n my-namespace
undefinedDebugging mTLS Issues
mTLS 问题排查
bash
undefinedbash
undefinedIstio - 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
undefinedlinkerd viz edges deployment -n my-namespace
linkerd viz tap deploy/my-app --to deploy/my-backend
undefinedBest 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 - 不要为了方便而关闭
- 不要忽略证书过期 - 自动化证书轮换
- 不要使用自签名证书 - 使用正规的证书层级结构
- 不要跳过证书验证 - 验证完整的证书链