利用服务网格实现全链路mTLS(一):在入口网关上提供mTLS服务

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 阿里云服务网格(Service Mesh,简称ASM)提供了一个全托管式的服务网格平台,兼容Istio开源服务网格,用于简化服务治理,包括流量管理和拆分、安全认证及网格可观测性,有效减轻开发运维负担。ASM支持通过mTLS提供服务,要求客户端提供证书以增强安全性。本文介绍如何在ASM入口网关上配置mTLS服务并通过授权策略实现特定用户的访问限制。首先需部署ASM实例和ACK集群,并开启sidecar自动注入。接着,在集群中部署入口网关和httpbin应用,并生成mTLS通信所需的根证书、服务器证书及客户端证书。最后,配置网关上的mTLS监听并设置授权策略,以限制特定客户端对特定路径的访问。

阿里云服务网格Service Mesh,简称ASM)提供一个全托管式的服务网格平台,兼容社区Istio开源服务网格,用于简化服务的治理,包括服务调用之间的流量路由与拆分管理、服务间通信的认证安全以及网格可观测性能力,从而极大地减轻开发与运维的工作负担。

ASM网关支持对外提供mTLS服务。mTLS要求客户端提供自身证书,该证书中包含了用户的身份信息。您可以在授权策略中配置只有特定的用户才可以成功访问该服务,进而为服务提供更加高级别的保护。

本文将介绍如何在ASM入口网关上配置mTLS服务,并且通过授权策略实现对特定用户的访问限制。

前提条件

步骤一:在集群中部署入口网关和httpbin应用

参考https://help.aliyun.com/zh/asm/getting-started/deploy-the-httpbin-application?spm=a2c4g.11186623.0.i3在集群二中部署httpbin应用,并且通过80端口暴露在ASM网关上。

步骤二:生成mTLS通信证书

以下创建证书过程中,如果遇到需要填写证书信息的地方,直接回车,使用默认值即可。因为默认值已经在配置文件中手动指定过了。

  1. 将以下内容保存在ca.cnf文件中,用于生成根证书:
