Cilium Service Mesh セキュリティ
サポート対象バージョン: Cilium 1.16+, Kubernetes 1.28+ 最終更新: July 13, 2026
概要
Cilium Service Mesh は、eBPF と SPIFFE に基づく堅牢なセキュリティ機能を提供します。透過的な mTLS、Identity ベースの Network Policy、WireGuard 暗号化により、ゼロトラストネットワーキングを実装できます。この章では、Cilium Service Mesh のセキュリティアーキテクチャと設定方法について詳しく説明します。
セキュリティアーキテクチャ
透過的 mTLS
Sidecar なしの mTLS
Cilium Service Mesh は、Sidecar proxy を使用せずに透過的な mTLS を提供します。
ztunnel によるネイティブ mTLS(2026 年アップデート)
2026 年 3 月、Cilium は Istio Ambient の ztunnel モデルに着想を得た新しい mTLS アーキテクチャを導入しました。これは、上記の純粋な eBPF ハンドシェイクから進化したものです。このスタックは、連携する次の 3 つのコンポーネントで構成されます。
- SPIRE — Workload Identity と X.509 証明書を発行します(以下の SPIRE ベース設定と同じ役割)。
- Cilium — outbound Pod traffic をポート 15001 の ztunnel へ透過的にリダイレクトする iptables ルールをインストールします。
- ztunnel — 実際の mTLS ハンドシェイクを実行し、Pod 間トラフィックを暗号化する、Node ごとの proxy です(Pod ごとの Sidecar ではありません)。
これにより、「Sidecar なし、アプリケーションの変更なし」という同じ保証を維持しながら、TLS ハンドシェイクは純粋に eBPF 内で実行されるのではなく、専用の Node ごとのプロセスで実行されるようになります。この設計は Cilium が Istio Ambient の ztunnel から直接採用したものです。2026 年 3 月時点で、これは Azure Kubernetes Service 上のパブリックプレビューとして利用できます(AKS 向けの「Cilium mTLS encryption」)。相互認証は引き続き Cilium 管理下の cluster 内でのみ機能し、外部 mTLS ソリューションとは互換性がありません。
完全なアーキテクチャの説明については、ネイティブ mTLS に関する Cilium ブログ記事を参照してください。
SPIRE ベースの mTLS 設定
# values.yaml - SPIRE integration configuration
authentication:
mutual:
spire:
enabled: true
install:
enabled: true
namespace: cilium-spire
server:
# SPIRE Server configuration
replicas: 1
dataStorage:
enabled: true
size: 1Gi
storageClass: gp3
# Trust Domain configuration
trustDomain: cluster.local
# CA configuration
ca:
# Use internal CA
keyType: ec-p256
ttl: 24h
# Node Attestor configuration
nodeAttestor:
k8sPsat:
enabled: true
agent:
# SPIRE Agent configuration
socketPath: /run/spire/sockets/agent.sock
# Workload Attestor configuration
workloadAttestor:
k8s:
enabled: true
disableContainerSelectors: falsemTLS Policy の強制
# Enable mTLS for entire cluster
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: enforce-mtls
spec:
endpointSelector: {}
authentication:
- mode: requiredNamespace ごとの mTLS 設定
# Apply mTLS to specific namespace only
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: namespace-mtls
namespace: production
spec:
endpointSelector: {}
ingress:
- fromEndpoints:
- {}
authentication:
- mode: required
egress:
- toEndpoints:
- {}
authentication:
- mode: requiredService ごとの mTLS 設定
# Enforce mTLS between specific services
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: service-mtls
namespace: default
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
authentication:
- mode: required
toPorts:
- ports:
- port: "8080"
protocol: TCPCiliumNetworkPolicy L7 ルール
HTTP L7 セキュリティ Policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: http-security-policy
namespace: default
spec:
endpointSelector:
matchLabels:
app: api-server
ingress:
# Read-only access
- fromEndpoints:
- matchLabels:
role: reader
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/api/.*"
# Admin access
- fromEndpoints:
- matchLabels:
role: admin
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: ".*"
path: "/api/.*"
headers:
- "Authorization: Bearer .*"
# Health checks
- fromEndpoints:
- matchLabels:
app: monitoring
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/health"
- method: GET
path: "/metrics"Kafka L7 セキュリティ Policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: kafka-security
namespace: kafka
spec:
endpointSelector:
matchLabels:
app: kafka
ingress:
# Producer - allow writing to specific topics only
- fromEndpoints:
- matchLabels:
role: producer
toPorts:
- ports:
- port: "9092"
protocol: TCP
rules:
kafka:
- apiKey: produce
topic: "orders"
- apiKey: produce
topic: "events"
- apiKey: metadata
# Consumer - allow reading from specific topics only
- fromEndpoints:
- matchLabels:
role: consumer
toPorts:
- ports:
- port: "9092"
protocol: TCP
rules:
kafka:
- apiKey: fetch
topic: "orders"
- apiKey: fetch
topic: "events"
- apiKey: listoffsets
topic: "orders"
- apiKey: listoffsets
topic: "events"
- apiKey: metadata
- apiKey: findcoordinator
- apiKey: joingroup
- apiKey: heartbeat
- apiKey: leavegroup
- apiKey: syncgroup
- apiKey: offsetcommit
topic: "orders"
- apiKey: offsetfetch
topic: "orders"DNS L7 セキュリティ Policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: dns-security
namespace: default
spec:
endpointSelector:
matchLabels:
app: web-application
egress:
# Restrict DNS queries
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
rules:
dns:
# Allow internal services only
- matchPattern: "*.svc.cluster.local"
# Allow specific external domains only
- matchName: "api.stripe.com"
- matchName: "api.aws.amazon.com"
- matchPattern: "*.s3.amazonaws.com"
# Egress to allowed external services
- toFQDNs:
- matchName: "api.stripe.com"
- matchName: "api.aws.amazon.com"
- matchPattern: "*.s3.amazonaws.com"
toPorts:
- ports:
- port: "443"
protocol: TCP相互認証
認証モード
# Cilium authentication mode options
# 1. disabled - no authentication (default)
authentication:
- mode: disabled
# 2. optional - use authentication if possible, otherwise allow
authentication:
- mode: optional
# 3. required - authentication required
authentication:
- mode: required
# 4. test-always-fail - for testing (always fails)
authentication:
- mode: test-always-fail相互認証 Policy の例
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: mutual-auth-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: secure-service
ingress:
# Allow authenticated clients only
- fromEndpoints:
- matchLabels:
app: trusted-client
authentication:
- mode: required
toPorts:
- ports:
- port: "443"
protocol: TCP
# Optional authentication for monitoring
- fromEndpoints:
- matchLabels:
app: prometheus
authentication:
- mode: optional
toPorts:
- ports:
- port: "9090"
protocol: TCPSPIFFE ID ベースの認証
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: spiffe-auth
namespace: default
spec:
endpointSelector:
matchLabels:
app: database
ingress:
# Allow specific SPIFFE ID only
- fromEndpoints:
- matchLabels:
app: backend
authentication:
- mode: required
# SPIFFE ID verification is performed automatically
# spiffe://cluster.local/ns/default/sa/backend暗号化
WireGuard 透過的暗号化
WireGuard は、Linux kernel レベルですべての Pod 間トラフィックを暗号化します。
# values.yaml - Enable WireGuard
encryption:
enabled: true
type: wireguard
wireguard:
# Userspace fallback (when kernel support unavailable)
userspaceFallback: true
# Node-to-node encryption
nodeEncryption: true# Check WireGuard status
cilium status | grep Encryption
# Expected output
Encryption: Wireguard [NodeEncryption: Enabled, cilium_wg0 (Pubkey: xxx, Port: 51871, Peers: 2)]
# Check WireGuard peers
cilium encrypt status
# Expected output
Encryption: Wireguard
Keys in use: 1
Max Seq. Number: 0x0
Errors: 0WireGuard アーキテクチャ
IPsec 暗号化
# values.yaml - Enable IPsec
encryption:
enabled: true
type: ipsec
ipsec:
# IPsec interface
interface: ""
# Key rotation interval
keyRotationDuration: "5m"
# Encryption interface
mountPath: /etc/ipsec
# Generate IPsec key
# kubectl create secret generic -n kube-system cilium-ipsec-keys \
# --from-literal=keys="3 rfc4106(gcm(aes)) $(openssl rand -hex 20) 128"暗号化の比較
| 機能 | WireGuard | IPsec |
|---|---|---|
| パフォーマンス | 非常に高い | 高い |
| 設定の複雑さ | 低い | 中程度 |
| Kernel サポート | 5.6+(組み込み) | すべてのバージョン |
| 暗号化アルゴリズム | ChaCha20Poly1305 | AES-GCM など |
| Key 管理 | 自動 | 手動/自動 |
| 標準 | 非標準 | IETF 標準 |
Identity ベースのセキュリティ
Cilium Identity
Cilium は IP ではなく Identity に基づいてセキュリティ Policy を適用します。
Identity コンポーネント
# Identity label composition
# - k8s:io.kubernetes.pod.namespace
# - k8s:io.cilium.k8s.policy.serviceaccount
# - k8s:app
# - k8s:version
# - Other user-defined labels
# List identities
cilium identity list
# Example output
IDENTITY LABELS
1 reserved:host
2 reserved:world
3 reserved:unmanaged
4 reserved:health
5 reserved:init
6 reserved:remote-node
12345 k8s:app=frontend,k8s:io.kubernetes.pod.namespace=default
12346 k8s:app=backend,k8s:io.kubernetes.pod.namespace=defaultIdentity ベースの Policy
# Identity-based network policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: identity-based-policy
namespace: default
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
# Allow only Pods with specific labels (Identity)
- fromEndpoints:
- matchLabels:
app: frontend
environment: production
toPorts:
- ports:
- port: "8080"
# Allow specific service from another namespace
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: monitoring
app: prometheus
toPorts:
- ports:
- port: "9090"IP と Identity の比較
外部 PKI 統合
cert-manager 統合
# Certificate management with cert-manager
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: cilium-ca-issuer
spec:
ca:
secretName: cilium-ca-secret
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cilium-spire-ca
namespace: cilium-spire
spec:
secretName: spire-ca-secret
duration: 8760h # 1 year
renewBefore: 720h # Renew 30 days before expiry
isCA: true
privateKey:
algorithm: ECDSA
size: 256
subject:
organizations:
- Cilium
commonName: SPIRE CA
issuerRef:
name: cilium-ca-issuer
kind: ClusterIssuerVault 統合
# Use Vault as CA in SPIRE
apiVersion: v1
kind: ConfigMap
metadata:
name: spire-server-config
namespace: cilium-spire
data:
server.conf: |
server {
trust_domain = "cluster.local"
ca_subject = {
country = ["US"]
organization = ["MyOrg"]
common_name = ""
}
# Vault UpstreamAuthority
UpstreamAuthority "vault" {
plugin_data {
vault_addr = "https://vault.vault.svc:8200"
pki_mount_path = "pki"
ca_cert_path = "/vault/ca/ca.crt"
token_path = "/vault/token/token"
}
}
}ゼロトラストネットワーキング
デフォルト拒否 Policy
# Cluster-wide default deny
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: default-deny
spec:
endpointSelector: {}
ingress:
- fromEndpoints:
- matchLabels:
reserved:host: ""
egress:
- toEndpoints:
- matchLabels:
reserved:host: ""
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP最小権限アクセス
# Production namespace security policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: production-security
namespace: production
spec:
# Apply to all Pods
endpointSelector: {}
# Default deny
ingressDeny:
- fromEntities:
- world
# Allow rules
ingress:
# Allow communication within same namespace
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: production
authentication:
- mode: required
# Allow access from Ingress Controller
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: ingress-nginx
app: nginx-ingress
toPorts:
- ports:
- port: "8080"
egress:
# DNS
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
# Communication within same namespace
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: production
authentication:
- mode: requiredマイクロセグメンテーション
# 3-tier architecture security
---
# Frontend policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: frontend-policy
namespace: app
spec:
endpointSelector:
matchLabels:
tier: frontend
ingress:
- fromEntities:
- world
toPorts:
- ports:
- port: "443"
egress:
- toEndpoints:
- matchLabels:
tier: backend
toPorts:
- ports:
- port: "8080"
---
# Backend policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: backend-policy
namespace: app
spec:
endpointSelector:
matchLabels:
tier: backend
ingress:
- fromEndpoints:
- matchLabels:
tier: frontend
toPorts:
- ports:
- port: "8080"
authentication:
- mode: required
egress:
- toEndpoints:
- matchLabels:
tier: database
toPorts:
- ports:
- port: "5432"
authentication:
- mode: required
---
# Database policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: database-policy
namespace: app
spec:
endpointSelector:
matchLabels:
tier: database
ingress:
- fromEndpoints:
- matchLabels:
tier: backend
toPorts:
- ports:
- port: "5432"
authentication:
- mode: required
# No external egress (data exfiltration prevention)
egressDeny:
- toEntities:
- worldセキュリティ監査とモニタリング
Policy 監査モード
# Test policy in audit mode
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: audit-policy
namespace: default
annotations:
# Audit mode - logging only, no blocking
cilium.io/audit-mode: "true"
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"Policy 違反のモニタリング
# Observe policy violations with Hubble
hubble observe --verdict DROPPED
# Dropped traffic in specific namespace
hubble observe --namespace production --verdict DROPPED
# Policy violation statistics
hubble observe --verdict DROPPED -o json | jq -r '.flow | "\(.source.namespace)/\(.source.pod_name) -> \(.destination.namespace)/\(.destination.pod_name)"' | sort | uniq -c | sort -rnPrometheus メトリクス
# Collect security-related metrics
hubble:
metrics:
enabled:
- dns
- drop
- flow
- http
- icmp
- port-distribution
- tcp
# Useful metrics
# - cilium_drop_count_total: Packets dropped by policy
# - cilium_policy_verdict: Policy decisions (allow/deny)
# - cilium_forward_count_total: Forwarded packets次のステップ
- オブザーバビリティ: Hubble によるセキュリティモニタリング
- Ingress と Gateway: 外部トラフィックのセキュリティ
- ベストプラクティス: 本番環境向けセキュリティ設定