写点什么

Flomesh Ingress 使用实践(二)TLS 进阶

作者:Flomesh
  • 2023-02-03
    北京
  • 本文字数:3225 字

    阅读完需:约 11 分钟

Flomesh Ingress 使用实践(二)TLS 进阶

在上一篇 Flomesh Ingress 基础功能 介绍中,我们使用 Flomesh Ingress 实现了 HTTPS 入口。实际上从客户端到上游应用会有如下的集中组合方式:


  • 客户端 -> HTTP Ingress -> HTTP Upstream

  • 客户端 -> HTTPS Ingress -> HTTP Upstream

  • 客户端 -> HTTP Ingress -> HTTPS Upstream

  • 客户端 -> HTTPS Ingress -> HTTPS Upstream


其中前两种已经做了实现,这篇将会介绍后两种模式所使用的 HTTPS 上游,以及基于 HTTPS 入口的客户端验证。这两种 TLS 的应用也是在 mTLS 中用到的。


  • HTTPS 上游:需要针对上游也就是后端服务的证书进行检查

  • 客户端验证:主要是使用 HTTPS 入口时,对客户端使用的证书进行检查

演示


继续使用之前的环境,和提供了 HTTP 8000 和 HTTPS 8443 访问的示例应用。

安装 Flomesh Ingress

通过 Helm 安装 fsm。


helm repo add fsm https://flomesh-io.github.io/fsmhelm repo update
helm install \ --namespace fsm \ --create-namespace \ --set fsm.version=0.2.1-alpha.2 \ --set fsm.ingress.tls.enabled=true \ --set fsm.serviceLB.enabled=true \ fsm fsm/fsm
复制代码

示例应用

这里使用的示例应用同时提供了 HTTP 8000 和 HTTPS 8443 访问,有下面几个 path


  • / 返回一个简单的 HTML 页面

  • /hi 返回 200 Hi, there!

  • /api/private 返回 401 Staff only


为了提供 HTTPS,需要为应用先签发 ca 和服务端证书。


openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 365000 \ -key ca-key.pem \ -out ca-cert.pem \ -subj '/CN=flomesh.io'
openssl genrsa -out server-key.pem 2048openssl req -new -key server-key.pem -out server.csr -subj '/CN=example.com'openssl x509 -req -in server.csr -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 365
复制代码


部署示例应用,先创建 Secret 将证书和密钥保存在 secret 中并挂载到应用 pod 中。


kubectl create namespace httpbin# mount self-signed cert to sample app pod via secretkubectl create secret generic -n httpbin server-cert \  --from-file=./server-cert.pem \  --from-file=./server-key.pem
kubectl apply -n httpbin -f - <<EOFapiVersion: v1kind: ServiceAccountmetadata: name: httpbin---apiVersion: v1kind: Servicemetadata: name: httpbin labels: app: httpbin service: httpbinspec: ports: - port: 8443 name: https - port: 8000 name: http selector: app: httpbin---apiVersion: apps/v1kind: Deploymentmetadata: name: httpbin labels: app: httpbinspec: replicas: 1 selector: matchLabels: app: httpbin template: metadata: labels: app: httpbin spec: containers: - name: pipy image: addozhang/httpbin:latest env: - name: PIPY_CONFIG_FILE value: /etc/pipy/tutorial/gateway/main.js ports: - containerPort: 8443 - containerPort: 8000 volumeMounts: - name: cert mountPath: "/etc/pipy/tutorial/gateway/secret" readOnly: true volumes: - name: cert secret: secretName: server-certEOF
复制代码

HTTPS 上游

这个示例用于演示 FSM Ingress 如何将请求发送到 HTTPS 后端。Flomesh Ingress 提供了如下 3 个注解:


  • pipy.ingress.kubernetes.io/upstream-ssl-name:上游服务的 SNI,如 example.com

  • pipy.ingress.kubernetes.io/upstream-ssl-secret:包含 TLS 证书的 secret,格式为 SERECT_NAME 或者 NAMESPACE/SECRET_NAME,如 httpbin/tls-cert

  • pipy.ingress.kubernetes.io/upstream-ssl-verify:是否对上游的证书进行校验,默认为 false,即证书校验失败也会继续完成连接的建立。


