Khi triển khai một dự án web, việc triển khai chứng chỉ SSL là một thách thức phổ biến mà mọi kỹ sư đều có thể gặp phải – và tôi cũng không ngoại lệ.
Thông thường, các công ty khởi nghiệp chọn chứng chỉ miễn phí như chứng chỉ từ Let's Encrypt. Tuy nhiên, những điều này đi kèm với những hạn chế và sự bất tiện cần xem xét, được trình bày chi tiết trên trang web của nhà cung cấp chứng chỉ .
Hãy cùng xem xét kỹ hơn các vấn đề mà cá nhân tôi đã gặp phải với các chứng chỉ miễn phí:
Thường xuyên phải đối mặt với những vấn đề này, tôi đã phát triển một cấu hình giải pháp tùy chỉnh sử dụng chứng chỉ Let's Encrypt. Trong bài viết này, tôi sẽ chia sẻ những phát hiện của mình và những bài học tôi đã học được trong quá trình thực hiện.
Gần đây, tôi đang tập trung vào một nhóm công nghệ cụ thể và muốn thảo luận về giải pháp cơ sở hạ tầng dựa trên cụm Kubernetes trong ngữ cảnh của nhà cung cấp đám mây Azure. Mặc dù trình quản lý chứng chỉ là một giải pháp phổ biến trong lĩnh vực này, nhưng tôi thích cài đặt nó qua Helm hơn để thuận tiện hơn.
Vì vậy, không cần phải quảng cáo thêm, hãy đi sâu vào:
helm repo add jetstack https: //charts.jetstack.io
helm repo update kubectl apply -f https: //github.com/jetstack/cert-manager/releases/download/v1.6.1/cert-manager.crds.yaml
helm install cert-manager jetstack/cert-manager -- namespace cert - manager -- create - namespace -- version v1 . 6 . 1
Sau đó, chúng ta có thể tạo một ClusterIssuer bằng tệp YAML sau:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-cluster-issuer
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: p…[email protected] #your e-mail
privateKeySecretRef:
name: letsencrypt-cluster-issuer
solvers:
- http01:
ingress:
class: nginx
Trong tương lai, có hai tùy chọn để triển khai chứng chỉ:
Hãy khám phá cả hai lựa chọn.
Trong kịch bản đầu tiên, các tệp YAML của tôi trông như thế này:
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: myservice2 namespace : test
Spec : duration : 2160h
renewBefore : 72h
dnsNames : - myservice2 . mydomain . org # you resources
secretName : myservice2 - tls
issuerRef : name : letsencrypt - cluster - issuer
kind : ClusterIssuer
Đáng chú ý là chỉ có "SecretName: myservice2-tls" được đề cập trong phần đầu vào trong phần TLS cho một dịch vụ cụ thể.
Nhân tiện, tệp YAML chứa một số tham số hữu ích, chẳng hạn như:
Nếu bạn cảm thấy thoải mái hơn khi làm việc với bảng điều khiển, hãy để tôi cung cấp cho bạn một cái nhìn toàn diện về chứng chỉ làm ví dụ.
kubectl describe certificates <cert name > -n <namespace name >
Vì vậy, những gì chúng ta có cuối cùng?
Cá nhân tôi thấy việc quản lý chứng chỉ Let's Encrypt thông qua Ingress đáng tin cậy và thuận tiện hơn, đó là lý do tại sao tôi đã sử dụng nó gần đây. Với phương pháp này, ngoài secretName và hostname trong phần TLS, bạn chỉ cần chỉ định các chú thích trong tệp YAML đầu vào.
annotations : cert-manager .io/cluster-issuer: "letsencrypt-cluster-issuer" cert-manager .io/renew-before: 72h
Và ở đó bạn có nó, sự kỳ diệu của tất cả! Chứng chỉ hiện được cấp lại tự động, với khoảng thời gian đệm là ba ngày trước khi chúng hết hạn trong ví dụ này. Cần lưu ý rằng, trong trường hợp của Let's Encrypt, khoảng thời gian mặc định là 90 ngày.
Tuy nhiên, do những hạn chế của chứng chỉ miễn phí từ Let's Encrypt, nhóm của chúng tôi cuối cùng đã dự tính nhu cầu về chứng chỉ toàn diện có thể bảo vệ không chỉ miền của chúng tôi mà cả các miền phụ. Khi chúng tôi tiếp tục phát triển dự án của mình trên Azure, chúng tôi nhận thấy rằng Azure Key Vault cung cấp một vị trí thuận tiện để lưu trữ các chứng chỉ đó. Chúng tôi đã và đang sử dụng tiện ích akv2k8s trong cụm Kubernetes của mình. Nếu bạn quan tâm, tôi khuyến khích bạn tìm hiểu thêm về nó .
Sau khi bạn đã nhận được chứng chỉ trong Azure, bước tiếp theo là thêm chứng chỉ đó vào Azure Key Vault (AKV). Mặc dù quy trình này tương đối đơn giản nhưng việc xác minh quyền sở hữu miền có thể hơi phức tạp. Tuy nhiên, sau khi tất cả các bước xác nhận được hoàn tất thành công, chứng chỉ sẽ xuất hiện trong phần "Bí mật" của kho khóa.
Một trong những lợi ích chính của phương pháp này là tự động gia hạn chứng chỉ. Chứng chỉ sẽ được cấp lại và cập nhật trong AKV sau một năm và nó sẽ tự động đồng bộ hóa với Secret trong Kubernetes.
Để cụm Kubernetes sử dụng chứng chỉ đã mua, bạn cần cấp cho nó một số quyền và quyền truy cập.
Để thực hiện việc này, trước tiên bạn cần có được idityProfile.kubeletidentity.objectId của cụm. Bạn có thể làm như vậy bằng cách sử dụng lệnh sau:
az aks show -g < RG > -n < AKS_name >
Nhóm tài nguyên (RG) là vị trí lưu trữ cụm và AKS_name là tên cụm của bạn.
Sau khi có được idityProfile.kubeletidentity.objectId, bạn cần sao chép nó. Tiếp theo, thêm giá trị vào lệnh cấp quyền truy cập bí mật:
az keyvault set-policy --name < name AKV > --object-id < get from first step value > --secret-permissions get
Tiếp theo, bạn có thể tiến hành cài đặt akv2k8s, có thể thực hiện thông qua Helm hoặc các phương pháp ưa thích khác, như được mô tả trong hướng dẫn cài đặt .
Theo tài liệu chính thức , sau đó bạn có thể đồng bộ hóa chứng chỉ Azure Key Vault của mình với Secret trong một không gian tên Kubernetes cụ thể. Đây là tệp YAML của tôi:
apiVersion: spv.no/v1 kind: AzureKeyVaultSecret metadata: name: wildcard-cert #any name namespace : default
spec : vault : name : SandboxKeyVault # name you keyvault in Azure
object : name : name_object_id # name object id from Azure AKV this cert
type : secret
output : secret : name : wildcard - cert # any name for secret in your namespace
type : kubernetes . io / tls
chainOrder : ensureserverfirst # very important values !!!
Hãy để tôi nhấn mạnh tầm quan trọng của dòng cuối cùng, vì nó đóng một vai trò quan trọng trong việc giải quyết vấn đề mà tôi gặp phải. Ban đầu, tôi có thể tải chứng chỉ lên Kubernetes thành công, nhưng nó không hoạt động như dự kiến. Phải mất một thời gian để chẩn đoán vấn đề.
Hóa ra, khi xuất chứng chỉ PFX từ Key Vault, chứng chỉ máy chủ đôi khi được định vị ở cuối chuỗi thay vì ở đầu chuỗi. Điều này có thể gây ra sự cố khi được sử dụng với các tham số như ingress-nginx, vì chứng chỉ không tải được và mặc định trở về giá trị ban đầu. Tuy nhiên, bằng cách đặt chainOrder thành ensureserverfirst, chứng chỉ máy chủ sẽ được đặt đầu tiên trong chuỗi.
Khi kiểm tra kỹ hơn chứng chỉ, tôi phát hiện ra rằng chuỗi được sắp xếp theo trình tự sau:
Sau khi đã thảo luận về các khía cạnh kỹ thuật và cấu hình, hãy quay lại tìm hiểu các đặc thù của chứng chỉ Azure.
Azure cung cấp hai tùy chọn để yêu cầu chứng chỉ, cả hai đều do GoDaddy cung cấp:
Chúng tôi đã chọn cái sau, hy vọng nó sẽ bảo vệ tất cả các ứng dụng và dịch vụ của chúng tôi. Tuy nhiên, có một vài sắc thái.
Chứng chỉ Azure Wildcard chỉ bảo vệ các tên miền phụ cấp một. Chẳng hạn, nếu chúng tôi có một miền có tên mydomain.com , chứng chỉ sẽ chỉ bao gồm các miền phụ cấp một ở dạng .mydomain.com .
Do đó, chứng chỉ sẽ hoạt động đối với các tài nguyên như service1.mydomain.com, service2.mydomain.com, service3.mydomain.com nhưng sẽ không áp dụng cho service1.test.mydomain.com hoặc mail.service1.mydomain.com .
Chúng ta có những lựa chọn nào sau đó?
Tùy chọn đầu tiên không khả thi vì số lượng tên miền phụ, đặc biệt là những tên miền ở cấp độ thứ hai, có thể rất lớn. Do đó, trả tiền để có được chứng chỉ ký tự đại diện cho mỗi tên miền phụ ( .service1.mydomain.com, *.dev.mydomain.com… ) không phải là giải pháp hợp lý nhất.
Đối với tùy chọn thứ hai, tôi đã có một cuộc trò chuyện dài với nhóm hỗ trợ Azure về vấn đề này, trải qua tất cả các giai đoạn từ chối, thất vọng và tức giận, chỉ để cuối cùng nhận ra rằng khả năng SAN cho các chứng chỉ vẫn chưa được triển khai.
Cho đến cuối cùng, tôi đã hy vọng rằng sự cố như vậy sẽ không bao giờ xảy ra trên Azure. Ngược lại, đối thủ cạnh tranh của họ, AWS Amazon, cung cấp chứng chỉ thông qua Trình quản lý chứng chỉ AWS (ACM) hỗ trợ tối đa 10 tên chủ đề thay thế, bao gồm cả ký tự đại diện. Nó cho phép bạn tạo 10 miền phụ với ký tự đại diện (*) và thậm chí yêu cầu tăng hạn ngạch trên AWS lên tới 100k.
Để kết thúc, tôi sẽ chia sẻ cách bạn có thể sử dụng chứng chỉ với dịch vụ Cửa trước trên Azure.
Đối với tôi, Azure Front Door (AFD) là một cổng toàn cầu và có thể mở rộng, tận dụng mạng biên toàn cầu của Microsoft để hướng lưu lượng truy cập đến các điểm cuối thích hợp, có thể là các ứng dụng hoặc dịch vụ web. Hoạt động ở lớp HTTP/HTTPS (lớp 7), Front Door định tuyến các yêu cầu của máy khách đến một máy chủ ứng dụng khả dụng từ nhóm. Phía máy chủ của ứng dụng có thể là bất kỳ dịch vụ nào có thể truy cập Internet, cho dù dịch vụ đó được lưu trữ bên trong hay bên ngoài Azure.
Một ví dụ từ trang web tài liệu https://docs.microsoft.com/
Azure Front Door là một công cụ tiện lợi cho phép bạn cân bằng và ủy quyền lưu lượng truy cập đến truy cập vào các ứng dụng và dịch vụ được phân phối trên toàn thế giới. Nó cung cấp một loạt các tính năng bao gồm khả năng liên kết các quy tắc khác nhau bằng cách định cấu hình trình xử lý quy tắc, tham gia chính sách và cài đặt tường lửa. Tôi sẽ không đi sâu vào các chi tiết cụ thể của dịch vụ AFD trong bài viết này mà sẽ tập trung vào các đặc thù dịch vụ của chứng chỉ.
Như bạn có thể mong đợi, lưu lượng truy cập đến Azure Front Door có thể là http hoặc https . Nếu chọn https , bạn có ba tùy chọn: tạo chứng chỉ trên chính dịch vụ Azure Front Door, tải chứng chỉ của riêng bạn lên hoặc đồng bộ hóa chứng chỉ hiện có của bạn với Azure Key Vault. Để cho phép dịch vụ Cửa trước truy cập Kho lưu trữ khóa, bạn cần định cấu hình các quyền cần thiết.
Tôi khuyên bạn nên sử dụng tùy chọn cuối cùng và chọn phiên bản mới nhất của chứng chỉ để tránh phải gia hạn hoặc tạo lại thủ công. Bằng cách kết nối chứng chỉ từ AKV, mọi thứ sẽ tự động cập nhật.
Thiết lập này sẽ cung cấp cho bạn kết quả như sau:
Đây là một điểm đặc biệt khác trong khi điều hướng lưu lượng truy cập từ Azure Front Door đến AKS.
Xử lý lưu lượng truy cập http không phải là vấn đề, nhưng có một chi tiết tinh tế cần lưu ý khi thiết lập nhóm tài nguyên và chỉ định địa chỉ IP bên ngoài của cụm AKS. Đảm bảo để trống trường "tiêu đề nút thành phần máy chủ" để đảm bảo rằng trường này được tự động điền các giá trị được nhập vào trường "IP hoặc tên nút".
Giả sử bạn có chứng chỉ ký tự đại diện tên miền được đính kèm thông qua AKV, chứng chỉ này được sử dụng bởi cả dịch vụ Cửa trước và được đưa vào cụm AKS thông qua akv2k8s. Tên máy chủ giao diện (và bản ghi CNAME trong DNS) cho tất cả các ứng dụng và dịch vụ của bạn có thể truy cập thông qua Front Door sẽ như sau:
Điều này sẽ cho phép tất cả các dịch vụ ở định dạng *.mydomain.com hoạt động bình thường. Khi bạn đã hoàn thành cấu hình này, bạn đã hoàn tất.
Trong một số trường hợp nhất định, việc chuyển hướng lưu lượng truy cập từ Azure Front Door sang AKS thông qua https có thể thuận lợi hơn. Để đảm bảo Azure Front Door hoạt động chính xác trong cài đặt nhóm máy chủ, điều quan trọng là phải chỉ định tên DNS tương ứng với cụm AKS của bạn , có liên quan đến SNI và kiểm tra tình trạng. Nếu không, thiết lập sẽ không hoạt động.
Trong trường hợp của tôi, không có tên nào được gán cho cụm AKS của tôi, tôi chỉ có các dịch vụ trước đây hoạt động trực tiếp nhưng phải hoạt động thông qua Azure Front Door. Để giải quyết vấn đề này, tôi phải tạo một tên DNS riêng cho cụm AKS, định cấu hình DNS và thiết lập một dịch vụ riêng có chứng chỉ được đính kèm với mục nhập. Chỉ sau đó, tôi mới có thể chuyển hướng lưu lượng truy cập https đến các cụm AKS và đảm bảo rằng nó hoạt động chính xác cho tất cả các dịch vụ có sẵn.
Điều quan trọng là phải xem xét các biện pháp bảo mật trong khi thiết lập quyền kết nối cho AKS. Để đảm bảo kết nối an toàn, bạn có thể giới hạn quyền kết nối với AKS chỉ từ các địa chỉ IP Azure Front Door trong Nhóm bảo mật mạng cho AKS (như minh họa trong hình bên dưới).
Ngoài ra, bạn có thể thiết lập lối vào AKS để chỉ chấp nhận các kết nối từ tiêu đề Azure Front Door của bạn theo ID bằng cách sử dụng tham số X-Azure-FDID .
1. Azure không cung cấp thông tin đầy đủ về các tính năng và nhược điểm của chứng chỉ của họ. Tuy nhiên, điều đáng nói là họ đã nhanh chóng hoàn trả cho chúng tôi chứng chỉ đã mua.
2. Trong quá trình phát triển, chúng tôi tiếp tục sử dụng Let's Encrypt. Mặc dù nó có những hạn chế, nhưng nó không phải là sự lựa chọn tồi tệ nhất hiện có.
3. Nếu dự án của bạn yêu cầu nhiều tên miền phụ với các mức tài nguyên khác nhau, bạn có thể muốn xem xét chứng chỉ "Ký tự đại diện (còn được gọi là Đa miền) có SAN" của nhà cung cấp bên thứ ba. Các chứng chỉ này có thể được nhập vào Azure và sử dụng hết tiềm năng của chúng.
4. Khi được định cấu hình chính xác, Azure Front Door là một dịch vụ xuất sắc. Tôi khuyên bạn nên nó.
Viết bởi Pavel Shapurau, Trưởng nhóm kỹ sư DevOps, Social Discovery Group