HOME = .`
RANDFILE = $ENV::HOME/.rnd
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
[ CA_default ]
default_days = 1000 # how long to certify for
default_crl_days = 30 # how long before next CRL
default_md = sha256 # use public key default MD
preserve = no # keep passed DN ordering
x509_extensions = ca_extensions # The extensions to add to the cert
email_in_dn = no # Don't concat the email in the DN
copy_extensions = copy # Required to copy SANs from CSR to cert
#====Following 7 lines are for signing other certs, not for making the CA cert.====
base_dir = .
certificate = $base_dir/cacert.pem # The CA certifcate
private_key = $base_dir/cakey.pem # The CA private key
new_certs_dir = $base_dir # Location for new certs after signing
database = $base_dir/index.txt # Database index file
serial = $base_dir/serial.txt # The current serial number
unique_subject = no # Set to 'no' to allow creation of several certificates with same subject.
####################################################################
[ req ]
default_bits = 4096
default_keyfile = cakey.pem
distinguished_name = ca_distinguished_name
x509_extensions = ca_extensions
string_mask = utf8only
####################################################################
[ ca_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = bj
localityName = Locality Name (eg, city)
localityName_default = bj
organizationName = Organization Name (eg, company)
organizationName_default = test-asm
organizationalUnitName = Organizational Unit (eg, division)
organizationalUnitName_default = R&D
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Test CA
emailAddress = Email Address
emailAddress_default = test@example.com
####################################################################
[ ca_extensions ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer
basicConstraints = critical, CA:true
keyUsage = keyCertSign, cRLSign
#====All lines below are for signing other certs, not for making the CA cert.======
####################################################################
[ signing_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ signing_req ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
  1. 执行以下命令,生成根证书:
openssl req -x509 -config ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM

执行完成后,可以看到输出了cacert.pemcakey.pem文件。

  1. 将以下内容保存在server.cnf文件中,用于创建服务器证书:
HOME = .
RANDFILE = $ENV::HOME/.rnd
####################################################################
[ req ]
default_bits = 2048
default_keyfile = serverkey.pem
distinguished_name = server_distinguished_name
req_extensions = server_req_extensions
string_mask = utf8only
####################################################################
[ server_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = bj
localityName = Locality Name (eg, city)
localityName_default = bj
organizationName = Organization Name (eg, company)
organizationName_default = test
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = test.com
emailAddress = Email Address
emailAddress_default = test@example.com
####################################################################
[ server_req_extensions ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
####################################################################
[ alternate_names ]
DNS.1 = test.com

从配置文件中可以看出,此处生成的证书将会用于test.com这个域名。

  1. 执行以下命令,生成服务器证书:
openssl req -config server.cnf -newkey rsa:2048 -sha256 -nodes -out server.csr -outform PEM
touch index.txt
echo '01' > serial.txt
openssl ca -config ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles server.csr

执行完毕后,可以得到servercert.pemserverkey.pem

  1. 将以下内容保存在client.cnf文件中,用于创建客户端证书:
HOME = .
RANDFILE = $ENV::HOME/.rnd
####################################################################
[ req ]
default_bits = 2048
default_keyfile = client.key.pem
distinguished_name = server_distinguished_name
req_extensions = server_req_extensions
string_mask = utf8only
####################################################################
[ server_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = bj
localityName = Locality Name (eg, city)
localityName_default = bj
organizationName = Organization Name (eg, company)
organizationName_default = test.client
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = test.client
emailAddress = Email Address
emailAddress_default = test.client@example.com
####################################################################
[ server_req_extensions ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
####################################################################
[ alternate_names ]
URI.1 = spiffe://test.client

客户端证书的CommonName为test.client,SAN信息中需要新增字段URI.1 = spiffe://test.client,这里需要额外加上spiffe://前缀,因为ASM的授权策略中principals字段会匹配spiffe://之后的部分。

  1. 执行以下命令,生成客户端证书:
openssl req -config client.cnf -newkey rsa:2048 -sha256 -nodes -out clientcert.csr -outform PEM
openssl ca -config ca.cnf -policy signing_policy -extensions signing_req -out clientcert.pem -infiles clientcert.csr

执行完毕后可以得到clientcert.pem以及client.key.pem

  1. 部署证书:

使用ASM证书管理导入mTLS证书,请确保此处导入的证书名称为test.com,如何使用ASM证书管理_服务网格(ASM)-阿里云帮助中心

您也可以使用kubectl直接创建secret完成证书导入。使用数据面集群的kubeconfig,执行如下命令即可:

kubectl create -n istio-system secret generic test.com \
  --from-file=tls.key=serverkey.pem \
  --from-file=tls.crt=servercert.pem \
  --from-file=ca.crt=cacert.pem

步骤三:在网关443端口上配置mTLS监听

本文需要额外在ASM网关的443端口配置mTLS监听,让外部客户端可以通过mTLS访问httpbin服务。请确保ASM网关开启了443端口。

使用ASM kubeconfig,修改网关规则,修改后的内容如下:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: httpbin
  namespace: default
spec:
  selector:
    istio: ingressgateway
  servers:
    - hosts:
        - '*'
      port:
        name: test
        number: 80
        protocol: HTTP
    - hosts:
      - test.com
      port:
        number: 443
        name: https
        protocol: HTTPS
      tls:
        mode: MUTUAL
        credentialName: test.com
  1. 验证访问

执行以下命令,使用client证书访问httpbin服务:

curl --header "host:test.com" --resolve "test.com:443:${ASM网关IP}" --cacert cacert.pem --cert clientcert.pem --key client.key.pem  https://test.com/status/200 -I
HTTP/2 200
server: istio-envoy
date: Sun, 28 Jul 2024 7:30:30 GMT
content-type: text/html; charset=utf-8
access-control-allow-origin: *
access-control-allow-credentials: true
content-length: 0
x-envoy-upstream-service-time: 6

步骤三:在集群二的网关上配置授权策略,限制test.client访问

  1. 部署以下授权策略,限制test.client不能访问httpbin应用的/status/418路径。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: test
  namespace: istio-system
spec:
  action: DENY
  rules:
    - from:
        - source:
            principals:
              - test.client
      to:
        - operation:
            paths:
              - /status/418
  selector:
    matchLabels:
      istio: ingressgateway
  1. 验证访问结果
  1. 使用client证书访问/status/200路径:
curl --header "host:test.com" --resolve "test.com:443:${ASM网关IP}" --cacert cacert.pem --cert clientcert.pem --key client.key.pem  https://test.com/status/200 -I
HTTP/2 200
server: istio-envoy
date: Sun, 28 Jul 2024 7:33:30 GMT
content-type: text/html; charset=utf-8
access-control-allow-origin: *
access-control-allow-credentials: true
content-length: 0
x-envoy-upstream-service-time: 6
  1. 使用client证书访问/status/418路径:
curl --header "host:test.com" --resolve "test.com:443:${ASM网关IP}" --cacert cacert.pem --cert clientcert.pem --key client.key.pem  https://test.com/status/418
RBAC: access denied%
  1. 使用server证书访问/status/418路径:
curl --header "host:test.com" --resolve "test.com:443:${ASM网关IP}" --cacert cacert.pem --cert servercert.pem --key serverkey.pem  https://test.com/status/418
    -=[ teapot ]=-
       _...._
     .'  _ _ `.
    | ."` ^ `". _,
    \_;`"---"`|//
      |       ;/
      \_     _/
        `"""`