在下面的 Ingress 资源示例中,通过注解 pipy.ingress.kubernetes.io/upstream-ssl-secret 指定了命名空间 httpbin 下包含 TLS 证书的 secret tls-cert


apiVersion: networking.k8s.io/v1kind: Ingressmetadata:  name: httpbin  annotations:    pipy.ingress.kubernetes.io/upstream-ssl-secret: httpbin/tls-cert    pipy.ingress.kubernetes.io/upstream-ssl-verify: 'true'spec:  ingressClassName: pipy  rules:  - host: example.com    http:      paths:        - path: /          pathType: Prefix          backend:            service:              name: httpbin              port:                number: 8443
复制代码


使用证书和密钥创建 secret tls-cert


kubectl create secret generic -n httpbin tls-cert \  --from-file=ca.crt=./ca-cert.pem
复制代码


应用上面的 Ingress 配置,然后使用 HTTP 入口来访问 HTTPS 上游应用。


curl http://example.com/hi --connect-to example.com:80:$HOST_IP:80Hi, there!
复制代码


检查 fsm-ingress-pipy-xxx pod 的日志,可以看到连接到的是上游的 HTTPS 8443 端口。


ingress 2023-01-31 09:05:03.285 [INF] [balancer] _sourceIP 10.42.0.1                                                                                                                                           ingress 2023-01-31 09:05:03.285 [INF] [balancer] _connectTLS true                                                                                                                                              ingress 2023-01-31 09:05:03.285 [INF] [balancer] _target.id 10.42.0.20:8443
复制代码

客户端证书校验

这个示例了演示了在开启 TLS 卸载以及 mTLS 的情况下,对客户端证书进行验证。


在使用 mTLS 功能之前,确保 FSM Ingress 已经启用并配置了 TLS,需要再 FSM 安装时提供参数 --set fsm.serviceLB.enabled=true


要启用 mTLS 功能,可以在 FSM Ingress 时通过参数 --set fsm.ingress.tls.mTLS=true 开启,或者在安装后修改配置来开启。具体操作是修改 FSM 命名空间下的 ConfigMap fsm-mesh-config,将 tls.mTLS 的值设置为 true


在 FSM Ingress 中,提供了注解 pipy.ingress.kubernetes.io/tls-trusted-ca-secret 来配置可信的客户端证书。


apiVersion: networking.k8s.io/v1kind: Ingressmetadata:  name: httpbin  annotations:    pipy.ingress.kubernetes.io/tls-trusted-ca-secret: httpbin/trust-client-certspec:  ingressClassName: pipy  rules:  - host: example.com    http:      paths:        - path: /          pathType: Prefix          backend:            service:              name: httpbin              port:                number: 8000  tls:  - hosts:    - example.com    secretName: ingress-cert
复制代码


为 Ingress 签发自签名证书。


openssl req -x509 -newkey rsa:4096 -keyout ingress-key.pem -out ingress-cert.pem -sha256 -days 365 -nodes -subj '/CN=example.com'
复制代码


使用证书和密钥创建 Secret。


kubectl create secret tls ingress-cert --cert=ingress-cert.pem --key=ingress-key.pem -n httpbin
复制代码


为客户端签发自签名证书。


openssl req -x509 -newkey rsa:4096 -keyout client-key.pem -out client-cert.pem -sha256 -days 365 -nodes -subj '/CN=flomesh.io'
复制代码


使用客户端证书作为内容创建 Secret。


kubectl create secret generic -n httpbin trust-client-cert \  --from-file=ca.crt=./client-cert.pem
复制代码


应用上面的 Ingress 配置。


curl --cacert ingress-cert.pem --cert client-cert.pem --key client-key.pem https://example.com/hi --connect-to example.com:443:$HOST_IP:443Hi, there!
复制代码


发布于: 刚刚阅读数: 5
用户头像

Flomesh

关注

微信订阅号:flomesh 2022-04-07 加入

一站式云原生应用流量管理供应商 官网:https://flomesh.io

评论

发布
暂无评论
Flomesh Ingress 使用实践(二)TLS 进阶_HTTP_Flomesh_InfoQ写作社区