Dalam artikel ini saya akan berbicara tentang cara mengotomatisasi pemesanan dan pembaruan sertifikat dari Let's Encrypt (dan tidak hanya) untuk Ingress di Kubernetes menggunakan add-on cert-manager. Tapi saya akan mulai dengan pengantar singkat tentang esensi masalah.Sedikit program pendidikan
Protokol HTTP, yang dikembangkan pada awal tahun 90-an abad lalu, memasuki kehidupan kita sehari-hari dengan sangat ketat sehingga sulit membayangkan setidaknya sehari tanpa menggunakannya. Namun, dengan sendirinya, itu bahkan tidak memberikan tingkat keamanan minimum ketika bertukar informasi antara pengguna dan server web. HTTPS ("S" - secure) datang untuk menyelamatkan: menggunakan kemasan data yang dikirimkan dalam SSL / TLS, protokol ini telah membuktikan dirinya dalam melindungi informasi dari intersepsi dan secara aktif dipromosikan oleh industri.Misalnya, Google telah mematuhi 2014Posisi "HTTPS di mana-mana" dan bahkan menurunkan prioritas situs tanpa itu dalam hasil pencarian. "Propaganda" ini tidak memintas konsumen biasa: browser modern memperingatkan pengguna mereka tentang keberadaan dan kebenaran sertifikat SSL untuk situs yang dikunjungi.