目录
相关文章
|
30天前
|
Java API 微服务
服务网关Gateway
该博客文章详细介绍了Spring Cloud Gateway的使用方法和概念。文章首先阐述了API网关在微服务架构中的重要性,解释了客户端直接与微服务通信可能带来的问题。接着,文章通过具体的示例代码,展示了如何在Spring Cloud Gateway中添加依赖、编写路由规则,并对路由规则中的基本概念如Route、Predicate和Filter进行了详细解释。最后,文章还提供了路由规则的测试方法。
服务网关Gateway
|
1月前
|
Kubernetes 安全 Cloud Native
解锁安全新纪元:利用服务网格Istio,打造全链路mTLS加密隧道,从入口网关到出口网关,守护数据安全的每一步
【8月更文挑战第2天】随着云原生技术的发展,服务网格(Service Mesh)如Istio已成为微服务架构的核心,通过双向TLS(mTLS)确保通信安全。首先,在Kubernetes部署Istio以管理服务通信。接着,配置入口网关实现所有入向流量的加密处理,防止数据泄露。最后,通过配置Sidecar代理如Envoy,确保服务网格安全访问外部mTLS服务,从而构建起全链路的数据安全防护。
51 11
|
1月前
|
Prometheus Kubernetes 监控
打造无缝灾备新境界:运用服务网格ASM,将集群外服务无缝融入集群内服务,铸就高可用性坚盾!
【8月更文挑战第2天】随着微服务架构的应用,服务的高可用性变得至关重要。服务网格如阿里巴巴的ASM提供流量管理、服务发现等功能,支撑高可靠服务系统。本文介绍如何利用ASM实现集群外服务作为集群内服务的灾备方案,确保服务连续性。先决条件包括已部署ASM的Kubernetes集群环境及内外部的关键服务副本。通过定义服务条目、配置虚拟服务和目的地规则,可实现自动或手动故障转移。借助ASM的流量管理能力,确保服务高可用性和业务连续性。
38 10
|
1月前
|
Kubernetes 安全 数据安全/隐私保护
利用服务网格实现全链路mTLS(二):通过出口网关访问外部mTLS服务
阿里云服务网格(Service Mesh,简称ASM)提供了一个全托管式的服务网格平台,兼容Istio开源服务网格,简化服务治理,包括流量管理、服务间通信安全及网格可观测性。ASM出口网关统一管理网格内的出口流量,实现全链路加密通信与精细访问控制。本文介绍如何配置ASM出口网关以管理出口流量并发起mTLS通信,涉及配置ServiceEntry、创建出口网关、设置虚拟服务及目标规则等步骤,最终实现安全可控的mTLS服务访问。
116 3
|
1月前
|
Perl
如何利用服务网格ASM使用集群外服务做集群内服务的灾备
本文档指导您如何配置阿里云服务网格(ASM)以实现在多集群环境下,服务间的优先访问及故障转移策略。
94 2
|
1月前
|
监控 供应链 安全
构建高效微服务架构:API网关与服务熔断策略
【7月更文挑战第38天】随着现代应用程序向微服务架构的转型,系统的稳定性和效率成为了开发团队关注的焦点。本文将探讨在微服务环境中实现系统可靠性的关键组件——API网关,以及如何在服务间通讯时采用熔断机制来防止故障蔓延。通过分析API网关的核心功能和设计原则,并结合熔断策略的最佳实践,我们旨在提供一套提高分布式系统弹性的策略。
|
1月前
|
负载均衡 Java 应用服务中间件
Gateway服务网关
本节针对微服务中另一重要组件:网关 进行了实战性演练,网关作为分布式架构中的重要中间件,不仅承担着路由分发(重点关注Path规则配置),同时可根据自身负载均衡策略,对多个注册服务实例进行均衡调用。本节我们借助GateWay实现的网关只是技术实现的方案之一,后续大家可能会接触像:Zuul、Kong等,其实现细节或有差异,但整体目标是一致的。
|
2月前
|
监控 负载均衡 Java
深入理解Spring Cloud中的服务网关
深入理解Spring Cloud中的服务网关
|
4月前
|
运维 网络协议 安全
长连接网关技术专题(十):百度基于Go的千万级统一长连接服务架构实践
本文将介绍百度基于golang实现的统一长连接服务,从统一长连接功能实现和性能优化等角度,描述了其在设计、开发和维护过程中面临的问题和挑战,并重点介绍了解决相关问题和挑战的方案和实践经验。
217 1
|
4月前
|
缓存 安全 API
【亿级数据专题】「高并发架构」盘点本年度探索对外服务的百万请求量的API网关设计实现
公司对外开放的OpenAPI-Server服务,作为核心内部系统与外部系统之间的重要通讯枢纽,每天处理数百万次的API调用、亿级别的消息推送以及TB/PB级别的数据同步。经过多年流量的持续增长,该服务体系依然稳固可靠,展现出强大的负载能力。
151 9
【亿级数据专题】「高并发架构」盘点本年度探索对外服务的百万请求量的API网关设计实现