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

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 阿里云服务网格(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 ]=-
       _...._
     .'  _ _ `.
    | ."` ^ `". _,
    \_;`"---"`|//
      |       ;/
      \_     _/
        `"""`
目录
相关文章
|
1月前
|
安全 5G 网络性能优化
|
2月前
|
监控 负载均衡 安全
微服务(五)-服务网关zuul(一)
微服务(五)-服务网关zuul(一)
|
12天前
|
负载均衡 Java 应用服务中间件
Gateway服务网关
Gateway服务网关
27 1
Gateway服务网关
|
1月前
|
前端开发 Java API
vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
本文是Vert.x学习系列的第五部分,讨论了回调函数的限制、Future和Promise在异步操作中的应用、响应式扩展以及Kotlin协程,并通过示例代码展示了如何在Vert.x中使用这些异步编程模式。
47 5
vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
|
2月前
|
测试技术 微服务
微服务(八)-服务网关zuul(四)
微服务(八)-服务网关zuul(四)
|
2月前
|
监控 前端开发 Java
微服务(七)-服务网关zuul(三)
微服务(七)-服务网关zuul(三)
|
2月前
|
负载均衡 前端开发 安全
微服务(六)-服务网关zuul(二)
微服务(六)-服务网关zuul(二)
|
3月前
|
Java API 微服务
服务网关Gateway
该博客文章详细介绍了Spring Cloud Gateway的使用方法和概念。文章首先阐述了API网关在微服务架构中的重要性,解释了客户端直接与微服务通信可能带来的问题。接着,文章通过具体的示例代码,展示了如何在Spring Cloud Gateway中添加依赖、编写路由规则,并对路由规则中的基本概念如Route、Predicate和Filter进行了详细解释。最后,文章还提供了路由规则的测试方法。
服务网关Gateway
|
3月前
|
Kubernetes 安全 Cloud Native
解锁安全新纪元:利用服务网格Istio,打造全链路mTLS加密隧道,从入口网关到出口网关,守护数据安全的每一步
【8月更文挑战第2天】随着云原生技术的发展,服务网格(Service Mesh)如Istio已成为微服务架构的核心,通过双向TLS(mTLS)确保通信安全。首先,在Kubernetes部署Istio以管理服务通信。接着,配置入口网关实现所有入向流量的加密处理,防止数据泄露。最后,通过配置Sidecar代理如Envoy,确保服务网格安全访问外部mTLS服务,从而构建起全链路的数据安全防护。
80 11
|
3月前
|
Prometheus Kubernetes 监控
打造无缝灾备新境界:运用服务网格ASM,将集群外服务无缝融入集群内服务,铸就高可用性坚盾!
【8月更文挑战第2天】随着微服务架构的应用,服务的高可用性变得至关重要。服务网格如阿里巴巴的ASM提供流量管理、服务发现等功能,支撑高可靠服务系统。本文介绍如何利用ASM实现集群外服务作为集群内服务的灾备方案,确保服务连续性。先决条件包括已部署ASM的Kubernetes集群环境及内外部的关键服务副本。通过定义服务条目、配置虚拟服务和目的地规则,可实现自动或手动故障转移。借助ASM的流量管理能力,确保服务高可用性和业务连续性。
52 10