Biaya sertifikat untuk situs pribadi dimulai dari puluhan dolar. Tidak selalu membeli itu dibenarkan dan sesuai. Untungnya, sejak akhir 2015, alternatif gratis dalam bentuk sertifikat Let's Encrypt (LE) tersedia . Proyek nirlaba ini dibuat oleh penggemar Mozilla untuk mencakup sebagian besar situs web dengan enkripsi.Otoritas Sertifikat mengeluarkan sertifikat yang divalidasi domain(yang paling sederhana di antara yang tersedia di pasar) dengan masa berlaku 90 hari, dan selama beberapa tahun sekarang yang disebut sertifikat wildcard untuk beberapa subdomain telah dikeluarkan.Untuk mendapatkan sertifikat, situs menggunakan algoritma yang dijelaskan dalam protokol Lingkungan Manajemen Sertifikat Otomatis (ACME), yang dibuat khusus untuk Let's Encrypt. Saat menggunakannya, konfirmasi kepemilikan domain dilakukan oleh permintaan melalui penempatan kode HTTP tertentu (disebut HTTP-01 ) atau pemasangan catatan DNS (DNS-01) - lebih lanjut tentang itu akan diberikan di bawah ini.Manajer sertifikasi
Cert-manager adalah proyek khusus untuk Kubernetes, yang merupakan sekumpulan CustomResourceDefinitions (karenanya pembatasan pada versi K8s yang didukung minimum - v1.12) untuk konfigurasi CA (otoritas sertifikasi) dan pemesanan langsung sertifikat. Menginstal CRD dalam sebuah cluster adalah sepele dan turun menggunakan satu file YAML:kubectl create ns cert-manager
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v0.13.0/cert-manager.yaml
( Ada juga kemungkinan menginstal menggunakan Helm.)Untuk memulai prosedur pemesanan, sumber daya dari otoritas sertifikasi (CA) harus dinyatakan dalam kluster: Issuer
atau ClusterIssuer
, - yang digunakan untuk menandatangani CSR (permintaan penerbitan sertifikat). Perbedaan antara sumber daya pertama dan kedua adalah dalam cakupan:Issuer
dapat digunakan dalam namespace yang sama,ClusterIssuer
adalah objek global cluster.
Berlatih dengan cert-manager
1 Sertifikat yang ditandatangani sendiri
Mari kita mulai dengan kasing paling sederhana - memesan sertifikat yang ditandatangani sendiri. Opsi ini cukup umum, misalnya, untuk lingkungan pengujian dinamis untuk pengembang atau dalam hal menggunakan penyeimbang eksternal yang menghentikan lalu lintas SSL.Sumber daya Issuer
akan terlihat seperti ini:apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: selfsigned
spec:
selfSigned: {}
Dan untuk mengeluarkan sertifikat, perlu untuk menggambarkan sumber Certificate
, di mana ditunjukkan bagaimana mengeluarkannya (lihat bagian di issuerRef
bawah) dan di mana kunci pribadi (bidang secretName
) berada. Setelah itu, Ingress perlu merujuk ke kunci ini (lihat bagian tls
c spec
):---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: selfsigned-crt
spec:
secretName: tls-secret
issuerRef:
kind: Issuer
name: selfsigned
commonName: "yet-another.website"
dnsNames:
- "yet-another.website"
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app
spec:
tls:
- hosts:
- "yet-another.website"
secretName: tls-secret
rules:
- host: "yet-another.website"
http:
paths:
- path: /
backend:
serviceName: app
servicePort: 8080
Beberapa detik setelah menambahkan sumber daya ini ke cluster, sertifikat akan dikeluarkan. Anda dapat melihat laporan terkait di output perintah:kubectl -n app describe certificate selfsigned-crt
...
Normal GeneratedKey 5s cert-manager Generated a new private key
Normal Requested 5s cert-manager Created new CertificateRequest resource "selfsigned-crt-4198958557"
Normal Issued 5s cert-manager Certificate issued successfully
Jika Anda melihat sumber rahasia itu sendiri, maka itu berisi:- kunci pribadi
tls.key
, - sertifikat root
ca.crt
, - Sertifikat yang ditandatangani sendiri kami
tls.crt
.
Isi file-file ini dapat dilihat menggunakan utilitas openssl
, misalnya, seperti ini:kubectl -n app get secret tls-secret -ojson | jq -r '.data."tls.crt"' | base64 -d | openssl x509 -dates -noout -issuer
notBefore=Feb 10 21:01:59 2020 GMT
notAfter=May 10 21:01:59 2020 GMT
issuer=O = cert-manager, CN = yet-another.website
Perlu dicatat bahwa dalam kasus umum, sertifikat yang dikeluarkan menggunakan ini tidak akan dipercaya olehIssuer
klien yang terhubung . Alasannya sederhana: tidak memiliki CA (lihat catatan di situs web proyek ) . Untuk menghindari ini, Anda perlu menentukan di jalur ke file rahasia di mana file itu terkandung . Ini bisa berupa organisasi CA perusahaan - untuk menandatangani sertifikat yang dikeluarkan untuk Ingress dengan kunci yang sudah digunakan untuk kebutuhan layanan server / sistem informasi lainnya.Certificate
ca.crt
2 Mari Enkripsi Sertifikat dengan Validasi HTTP
Untuk menerbitkan sertifikat LE, seperti yang disebutkan sebelumnya, ada dua jenis konfirmasi kepemilikan domain yang tersedia : HTTP-01 dan DNS-01.Pendekatan pertama (HTTP-01) adalah meluncurkan server web kecil dengan penyebaran terpisah, yang akan dikirim ke Internet melalui tautan <YOUR_DOMAIN > /. Terkenal / acme-challenge / <TOKEN> beberapa data yang diminta dari server sertifikasi. Oleh karena itu, metode ini menyiratkan ketersediaan Ingress dari luar pada port 80 dan resolusi catatan DNS domain ke alamat IP publik.Pilihan kedua untuk memverifikasi sertifikat yang dikeluarkan (DNS-01) berasaldari memiliki API ke server DNS yang menampung catatan domain. Penerbit, menggunakan token yang ditunjukkan, membuat catatan TXT pada domain, yang kemudian diterima server ACME selama konfirmasi. Di antara penyedia DNS yang didukung secara resmi adalah CloudFlare, AWS Route53, Google CloudDNS dan lainnya, termasuk implementasinya sendiri ( acme-dns ).Catatan : Let's Encrypt memiliki batasan yang cukup ketat pada permintaan ke server ACME. Agar tidak dicekal , disarankan untuk menggunakan tipe sertifikat letsencrypt-staging untuk debugging (perbedaannya hanya di server ACME).Jadi, kami menggambarkan sumber daya:apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
ingress:
class: nginx
---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: le-crt
spec:
secretName: tls-secret
issuerRef:
kind: Issuer
name: letsencrypt
commonName: yet-another.website
dnsNames:
- yet-another.website
Perhatikan bahwa alamat server pementasan ditentukan sebagai server
y acme
(c Issuer
) . Menggantinya dengan pertempuran akan dimungkinkan nanti. Menerapkan konfigurasi ini, kami melacak seluruh jalur pesanan:- Penciptaan
Certificate
melahirkan sumber daya baru CertificateRequest
:
kubectl -n app describe certificate le-crt
...
Created new CertificateRequest resource "le-crt-1127528680"
- Dalam deskripsinya - tanda pada ciptaan
Order
:
kubectl -n app describe certificaterequests le-crt-1127528680
…
Created Order resource app/le-crt-1127528680-1805948596
- Ini
Order
menjelaskan dengan parameter apa tes lulus dan apa status saat ini. Verifikasi semacam itu dilakukan oleh sumber Challenge
:
kubectl -n app describe order le-crt-1127528680-1805948596
…
Created Challenge resource "le-crt-1127528680-1805948596-1231544594" for domain "yet-another.website"
- Akhirnya, perincian sumber daya ini memuat informasi tentang status pemindaian itu sendiri:
kubectl -n app describe challenges le-crt-1127528680-1805948596-1231544594
...
Reason: Successfully authorized domain
...
Normal Started 2m45s cert-manager Challenge scheduled for processing
Normal Presented 2m45s cert-manager Presented challenge using http-01 challenge mechanism
Normal DomainVerified 2m22s cert-manager Domain "yet-another.website" verified with "http-01" validation
Jika semua persyaratan telah dipenuhi (mis. Domain dapat diakses dari luar, tidak ada larangan dari LE ...) - dalam waktu kurang dari satu menit, sertifikat akan dikeluarkan. Jika berhasil, describe certificate le-crt
catatan akan muncul di output Certificate issued successfully
.Sekarang Anda dapat dengan aman mengubah alamat server untuk memerangi ( https://acme-v02.api.letsencrypt.org/directory
) dan memesan kembali sertifikat asli yang sudah ditandatangani bukan Fake LE Intermediate X1
, tetapi Let's Encrypt Authority X3
.Untuk melakukan ini, pertama-tama Anda harus menghapus sumber Certificate
: jika tidak, prosedur pemesanan tidak diaktifkan, karena sertifikat sudah ada dan relevan. Menghapus rahasia akan mengarah ke pengembaliannya segera dengan pesan ke describe certificate
: Normal PrivateKeyLost 44s cert-manager Lost private key for CertificateRequest "le-crt-613810377", deleting old resource
Tetap menerapkan manifesto "tempur" untuk Issuer
yang sudah dijelaskan di atas Certificate
(itu belum berubah):apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
ingress:
class: nginx
Setelah menerima pesan Certificate issued successfully
, describe
periksa:kubectl -n app get secret tls-secret -ojson | jq -r '.data."tls.crt"' | base64 -d | openssl x509 -dates -noout -issuer
notBefore=Feb 10 21:11:48 2020 GMT
notAfter=May 10 21:11:48 2020 GMT
issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
Nomor 3. Wildcard LE dengan validasi DNS
Kami akan menyulitkan tugas dengan segera menulis sertifikat ke semua subdomain situs dan menggunakan waktu ini untuk memeriksa DNS (melalui CloudFlare).Pertama, dapatkan token di panel kontrol CloudFlare untuk bekerja melalui API:- Profil → Token API → Buat Token.
- Tetapkan izin sebagai berikut:
- Izin:
- Zone - DNS - Edit
- Zone - Zone - Baca
- Sumber Daya Zona:
- Salin token yang diterima setelah disimpan (misalnya :)
y_JNkgQwkroIsflbbYqYmBooyspN6BskXZpsiH4M
.
Buat sebuah Rahasia di mana token ini akan disimpan, dan merujuknya di Penerbit:apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token
type: Opaque
stringData:
api-token: y_JNkgQwkroIsflbbYqYmBooyspN6BskXZpsiH4M
---
apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt
solvers:
- dns01:
cloudflare:
email: my-cloudflare-acc@example.com
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: le-crt
spec:
secretName: tls-secret
issuerRef:
kind: Issuer
name: letsencrypt
commonName: yet-another.website
dnsNames:
- "yet-another.website"
- "*.yet-another.website"
(Jangan lupa untuk menggunakan pementasan jika Anda sedang bereksperimen!)Mari kita melalui proses mengonfirmasi kepemilikan domain:kubectl -n app describe challenges.acme.cert-manager.io le-crt-613810377-1285319347-3806582233
...
Status:
Presented: true
Processing: true
Reason: Waiting for dns-01 challenge propagation: DNS record for "yet-another.website" not yet propagated
State: pending
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Started 54s cert-manager Challenge scheduled for processing
Normal Presented 53s cert-manager Presented challenge using dns-01 challenge mechanism
Data TXT akan muncul di panel:
... dan setelah beberapa saat statusnya akan berubah menjadi:Domain "yet-another.website" verified with "dns-01" validation
Pastikan sertifikat itu valid untuk subdomain apa pun:kubectl -n app get secret tls-secret -ojson | jq -r '.data."tls.crt"' | base64 -d | openssl x509 -dates -noout -text |grep DNS:
DNS:*.yet-another.website, DNS:yet-another.website
Validasi oleh DNS, sebagai suatu peraturan, tidak terjadi dengan cepat, karena sebagian besar penyedia DNS memiliki periode pembaruan data yang menunjukkan berapa banyak waktu berlalu sejak saat catatan DNS diubah menjadi pembaruan aktual semua server DNS penyedia. Namun, standar ACME juga menyediakan kombinasi dua opsi verifikasi, yang dapat digunakan untuk mempercepat penerimaan sertifikat untuk domain utama. Dalam hal ini, uraiannya Issuer
adalah sebagai berikut:apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: letsencrypt
spec:
acme:
server: https:
privateKeySecretRef:
name: letsencrypt
solvers:
- selector:
dnsNames:
- "*.yet-another.website"
dns01:
cloudflare:
email: my-cloudflare-acc@example.com
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
- selector:
dnsNames:
- "yet-another.website"
http01:
ingress:
class: nginx
Jika Anda menerapkan konfigurasi ini, dua sumber daya akan dibuat Challenge
:kubectl -n app describe orders le-crt-613810377-1285319347
…
Normal Created 3m29s cert-manager Created Challenge resource "le-crt-613810377-1285319347-3996324737" for domain "yet-another.website"
Normal Created 3m29s cert-manager Created Challenge resource "le-crt-613810377-1285319347-1443470517" for domain "yet-another.website"
Nomor 4 Menggunakan Anotasi Khusus Ingress
Selain jalur langsung untuk membuat sertifikat di cert-manager, dimungkinkan untuk menggunakan komponen yang disebut ingress-shim dan tidak secara eksplisit membuat sumber daya Certificate
. Idenya adalah bahwa dengan bantuan anotasi Ingress khusus, sertifikat akan secara otomatis dipesan menggunakan yang ditunjukkan di dalamnya Issuer
. Hasilnya kira-kira sumber daya Ingress berikut:apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- "yet-another.website"
secretName: tls-secret
rules:
- host: "yet-another.website"
http:
paths:
- path: /
backend:
serviceName: app
servicePort: 8080
Untuk operasi yang benar, hanya kehadiran Emiten yang cukup di sini, yaitu membuat satu entitas kurang.Selain itu, ada anotasi kube-lego usang , - , - yang memerlukan tugas default saat memasang cert-manager menggunakan parameter Helm (atau dalam opsi peluncuran wadah manajer). Kami di perusahaan tidak menggunakan opsi ini dan tidak dapat menyarankan mereka karena opacity dari pendekatan yang digunakan untuk memesan sertifikat SSL (dan pada saat yang sama untuk berbagai masalah yang muncul ), tetapi masih memutuskan untuk menyebutkan dalam artikel untuk gambaran yang lebih lengkap.kubernetes.io/tls-acme: "true"
Issuer
Alih-alih sebuah kesimpulan
Melalui manipulasi sederhana dengan CRD, kami belajar cara menulis sertifikat SSL yang dapat diperpanjang secara otomatis, ditandatangani sendiri, dan gratis dari proyek Let's Encrypt untuk domain situs web yang diluncurkan sebagai bagian dari Ingresss di kluster Kubernetes.Artikel ini memberikan contoh penyelesaian masalah yang paling umum dalam praktik kami. Namun, fungsi manajer sertifikat tidak terbatas pada fitur yang dijelaskan di atas. Di situs web utilitas, Anda dapat menemukan contoh bekerja dengan layanan lain - misalnya, bundel dengan Vault atau penggunaan pusat penerbit eksternal (penerbit).PS
Baca juga di blog kami: