使用ACME CA为ASM网关签发证书

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
.cn 域名,1个 12个月
云解析 DNS,旗舰版 1个月
简介: 阿里云服务网格ASM提供全托管式服务网格平台,兼容Istio开源服务网格,简化服务治理,包括流量管理、认证安全和可观测性。产品文档:[https://help.aliyun.com/zh/asm](https://help.aliyun.com/zh/asm)。本文指导如何使用cert-manager和ACME CA为ASM网关获取HTTPS证书,涉及ACME协议、挑战验证及Let's Encrypt的使用。

阿里云服务网格Service Mesh,简称ASM)提供一个全托管式的服务网格平台,兼容社区Istio开源服务网格,用于简化服务的治理,包括服务调用之间的流量路由与拆分管理、服务间通信的认证安全以及网格可观测性能力,从而极大地减轻开发与运维的工作负担。产品文档主页:https://help.aliyun.com/zh/asm/product-overview/what-is-asm?spm=a2c4g.11186623.0.0.3dcb29aae25AFJ

本文演示如何使用cert-manager对接ACME CA,为ASM网关签发浏览器信任的HTTPS证书。

ACME是什么?

ACME的定义可以参考RFC 8555: Automatic Certificate Management Environment (ACME)

简而言之,ACME就是一种可以自动化处理X.509证书签发请求的协议。通过这个协议,可以对证书申请者的身份进行验证,从而为其签发证书。

当前有很多公共的ACME CA。Let's Encrypt就是一个非营利性的公共ACME CA,它可以签发出一般浏览器信任的证书。入门指南

本文也将使用let's Encrypt来做演示。

cert-manager中对于ACME的说明

cert-manager的ACME Issuer会向ACME CA Server注册一个账户。当你创建一个ACME Issuer,cert-manager将会生成一个私钥,用来和ACME Server通信。公共ACME Server颁发的证书通常是被客户端信任的。这意味着:客户端浏览器访问时,会信任你当前的URL。

提示一下:

用公共CA为自己的网站颁发证书,主要是为了让浏览器相信:当前Server就是为这个域名提供服务。所以公共CA需要确认:申请证书的Server就是这个域名的拥有者。

Solving Challenges

Challenges是ACME中的一个概念。申请证书时,为了让ACME CA Server确认当前客户端(证书申请者)确实拥有这个域名,客户端一般需要完成一些挑战(challenges)。这是为了确保让不拥有这个域名的人申请到这个证书,防止出现域名欺骗的问题。cert-manager目前提供了两种验证challenge - HTTP01和DNS01 challenge。

HTTP01 challenge是通过server提供计算出的密钥来完成的,该密钥应该存在于 HTTP URL 端点上并且可以通过互联网进行路由。这个URL需要使用当前申请的证书的域名。一旦ACME Server可以通过互联网在这个URL中获取到这个key,ACME server就会确认“你是当前域名的所有者”。当你创建了一个HTTP01 challenge,cert-manager会自动配置你集群的Ingress,来将这个URL的请求路由到一个小的web server上,这个web server上会存有这个key。

DNS01 challenge时通过提供DNS TXT记录中存在的一个计算出来的密钥来完成的。一旦这个TXT记录在互联网上传播开来,ACME server就可以通过DNS查找来获取这个key,并确认当前客户端确实拥有这个域名。拥有了正确的权限后,cert-manager将自动为给定的DNS提供商提供此TXT记录。

使用前提

步骤一:准备公网域名

要使用Let's Encrypt为域名签发证书,首先需要有一个公网域名,并且需要您将公网域名指向要使用的ASM网关。具体流程需要查看您的DNS提供商的文档。如果您使用的是阿里云提供的DNS服务,可以参考:如何添加域名解析记录_云解析DNS(DNS)-阿里云帮助中心

步骤二:创建对接Let's Encrypt的Issuer资源

使用数据面集群的kubeconfig,创建如下资源:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-prod-issuer
  namespace: istio-system
spec:
  acme:
    email: 'test@mail.com'    # 这个不是必填字段,但是建议填写。ACME Server可能通过该邮箱向您发送与证书相关的重要通知。
    privateKeySecretRef:
      name: letsencrypt-prod
    server: https://acme-v02.api.letsencrypt.org/directory
    solvers:
    - http01:
        ingress:
          ingressClassName: istio

上述issuer资源指定了一个http01类型的solver,使用Ingress API,ingressClassName是istio。下面步骤中将会解释这个solver如何生效。

说明:

