Mulai versi 1.23, Kubernetes tidak lagi mendukung validasi identitas server menggunakan kolom Common Name (CN) X.509 dalam sertifikat. Sebagai gantinya, Kubernetes hanya akan mengandalkan informasi di kolom X.509 Subject Alternative Name (SAN).
Untuk mencegah dampak pada cluster, Anda harus mengganti sertifikat yang tidak kompatibel dan tidak memiliki SAN untuk backend webhook dan server API gabungan sebelum mengupgrade cluster ke Kubernetes versi 1.23.
Alasan Kubernetes tidak lagi mendukung sertifikat backend tanpa SAN
GKE mengoperasikan Kubernetes open source, yang menggunakan komponen kube-apiserver untuk menghubungi webhook dan backend server API gabungan menggunakan Transport Layer Security (TLS). Komponen kube-apiserver ditulis dalam bahasa pemrograman Go.
Sebelum Go 1.15, klien TLS memvalidasi identitas server yang dihubungkan menggunakan proses dua langkah:
- Memeriksa apakah nama DNS (atau alamat IP) server ada sebagai salah satu SAN pada sertifikat server.
- Jika pemeriksaan tersebut gagal, klien TLS akan memeriksa apakah nama DNS (atau alamat IP) server sama dengan CN pada sertifikat server.
RFC 6125 sepenuhnya menghentikan penggunaan validasi identitas server menggunakan kolom CN pada tahun 2011. Browser dan aplikasi lain yang penting bagi keamanan tidak lagi menggunakan kolom ini.
Agar selaras dengan ekosistem TLS yang lebih luas,
Go 1.15 menghapus Langkah 2
dari proses validasinya, tetapi membiarkan tombol debug (x509ignoreCN=0
) untuk
mengaktifkan perilaku lama guna memudahkan proses migrasi. Kubernetes versi 1.19 adalah versi pertama yang dibangun menggunakan Go 1.15. Cluster GKE pada
versi dari 1.19 hingga 1.22 mengaktifkan tombol debug secara default untuk memberi
pelanggan lebih banyak waktu guna mengganti sertifikat untuk webhook dan backend server API gabungan yang terpengaruh.
Kubernetes versi 1.23 dibangun dengan Go 1.17, yang menghapus tombol debug. Setelah GKE mengupgrade cluster Anda ke versi 1.23, panggilan dari panel kontrol cluster ke webhook atau layanan API gabungan yang tidak memberikan sertifikat X.509 yang valid dengan SAN yang sesuai akan gagal terhubung.
Mengidentifikasi cluster yang terpengaruh
Untuk cluster yang menjalankan versi patch minimal 1.21.9 atau 1.22.3
Untuk cluster pada versi patch 1.21.9 dan 1.22.3 atau yang lebih baru dengan Cloud Logging diaktifkan, GKE menyediakan log Cloud Audit Logs untuk mengidentifikasi panggilan ke backend yang terpengaruh dari cluster Anda. Anda dapat menggunakan filter berikut untuk menelusuri log:
logName =~ "projects/.*/logs/cloudaudit.googleapis.com%2Factivity"
resource.type = "k8s_cluster"
operation.producer = "k8s.io"
"invalid-cert.webhook.gke.io"
Jika cluster Anda belum memanggil backend dengan sertifikat yang terpengaruh, Anda tidak akan melihat log apa pun. Jika Anda melihat log audit seperti itu, log tersebut akan menyertakan nama host dari backend yang terpengaruh.
Berikut adalah contoh entri log, untuk backend webhook yang dihosting oleh layanan bernama example-webhook di namespace default:
{
...
resource {
type: "k8s_cluster",
"labels": {
"location": "us-central1-c",
"cluster_name": "example-cluster",
"project_id": "example-project"
}
},
labels: {
invalid-cert.webhook.gke.io/example-webhook.default.svc: "No subjectAltNames returned from example-webhook.default.svc:8443",
...
},
logName: "projects/example-project/logs/cloudaudit.googleapis.com%2Factivity",
operation: {
...
producer: "k8s.io",
...
},
...
}
Nama host layanan yang terpengaruh (misalnya, example-webhook.default.svc
)
disertakan sebagai akhiran dalam nama label yang diawali dengan
invalid-cert.webhook.gke.io/
. Anda juga bisa mendapatkan nama cluster yang
melakukan panggilan dari label resource.labels.cluster_name
, yang memiliki
nilai example-cluster
dalam contoh ini.
Insight penghentian penggunaan
Anda dapat mengetahui cluster mana yang menggunakan sertifikat yang tidak kompatibel dengan melihat insight penghentian penggunaan. Insight tersedia untuk cluster yang menjalankan versi 1.22.6-gke.1000 atau yang lebih baru.
Versi cluster lainnya
Jika Anda memiliki cluster pada versi patch yang lebih lama dari 1.22.3 pada versi minor 1.22, atau versi patch yang lebih lama dari 1.21.9, Anda memiliki dua opsi untuk menentukan apakah cluster Anda terpengaruh oleh penghentian penggunaan ini:
Opsi 1 (direkomendasikan): Upgrade cluster Anda ke versi patch yang mendukung identifikasi sertifikat yang terpengaruh dengan log. Pastikan Cloud Logging diaktifkan untuk cluster Anda. Setelah cluster Anda diupgrade, log Cloud Audit Logs yang mengidentifikasi akan dihasilkan setiap kali cluster mencoba memanggil Layanan yang tidak menyediakan sertifikat dengan SAN yang sesuai. Karena log hanya akan dibuat pada saat ada upaya panggilan, sebaiknya tunggu selama 30 hari setelah upgrade untuk memberi waktu yang cukup agar semua jalur panggilan dipanggil.
Sebaiknya gunakan log untuk mengidentifikasi layanan yang terpengaruh karena pendekatan ini meminimalkan upaya manual dengan otomatis membuat log guna menampilkan layanan yang terpengaruh.
Opsi 2: Periksa sertifikat yang digunakan oleh Webhook atau Server API Agregat di cluster Anda untuk menentukan apakah sertifikat tersebut terpengaruh karena tidak memiliki SAN:
- Dapatkan daftar Webhook dan Server API Agregat di cluster Anda, lalu identifikasi backend-nya (Layanan atau URL).
- Periksa sertifikat yang digunakan oleh layanan backend.
Mengingat upaya manual yang diperlukan untuk memeriksa semua sertifikat dengan cara ini, metode ini hanya boleh dilakukan jika Anda perlu menilai dampak penghentian penggunaan di Kubernetes versi 1.23 sebelum mengupgrade cluster ke versi 1.21. Jika dapat mengupgrade cluster ke 1.21, Anda harus mengupgradenya terlebih dahulu, lalu mengikuti petunjuk di Opsi 1 untuk menghindari upaya manual.
Mengidentifikasi layanan backend yang akan diperiksa
Untuk mengidentifikasi backend yang mungkin terpengaruh oleh penghentian penggunaan, dapatkan daftar Webhook dan Layanan API Gabungan serta backend terkaitnya di cluster.
Untuk menampilkan daftar semua webhook yang relevan di cluster, gunakan perintah kubectl
berikut:
kubectl get mutatingwebhookconfigurations -A # mutating admission webhooks
kubectl get validatingwebhookconfigurations -A # validating admission webhooks
Anda bisa mendapatkan Layanan atau URL backend terkait untuk Webhook tertentu dengan memeriksa kolom clientConfig.service
atau kolom webhooks.clientConfig.url
di konfigurasi Webhook:
kubectl get mutatingwebhookconfigurations example-webhook -o yaml
Output perintah ini akan mirip dengan berikut ini:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
webhooks:
- admissionReviewVersions:
clientConfig:
service:
name: example-service
namespace: default
port: 443
Perlu diperhatikan bahwa clientConfig dapat menentukan backend-nya sebagai URL (clientConfig.url
), atau sebagai Layanan (clientConfig.service
) Kubernetes.
Untuk menampilkan daftar semua Layanan API Gabungan yang relevan di cluster, gunakan perintah
kubectl
berikut:
kubectl get apiservices -A |grep -v Local # aggregated API services
Output perintah ini akan mirip dengan berikut ini:
NAME SERVICE AVAILABLE AGE
v1beta1.metrics.k8s.io kube-system/metrics-server True 237d
Contoh ini menampilkan Layanan metric-server
dari namespace kube-system
.
Anda bisa mendapatkan Layanan terkait untuk API Gabungan tertentu dengan memeriksa kolom spec.service
:
kubectl get apiservices v1beta1.metrics.k8s.io -o yaml
Output perintah ini akan mirip dengan berikut ini:
...
apiVersion: apiregistration.k8s.io/v1
kind: APIService
spec:
service:
name: metrics-server
namespace: kube-system
port: 443
Memeriksa sertifikat Layanan
Setelah mengidentifikasi Layanan backend
yang relevan untuk diperiksa, Anda dapat memeriksa sertifikat setiap Layanan tertentu,
seperti example-service
:
Temukan pemilih dan port target layanan:
kubectl describe service example-service
Output perintah ini akan mirip dengan berikut ini:
Name: example-service Namespace: default Labels: run=nginx Selector: run=nginx Type: ClusterIP IP: 172.21.xxx.xxx Port: 443 TargetPort: 444
Dalam contoh ini,
example-service
memiliki pemilihrun=nginx
dan target port444
.Temukan pod yang cocok dengan pemilih:
kubectl get pods --selector=run=nginx
Output perintah ini akan mirip dengan berikut ini:
NAME READY STATUS RESTARTS AGE example-pod 1/1 Running 0 21m
Siapkan penerusan port
dari localhost
kubectl
ke pod.kubectl port-forward pods/example-pod LOCALHOST_PORT:TARGET_PORT # port forwarding in background
Ganti kode berikut dalam perintah:
LOCALHOST_PORT
: alamat yang akan diproses.TARGET_PORT
TargetPort
dari Langkah 1.
Gunakan
openssl
untuk mencetak sertifikat yang digunakan oleh Layanan:openssl s_client -connect localhost:LOCALHOST_PORT </dev/null | openssl x509 -noout -text
Contoh output ini menunjukkan sertifikat yang valid (dengan entri SAN):
Subject: CN = example-service.default.svc X509v3 extensions: X509v3 Subject Alternative Name: DNS:example-service.default.svc
Contoh output ini menunjukkan sertifikat dengan SAN yang tidak ada:
Subject: CN = example-service.default.svc X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Authority Key Identifier: keyid:1A:5F:29:D8:E9:3C:54:3C:35:CC:D8:AB:D1:21:FD:C3:56:25:C0:74
Hapus penerusan port agar tidak berjalan di latar belakang dengan perintah berikut:
$ jobs [1]+ Running kubectl port-forward pods/example-pod 8888:444 & $ kill %1 [1]+ Terminated kubectl port-forward pods/example 8888:444
Memeriksa sertifikat backend URL
Jika webhook menggunakan backend url
, langsung hubungkan ke nama host yang ditentukan dalam URL. Misalnya, jika URL-nya adalah https://example.com:123/foo/bar
, gunakan perintah openssl
berikut untuk mencetak sertifikat yang digunakan oleh backend:
openssl s_client -connect example.com:123 </dev/null | openssl x509 -noout -text
Memitigasi risiko upgrade 1.23
Setelah mengidentifikasi cluster yang terpengaruh dan layanan backend-nya yang menggunakan sertifikat tanpa SAN, Anda harus memperbarui webhook dan backend server API gabungan agar menggunakan sertifikat dengan SAN yang sesuai sebelum mengupgrade cluster ke versi 1.23.
GKE tidak akan otomatis mengupgrade cluster pada versi 1.22.6-gke.1000 atau yang lebih baru dengan backend yang menggunakan sertifikat yang tidak kompatibel sampai Anda mengganti sertifikat tersebut atau sampai versi 1.22 mencapai akhir dukungan standar.
Jika cluster Anda menggunakan versi GKE yang lebih lama dari 1.22.6-gke.1000, Anda dapat mencegah upgrade otomatis untuk sementara dengan mengonfigurasi pengecualian pemeliharaan guna mencegah upgrade minor.
Resource
Silakan melihat referensi berikut untuk mengetahui informasi tambahan tentang perubahan ini:
- Catatan rilis Kubernetes 1.23
- Kubernetes dibangun menggunakan Go 1.17. Versi Go ini menghapus
kemampuan untuk menggunakan setelan lingkungan
GODEBUG=x509ignoreCN=0
. Setelan ini memungkinkan untuk mengaktifkan kembali perilaku lama yang tidak digunakan lagi, yaitu memperlakukan CN X.509 yang menayangkan sertifikat sebagai nama host.
- Kubernetes dibangun menggunakan Go 1.17. Versi Go ini menghapus
kemampuan untuk menggunakan setelan lingkungan
- Catatan rilis Kubernetes 1.19
dan
Kubernetes 1.20
- Perilaku lama yang tidak digunakan lagi, yaitu memperlakukan kolom CN pada X.509 yang menayangkan sertifikat sebagai nama host jika tidak ada SAN, kini dinonaktifkan secara default.
- Catatan rilis Go 1.17
- Flag
GODEBUG=x509ignoreCN=0
sementara kini telah dihapus.
- Flag
- Catatan rilis Go 1.15
- Perilaku lama yang tidak digunakan lagi, yaitu memperlakukan kolom CN pada sertifikat X.509 sebagai host jika tidak ada SAN, kini dinonaktifkan secara default.
- RFC 6125
(halaman 46)
- Meskipun penggunaan nilai CN adalah praktik yang sudah ada, nilai tersebut tidak digunakan lagi, dan sebagai gantinya Certificate Authority sebaiknya memberikan nilai
subjectAltName
.
- Meskipun penggunaan nilai CN adalah praktik yang sudah ada, nilai tersebut tidak digunakan lagi, dan sebagai gantinya Certificate Authority sebaiknya memberikan nilai
- Webhook akses