【问题标题】:How to redirect HTTP to HTTPS using GCP load balancer如何使用 GCP 负载平衡器将 HTTP 重定向到 HTTPS
【发布时间】:2018-12-06 09:25:30
【问题描述】:

我正在 GCP 中设置我的负载均衡器,它有 2 个节点 (Apache httpd),域为 lblb.tonegroup.net。

目前我的负载均衡器工作正常,流量在 2 个节点之间切换,但我如何配置将 http://lblb.tonegroup.net 重定向到 https://lblb.tonegroup.net

是否可以在负载均衡器级别进行配置,或者我需要在 apache 级别进行配置?我已安装 Google 托管 SSL 证书,仅供参考。

【问题讨论】:

标签: linux apache google-cloud-platform load-balancing


【解决方案1】:

现在可以通过负载均衡器的流量管理从 http 重定向到 https

以下是如何在其文档中进行设置的示例: https://cloud.google.com/load-balancing/docs/https/setting-up-traffic-management#console

基本上,您将创建两个“转发规则”,targetproxy 和 urlmap。

2 个 URLMaps

  • 在第一个 URL 映射中,您只需设置一个重定向。定义重定向规则如下,这里不需要定义后端服务
    • httpsRedirect: true
    • redirectResponseCode: FOUND
  • 在第二张地图中,您必须在那里定义您的后端服务

2条转发规则

  • 第一个转发规则是服务于 http 请求,所以基本上是端口 80
  • 第二个转发规则是服务http请求所以端口443

2 个目标代理

  • 第一个目标代理是targetHttpProxy,这将是第一个转发规则被转发到并映射到第一个URLMap的地方
  • 第二个目标代理是targetHttpsProxy,第二个转发规则被转发到并映射到第二个URLMap

================================================ ==========================

下面是一个以托管证书和存储桶作为后端的云部署管理器示例

storagebuckets-template.jinja

resources:
- name: {{ properties["bucketExample"] }}
  type: storage.v1.bucket
  properties:
    storageClass: REGIONAL
    location: asia-east2
    cors:
    - origin: ["*"]
      method: [GET]
      responseHeader: [Content-Type]
      maxAgeSeconds: 3600
    defaultObjectAcl:
    - bucket: {{ properties["bucketExample"] }}
      entity: allUsers
      role: READER
    website:
     mainPageSuffix: index.html

backendbuckets-template.jinja

resources:
- name: {{ properties["bucketExample"] }}-backend
  type: compute.beta.backendBucket
  properties:
    bucketName: $(ref.{{ properties["bucketExample"] }}.name)
    enableCdn: true

ipaddresses-template.jinja

resources:
- name: lb-ipaddress
  type: compute.v1.globalAddress

sslcertificates-template.jinja

resources:
- name: example
  type: compute.v1.sslCertificate
  properties:
    type: MANAGED
    managed:
      domains:
      - example1.com
      - example2.com
      - example3.com

loadbalancer-template.jinja

resources:
- name: centralized-lb-http
  type: compute.v1.urlMap
  properties:
    defaultUrlRedirect:
      httpsRedirect: true
      redirectResponseCode: FOUND