cert-manager支持使用Ingress API和Gateway API两种类型的solver。ASM对这两种API都提供了支持。

本例中使用Ingress API。

等待issuer就绪,可以使用如下命令查看issuer状态:

k -n istio-system get issuer letsencrypt-prod-issuer
NAME                      READY   AGE
letsencrypt-prod-issuer   True    8m3s

步骤三:为ASM网关签发证书

使用数据面集群的kubeconfig,创建如下资源:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: istio-ingressgateway-certs
  namespace: istio-system
spec:
  dnsNames:
  - ${测试域名}    # test.com
  issuerRef:
    group: cert-manager.io
    kind: Issuer
    name: letsencrypt-prod-issuer
  secretName: istio-ingressgateway-certs

等待certificate就绪,可以用如下命令查看certificate状态:

kubectl -n istio-system get certificate istio-ingressgateway-certs
NAME                         READY   SECRET                       AGE
istio-ingressgateway-certs   True    istio-ingressgateway-certs   59m

证书签发的过程解析

创建certificate资源之后,cert-manager就会使用上一步创建的issuer为这个域名签发证书。这个过程中,我们上一步配置的solver就会生效。

Let's Encrypt将会使用HTTP01 challenge来确认:当前server是这个域名的所有者。为此,Let's Encrypt将会发送一个HTTP请求到这个域名,然后它需要获取到一个合法的返回值,才可以完成验证。

可是在这个例子中,我们的网关上只有httpbin的路由规则,并没有任何和challenge有关的配置。Let's Encrypt是否真的发送了challenge请求?以及请求是如何被响应的呢?

首先可以确认的是:Let's Encrypt确实发送了challenge请求,这一点可以通过网关日志来确认。使用如下命令查看网关日志:

kubectl -n istio-system logs ${网关pod名称} | grep letsencrypt | tail -1
{"authority_for":"xxxxxxx","bytes_received":"0","bytes_sent":"87","downstream_local_address":"xx.xx.xx.xx:80","downstream_remote_address":"xx.xx.xx.xx:57101","duration":"0","istio_policy_status":"-","method":"GET","path":"/.well-known/acme-challenge/JfKvfdSNmkR7UqmCQU0OSkJC3EsnP4ZUiCc28OLLLxA","protocol":"HTTP/1.1","request_id":"e6806d08-0469-4383-be8e-4d7506b39ec5","requested_server_name":"-","response_code":"200","response_flags":"-","route_name":"-","start_time":"2024-04-08T12:04:06.153Z","trace_id":"-","upstream_cluster":"outbound|8089||cm-acme-http-solver-c4ch9.istio-system.svc.cluster.local","upstream_host":"xx.xx.xx.xx:8089","upstream_local_address":"xx.xx.xx.xx:55886","upstream_response_time":"0","upstream_service_time":"0","upstream_transport_failure_reason":"-","user_agent":"Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)","x_forwarded_for":"xx.xx.xx.xx"}

可以看到网关上确实存在Let's Encrypt发出的请求,并且该请求被正常返回了。这是为什么呢?

此时自然可以想到前面在issuer中配置了ingressClassName为istio。其实,cert-manager会自动创建一个ingressClassName为istio的ingress资源,将challenge请求转发给cert-manager对应的solver来完成验证。

可是在certificate就绪之后,使用kubectl -n istio-system get ingress无法看到相关的ingress资源,这是为什么呢?

这是因为cert-manager在完成证书签发后,会自动删除solver相关的资源,其中就包括ingress、service、deployment等资源。

步骤四:验证Let's Encrypt签发的证书

创建如下网关规则,在网关的443端口上配置上一步生成的证书:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: httpbin-https
  namespace: default
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - ${测试域名}
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      credentialName: istio-ingressgateway-certs
      mode: SIMPLE

修改原有的httpbin-vs虚拟服务,为如下内容:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: httpbin-vs
  namespace: default
spec:
  gateways:
    - httpbin
    - httpbin-https  # 新增这一行
  hosts:
    - '*'
  http:
    - name: test
      route:
        - destination:
            host: httpbin.default.svc.cluster.local
            port:
              number: 8000

配置完成之后,在浏览器中访问https://${测试域名},可以看到如下形式的浏览器地址栏,点击小锁图标,可以看到显示“连接安全”:

image.png

此时浏览器已经信任您的证书。

说明

实际场景中,您需要确认您当前的证书颁发机构是否支持ACME协议。如果支持,则ASM网关可以通过cert-manager自动从CA处获取证书。比如Sectigo目前已经支持了ACME协议,其原理与本文所述类似,您可以参考Overview :: Sectigo Certificate Manager Documentation


