首页 > 解决方案 > Istio:如何重定向到 HTTPS,除了 /.well-known/acme-challenge

问题描述

我希望流量以 HTTP 的形式进入我的集群以重定向到 HTTPS。但是,集群接收来自数百个动态变化的域的请求(使用 cert-manager 创建新证书)。所以我希望重定向仅在 URI 没有前缀时发生/.well-known/acme-challenge

我正在使用一个监听 443 的网关和一个监听 80 并将 HTTP 发送到 acme-solver 虚拟服务的网关。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: default-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - site1.com
    port:
      name: https-site1.com
      number: 443
      protocol: HTTPS
    tls:
      credentialName: cert-site1.com
      mode: SIMPLE
  - hosts:
    - site2.com
    port:
      name: https-site2.com
      number: 443
      protocol: HTTPS
    tls:
      credentialName: cert-site2.com
      mode: SIMPLE
  ...
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: acme-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*'
    port:
      name: http
      number: 80
      protocol: HTTP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: acme-solver
  namespace: istio-system
spec:
  hosts:
  - "*"
  gateways:
  - acme-gateway
  http:
  - match:
    - uri:
        prefix: /.well-known/acme-challenge
    route:
    - destination:
        host: acme-solver.istio-system.svc.cluster.local
        port:
          number: 8089
  - redirect:
      authority: # Should redirect to https://$HOST, but I don't know how to get the $HOST

我怎样才能使用 istio 做到这一点?

标签: kuberneteshttpsistiocert-manageracme

解决方案


查看文档:

  • HTTP-01 质询只能在端口 80 上完成。允许客户端指定任意端口会降低质询的安全性,因此 ACME 标准不允许这样做。

作为一种解决方法:

  1. 请考虑使用 DNS-01 质询:

a) 只有当您的 DNS 提供商有一个 API 可用于自动更新时,使用 DNS-01 挑战才有意义。

b)使用这种方法,您应该考虑文档中所述的额外安全风险:

优点:您可以使用此挑战来颁发包含通配符域名的证书。即使您有多个 Web 服务器,它也能正常工作。

缺点: *在您的 Web 服务器上保存 API 凭证是有风险的。 您的 DNS 提供商可能不提供 API。您的 DNS API 可能不会提供有关传播时间的信息。

如此处所述:

但是,为了实现自动化,请求证书的软件还需要能够修改该域的 DNS 记录。为了修改 DNS 记录,该软件还需要访问 DNS 服务的凭证(例如登录名和密码,或加密令牌),并且这些凭证必须存储在自动化发生的任何地方。在许多情况下,这意味着如果处理该进程的机器受到威胁,DNS 凭据也会受到威胁,这就是真正的危险所在。


  1. 我还建议使用另一种方法来使用一些简单的 nginx pod,它将所有 http 流量重定向到 https。

您可以尝试使用有关带有 nginx 配置的介质的教程。

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    server {
      listen 80 default_server;
      server_name _;
      return 301 https://$host$request_uri;
    }
---
apiVersion: v1
kind: Service
metadata:
  name: redirect
  labels:
    app: redirect
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: redirect
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redirect
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redirect
  template:
    metadata:
      labels:
        app: redirect
    spec:
      containers:
      - name: redirect
        image: nginx:stable
        resources:
          requests:
            cpu: "100m"
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /etc/nginx/conf.d
          name: config
      volumes:
      - name: config
        configMap:
          name: nginx-config

此外,您必须更改您的虚拟服务以发送除prefix: /.well-known/acme-challengenginx 之外的所有流量。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: acme-solver
  namespace: istio-system
spec:
  hosts:
  - "*"
  gateways:
  - acme-gateway
  http:
  - name: "acmesolver"
    match:
    - uri:
        prefix: /.well-known/acme-challenge
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        port:
          number: 8089
  - name: "nginx"
    route:
    - destination:
        host: nginx

推荐阅读