- name: centralized-lb-https
  type: compute.v1.urlMap
  properties:
    defaultService: {{ properties["bucketExample"] }}
    pathMatchers:
    - name: example
      defaultService: {{ properties["bucketExample"] }}
      pathRules:
      - service: {{ properties["bucketExample"] }}
        paths:
        - /*
    hostRules:
    - hosts:
      - example1.com
      pathMatcher: example
    - hosts:
      - example2.com
      pathMatcher: example
    - hosts:
      - example3.com
      pathMatcher: example

httpproxies-template.jinja

resources:
- name: lb-http-proxy
  type: compute.v1.targetHttpProxy
  properties:
    urlMap: $(ref.centralized-lb-http.selfLink)
- name: lb-https-proxy
  type: compute.v1.targetHttpsProxy
  properties:
    urlMap: $(ref.centralized-lb-https.selfLink)
    sslCertificates: [$(ref.example.selfLink)]
- name: lb-http-forwardingrule
  type: compute.v1.globalForwardingRule
  properties:
    target: $(ref.lb-http-proxy.selfLink)
    IPAddress: $(ref.lb-ipaddress.address)
    IPProtocol: TCP
    portRange: 80-80
- name: lb-https-forwardingrule
  type: compute.v1.globalForwardingRule
  properties:
    target: $(ref.lb-https-proxy.selfLink)
    IPAddress: $(ref.lb-ipaddress.address)
    IPProtocol: TCP
    portRange: 443-443

templates-bundle.yaml

 imports:
 - path: backendbuckets-template.jinja
 - path: httpproxies-template.jinja
 - path: ipaddresses-template.jinja
 - path: loadbalancer-template.jinja
 - path: storagebuckets-template.jinja
 - path: sslcertificates-template.jinja

resources:
 - name: storagebuckets
   type: storagebuckets-template.jinja
   properties:
     bucketExample: example-sb
 - name: backendbuckets
   type: backendbuckets-template.jinja
   properties:
     bucketExample: example-sb
 - name: loadbalancer
   type: loadbalancer-template.jinja
   properties:
     bucketExample: $(ref.example-sb-backend.selfLink)
 - name: ipaddresses
   type: ipaddresses-template.jinja
 - name: httpproxies
   type: httpproxies-template.jinja
 - name: sslcertificates
   type: sslcertificates-template.jinja

$ gcloud deployment-manager deployments create infrastructure --config=templates-bundle.yaml > output 命令输出

 NAME                                   TYPE                             STATE      ERRORS  INTENT
 centralized-lb-http                    compute.v1.urlMap                COMPLETED  []
 centralized-lb-https                   compute.v1.urlMap                COMPLETED  []
 example                                compute.v1.sslCertificate        COMPLETED  []
 example-sb                             storage.v1.bucket                COMPLETED  []
 example-sb-backend                     compute.beta.backendBucket       COMPLETED  []
 lb-http-forwardingrule                 compute.v1.globalForwardingRule  COMPLETED  []
 lb-http-proxy                          compute.v1.targetHttpProxy       COMPLETED  []
 lb-https-forwardingrule                compute.v1.globalForwardingRule  COMPLETED  []
 lb-https-proxy                         compute.v1.targetHttpsProxy      COMPLETED  []
 lb-ipaddress                           compute.v1.globalAddress         COMPLETED  []

【讨论】:

    【解决方案2】:

    我相信Alexandre之前提供的答案是正确的;目前,在使用 HTTP(S) 负载均衡器时,无法将所有 HTTP 流量重定向到 HTTPS。我发现已经为此功能提交了功能请求;您可以使用此link 访问它并添加您的评论。

    您还提到您正在使用 Google 管理的 SSL 证书,但我发现的唯一解决方法是在服务器级别重定向它。在这种情况下,您将不得不使用self-managed SSL certificate.

    要将 HTTP URL 重定向到 HTTPS,请在 Apache 服务器中执行以下操作:

    <VirtualHost *:80>
        ServerName www.example.com
        Redirect "/" "https://www.example.com/"
    </VirtualHost>
    
    <VirtualHost *:443>
        ServerName www.example.com
        # ... SSL configuration goes here
    </VirtualHost>
    

    您必须配置一个 Apache 服务器配置文件。详情请参阅apache.org documentation on Simple Redirection

    【讨论】:

    • 在通过负载均衡器请求时,在单个 VM 实例上重定向无济于事,因为重定向发生在两者之间。
    【解决方案3】:

    无法直接在 GCP 负载均衡器上执行此操作。

    一种可能性是在您的后端服务上进行重定向。 GCP Loader 平衡器在请求标头中添加 x-forwarded-proto 属性,该属性等于 http 或 https。您可以根据此属性添加条件以进行重定向。

    【讨论】:

    • 我发现我需要使用 301 重定向而不是 302 重定向(如果您使用的是 nodejs,这是快速“重定向”方法中的默认值)
    • 这是答案,尤其是加上serverfault.com/questions/502733/…
    【解决方案4】:

    也许为时已晚,但我遇到了同样的问题,这里有我的解决方案:

    1. 在 GCP 负载平衡器上配置两个前端(HTTP 和 HTTPS)。
    2. 将端口 80(http 协议)设置为与后端服务和最终 VM 通信。
    3. 在后端服务中添加 Google 变量:{tls_version} 作为 X-SSL-Protocol 自定义标头。
    4. 在最终服务器上根据X-SSL-Protocol 值执行重定向:
    5. 如果为空(无 https),则重定向(301),否则什么也不做。

    您可以在 Web 服务器上或从中间负载平衡器 VM 实例检查标头值。我的 HAProxy 案例:

    frontend fe_http
            bind *:80
            mode http
            #check if value is empty
            acl is_http res.hdr(X-SSL-Protocol) -m len 0
            #perform redirection only if no value found in custom header
            redirect scheme https code 301 if is_http
            #when redirect is performed, subsequent instructions are not reached
            default_backend bk_http1
    

    【讨论】:

      【解决方案5】:

      如果您使用Terraform(强烈推荐用于 GCP 配置),这里有一个示例配置。此代码创建两个 IP 地址(v4 和 v6)——您也可以在 https 转发规则中使用它们。

      // HTTP -> HTTPS redirector
      resource "google_compute_url_map" "http-to-https" {
        name = "my-http-to-https"
      
        default_url_redirect {
          https_redirect         = true
          strip_query            = false
          redirect_response_code = "PERMANENT_REDIRECT"
        }
      }
      
      resource "google_compute_target_http_proxy" "proxy" {
        name    = "my-http-proxy"
        url_map = google_compute_url_map.http-to-https.self_link
      }
      
      resource "google_compute_global_forwarding_rule" "http-v4" {
        name       = "my-fwrule-http-v4"
        target     = google_compute_target_http_proxy.proxy.self_link
        ip_address = google_compute_global_address.IPv4.address
        port_range = "80"
      }
      
      resource "google_compute_global_forwarding_rule" "http-v6" {
        name       = "my-fwrule-http-v6"
        target     = google_compute_target_http_proxy.proxy.self_link
        ip_address = google_compute_global_address.IPv6.address
        port_range = "80"
      }
      
      resource "google_compute_global_address" "IPv4" {
        name = "my-ip-v4-address"
      }
      
      resource "google_compute_global_address" "IPv6" {
        name       = "my-ip-v6-address"
        ip_version = "IPV6"
      }
      

      【讨论】:

        【解决方案6】:

        概括地说,要将 HTTP 流量重定向到 HTTPS,您必须执行以下操作:

        1. 创建 HTTPS LB1(此处称为 web-map-https)。
        2. 使用 LB1 中使用的相同 IP 地址和 URL 映射中配置的重定向创建 HTTP LB2(无后端)(此处称为 web-map-http)。

        请检查: https://cloud.google.com/load-balancing/docs/https/setting-up-http-https-redirect

        【讨论】:

          【解决方案7】:

          也许我迟到了,但我使用了以下内容:

          [ingress.yaml]:

          apiVersion: networking.k8s.io/v1
          kind: Ingress
          metadata:
            name: managed-cert-ingress
            annotations:
              kubernetes.io/ingress.global-static-ip-name: my-external-ip
              networking.gke.io/managed-certificates: my-google-managed-certs
              kubernetes.io/ingress.class: "gce"
              networking.gke.io/v1beta1.FrontendConfig: redirect-frontend-config
          spec:
            defaultBackend:
              service:
                name: online-service
                port:
                  number: 80
          

          [重定向前端配置.yaml]

          apiVersion: networking.gke.io/v1beta1
          kind: FrontendConfig
          metadata:
            name: redirect-frontend-config
          spec:
            redirectToHttps:
              enabled: true
          

          我使用的是默认的“301 Moved Permanently”,但如果您想使用其他内容,只需在包含以下内容的 redirectToHttps 下添加一行

          responseCodeName: <CHOSEN REDIRECT RESPONSE CODE>
          

          MOVED_PERMANENTLY_DEFAULT 返回 301 重定向响应代码(默认)。

          发现返回 302 重定向响应代码。

          SEE_OTHER 返回 303 重定向响应代码。

          TEMPORARY_REDIRECT 返回 307 重定向响应代码。

          PERMANENT_REDIRECT 返回 308 重定向响应代码。

          进一步阅读 https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features https://cloud.google.com/kubernetes-engine/docs/concepts/ingress

          【讨论】:

            猜你喜欢
            • 2017-04-18
            • 2016-09-13
            • 1970-01-01
            • 2015-03-18
            • 2020-02-04
            • 1970-01-01
            • 2017-02-20
            • 2016-03-14
            • 2018-06-07
            相关资源
            最近更新 更多