目录
相关文章
|
3月前
|
运维 Kubernetes 安全
利用服务网格实现全链路mTLS(一):在入口网关上提供mTLS服务
阿里云服务网格(Service Mesh,简称ASM)提供了一个全托管式的服务网格平台,兼容Istio开源服务网格,用于简化服务治理,包括流量管理和拆分、安全认证及网格可观测性,有效减轻开发运维负担。ASM支持通过mTLS提供服务,要求客户端提供证书以增强安全性。本文介绍如何在ASM入口网关上配置mTLS服务并通过授权策略实现特定用户的访问限制。首先需部署ASM实例和ACK集群,并开启sidecar自动注入。接着,在集群中部署入口网关和httpbin应用,并生成mTLS通信所需的根证书、服务器证书及客户端证书。最后,配置网关上的mTLS监听并设置授权策略,以限制特定客户端对特定路径的访问。
130 2
|
3月前
|
Kubernetes 安全 Cloud Native
解锁安全新纪元:利用服务网格Istio,打造全链路mTLS加密隧道,从入口网关到出口网关,守护数据安全的每一步
【8月更文挑战第2天】随着云原生技术的发展,服务网格(Service Mesh)如Istio已成为微服务架构的核心,通过双向TLS(mTLS)确保通信安全。首先,在Kubernetes部署Istio以管理服务通信。接着,配置入口网关实现所有入向流量的加密处理,防止数据泄露。最后,通过配置Sidecar代理如Envoy,确保服务网格安全访问外部mTLS服务,从而构建起全链路的数据安全防护。
80 11
|
3月前
|
Kubernetes 安全 数据安全/隐私保护
利用服务网格实现全链路mTLS(二):通过出口网关访问外部mTLS服务
阿里云服务网格(Service Mesh,简称ASM)提供了一个全托管式的服务网格平台,兼容Istio开源服务网格,简化服务治理,包括流量管理、服务间通信安全及网格可观测性。ASM出口网关统一管理网格内的出口流量,实现全链路加密通信与精细访问控制。本文介绍如何配置ASM出口网关以管理出口流量并发起mTLS通信,涉及配置ServiceEntry、创建出口网关、设置虚拟服务及目标规则等步骤,最终实现安全可控的mTLS服务访问。
149 3
|
6月前
|
运维 负载均衡 Cloud Native
Serverless 应用引擎产品使用之在Serverless 应用引擎中,使用云原生网关的情况下,SLB(负载均衡器)和证书配置如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
弹性计算 运维 Serverless
使用ASM Serverless网关支撑各种弹性业务场景
ASM Serverless网关就是基于虚拟节点和ECI提供的一种Serverless 网关形态,充分支撑各种弹性和免节点运维场景的用户诉求。
215 1
|
Serverless Perl 测试技术
使用ASM管理Knative服务(4):使用ASM网关实现HTTPS访问Knative服务
ASM网关支持HTTPS协议和动态加载证书功能。在使用Knative on ASM时,可以通过ASM网关来实现HTTPS访问。本文将演示如何使用ASM网关来实现HTTPS访问Knative服务。
260 0
使用ASM管理Knative服务(4):使用ASM网关实现HTTPS访问Knative服务
|
域名解析 运维 Kubernetes
如何使用ASM网关对接阿里云WAF
Web应用防火墙(Web Application Firewall,简称WAF)为您的网站或App业务提供一站式安全防护。WAF可以有效识别Web业务流量的恶意特征,在对流量清洗和过滤后,将正常、安全的流量返回给服务器,避免网站服务器被恶意入侵导致性能异常等问题,从而保障网站的业务安全和数据安全。 ASM网关支持对接WAF,并且可以通过自定义访问日志格式来查看WAF对回源请求添加的Header,更方便线上运维。本文将介绍ASM网关如何对接WAF,以及如何使用ASM的自定义访问日志能力进行调试。
347 0
如何使用ASM网关对接阿里云WAF
|
调度 UED Perl
部署ASM网关Pod到指定的节点上
配置高性能和高可用的ASM网关,可确保业务连续性并提升用户体验。本文介绍如何配置ASM网关,将网关Pod部署到指定节点上,从而提高ASM网关的高可用性并增强与业务Pod的隔离性。
197 0
|
4月前
|
监控 负载均衡 Java
深入理解Spring Cloud中的服务网关
深入理解Spring Cloud中的服务网关
|
1月前
|
安全 5G 网络性能优化